Can not figure out how to get "While" working

I have the basic program running with no issues. It reads 3 voltages, Battery/Solar, 110VAC to 12VDC power supply, the load side of 2 Blocking Diodes and prints them out. Now I want to read each voltage 10 times to get a better average of the actual voltage. I am trying to use “While” in a loop, to get the 10 voltage readings, then divide the sum of the 10 readings by 10 and use the average in the display calculation.

No mater where I place the While code, it doesn’t work. I have tried numerous examples, with no luck.

Here is the working code, with the :“While” code commented out, between the dashed lines. I also commented out all but the A0 entries needed for the averaging code.

Also, after much redoing, I finally got the voltages to display properly whether the input voltage is 12, 9 or 5 VDC. I designed a UPS PCB board that I am using for my Home Automation and Energy Management electronics which will use battery & SOLAR and a 110VAC to 12VDC 20 Amp power supply as inputs. When the AC Power supply drops off because of a power outage the electronics will continue working with no interruptions as the Battery/Solar will be also powering it.

Thanks

// set reference voltage;
  float refVcc = 12.0;
 // float refVcc = 09.0;
 // float refVcc = 5.0;
 
  #define NUM_SAMPLES 10          // Number of samples to take

  int sum_A0 = 0;                    // sum of A0 samples taken
 // int sum_A1 = 0;                    // sum of A1 samples taken
 // int sum_A2 = 0;                    // sum of A2 samples taken  
 
  unsigned char sample_count_A0 = 0; // current sample for A0
 // unsigned char sample_count_A1 = 0; // current sample for A1
 // unsigned char sample_count_A2 = 0; // current sample for A2

  void setup() 
 {
  Serial.begin(9600);
 }
  void loop() 
 {
 
 // read the input on analog pin 0, 1, 2:
  int DiodeOutputVoltage = analogRead(A0);
  
// -------------------------------------------------------------
// While sample_count_A0 is < NUM_SAMPLES 
//   {
//        sum_A0 += analogRead(A0);          Not sure if this code will work
//        sample_count_A0 ++;                I have tried it in different places
//        delay(10);                         with no luck. Need to do a sample of
//   }                                       10 to average out the voltages
// -------------------------------------------------------------
  
  int VoltageSource_1 = analogRead(A1);
  int VoltageSource_2 = analogRead(A2);
 
 // print out the converted (voltage) value 
  Serial.println ("----------------------------------------"); 
  Serial.println ("  HOME AUTOMATION - ENERGY MANAGEMENT");
  Serial.println ("      UPS System Control Voltages");
  Serial.println ("----------------------------------------");
  Serial.print ("Diode  Output Voltage:       ");
  Serial.print (DiodeOutputVoltage * 1.6 * refVcc/1024);
  Serial.println ( " Volts");
  Serial.println ();

  Serial.print ("SOLAR / BATTERY INPUT:        ");
  Serial.print (VoltageSource_1 * 1.61 * refVcc/1024);
  Serial.println ( " Volts");
  Serial.println ();

  Serial.print ("AC POWER SUPPLY INPUT:       ");
  Serial.print (VoltageSource_2 * 1.61 * refVcc/1024);
  Serial.println ( " Volts");
  Serial.println ("----------------------------------------");
  Serial.println ();
  Serial.println ();

  delay(5000);        
 }

Serial Monitor Output:

18:16:56.066 -> 
18:17:00.982 -> ----------------------------------------
18:17:01.029 ->   HOME AUTOMATION - ENERGY MANAGEMENT
18:17:01.082 ->       UPS System Control Voltages
18:17:01.082 -> ----------------------------------------
18:17:01.129 -> Diode  Output Voltage:           12.04 Volts
18:17:01.183 -> 
18:17:01.183 -> SOLAR / BATTERY INPUT:        12.06 Volts
18:17:01.229 -> 
18:17:01.229 -> AC POWER SUPPLY INPUT:       12.02 Volts
18:17:01.283 -> ----------------------------------------
18:17:01.330 -> 
18:17:01.330 ->

