return from AnalogueIn .. is it really rounded to 1 dp.

30 Oct 2009 . Edited: 30 Oct 2009

Hi all..

So I'm playing with analogueIn, and I'm using it to turn a relay on and off depending on the input voltage.

so, quite a simple bit of code, and a couple of resistors to bring my input voltage into the range 0 - 3.3v.

a 12k and a 68k resistor working as a potential divider. (is that a term?) to bring a 0-18v voltage down to 0 to 3.3v

(the theory being I can multiple whatever I get from analogueIn by 3.3 and 6.66 to find what the voltage was on the outside) but I'm having problems getting it to turn on and off when I want.

then I noticed that it says analogueIn returns a float between 0.0 and 1.0        (1 decimal place I noted)

1.9v at the pin, would give a value of 0.57 on the 0.0 - 1.0 scale (if the pin can read 0 to 3.3v).

but it looks like 1.9v at the pin gives me 0.6 from analogueIn.

is that correct ? or have I damaged my mbed ?

or have I completely missed something.

Bear with my as I'm usually a Java programmer.. but this is my code. the chargeOne turns the relay off when the input measured at the pin is 1.9v, (12.4 after the calculation) yet upper_charge_limit for the comparisin is 13.0

If 1.9v (analogueIn of 0.57) gets rounded to analogueIn of 0.6, then the calculation returns 13.2.

which would explain why it turns off.

So it does look like analogueIn just rounds to 1 dp.

cheers

Dave

 

30 Oct 2009 . Edited: 30 Oct 2009

Hi Dave,

David Styles wrote:
I noticed that it says analogueIn returns a float between 0.0 and 1.0        (1 decimal place I noted) 1.9v at the pin, would give a value of 0.57 on the 0.0 - 1.0 scale (if the pin can read 0 to 3.3v). but it looks like 1.9v at the pin gives me 0.6 from analogueIn.

To clarify, the notation "1.0" is simply an easy way in C to specify a number as floating-point, compared to "1", which would be interpreted as a fixed-point/integer number.

It is not an indication of the number of decimal places the AnalogIn is accurate to; this is actually a function of the underlying analog-to-digital converter (ADC) of the hardware.

For the LPC2368, this is a 10-bit ADC, which means you would get steps of 1 / (2^10) which is approximately 0.001. For the LPC1768, it is a 12-bit ADC, so it is finer again. Add in noise, and you're less accurate!

There is obviously a whole mix of things here related to the theory of floating-point numbers, ADCs etc (Java programmers may have come across the great article What Every Computer Scientist Should Know About Floating-Point Arithmetic), but I hope this is enough to give you the information you need.

Btw, if you want to publish your program in the forum, you can always right-click your program in the compiler IDE and just hit "publish"; it'll post it to the website and you'll get a URL you can include in your post. This makes it easy for anyone to import it, and also avoids lots of code text in the forum. It is not that slick a process at the moment I know, but we're working on that :)

Simon

30 Oct 2009 . Edited: 30 Oct 2009

ah, apologies for that, I have published it here..

http://mbed.org/users/DaveStyles/published/58496922433919e2c3ce5f8103198247/LPC1.zip

I'm afraid I can't edit my previous post to remove the program stuff. <edit> I just found the edit button ! <edit>

I'm not asking you to debug my code, honest... ! its just this bit is simple, yet doesn't behave how I expect, (and now really doesn't behave how I'd expect) so I got a multimeter out to double check it wasn't hardware.

load1 is 1.9v at the mbed pin. (verified with a multimeter)

and yet this "if" returns true ?

#define rRatio  6.6355
#define UPPER_CHARGE_LIMIT  13. 

...

voltage1 = load1*rRatio*3.3000;
     if (voltage1 >= UPPER_CHARGE_LIMIT ) {
        flash();
        relay1=0;   
        chargeLED=0;
        return;
     }   

any ideas what I'm doing wrong. ?

cheers

Dave.

02 Nov 2009

Hi David

Just in case we can help eachother, I've posted a problem I'm having with AnalogIn here http://mbed.org/forum/topic/131/?page=1#comment-646

I'll have a look at your code.

Regards

Rob

02 Nov 2009

Hi David

