Func freeze the loop, unless i use a serial.print

First, this is a project where im counting pulses on my electrical powermeter. It adds up some samples, calculate average, and prints on lcd + sends over ethernet.

So, my first version i didnt have any functions, this is my first time i write C. Today i cleaned up the code and sorted it out in different functions.
My largest function getAvgWatt() is a while loop that reads an LDR, measures time between the led pulses, calculates average, and return current power consumption in watts. This worked perfectly yesterday. Today it freezes the Arduiono, it wont even count a sigle pulse. After much debugging (putting serial.print everywhere) I found out that the while loop stops after one run. However, if i added a serial.print(variable); inside the whileloop everything runs like it should.

So why do i need to print to Serial inside the while loop to keep it from freezing? My first guess was that it needed a delay, so i tried with delay(10) to delay(500), but still freezes. Anyway, i cant have a big delay inside that loop, because it calculates time between pulses, and the time would be affected by the delay(), the serial.print() does not seem to affect the time.

Heres the code:

#include <TimedAction.h>
#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
int ledPin = 13;
int avgwatt = 5;
int switchPin = 7;              
const int numReadings = 20; 

TimedAction timedAction = TimedAction(60000,sendData); // run sendData() every 1 minute

void setup()                    
{
  Serial.begin(9600);           
  pinMode(switchPin, INPUT);    
  pinMode(ledPin, OUTPUT);
  lcd.begin(16, 2);

} 
void loop()                     
{
  
      avgwatt = getAvgWatt();   // returns average watt
      lcd.setCursor(0,0);
      lcd.print(avgwatt);
      lcd.print(" WATT   ");
      Serial.print("Avgwatt er utregnet til: ");  // for debugging
      Serial.println(avgwatt);
      timedAction.check(); // check if its time to do the Senddata()
      
}

void sendData(){  // for debugging, sending over ethernet will be added here.
  Serial.println("#####################----#######################");
  Serial.println(avgwatt);
  Serial.println("#####################----#######################");

}
  

int getAvgWatt(){
  unsigned long watt = 0;
  int index = 0; 
  float average= 0;
  float total = 0;     
  int old_val = 0;
  unsigned long current_time = 0;
  unsigned long last_time = 0;
  float delayarray[numReadings]; 
  float pulsedelay;
  int val = LOW;
  last_time = millis();
  for (int thisReading = 0; thisReading < numReadings; thisReading++)
  {
     delayarray[thisReading] = 0;   
  }
   while (index <= numReadings){
       val = (digitalRead(switchPin));              // Reads value  high/low and saves it
       if ((val == HIGH) && (old_val == LOW)) {     // We have light, lets read the time, and value.
       current_time = millis();                         // Current time
       pulsedelay = current_time - last_time;             // Delay since last pulse
       pulsedelay = pulsedelay / 1000;                     // I want seconds, not ms

       digitalWrite(ledPin, HIGH);                  // Blinks the LED
       delayarray[index] = pulsedelay;              // Add the value to the array
       old_val = val;                               // Sets old_val high
       Serial.println(pulsedelay);                              // THIS IS THE ONE THAT KEEPS IT FROM FREEZING
       last_time = current_time;                    // for the next whileloop-cycle to know the next delay.
       index +=1;    
     
   }
   else {
       digitalWrite(ledPin, LOW); // No light detected
       old_val = val;
       }  
  }  

  
  for (int i = 1; i< numReadings;i++){       //Skip the first value in the array, since millis() from the start is off.
     total = total + delayarray[i];   
               }      
     average = total / (numReadings-1); // Minus 1 since we skipped the first value in the array.
     watt = 360 / average; // 360 / average delay gives us current powerconsumption in watts.        
     total = 0;  // for the next cycle
     index = 0;  // for the next cycle
     average= 0; // for the next cycle    
     
     // Empty out the array. Not sure if this is needed.
      for (int y = 0; y < numReadings; y++) {
     delayarray[y] = 0;   
     }
     return watt;    
}

It’s been my experience that when adding/removing debug statements influences the behavior of the program, it is an indication that memory is being overwritten somewhere.

The added debug statements change where the memory location is that is being overwritten, so that the overwritten memory may or may not matter.

You have a situation where memory is being overwritten. Whether correcting that will fix your problem, or not, I do not know. Fixing it would be a good thing, though.

You have “const int numReadings = 20” at the top. Then, you have “float delay[numReadings]” in getAvgWatt. This declares an array of 20 values, with indices from 0 to 19.

Your while loop has “index <= numReadings” as it conditional clause. So, index can get to be 20. When it is, you store a value in delay[20], which is outside the block of memory reserved for that array, overwriting something reserved elsewhere.

Other than that, I see no reason why the Serial.print statement would have any affect on the behavior of the program. On the other hand, I don’t see how, without it, you know where the program is hanging.

Thanks for your reply, and for pointing out that mistake.

I`ll try to use numReadings - 1 in the loop.

But on the other hand, whilst using Serial.print() to debug, it does output correct data when printint delayarray[20]

Well, that didnt fix it. If the getAvgWatt functions doesnt contain a Serial.print(); The whole loop stops when entering the function. The while loop doesnt get executed.

I dont think you can use "else" in a "while" loop, but only in a "for" loop

kind regards Jens

Correction: You can only use "else" in a "if" sentence.

Jens

The else does go with the if. It's poorly formatted code that make it look like the else goes with the while.

This is cool

And this belongs in the Hardware/Troubleshooting section because?

Lefty

Sorry if its missplaced, i didnt find any other subforum where this kind of troubleshooting is discussed.

Still have the problem thoug…

Yeah maybe my code is poorly formatted. This is my first time coding “for real” so bear with me.