// While sample_count_A0 is < NUM_SAMPLES

It’s not English, or COBOL, so you need fewer words and more punctuation:

 while ( sample_count_A0 < NUM_SAMPLES )

while(bla bla bla) {
do something;
}

you forgot the ( ) brackets.

-jim lee

just not fast enough..

-jim lee

sum_A0 = 0;
sample_count_A0 = 0;
while(sample_count_A0 < NUM_SAMPLES)
{
sum_A0 += analogRead(A0);
sample_count_A0 ++;
delay(10);
}

What’s wrong with a for loop?

you forgot the ( ) brackets.

They already had the bracket on the next line. Not my favorite coding style, but sufficient...

What's wrong with a for loop?

Nothing is wrong with a for loop, bu when I answer a question, especially a beginner question, I usually try to answer the question that was asked, rather than devolve into different/better ways to do the same thing. And C's "for" syntax is relatively weird.

Wiring diagram please.

JCA34F:
Wiring diagram please.

Well, I would but can't as it wants a URL.

Almost there!

Changed "While" to "while" and added the parentheses. Amazing how that will get the program running.

It runs through getting the A0, A1 and A2 voltage readings (once) and then just keeps cycling through the display section without returning to get new voltage readings. I tried moving the brackets around with no success. I am thinking that that is the issue. Maybe...

So, do I need to rewrite the entire script to get it to return to the beginning to get the current analog voltages? I added comments to show where I am using code to figure out where I am going wrong.

Thanks

Most likely, I would guess, you are missing the line....

sample_count_A0 = 0;

...immediately before the while loop.

It is not enough to have this...

 unsigned char sample_count_A0 = 0;

That line gets executed only once, when the Arduino first starts up.

Therefore, second time through loop(), the condition is satisfied before the while even executes.

But you need to post your modified code if you change something and it doesn’t work. We’ve no idea what you changed otherwise, or if you changed it correctly.

pcbbc:
Most likely, I would guess, you are missing the line…

sample_count_A0 = 0;

…immediately before the while loop.

It is not enough to have this…

 unsigned char sample_count_A0 = 0;

That line gets executed only once, when the Arduino first starts up.

Therefore, second time through loop(), the condition is satisfied before the while even executes.

But you need to post your modified code if you change something and it doesn’t work. We’ve no idea what you changed otherwise, or if you changed it correctly.

OK, First off, relocating setting the variables back to “0” to the “void Loop” section worked perfectly. Granted, my code may not be the best way of doing it, but it is a start.

Thanks

// set reference voltage;
float refVcc = 12.0;
// float refVcc = 5.0;

// the setup routine runs once when you press reset:

// number of analog samples to take per reading
#define NUM_SAMPLES_A0 10          // Number of samples to take
#define NUM_SAMPLES_A1 10          // Number of A1 samples to take
#define NUM_SAMPLES_A2 10          // Number of A2 samples to take 