I've had a look at your code and I wonder if the problems are related.  What I found is that with any reasonable real-world circuit connected to an ADC input I would get a small number of spurious values intermingled with the valid ones.  What you are doing is to read the ADC input repeatedly and I guess in that case if you did get a single spurious value above the valid level then it would trigger the if clause in the way you are seeing.

If you have time it might be worth trying to run a modification of the AnalogIn sample (from the AnalogIn documentation page). The sample as published simply collects 1024 samples from the ADC and prints them out. I modified it to only print the ones above a threshold (hard coded to 0x100 in my program) as I was holding the analog input pin to ground.  I've published my modified version here http://mbed.org/users/Bobty/published/6f58026a04d8805bfc335eb79e7aad63/AnalogInExample.zip

If you were to tie the analog in pin to a fixed level (as you suggested you have done at 1.9V) and then find what ADC reading you get for that level (e.g. centeredaround 590 in the example below - I calculated this as 1024 * 1.9 / 3.3 but it would need to be checked) and then put a threshold around the value to print out spurious ones, e.g:

 

...

const int LOWERTHRESHOLD = 550;

const int UPPERTHRESHOLD = 630;

...

printf("Results:\n");
for(int i=0; i<1024; i++) {
if ((samples[i] < LOWERTHRESHOLD) || (samples[i] > UPPERTHRESHOLD))
printf("%d, 0x%04X\n", i, samples[i]);
}

...

Then you could see if you are getting spurious values.

Regards

Rob

 

02 Nov 2009

Hi Rob, thanks for the reply..

I have the problem that what I am trying to do is sense the charge state of a 12v lead acid battery, lead acid batteries are starnge, in that you can sense their charge state from their voltage.

usually they are between 11.9v and 14.8v.

Problem is.. connect them to a charger and it drives the battery up about 0.7v.. and then it settles back down.

(actually it jumps around all over the place, varying by about 0.3v)

I was having a problem that my mbed wasn't agreeing with my multimeter about the voltage.

I think my problem is more in the way I'm using it.. its spikey spikey and I don't have anything smoothing it in the circuit. (I don't want anything smoothing it in hardware infact)

My other problem was that I wasn't using tera term to print out  what was going on... I just had a multimeter connected, and it was switching when I wasn't expecting it to.

I'd now say TeraTerm is a MUST for anyone using mbed !

anyway..

I can see my values are all in range.. but are very jumpy.. what I really want is the mean of those values. so I did this...

float aveVolt() {
float outside = 0;
 for (int j=0;j<3;j++)  {
     float average = 0;
     for (int i=0;i<1024;i++)  { 
           average = average + load1*rRatio*3.3000;
      }
      average = average / 1024;
      wait(1.2);
      outside = outside + average;
 }
return outside / 3;
}

its a little "manual", and it takes the average of the 3 that I take 1.5 secs apart, but as I am careful about where it is in my code (it takes 4.5 secs to execute with the wait, but I'm happy with that) it appears to work ok.

I wondering whether to make the 1024 bigger... I need to go see how fast an mbed runs.. I'm wondering if a sample taken over half a second (I need to see what the number is for that) would be much more use.

cheers

Dave.

PS. I'd moved my charge points to 12v and 13v (flat and charged) and this is when it went grumpy. I've moved them back to 11.9 and 14.8, and these are far enough apart for it not to keep switching itself in a grumpy manner.

 

 

02 Nov 2009

I've put it upto 10,000 cycles, with no discernable performance difference.. but mine is hardly a realtime application. 

I couldn't find a number for how fast the ADC runs ? so I played with some numbers..

mine is still varying wildly by about 0.3v on each reading, but I think thats the hardware.

 

02 Nov 2009

Hi David

It's good to hear that you have got it stabilized although jumping around by 0.3V still sounds a bit strange, you would think the battery itself would be a pretty good smoothing device - they generally are in my experience.

I hope the good progress continues.

Cheers

Rob

02 Nov 2009

Hi Dave,

You could try running a ticker in the back ground to do a running average, then use the calculated average in your code to make decisions. Try something like this..

http://mbed.org/users/chris/published/821807e6a4fb7520bbdeba207ac1333f/AnalogAverage.zip

Cheers,
Chris