Why does "for" not work

I jumpered the Arduino voltage of 5.0VDC direct to analog pin #5 (m168 pin $28).

With the following code, if I read the input pin a single time as in

voltraw - analogRead(volt_pin);

the result is exactly 5.0 vdc which is exactly what I read with the DVM on the pin.

BUT if I do the following I get 5.26 and the volt_pin gives 1076 as the average.

 // variables for input pin and control LED
#include <LiquidCrystal.h>

int volt_pin = 5;  //pin 24

int voltraw = 0;
int voltP = 0;
float volt = 0.0;

LiquidCrystal lcd(7, 6, 5, 4, 3, 2); // (RS, Enable, data lines)this meets the include LiquidCrystal.h above

void setup()
{
  pinMode(volt_pin, INPUT); // declaration of pin modes
  lcd.begin(16,2); // setup to send to LCD with 16 columns and 2 lines.
}
void loop(){
  {
   for (int i = 0; i < 20; i++) //this is to setup the following.
   voltraw = voltraw+analogRead(volt_pin); //this is to read input pin 20 times and add the result.
       voltraw = voltraw / 20;  // this divides by 20 to get the average of 20 reads.
    volt = ((voltraw * 5.0) / 1023);  //this should cover the voltraw to actual volts

    lcd.setCursor(0,0);
    lcd.print("V=");
    lcd.print(volt, 2);  //to print the calculated volts to 2 decimals

    lcd.setCursor(0,1);
    lcd.print("Vraw=");
    lcd.print(voltraw);  //this prints the input in bits. 

    delay(300);
  }
}

Comments please to help me understand why if 1023 is read in a single time it comes out at 1023, but if it's read 20 times and divided by 20 it comes out at 1076. If I do the read at 5 or 10, it's even more off. and at 100 times it's really off.

Is there that much error in the ADC? OR am I doing something wrong with the code?

Thanks for any help and info.

Ken H>

for (int i = 0; i < 20; i++) //this is to setup the following.

http://arduino.cc/en/Reference/For

Osgeld - thanks for the link, but that is where I got my info. From what I can see, it's exactly the same. I can "make" the result correct by fudging the default voltage setting to 4.8 rather than the measured 5.0.

Am I missing something?

[edit]if you are referring to the "x" that is called (is that the correct term?) in the println(x); line, it won't compile in my sketch. I must have "volt" in that place.

I expect I'm missing something - darn if I can see it.
[/edit]

Ken H.

Ken,

You have a compounding problem... the issue is not your For() loop, it just looks weird because you didn't use brackets.. but it works fine for one instruction.

The issue is that you never clear voltraw, before you start adding up your 20 reads. The first time through the loop it's fine, but successive times it is over flowing your INT variable, and then dividing by 20 still.

Just put voltraw = 0; before your For() loop.

One change in setup...

void setup()
{
[glow]/* Remove this line of code.  It changes the digital pin 5 to an input which may interfere with the LCD
  pinMode(volt_pin, INPUT); // declaration of pin modes
*/[/glow]
  lcd.begin(16,2); // setup to send to LCD with 16 columns and 2 lines.
}

Depending on how the number of times through loop, this change will make a very big difference in the result...

void loop(){
  {
[glow]   voltraw = 0;[/glow]
   for (int i = 0; i < 20; i++) //this is to setup the following.
   voltraw = voltraw+analogRead(volt_pin); //this is to read input pin 20 times and add the result.

@BrettW - THANK YOU!! That did the trick. I did not realize what I had to do that - put the clear statement just before. I will try to remember that. I have been having to fudge things for the last while to make the analog inputs read correctly for the last couple of projects I have done. Thank you.

@Coding Badly: Thank you for making the clear statement clear with your example.
Also of great interest is your comment on "pin 5" is something I've been wondering about for a long time (weeks) - how does the Arduino IDE know if a pin assignment is "pin 5 - Analog (m168 pin 28)" or pin 5 - digital (m168 pin 11)"?

I work with the m168 pins and have to refer to a the Arduino pin mapping to help keep pins straight. Most of my projects use a home etched PCB with the m168 installed.

Can you - or anyone - shed light on how the IDE keeps those pins straight?

AND a BIG THANK YOU to all the folks who make this a GREAT group.

Ken H>

how does the Arduino IDE know if a pin assignment is "pin 5 - Analog (m168 pin 28)" or pin 5

It's the set of functions you use. pinMode, digitalRead, and digitalWrite refer to digital pins. analogRead refers to analog pins.

The two spaces overlap. There's a digital pin 5 and an analog pin 5 but they're not the same physical pin.

Can you - or anyone - shed light on how the IDE keeps those pins straight?

For digital pins, there's a pair of mapping functions / tables in the library. One map is used to determine the port. The other map determines the bit on the port.

I have no idea how analog pins are mapped to physical pins.

You don't need to do a pinMode for the analog in pins.

By using the analogRead() command that is enough for it to know that you want to use the analog pins.

Thanks to both of ya'll for helping me understand. I'll go back and remove all those pinModes from my code for analog inputs. Darn, there is so much to this stuff. Just when I think I'm starting to learn some....

Ya'll all help a LOT!!!

Ken H>

I think I understand the problem even better now - I had set voltraw to zero, but it was in teh first section (declarations?) of the sketch where I have the "int voltraw = 0;" and this ran only one time at start of sketch.

The "voltraw = 0" has to be declared in the loop section so it gets reset to zero EACH time thru the loop. There is no real need to use the "int voltraw = 0;" in the first section, just in the loop section of code.

Should I have just used "int voltraw = 0;" in the first section of the "for" statement and not put at all in the declaration section at the beginning? OR is it better declare the "int voltraw = 0;" in the declaration section to run one time, then in the "for" statement in the loop section put the "voltraw = 0:" so it clears each time the program loops?

Thanks again for all the help.

ken H.

If you mean doing this:

for( int i=0, int voltageraw=0 ; i<20; i++) 
{
    // stuff
}

// voltageraw no longer exists here

Then voltageraw will only exist inside the for loop because you're declaring it inside the loop. You probably want to use the value after the for loop is done though.

But this should work:

int voltageraw;

for( int i = 0, voltageraw = 0; i<20; i++)
{
// stuff
}

// i no longer exists, but voltageraw does

Because voltageraw is declared before teh for loop, it continues to exist after the loop.

Er, my bad... I don't think the second example would work as expected either. I think it would create a second voltageraw that would only exist in the for loop, and outside of the loop, you'd be accessing the original voltageraw (which was not changed during the loop).

This is why I always consider it best practice to declare my variables at the beginning of my function rather than later in the code, so that they're all declared in an easy to find spot and I don't get tripped up on scoping rules.

This will work:

int i, voltageraw;

for( i=0, voltageraw=0 ; i<20; i++)
{
    // stuff
}

Thank you Dilbert - I'm studying your statements and trying to understand. Allow me time to run the code thru a breadboard setup - that always helps me understand. I had never really understood what that section of code did other than "smoothed" (averaged) analog input readings. Now I am starting to understand more what is actually going on.

Ya'll are my only teachers here other than all the reading/coding I'm doing, and I sure do appreciate the help. Thank you.

Ken H>