void setup()
{
  Serial.begin(9600);
}
// the loop routine runs over and over again forever:
void loop()
{
  int sum_A0 = 0;                    // sum of A0 samples taken
  int sum_A1 = 0;                    // sum of A0 samples taken
  int sum_A2 = 0;                    // sum of A0 samples taken
  unsigned char sample_count_A0 = 0; // current sample number
  unsigned char sample_count_A1 = 0; // current sample number
  unsigned char sample_count_A2 = 0; // current sample number

  // Take Analog samples on A0
  while (sample_count_A0 < NUM_SAMPLES_A0)
  {
    int DiodeOutputVoltage = analogRead(A0);
    sum_A0 += analogRead(A0);
    sample_count_A0 ++;
    delay(10);
  }
  // Take Analog samples on A1
  int VoltageSource_1 = analogRead(A1);
  while (sample_count_A1 < NUM_SAMPLES_A1)
  {
    sum_A1 += analogRead(A1);
    sample_count_A1 ++;
    delay(10);
  }
  // Take Analog samples on A2
  int VoltageSource_2 = analogRead(A2);
  while (sample_count_A2 < NUM_SAMPLES_A2)
  {
    sum_A2 += analogRead(A2);
    sample_count_A2 ++;
    delay(10);
  }
  // print out the converted (voltage) value

  Serial.println ("----------------------------------------");
  Serial.println ("  HOME AUTOMATION - ENERGY MANAGEMENT");
  Serial.println ("      UPS System Control Voltages");
  Serial.println ("----------------------------------------");
  Serial.print ("Diode  Output Voltage:       ");
  Serial.print ((sum_A0 / NUM_SAMPLES_A0)  * 1.6 * (refVcc / 1024));
  Serial.println ( " Volts");
  Serial.println (sum_A0);                        // Test line
  Serial.println ();

  Serial.print ("SOLAR / BATTERY INPUT:       ");
  Serial.print ((sum_A1 / NUM_SAMPLES_A1) * 1.61 * refVcc / 1024);
  Serial.println ( " Volts");
  Serial.println (sum_A1);                        // Test line
  Serial.println ();

  Serial.print ("AC POWER SUPPLY INPUT:       ");
  Serial.print ((sum_A2 / NUM_SAMPLES_A2) * 1.61 * refVcc / 1024);
  Serial.println ( " Volts");
  Serial.println (sum_A2);                        // Test line
  Serial.println ("----------------------------------------");
  Serial.println ();
  Serial.println ();

  delay(5000);        // delay 5 second before reading analog inputs again

}

Thank you

Well done.

But why are you reading A0 twice every time…

    int DiodeOutputVoltage = analogRead(A0);
    sum_A0 += analogRead(A0);

Reading A1 once here, but doing nothing with VoltageSource_1 ever…

  int VoltageSource_1 = analogRead(A1);

Reading A2 once here, but doing nothing with VoltageSource_2 ever…

  int VoltageSource_2 = analogRead(A2);

Using a multiplier of 1.6 for A0, but then 1.61 for A1 and A2?

Nothing wrong with your “while” loops now, but they are a somewhat blunt instrument for doing a loop a set number of times.

Usually that is the job of “for”…

// set reference voltage;
float refVcc = 12.0;

// the setup routine runs once when you press reset:

// number of analog samples to take per reading
#define NUM_SAMPLES_A0 10          // Number of samples to take
#define NUM_SAMPLES_A1 10          // Number of A1 samples to take
#define NUM_SAMPLES_A2 10          // Number of A2 samples to take

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

// the loop routine runs over and over again forever:
void loop()
{
  int sum_A0 = 0;                    // sum of A0 samples taken
  // Take Analog samples on A0
  for (int i = 0; i < NUM_SAMPLES_A0; i++)
  {
    sum_A0 += analogRead(A0);
    delay(10);
  }

  int sum_A1 = 0;                    // sum of A0 samples taken
  // Take Analog samples on A1
  for (int i = 0; i < NUM_SAMPLES_A1; i++)
  {
    sum_A1 += analogRead(A1);
    delay(10);
  }

  int sum_A2 = 0;                    // sum of A0 samples taken
  // Take Analog samples on A2
  for (int i = 0; i < NUM_SAMPLES_A2; i++)
  {
    sum_A2 += analogRead(A2);
    delay(10);
  }

  Serial.println ("----------------------------------------");
  Serial.println ("  HOME AUTOMATION - ENERGY MANAGEMENT");
  Serial.println ("      UPS System Control Voltages");
  Serial.println ("----------------------------------------");
  Serial.print ("Diode  Output Voltage:       ");
  Serial.print ((sum_A0 / NUM_SAMPLES_A0)  * 1.61 * refVcc / 1024);
  Serial.println ( " Volts");
  Serial.println (sum_A0);                        // Test line
  Serial.println ();

  Serial.print ("SOLAR / BATTERY INPUT:       ");
  Serial.print ((sum_A1 / NUM_SAMPLES_A1) * 1.61 * refVcc / 1024);
  Serial.println ( " Volts");
  Serial.println (sum_A1);                        // Test line
  Serial.println ();

  Serial.print ("AC POWER SUPPLY INPUT:       ");
  Serial.print ((sum_A2 / NUM_SAMPLES_A2) * 1.61 * refVcc / 1024);
  Serial.println ( " Volts");
  Serial.println (sum_A2);                        // Test line
  Serial.println ("----------------------------------------");
  Serial.println ();
  Serial.println ();

  delay(5000);        // delay 5 second before reading analog inputs again

}

