CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Ground potential on ADC

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
SkeeterHawk



Joined: 16 Oct 2010
Posts: 31
Location: Florissant, CO

View user's profile Send private message

Ground potential on ADC
PostPosted: Sun May 06, 2012 1:59 am     Reply with quote

Hello all,

I am new to writing C, but have been writing assembly for over 10 years, so I am trying to adapt.

My main problem is that I have some ground potential between my analog measurement and the - reference on the PIC. When I am reading my ADC, it will go towards ground until (right at the end of the sweep) it loops back around and all of the MSBs are populated. I am assuming that it is going to a signed integer at this point and all of the bits is just telling me it is negative. Should I just test the MSB and hard-code the register to zero when it is set? I am sure others have dealt with this, so I would appreciate the insight. My search through the forum wasn't fruitful.

Can you point me to some tips on using the watch windows? I must be missing something. The only way I can see my variables is to make them global. I'm using PCWHD with the IDE, so hopefully this question will be a "piece of cake"

Thanks so much for your insight.
_________________
Life is too short to only write code in assembly...
Mike Walne



Joined: 19 Feb 2004
Posts: 1785
Location: Boston Spa UK

View user's profile Send private message

PostPosted: Sun May 06, 2012 2:23 am     Reply with quote

Quote:

My main problem is that I have some ground potential between my analog measurement and the - reference on the PIC. When I am reading my ADC, it will go towards ground until (right at the end of the sweep) it loops back around and all of the MSBs are populated. I am assuming that it is going to a signed integer at this point and all of the bits is just telling me it is negative.

Anything could be happening when you take your analogue input negative relative to the PIC GND.
Quote:

Should I just test the MSB and hard-code the register to zero when it is set? I am sure others have dealt with this, so I would appreciate the insight. My search through the forum wasn't fruitful.

MSBs read 1 at the other end of the scale.

How would you know which end you are at?

In my view work on the KISS principal, get rid of the GND offset problem.
Quote:

Can you point me to some tips on using the watch windows? I must be missing something. The only way I can see my variables is to make them global. I'm using PCWHD with the IDE, so hopefully this question will be a "piece of cake"

I'm still using PIC16/18's. I expect to see the non-global variables when I'm in the section of code where they're being used. Elsewhere their values are irrelevant.

Mike
Ttelmah



Joined: 11 Mar 2010
Posts: 19561

View user's profile Send private message

PostPosted: Sun May 06, 2012 4:17 am     Reply with quote

The ADC, _only_ reports unsigned.
What it is reporting is basically undefined.

_Unlike_ the digital inputs, which support operation potentially to Vss-0.3v at the bottom of their range, the analog inputs are _only_ allowed to be in the range Vref- to Vref+. If an input goes below Vref-, it goes below the input range of the comparator used inside the ADC, giving an indeterminate result, and also will reverse bias the FET's in the input multiplexor, potentially affecting other inputs (if you are using multiple ADC channels).

You _need_ to arrange your analog input circuitry to keep the voltage inside the legal range for the ADC. Typically use a buffer op-amp, and add an offset voltage to ensure the PIC input never goes negative.

Depending on your PIC, some will allow Vref- to be taken negative of Vss to as low as AVss-0.3v. and sample a tiny way below 0v. If the amount your signals go negative is small, you might want to look at this.

Best Wishes
SkeeterHawk



Joined: 16 Oct 2010
Posts: 31
Location: Florissant, CO

View user's profile Send private message

Forcing it to go...
PostPosted: Sun May 06, 2012 12:18 pm     Reply with quote

Thank you both for your feedback. It seemed that I was getting into an undefined state, that is why I am asking for opinions before I bit-bang some ugly code because that is where I immediately go being so fresh from assembly. I am reading a 12-bit result in a 16-bit integer. The only time my MSB is set (as has been observed) is when it hits this state.

My potential is only 30mV, which is well within the max specification for the 18F87K90 that I am using of 300mV. Unfortunately I don't have the luxury of being able to re-route my reference and make a star ground as this obviously needs because I have over 80 bare boards produced already with this design. Unfortunately I have a trim-pot right next to the power entry and there is some potential on the ground trace coming from the chip, lifting up the ground for the PIC, and the associated reference.

So, I am stuck with the analog design and its idiosyncrasies. I don't feel that I am in danger of smoking the PIC, so I don't have to raise the white flag and call for a redesign. Unless some of you have a more elegant way of approaching this, I am probably going to do something "caveman", like this:

result = read_adc();
if (result && 0x08000)
result = 0;

Maybe this won't work at all, but you can see the neanderthal approach I am taking. Is this the right direction to go to solve this problem? C is such a program of elegance, and I am a long way from elegant at this point Embarassed Thanks so much for your elegant insight.
_________________
Life is too short to only write code in assembly...
SkeeterHawk



Joined: 16 Oct 2010
Posts: 31
Location: Florissant, CO

View user's profile Send private message

Update
PostPosted: Sun May 06, 2012 1:21 pm     Reply with quote

Hello again,

I have been testing it to verify that what I said was true, and it is. I still can't get a watch window to show a local variable for some reason no matter where my cursor is when I invoke it.

