Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Arduino: Why does while() loop with boolean argument cause dynamic memory to skyrocket?

I am attempting to run communication between two RF transmitors on Arduino Uno boards.


When initiating the while() loop at the top of the code excerpt below, the dynamic memory usage shoots to 205% (4.2kB) if I use the '==' operator.

However, when using a single '=' as an assignment operator within the loop, this issue does not occur (obviously, the code does not function as required when this is the case).

This is where it gets interesting. Deleting the while() loop and its content completely does not reduce the dynamic memory usage. So it looks to me as if using an assignment operator within the loop actually reduces the dynamic memory usage of the entire sketch (to 15% / 325 bytes).

Oddly, it does not appear to be a leakage problem because even deleting the contents of the while() loop completely does not solve any problems.

I'm fairly fresh-faced to using C++ and Arduino, but assume it may be to do with assignment of global variables...

Any help troubleshooting why the dynamic memory usage is so high would be much appreciated!


I am coding in the Arduino IDE (v1.8.5), writing to an Arduino Uno (ATMega328 chip).

while (loop_var == true){
if (radio.sendWithRetry(TONODEID, &connection_checker, sizeof(connection_checker))){
  if (tick == 0) {
    Serial.print(F("Node ")); Serial.print(TONODEID); Serial.print(F(" detected. \n"));
    tick = 1;
  }
  loop_var = false;
} 
else {
  while (tock == 0){
    Serial.print(F("Node ")); Serial.print(TONODEID); 
    Serial.print(F(" - No ACK received, retrying... \n"));
    tock++;
  }
  loop_var = true;
}
like image 619
Triz Avatar asked Jan 20 '26 23:01

Triz


1 Answers

It's not about what's happening inside the loop, but what's happening outside.

The C++ compiler that comes bundled with Arduino is pretty smart. It figures out whether it is possible to reach an instruction or not. If a large declared variable is only referenced in a part of the code which will never be reached, it does not calculate the memory required for that variable while calculating dynamic memory.

A simple test case would be the following.

int test[100],test2[100];
void loop() {
  bool data=true;
#ifdef WHILE_COMPARE
  while(data == true ){
#else
  while(data = true){
#endif
    for(int i=0;i<100;i++){
      test[i]=0;
    }
    data=false;
  }
#ifdef USE_TEST2
    for(int i=0;i<100;i++){
      test2[i]=0;
    }
#endif
}

Now depending on which of the following combination are declared, the dynamic memory changes in the following manner.

WHILE_COMPARE is defined, USE_TEST2 is defined, the DM shoots to 402 bytes

WHILE_COMPARE is not defined, USE_TEST2 is defined, the DM is 209 bytes

WHILE_COMPARE is defined, USE_TEST2 is not defined, the DM is 209 bytes

WHILE_COMPARE is not defined, USE_TEST2 is not defined, the DM is 209 bytes

I hope this helps.

like image 121
Vinayak Shantaram Joshi Avatar answered Jan 23 '26 13:01

Vinayak Shantaram Joshi