JCA34F:
Wiring diagram please.

Here is the link to a picture of the UPS-PCB that I designed and working on the Arduino code for. It has 2 inputs and 4 outputs. I will be enhancing the Arduino's code to send me a text message/email when either (or both) the Battery/Solar power source or the 110VAC to 12VDC power supply inputs drop below a specified voltage or goes above a specified voltage. It also monitors the voltage on the load side of the 30 amp Blocking Diodes. The blocking diodes allow for the use of 2 different power sources without an interruption to power. They keep the input power from reaching the other power source. The green LED's on the right show which input has power, the blue LED on the left just shows that there is power on the load side. It has the capabilities of 6 voltage dividers of which 3 (in the picture) are designed into the PCB and connected to the 2 inputs and blocking diode outputs. The 2 blue 470mf electrolytic capacitors absorb any voltage fluctuations, should one of the power sources drop off.

This UPS-PCB is designed to keep all my Home Automation and Energy Management equipment up and running during the MANY power outages here in Florida. Most of the time the power outages range from a few seconds to hours, constantly making the electronics reboot and sometimes need to be rebooted after the power failure as they did not come back on line working properly. It also allows keeping the Energy management equipment up and running monitoring the power companies power outage.

My website link

Picture of the UPS-PCB circuit board.

pcbbc:
Well done.

But why are you reading A0 twice every time…

    int DiodeOutputVoltage = analogRead(A0);

sum_A0 += analogRead(A0);




Reading A1 once here, but doing nothing with VoltageSource_1 ever...


int VoltageSource_1 = analogRead(A1);




Reading A2 once here, but doing nothing with VoltageSource_2 ever...


int VoltageSource_2 = analogRead(A2);




Using a multiplier of 1.6 for A0, but then 1.61 for A1 and A2?


Nothing wrong with your "while" loops now, but they are a somewhat blunt instrument for doing a loop a set number of times.

Usually that is the job of "for"...


// set reference voltage;
float refVcc = 12.0;

// the setup routine runs once when you press reset:

// number of analog samples to take per reading
#define NUM_SAMPLES_A0 10          // Number of samples to take
#define NUM_SAMPLES_A1 10          // Number of A1 samples to take
#define NUM_SAMPLES_A2 10          // Number of A2 samples to take

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

