Averaging analog inputs without delay() help needed

Hello,
I am fairly new to the scene and have ran into a roadblock that I can’t seem to get around.
My ultimate goal is to have a reading from a photodiode read and turn on or off an LED based on the reading.
I also have LED that is activated based on battery status, once it hits 2.9V, the LED will fade in and out, once it hits 2.7V, the LED will stay on solid.
The code worked well before I thought of making the LED fade and since I use delay for the averaging, the output becomes very choppy.
I have looked at blinkwithoutdelay, and the article on avoiding delay, and attempted to make millis() work in my code, but I can’t seem to get the averaging to work with it.
Most of the body of the code I learned from google searching or from learning page, but the section that does the averaging and the section that uses cosign to fade the LED is mostly just copy and pasted into the sketch and I only adapted it to work for me. I don’t really understand those very much.
Here is the code that has delay and everything works except the LED fading:

const int Vent = 13;                                   //Vent LED location
const int LowBat = 11;                                 //Low Battery LED Location
const int Read = A2;                                   //For sensor averaging
int value, value2;                                     //For LowBatFade
int period = 2000;                                     //For LowBatFade
int displace = 500;                                    //For LowBatFade
long time = 0;                                         //For LowBatFade

void setup() {
  pinMode(Vent, OUTPUT);                               //Set vent LED pin as OUTPUT
  pinMode(LowBat, OUTPUT);                             //Set low battery LED pin as OUTPUT
  Serial.begin(57600);                                 //Set Serial baud rate
}

void loop() {
  int photodiode = analogRead(A2);                     //Photodiode input location
    photodiode = readLED(50);
    Serial.println(photodiode);                        //Display photodiode reading in Serial Monitor
    if (photodiode > 10)                               //Ambient light reading
      digitalWrite(Vent, HIGH);                        //Activate vent LEDs
    else
      digitalWrite(Vent, LOW);                         //Dissable vent LEDs
    if (photodiode > 10)                               //Ambient light reading
      Serial.println("ON");                            //Display vent LED status as ON in Serial Monitor
    else
      Serial.println("OFF");                           //Display vent LED status as OFF in Serial Monitor
  int BatIn = analogRead(A1);                          //Battery input location
    float BatVolt = BatIn * (5.0 / 1023.0);            //Convert 0-1023 reading to voltage
    Serial.println(BatVolt);                           //Display battery voltage in Serial Monitor
    if (BatVolt < 3.7) {                               //Low battery voltage
      LowBatFade();                                    //Run LowBatFade
    }
    else
      digitalWrite(LowBat, LOW);                       //Dissable low battery LED
    if (BatVolt < 3.7)                                 //Low battery voltage
      Serial.println("LOW BATTERY");                   //Display battery status as LOW BATTERY in Serial Monitor
    else
      Serial.println("BATTERY OK");                    //Display battery status as BATTERY OK in Serial Monitor
    if (BatVolt <= 2.7)                                //Very low battery voltage
      digitalWrite(LowBat, HIGH);                      //Activate low battery LED
    if (BatVolt <= 2.7)                                //Very low battery voltage
      Serial.println("!!!!!!!!!!!");                   //Display battery status as !!!!!!!!!!! in Serial Monitor
}

void LowBatFade() {                                    //Code to run to fade the low battery LED
    time = millis();
    value = 128+127*cos(2*PI/period*time);
    value2 = 128+127*cos(2*PI/period*(displace-time)); 
    analogWrite(LowBat, value2);
}

int readLED(int number) {                              //Code to average sensor input data
  int total = 300;
  for(int x = 0; x < number; x++) {
    total += analogRead(Read);
      delay(10);                                       //Sample rate
  }
  return total/number;
}

Note, to easily test the fading LED I set the activate voltage to 3.7 so I can just jumper to the 3.3v output pin on my Arduino Nano board.

Here is the code that I attempted to get rid of delay and failed getting any kind of averaging.:

const int Vent = 13;                                   //Vent LED location
const int LowBat = 11;                                 //Low Battery LED Location
int value, value2;                                     //For LowBatFade
int period = 2000;                                     //For LowBatFade
int displace = 500;                                    //For LowBatFade
long time = 0;                                         //For LowBatFade
long PhotodiodeMS = 0;                                 //For photodiode reading
long PhotodiodeRead = 700;                             //Photodiode sample rate
long BatInMS = 0;                                      //For battery voltage reading
long BatInRead = 5;                                    //Battery voltage sample rate, also controls LowBatFade smoothness

void setup() {
  pinMode(Vent, OUTPUT);                               //Set vent LED pin as OUTPUT
  pinMode(LowBat, OUTPUT);                             //Set low battery LED pin as OUTPUT
  Serial.begin(57600);                                 //Set Serial baud rate

}

void loop() {
  unsigned long currentmillis = millis();
  if (currentmillis - PhotodiodeMS > PhotodiodeRead) {
        PhotodiodeMS = currentmillis;
  int photodiode = analogRead(A2);                     //Photodiode input location
    Serial.println(photodiode);                        //Display photodiode reading in Serial Monitor
    if (photodiode > 10)                               //Ambient light reading
      digitalWrite(Vent, HIGH);                        //Activate vent LEDs
    else
      digitalWrite(Vent, LOW);                         //Dissable vent LEDs
    if (photodiode > 10)                               //Ambient light reading
      Serial.println("ON");                            //Display vent LED status as ON in Serial Monitor
    else
      Serial.println("OFF");                           //Display vent LED status as OFF in Serial Monitor
  }
  if (currentmillis - BatInMS > BatInRead) {
    BatInMS = currentmillis;
  int BatIn = analogRead(A1);                          //Battery input location
    float BatVolt = BatIn * (5.0 / 1023.0);            //Convert 0-1023 reading to voltage
    Serial.println(BatVolt);                           //Display battery voltage in Serial Monitor
    if (BatVolt < 3.7) {                               //Low battery voltage
      LowBatFade();                                    //Run LowBatFade
    }
    else
      digitalWrite(LowBat, LOW);                       //Dissable low battery LED
    if (BatVolt < 3.7)                                 //Low battery voltage
      Serial.println("LOW BATTERY");                   //Display battery status as LOW BATTERY in Serial Monitor
    else
      Serial.println("BATTERY OK");                    //Display battery status as BATTERY OK in Serial Monitor
    if (BatVolt <= 2.7)                                //Very low battery voltage
      digitalWrite(LowBat, HIGH);                      //Activate low battery LED
    if (BatVolt <= 2.7)                                //Very low battery voltage
      Serial.println("!!!!!!!!!!!");                   //Display battery status as !!!!!!!!!!! in Serial Monitor
  }
}

void LowBatFade() {                                    //Code to run to fade the low battery LED
    time = millis();
    value = 128+127*cos(2*PI/period*time);
    value2 = 128+127*cos(2*PI/period*(displace-time)); 
    analogWrite(LowBat, value2);
}

Thanks for the help!
Edit: Change title for better clarity of issue

Some meaningful names for variables and functions would be a good start.

const int Read = A2;                                   //For sensor averaging

You’ve connected a Read to the pin? Does that make sense?

int value, value2; //For LowBatFade

Now, that’s creative. Everyone can see how these are used.

  int photodiode = analogRead(A2);                     //Photodiode input location
    photodiode = readLED(50);

You’ve given the pin a (creative) name. Why not use it?

int readLED(int number) {                              //Code to average sensor input data
  int total = 300;
  for(int x = 0; x < number; x++) {
    total += analogRead(Read);
      delay(10);                                       //Sample rate
  }
  return total/number;
}

You are reading from a light emitting diode? I didn’t think so. So, why does the function name say that you are? readElephantPoop() would be just as meaningful.

Why is total initialized to 300? For ANY value other than 0, you need a comment to explain why! Suppose that the average reading from the pin was 750. 50 * 750 = 37500, which overflowed your int.