Regardless, on the analog point, I am reading a clean 16-bit result through the entire sweep of my trimpot with the top nybble being all 0's as it should be. When I get down to 0 bits it will roll over to all 1's and pretty much stay there until the signal is increased.

Since it is consistent, and I am only losing 30mV of a 5V signal, which is 0.6%, I think I can live with that. Is the code I mentioned earlier the most elegant way to tackle this? Thanks again!

update - It seems to be working using:
If (result >= 0x0FFF)
result = 0;

Let me know if this isn't a good way to do it. Thanks again for your input.
_________________
Life is too short to only write code in assembly...
Mike Walne



Joined: 19 Feb 2004
Posts: 1785
Location: Boston Spa UK

View user's profile Send private message

PostPosted: Tue May 08, 2012 2:51 am     Reply with quote

I still don't like a software fudge. If you are certain that NO other condition sets the MSB's you're testing then you may get away with it.

How many analogue inputs are you using? If it's only the one (or a few) I'd be tempted to dab a resistor from analogue signal to +5V and bring the analogue voltage above GND at all times.

Could you cut the power input GND pin and re-route to the PIC GND pin?

You know your layout, so I'm sure you can work it out.



I compiled and single stepped through this code with MPLAB SIM:-
Code:

///////////////////////////////////////////////
//     Watch Window demo                     //
///////////////////////////////////////////////
#include <18F458.h>

#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=4000000)
void test_loop();

int8 i;

void main()
{
  while (1)
  {
    i++;
    test_loop();
  }
}
 
void test_loop()
{
int8 j;

   j++;
   j++;
}

I put i and j into a watch window.

The i value showed all the time.

The j value read "out of scope" except when I was stepping through the test_loop() section.

Mike
Ttelmah



Joined: 11 Mar 2010
Posts: 19561

View user's profile Send private message

PostPosted: Tue May 08, 2012 2:56 am     Reply with quote

Yes, and yes.

Worth realising that a variable _doesn't even exist_, when you are outside the function. The memory it uses can be used for other variables, hence there is no way it can be displayed. Things that exist, are:
1) Global variables.
2) Variables declared in a function, exist when you are in every function called 'from' that function.
3) Static variables.

Best Wishes
RF_Developer



Joined: 07 Feb 2011
Posts: 839

View user's profile Send private message

PostPosted: Tue May 08, 2012 7:20 am     Reply with quote

Caveman? Ughh!
Quote:

result = read_adc();
if (result && 0x08000)
result = 0;


If this was to work you'd want '&' not '&&'. '&' is the bitwise and, used on multi-bit variables, '&&' is the logical and, and is used to and two logical conditions, or single bit variables.

Quote:

update - It seems to be working using:
If (result >= 0x0FFF)
result = 0;


It might be "working", but its not correct. 0x0FFF is the full range value for 12 bit ADCs. In your code you set the result to zero if is greater OR EQUAL to 0x0FFF. That means you'll set all full range readings, and overranges to zero. That may be OK for you, but it wouldn't be good for all applications.

In any event, the undefined readings, probably caused by illegal input voltages, i.e. lower than the analogue reference voltage, are a clear sign that the PIC is being operated outside its working limits. It may work, it may not, it may not be reliable, or work for a long time. This example might work, another might not. All in all its not good engineering practice, and frankly asking for trouble, to operate these PICs like this. I HAVE blown up PICs, PIC18F8585s in fact, through applying negative voltages to their analogue inputs. Some with full-on blue smoke. So it can happen.

Having such voltages around suggests either your analogue sensing is far away from the PIC and you have long wires, or you have high currents flowing in your grounds, or there is RF or similar floating around causing big-time ground issues. All are not good. What is the cause in your system?

RF Developer
SkeeterHawk



Joined: 16 Oct 2010
Posts: 31
Location: Florissant, CO

View user's profile Send private message

PostPosted: Tue May 08, 2012 10:09 am     Reply with quote

RF_Developer wrote:

Quote:

update - It seems to be working using:
If (result >= 0x0FFF)
result = 0;


It might be "working", but its not correct. 0x0FFF is the full range value for 12 bit ADCs. In your code you set the result to zero if is greater OR EQUAL to 0x0FFF. That means you'll set all full range readings, and overranges to zero.


You are absolutely right. I didn't think of that since my signal was effectively offset by 30mV. I was never seeing the "all ones" state...yet, but that certainly would have occurred and been ugly as sin.


RF_Developer wrote:

...the undefined readings...are a clear sign that the PIC is being operated outside its working limits.


I agree. Point taken. I will have to see what I can do to eliminate the potential. Another sign something was up was that the debugger would take a couple seconds to step through that routine when in this state, when otherwise it was as fast as you can hit the step button.

RF_Developer wrote:

Having such voltages around suggests either your analogue sensing is far away from the PIC and you have long wires, or you have high currents flowing in your grounds,


All of the above pretty much. My sensors are at the power entry and there are some LEDs on the other side of the board, and it is all returning the whole way across the board. Unfortunately I didn't lay this board out myself, and I forgot to address a star ground on my spec. Now I am paying the price.

Thank you, one and all, for your help on this topic...though a bitter pill is hard to swallow, I will see what I can do to eliminate the possibility of the potential in hardware. Drat!...and double-Drat! Evil or Very Mad

Thanks again.
_________________
Life is too short to only write code in assembly...
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group