Adding Variable Values Consecutively

Hey all,

I’ve been banging my head on this problem all day, and I struck out searching the references, forums and the greater internet, so here goes:

A sensor is hooked up to pins 3 (pos) and A0 (220k<–neg). It’s a reverse biased LED I’ve been messing with as an alternative to a photodiode. Eventually, this LED is getting replaced with a quantum light sensor, and I’d like to be able to compute the the integrated PPF. To do that, I’ve got to compound the sensor readings for the entire day into a single value.

The sensor is polled once per second, and that value is (at the moment) being sent out the serial port and into Processing for visualization.

Intuitively (for a programming noob, that is), I imagine that adding the consecutive values should work like this:

int total = 0;
int SensVal = 0;

void setup()

// hardware stuff here

void loop() 
{
SensVal = analogRead(A0);

total += SensVal;

// print value of total to serial.
}

In my mind, it seems like this should work - store the value from the sensor in the SensVal variable, then set the total variable equal to itself plus SensVal. However, the total variable just ends up getting set to SensVal.

I ran across some code for keeping a running average that used an array as an index, but I haven’t been able to figure out how to implement for my own purposes.

If anyone could provide a hint, I’d be appreciative. I know this must seem like a stupid simple question, but it seems there’s a fundamental flaw in my understanding of this language, and the embarrassment of asking outweighs the potential knowledge to be gained. :wink:

long total;

It's not so easy to tell what your program is doing as you have only shown some of it. How are you "printing the value of total"? What is in your setup()?

Magician: long total;

As Magician suggests, one problem is probably that the variable, "total", that you are accumulating to is an int. This has a range of only up to +32,767 and just a few -- on the order of 64 readings summed in will exceed this limit. A long has a much larger range, but will still overflow after about a million readings. Your next stop is long long.

Simply adding them up forever does not seem like an interesting or useful thing to do. I would expect you to be integrating over some specific interval or something. What should eventually happen to this data?

I just ran this program:

int total = 0;
int SensVal = 0;

void setup()  {
    Serial.begin(115200);
}

// hardware stuff here

void loop() 
{
    SensVal = analogRead(A0);

    total += SensVal;

    // print value of total to serial.
    Serial.println(total);
}

And it printed out a value that kept going up until it wrapped around (rather frequently, I admit).

Conclusion: the error is in your actual code and not this snippet that doesn’t show anything.

For a running mean, you can do something like this:

int medianBuf[5];
int ctr;
void loop() {
  int val = analogRead(A0);
  medianBuf[ctr] = val;
  ctr++;
  if (ctr >= 5) ctr = 0;
  
  int total = 0;
  for (int i=0; i<5; i++) {
    total += medianBuf[i];
  }
  int mean = (total+2) / 5; // +2 is to round correctly
}

For a running median, you just sort the array and take the third element. Google for sorting algorithms, there are dozens of books devoted to how to sort.

Alright, I think I made a stupid mistake - I had the variables initialize in the void loop() portion of the code. Initializing them before the setup and loop functions causes it to behave as expected.

@gardner: the actual quantum sensor outputs an analog signal, 5mV for every 1 ?mol/m^2 of light. Grabbing data every second gives me ?mol/m^2/sec, I’d like a running total of ?molmol/m^2/day as well, as I need to monitor the amount of light a greenhouse crop receives each day. Light regulation will happen via relays connected to supplementary lighting.

(the crop is lettuce, btw.)

Just adding up the sensor data obviously won’t yield any usable info, but I thought I might completely misunderstand how the operators worked, so I came up with that first piece of code.

Thanks for the help, guys. I now know that variables can’t be initialized within functions. :*

I had the variables initialize in the void loop() portion of the code.

That's what happens when you don't post the actual code, people waste time figuring out what was a simple problem.

I know it often make sense to cut the code down because at the other extreme we don't want to wade through a 1000 lines of code, but the code presented has to have the same "bug" or there's no point.

I now know that variables can't be initialized within functions.

They can if you use the static keyword, for example

loop () {

static int total = 0;

is OK because it make total non-automatic (IE not on the stack) but still local to loop().


Rob

As Magician suggests, one problem is probably that the variable, "total", that you are accumulating to is an int. This has a range of only up to +32,767 and just a few -- on the order of 64 readings summed in will exceed this limit. A long has a much larger range, but will still overflow after about a million readings. Your next stop is long long.

Or, since the readings are all positive, double the range using unsigned long. Or, shorten the interval and keep an array of values by hour. Have the PC sum the value for a full day, where it has better support for larger data types.

Ah ha, thanks for the tip on the variables, Graynomad, that'll come in handy. I'll be sure to post full code, where appropriate, in the future.

@PaulS - I'll probably end up doing something similar. The Arduino doesn't seem to have enough memory to store that giant array (computing the Riemann sum seems to be as close as I get to real integration). If the Raspberry Pi boards ever start shipping, I was planning on using one for data logging and wireless communication, so I may as well use up some of that horsepower while I'm at it.

Thanks for the help, guys.