void LowBatFade() {                                    //Code to run to fade the low battery LED
    time = millis();
    value = 128+127*cos(2*PI/period*time);
    value2 = 128+127*cos(2*PI/period*(displace-time)); 
    analogWrite(LowBat, value2);
}

Where is value used? Why is it a global?

Where else is value2 used? Why is it a global?

OK. Enough picking. On to your formatting. If you put each { on a new line, use Tools + Auto Format, and add a bit of white space, you just might spot what the problem is with your code. Or not, but at least it would help us.

Just about all the points of code you pointed out were the sections that I copied over to try to make the averaging and fading work. I’m still trying to figure them out completely. My thinking was that if they worked in the sketch that I found them in, then I can try to copy over the code into my sketch and hopefully have a similar result. I pulled everything that seemed to be related.

The parts that I tried to mark for the averaging was from an instructable that used a LED as a light sensor and the code for fading was from a forum (I forget which) that someone suggested using a cosign wave.

You’ve connected a Read to the pin? Does that make sense?

To me, the Read seemed to connect to the part of the code here:

int readLED(int number) {                              //Code to average sensor input data
  int total = 300;
  for(int x = 0; x < number; x++) {
    total += analogRead(Read);
      delay(10);                                       //Sample rate
  }
  return total/number;
}

Same with readLED, which the project this came from did use a LED in place of a photodiode.

Why is total initialized to 300? For ANY value other than 0, you need a comment to explain why! Suppose that the average reading from the pin was 750. 50 * 750 = 37500, which overflowed your int.

I’m not sure why to be honest, again code that was copied over.

Now, that’s creative. Everyone can see how these are used.

Where is value used? Why is it a global?

Where else is value2 used? Why is it a global?

Same story as before, this is just how that bit of code was written before and I don’t yet understand this enough yet.

OK. Enough picking. On to your formatting. If you put each { on a new line, use Tools + Auto Format, and add a bit of white space, you just might spot what the problem is with your code. Or not, but at least it would help us.

I’ll format it better and add more space between lines in the morning and see where that gets us.
Thanks for the pointers and taking the time to reply. I’ve only had my Arduino board for about a week or so now and still have tons to learn about it, but I am trying.

Thanks again

Last time I played with using a led to control the brightness of the led, I started with this:

http://playground.arduino.cc//Learning/LEDSensor

and I ended up with slightly different code. It does flicker in low light.

//
// This example shows one way of using an LED as a light sensor.
// You will need to wire up your components as such:
//
//           + digital2
//           |
//           <
//           > 100 ohm resistor
//           <
//           |
//           |
//         -----
//          / \  LED, maybe a 5mm, clear plastic is good
//         -----
//           |
//           |
//           + digital3
//
// What we are going to do is apply a positive voltage at digital2 and
// a low voltage at digital3. This is backwards for the LED, current will
// not flow and light will not come out, but we will charge up the 
// capacitance of the LED junction and the Arduino pin.
//
// Then we are going to disconnect the output drivers from digital2 and
// count how long it takes the stored charge to bleed off through the 
// the LED. The brighter the light, the faster it will bleed away to 
// digital3.
//
// Then just to be perverse we will display the brightness back on the 
// same LED by turning it on for a millisecond. This happens more often
// with brighter lighting, so the LED is dim in a dim room and brighter 
// in a bright room. Quite nice.
//
// (Though a nice idea, this implementation is flawed because the refresh
// rate gets too long in the dark and it flickers disturbingly.)


// just a few changes then....

#define LED_N_SIDE 7
#define LED_P_SIDE 6

unsigned long  now, mark, interval;
unsigned long checkUSecs = 2UL, ledOnTime = 100UL, senseMaxUSecs = 5000UL; 

char  state = 0; // -128 <--> 127

void setup()
{
  //  now = micros();
}

void loop()
{
  static  unsigned int j = 0U;

  switch ( state )
  {
  case  0:
    {
      // Apply reverse voltage, charge up the pin and led capacitance
      pinMode(LED_N_SIDE,OUTPUT);
      pinMode(LED_P_SIDE,OUTPUT);
      digitalWrite(LED_N_SIDE,HIGH);
      digitalWrite(LED_P_SIDE,LOW);

      // Isolate the pin 2 end of the diode
      pinMode(LED_N_SIDE,INPUT);
      digitalWrite(LED_N_SIDE,LOW);  // turn off internal pull-up resistor

      now = mark = micros();
      state = 1;
      j = 0U;
      break;
    }

  case  1:
    {
//      if ( micros() != mark )
//      {
//        mark = micros();
        if ( digitalRead(LED_N_SIDE)) 
        {
          if (( micros() - now ) >= senseMaxUSecs )
          {
            state = 2; // quit reading
          }
        }
        else
        {
          state = 2;
        }
//      }
      break;
    }

  case  2:
    {
      // Turn the light on 

      digitalWrite(LED_P_SIDE,HIGH);
      digitalWrite(LED_N_SIDE,LOW);
      pinMode(LED_P_SIDE,OUTPUT);
      pinMode(LED_N_SIDE,OUTPUT);
      mark = micros();
      state = 3;
      break;
    }  

  case  3:
    {
      // Turn the light off after ledOnTime microseconds
      if ( micros() - mark >= ledOnTime )
      {
        digitalWrite(LED_P_SIDE,LOW);
        //      delayMicroseconds(1000);
        // we could turn it off, but we know that is about to happen at the loop() start
        state = 0;
        break;
      }
    }
    break;
  }
}

Thanks for the reply!
Unfortunately, that code still uses the delay function and I’m really trying to steer away from that if possible.
I took a couple of days to clear my head of the matter and I’m starting in on it once again tonight.
I took the advice of PaulS and created new lines for the { in my code to give more “white space” and it does make things easier to read, but my issue still remains trying to find a way to average an analog sensor reading without the use of delay at all.
My code compiles without errors and runs well. The only issue I’m having is with the code that fades the low battery LED being choppy due to the delay function that I use for the input averaging.

Edit: To help clarify my current fading code (I can’t find the instructable I used for the averaging), here are the sources if anyone is interested:
Fading was from reply #6 in this thread:

Edit 2: After looking closer at the fade code I understood it a bit better and also altered my code to better fit.

const int Vent = 10;                                   //Vent LED location
const int LowBat = 11;                                 //Low Battery LED Location
int Fade;                                              //For LowBatFade
int period = 2000;                                     //For LowBatFade
int displace = 500;                                    //For LowBatFade
long time = 0;                                         //For LowBatFade

void setup()
{
  pinMode(Vent, OUTPUT);                               //Set vent LED pin as OUTPUT
  pinMode(LowBat, OUTPUT);                             //Set low battery LED pin as OUTPUT
  Serial.begin(57600);                                 //Set Serial baud rate
}

void loop()
{
  int photodiode = analogRead(A2);                     //Photodiode input location
//  photodiode = Average(50);
  Serial.println(photodiode);                          //Display photodiode reading in Serial Monitor
  if (photodiode > 10)                                 //Ambient light reading
    digitalWrite(Vent, HIGH);                          //Activate vent LEDs
  else
    digitalWrite(Vent, LOW);                           //Dissable vent LEDs
  if (photodiode > 10)                                 //Ambient light reading
    Serial.println("ON");                              //Display vent LED status as ON in Serial Monitor
  else
    Serial.println("OFF");                             //Display vent LED status as OFF in Serial Monitor
  int BatIn = analogRead(A1);                          //Battery input location
  float BatVolt = BatIn * (5.0 / 1023.0);              //Convert 0-1023 reading to voltage
  Serial.println(BatVolt);                             //Display battery voltage in Serial Monitor
  if (BatVolt < 3.7)
  {                                                    //Low battery voltage
    LowBatFade();                                      //Run LowBatFade
  }
  else
    digitalWrite(LowBat, LOW);                         //Dissable low battery LED
  if (BatVolt < 3.7)                                   //Low battery voltage
    Serial.println("LOW BATTERY");                     //Display battery status as LOW BATTERY in Serial Monitor
  else
    Serial.println("BATTERY OK");                      //Display battery status as BATTERY OK in Serial Monitor
  if (BatVolt <= 2.7)                                  //Very low battery voltage
    digitalWrite(LowBat, HIGH);                        //Activate low battery LED
  if (BatVolt <= 2.7)                                  //Very low battery voltage
    Serial.println("!!!!!!!!!!!");                     //Display battery status as !!!!!!!!!!! in Serial Monitor
}

void LowBatFade()
{                                                      //Code to run to fade the low battery LED
  time = millis();
  Fade = 128+127*cos(2*PI/period*(displace-time)); 
  analogWrite(LowBat, Fade);
}
/*
int Average(int number)
{                                                      //Code to average sensor input data
  int total = 300;
  for(int x = 0; x < number; x++)
  {
    total += analogRead(A2);
    delay(10);                                       //Sample rate (Average 50ms * delay 10ms = 500ms sample rate)
  }
  return total/number;
}
*/

Here I omitted the averaging sections so that the fade works, but without the average from the photodiode, the readings vary too much to be usable. Also, serial monitor goes nuts without the delay. Any advice?

You could use an exponential moving average:

// untested code

const double k = 2.0 / (50.0 + 1.0);    // 50 is the period
const double oneMinusK = 1.0 - (2.0 / (50.0 + 1.0));

void loop()
{
  static double exponentialMovingAverage = (double) analogRead(A2);
  int photodiode = analogRead(A2);                     //Photodiode input location
  exponentialMovingAverage = exponentialMovingAverage * oneMinusK + (double) photodiode * k;
  photodiode = (int) exponentialMovingAverage;
//  photodiode = Average(50);
  Serial.println(photodiode);                          //Display photodiode reading in Serial Monitor
  if (photodiode > 10)                                 //Ambient light reading
    digitalWrite(Vent, HIGH);                          //Activate vent LEDs
  else
    digitalWrite(Vent, LOW);                           //Dissable vent LEDs
...

Ummm... just out of curiosity, why does your average function start the total at 300?

Or a normal moving average - multiply the current average by nine, add the new reading, divide by ten.

As to the serial port, use the blink without delay technique and only print once a second or so.

Zebes:
Thanks for the reply!
Unfortunately, that code still uses the delay function and I’m really trying to steer away from that if possible.

If that is in response to what I posted then you have a reading or attention problem.
The only time the word delay appears there is in a commented out line.
It certainly does NOT use delay.

Thanks for everyone's input! I'm not sure why that 300 was in there, but I reset it back to 0 and everything seems to still be running the same. Thanks for the sharp eyes! TanHadron, I'll try that code now and report back, thanks! wildbill, will give that a go too, I never thought of using that to control only the Serial.println function. GoForSmoke, sorry man, I didn't catch the // before the delaymicroseconds function, I'll give you code a try too.

I really appreciate all the help and willingness to work with my noobness. I'll post an update to my code once I try these suggestions! Thanks again! :)

Edit: Small update. The running average code that TanHadron seems to be promising for the photodiode reading so far and the tip for using the blinkwithoutdelay code for serial monitor is brilliant. I still have quite a few bugs to work out with everything, but defiantly on the right track. Thanks for all the help so far!

If you look in the code I gave you, case 3 uses the blink without delay time check to control the led ON time.

Ok, so after lots of trial and error I think that I have it just about finished up. I just need some advice on the averaging section.
As of now I am using the exponential moving average code that TanHadron left for the photodiode and it seems to be working very well and for the battery voltage I found some code that someone used for averaging readings from a moisture monitor that seems to be working well.
My question is, for best accuracy and reliability, should I ditch the averaging code I have for the battery and replace it with the exponential moving average code or keep it how it is?

Here is the section I was reffering to for the battery voltage averaging.

    int BA(0);                                         //BA = battery average
    for (int i = 0; i< BatFadeRead; i++) BA += BatFade;
    BA /= BatFadeRead;

Here is my complete sketch so far:

const int VentLED = 10;                                //Vent LED location
const int LowBatLED = 11;                              //Low Battery LED Location
const double AP = 2.0 / (50.0 + 1.0);                  //50 is the period
const double OMAP = 1.0 - AP;                          //OMAP = one minus AP
int Fade;                                              //For LowBatLEDFade
int FP = 2000;                                         //For LowBatLEDFade period
int FD = 500;                                          //For LowBatLEDFade displace
long FT = 0;                                           //For LowBatLEDFade time
long SerPreMil = 0;                                    //Last time Serial.printin was used
long SerInt = 1500;                                    //Interval to print to Serial Monitor
long SerPri = 0;                                       //For serial print delay

void setup()
{
  pinMode(VentLED, OUTPUT);                            //Set vent LED pin as OUTPUT
  pinMode(LowBatLED, OUTPUT);                          //Set low battery LED pin as OUTPUT
  Serial.begin(57600);                                 //Set Serial baud rate
}

void loop()
{
  static double EMA = (double) analogRead(A2);         //EMA = exponential moving average
  int Photodiode = analogRead(A2);                     //Photodiode input location
  EMA = EMA * OMAP + (double) Photodiode * AP;
  Photodiode = (int) EMA;
  if (Photodiode > 25)                                 //Ambient light reading
    digitalWrite(VentLED, HIGH);                       //Activate vent LEDs
  else
    digitalWrite(VentLED, LOW);                        //Disable vent LEDs

  int BatIn= analogRead(A1);                           //Battery read input location
  float BatVolt = BatIn * (5.0 / 1023.0);              //Convert 0-1023 reading to voltage
  if (BatVolt <= 3.1)                                  //Activate low battery LED (variable fade)
  {
    float RecBat = 175/BatVolt;                        //Increase BatVolt reading (lower BatVolt = higher RecBat)
    float BatFade = RecBat - 55.45;                    //Lower RecBat to a usable number (1-9)
    int BatFadeRead = 50;                              //Number of readings to average
    int BA(0);                                         //BA = battery average
    for (int i = 0; i< BatFadeRead; i++) BA += BatFade;
    BA /= BatFadeRead;
    //    Serial.println(BA);                          //Display averaged BatFade reading in Serial Monitor
    FT = millis();
    Fade = 128+127*cos(BA*PI/FP*(FD-FT));
    analogWrite(LowBatLED, Fade);
    if (BatVolt <= 2.7)
      digitalWrite(LowBatLED, HIGH);                   //Activate low battery LED (constant on)
  }

  unsigned long SerCurMil = millis();                  //SerCurMil = serial current milliseconds
  if(SerCurMil - SerPreMil > SerInt)                   //SerInt = serial interval
  {
    SerPreMil = SerCurMil;                             //SerPriMil = serial print milliseconds
    if (SerPri == 0)
      Serial.print("Light reading is: ");
      Serial.println(Photodiode);                      //Display photodiode reading in Serial Monitor
      if (Photodiode > 25)                             //Display Vent LED status in Serial Monitor
        Serial.println("Vent LEDs are ON");
      else
        Serial.println("Vent LEDs are OFF");
      Serial.print("Battery voltage is: ");
      Serial.println(BatVolt);                         //Display battery voltage reading in Serial Monitor
      if (BatVolt <= 3.1)                              //Display battery voltage status in Serial Monitor
        Serial.println("Battery voltage is low");
      else
        Serial.println("Battery voltage is OK");
      Serial.println("");                              //Space between readings
  }
}

The Blinkwithoutdelay tip for the serial print was awesome, took a bit of work to figure out how to make it work for all of my serial print commands, but I got it working perfectly now.
If anyone has any other advice on cleaning things up a bit I would be happy to here them. Everyone’s input has been awesome and defiantly got me to this point.

GoForSmoke, Thanks for your input on that too. I’m actually incorporating most of that code you posted into a different project and it is proving to be very helpful!

Edit: Anyone have any ideas why this thread has a crazy amount of views? Glitch? I cant see there really being that many views.

    int BatFadeRead = 50;                              //Number of readings to average
    int BA(0);                                         //BA = battery average
    for (int i = 0; i< BatFadeRead; i++) BA += BatFade;

That for loop might as well be:

    BA += BatFade * BatFadeRead;

I don’t see where in that code 50 readings are averaged at all.
There are statistics methods that let you keep one running value that each new data point changes but it’s been so long ago for me that I can only remember squares being involved.

You can save a bit on parts like this:

      if (Photodiode > 25)                             //Display Vent LED status in Serial Monitor
        Serial.println("Vent LEDs are ON");
      else
        Serial.println("Vent LEDs are OFF");

by doing like this:

      Serial.println("Vent LEDs are ");
      if (Photodiode > 25)                             //Display Vent LED status in Serial Monitor
        Serial.println("ON");
      else
        Serial.println("OFF");

Go over conditions and often you will find prints or commands that are common and can be moved above or below the block they are in. Just checking your code over and working out what can and can’t be done and how will not only get you to improve your code but your own code skills as well.
The more aggressive you get with your code, the tighter it will get and the better you will do next time, etc. I’ve seen Comp-Sci Masters (as in degree holders) that hadn’t learned that lesson and High School students that had… back in the 80’s! It’s a crazy world.

GoForSmoke, Thanks for your input on that too. I’m actually incorporating most of that code you posted into a different project and it is proving to be very helpful!

I hope you like the state machine and see how simple one can be. If need be you can run code on several state variables but take care that they don’t step on each other.

For responsive code you want to make sure that loop() runs fast, always. One thing you do in this sketch is an analog read every time through loop. Analog read takes about 105 millis (edit: MICROS, but still 100 micros is a good while in AVR-land) which in itself isn’t much but -do- you need to check the battery that often?

Edit: Anyone have any ideas why this thread has a crazy amount of views? Glitch? I cant see there really being that many views.

There’s been some forum admin work going on. OTOH maybe a lot of people are interested but don’t have much to say that hasn’t been said. The thread title is interesting in itself.

I agree with GoForSmoke. If you’re going to average the battery fade, you need to somehow have the analogRead() in the loop that averages. Otherwise, you’re averaging a constant, which isn’t useful.

Analog read takes about 105 millis which in itself isn’t much but -do- you need to check the battery that often?

Uhh… Are you sure that’s right? I calculate about 104 micros, which is about 3 orders of magnitude different.

TanHadron:

Analog read takes about 105 millis which in itself isn’t much but -do- you need to check the battery that often?

Uhh… Are you sure that’s right? I calculate about 104 micros, which is about 3 orders of magnitude different.

Ooops, yes, micros! I forget if the doc says 104 or 105 or how exact that is.

I go now to edit my screwup above.

Yeah, the code that I used for battery averaging isn’t doing me a whole lot of good over all. All I need from reading the battery voltage is a stable output to control the LED functions with it, the actual reading that shows in serial monitor is stable enough to get a good idea of the level. I found that if it isn’t stable the LED would just flicker between fading speeds. Really, if I could get away with checking the voltage every minute or so and keep the cosign fade running smooth that would be perfect.

As per your advice GoForSmoke, I changed the section with the similar serial print lines to what you suggested and it did save a bit of space.
Here is what that section looks like now:

  unsigned long SerCurMil = millis();                  //SerCurMil = serial current milliseconds
  if(SerCurMil - SerPreMil > SerInt)                   //SerInt = serial interval
  {
    SerPreMil = SerCurMil;                             //SerPriMil = serial print milliseconds
    if (SerPri == 0)
      Serial.print("Light reading is: ");
      Serial.println(Photodiode);                      //Display photodiode reading in Serial Monitor
      Serial.print("Vent LEDs are ");
        if (Photodiode > 25)                           //Display Vent LED status in Serial Monitor
          Serial.println("ON");
        else
          Serial.println("OFF");
      Serial.print("Battery voltage is: ");
      Serial.println(BatVolt);                         //Display battery voltage reading in Serial Monitor
      Serial.print("Battery voltage is ");
        if (BatVolt <= 3.1)                            //Display battery voltage status in Serial Monitor
          Serial.println("low!");
        else
          Serial.println("OK!");
      Serial.println("");                              //Space between readings
  }

I think I have to keep the two lines reading “Battery voltage is” though since I want two lines printed with different information right?

I attempted to change what I have as the battery reading averaging code to what you suggested with no luck. I was late and I was probably missing something obvious that was keeping it from working, but it would seem to cause everything to hang. I didn’t have an issue with it being verified, but I never got anything in serial monitor.

I hope you like the state machine and see how simple one can be. If need be you can run code on several state variables but take care that they don’t step on each other.

Yeah, the state machine is very cool, it was kind of hard to understand at first, but after looking it over a few times and changing different things I am starting to understand it better. Very powerful.

Go over conditions and often you will find prints or commands that are common and can be moved above or below the block they are in. Just checking your code over and working out what can and can’t be done and how will not only get you to improve your code but your own code skills as well.
The more aggressive you get with your code, the tighter it will get and the better you will do next time, etc. I’ve seen Comp-Sci Masters (as in degree holders) that hadn’t learned that lesson and High School students that had… back in the 80’s! It’s a crazy world.

I must say that it is exciting to see how many different ways there are to do similar things in C. I have never messed with any kind of programming until I started with this project and it really plows me away with how it can be so complex, yet simple at the same time. I have always worked with the hardware side of things in the past and it is neat to cross over to the software side of things now too.

Once again, thank you guys for all the help.
I’m going to go do some research on the averaging and getting the battery voltage reading slower.

Zebes: I think I have to keep the two lines reading "Battery voltage is" though since I want two lines printed with different information right?

I dunno what you want there. I might make one longer line saying like Battery voltage is LOW at 2.9V.

I attempted to change what I have as the battery reading averaging code to what you suggested with no luck.

That "might as well be" was not a suggestion to do that. It was an observation that you are using a loop to add the same value to an accumulated value 50 times. The averaging code is something else you should get help with (and a book) as it's been so long since I messed with statistics (1977) that I can't even remember the names of the methods.

I hope you like the state machine and see how simple one can be. If need be you can run code on several state variables but take care that they don't step on each other.

Yeah, the state machine is very cool, it was kind of hard to understand at first, but after looking it over a few times and changing different things I am starting to understand it better. Very powerful.

Beginner programming teaches a start - middle - end approach which fits a lot of things done with computers. But real time code only ends when the user chooses, power runs out or you hit a nasty bug. Otherwise it goes around and around keeping track of what went on to know what to do with what goes on.

I must say that it is exciting to see how many different ways there are to do similar things in C. I have never messed with any kind of programming until I started with this project and it really plows me away with how it can be so complex, yet simple at the same time.

Keep it simple and use the Feynmann learning technique when something looks hard. https://www.youtube.com/watch?v=FrNqSLPaZLc You can probably find more on that in a book in one of those places they keep lots of books. :D

I grew up on pencil and paper. It slows you down, gives you time to think and if you're good it gives you a record or picture of what you have done or want to do. Thinking at the keyboard I find rushes things and you end up with something you can't see the whole of at once.

I have always worked with the hardware side of things in the past and it is neat to cross over to the software side of things now too.

It just gets better and learning cross-discipline lets you talk better with that crowd that can't change a lightbulb because it's a hardware problem (old joke, how many programmers does it take to....).