// the loop routine runs over and over again forever:
void loop()
{
  int sum_A0 = 0;                    // sum of A0 samples taken
  // Take Analog samples on A0
  for (int i = 0; i < NUM_SAMPLES_A0; i++)
  {
    sum_A0 += analogRead(A0);
    delay(10);
  }

int sum_A1 = 0;                    // sum of A0 samples taken
  // Take Analog samples on A1
  for (int i = 0; i < NUM_SAMPLES_A1; i++)
  {
    sum_A1 += analogRead(A1);
    delay(10);
  }

int sum_A2 = 0;                    // sum of A0 samples taken
  // Take Analog samples on A2
  for (int i = 0; i < NUM_SAMPLES_A2; i++)
  {
    sum_A2 += analogRead(A2);
    delay(10);
  }

Serial.println ("----------------------------------------");
  Serial.println ("  HOME AUTOMATION - ENERGY MANAGEMENT");
  Serial.println ("      UPS System Control Voltages");
  Serial.println ("----------------------------------------");
  Serial.print ("Diode  Output Voltage:      “);
  Serial.print ((sum_A0 / NUM_SAMPLES_A0)  * 1.61 * refVcc / 1024);
  Serial.println ( " Volts”);
  Serial.println (sum_A0);                        // Test line
  Serial.println ();

Serial.print ("SOLAR / BATTERY INPUT:      “);
  Serial.print ((sum_A1 / NUM_SAMPLES_A1) * 1.61 * refVcc / 1024);
  Serial.println ( " Volts”);
  Serial.println (sum_A1);                        // Test line
  Serial.println ();

Serial.print (“AC POWER SUPPLY INPUT:      “);
  Serial.print ((sum_A2 / NUM_SAMPLES_A2) * 1.61 * refVcc / 1024);
  Serial.println ( " Volts”);
  Serial.println (sum_A2);                        // Test line
  Serial.println (”----------------------------------------");
  Serial.println ();
  Serial.println ();

delay(5000);        // delay 5 second before reading analog inputs again

}

Thank you!
Originally I was using those variables and decided to use different names and needless to say, I forgot to remove the old ones. Need to do a little better cleanup of code.

I will give the “for” method a try to see how that goes.

I must have truncated the last number in the 1.61 in the equation when copying it to the others
…Corrected.

The voltages are more constant now with the averaging

Again thanks to everyone

Thanks again, working perfectly. Here is the latest code. Will try using the “for” tonight.

// set reference voltage;
float refVcc = 12.0;
// float refVcc = 9.0;
// float refVcc = 5.0;

// the setup routine runs once when you press reset:

// number of analog samples to take per reading
#define NUM_SAMPLES 10          // Number of samples to take

void setup()
{
  Serial.begin(9600);
}
// the loop routine runs over and over again forever:
void loop()
{
  int sum_A0 = 0;                    // sum of A0 samples taken
  int sum_A1 = 0;                    // sum of A0 samples taken
  int sum_A2 = 0;                    // sum of A0 samples taken
  unsigned char sample_count_A0 = 0; // current sample number
  unsigned char sample_count_A1 = 0; // current sample number
  unsigned char sample_count_A2 = 0; // current sample number

  while (sample_count_A0 < NUM_SAMPLES)
  {
    sum_A0 += analogRead(A0);
    sample_count_A0 ++;
    delay(10);
  }

  while (sample_count_A1 < NUM_SAMPLES)
  {
    sum_A1 += analogRead(A1);
    sample_count_A1 ++;
    delay(10);
  }

  while (sample_count_A2 < NUM_SAMPLES)
  {
    sum_A2 += analogRead(A2);
    sample_count_A2 ++;
    delay(10);
  }
// 
  Serial.println ("----------------------------------------");
  Serial.println ("  HOME AUTOMATION - ENERGY MANAGEMENT");
  Serial.println ("      UPS System Control Voltages");
  Serial.println ("----------------------------------------");
  Serial.print ("Diode  Output Voltage:       ");
  Serial.print ((sum_A0 / NUM_SAMPLES)  * 1.61 * (refVcc / 1024));
  Serial.println ( " Volts");
  Serial.println ();

  Serial.print ("SOLAR / BATTERY INPUT:       ");
  Serial.print ((sum_A1 / NUM_SAMPLES) * 1.61 * refVcc / 1024);
  Serial.println ( " Volts");
  Serial.println ();

  Serial.print ("AC POWER SUPPLY INPUT:       ");
  Serial.print ((sum_A2 / NUM_SAMPLES) * 1.61 * refVcc / 1024);
  Serial.println ( " Volts");
  Serial.println ("----------------------------------------");
  Serial.println ();
  Serial.println ();

  delay(5000);        // delay 5 second before reading analog inputs again

}