2

I've written some Arduino Code which kept crashing and i couldn't find out why. Then i reduced the code as much as i could in order to see the problem. The reduced code currently doesn't do anything extraordinary except printing some strings over the serial line.

This is the reduced code:

void setup() 
{
  Serial.begin(9600);
  Serial.print("Begin\r\n");
  send_wifi_beacon();
}
void loop()
{  
  delay(1000);
}
void send_wifi_beacon()
{
  send_wlan_chip_command("AT+CIFSR");
  Serial.print("notreached"); // this part is never reached
  send_data_over_network(); // can't remove this line otherwise the crash won't happen which is weird since this is never called
}
void read_response_from_serial()
{  
  delay(2000);
  Serial.print("==-1\r\n"); // crashes here
}
void send_wlan_chip_command(char* command)
{
  Serial.print("Sending command to wifi module: ");
  Serial.print(command);
  read_response_from_serial();
  Serial.print("Command response: ");
}
// this function is never called, since the crash happens before the call, but it can't be removed otherwise the crash won't happen
// also it can't  be altered then, the crash also will not happen.
void send_data_over_network()
{
  char number[3] = "12";
  //char number[3] = "";
  char length_of_payload[20] = "0123456789012345678"; // 20 digits if assuming 64 bit integer is the maximum this code will ever run on
//  char length_of_payload[20] = "";
  char *command;

  command = malloc(26);
  command = "AT+CIPSSEND";
  strcat(command, number);
  strcat(command, ",");
  strcat(command, length_of_payload);
  send_wlan_chip_command(command);
  free(command);
}

This is the according output:

Begin Sending command to wifi module: AT+CIFSR==Begin
Sending command to wifi module: AT+CIFSR==Begin
Sending command to wifi module: AT+CIFSR==Begin
Sending command to wifi module: AT+CIFSR==Begin

Which means that the arduino keeps crashing and resetting. This goes on forever.

The weird thing is, if I change the following two lines to: (in the"send_data_over_network" function as in example above)

char number[3] = "1"; // changed from => char number[3] = "";
char length_of_payload[20] = "123"; // changed from => char length_of_payload[20] = "0123456789012345678";

The output now changes to :

exact output

I call this behaviour weird since it shouldn't have any influence on the result because this function(send_data_over_network) is never called in the crash example from before.

Troubleshooting options i already tried:

  • Reinstalling Arduino IDE , i tried with mutliple versions 1.8 , 1.6, 1.4. 1.0
  • Different Arduino Boards (Arduino Uno and Arduino Mega)
  • Different Laptops (since i thought maybe it's related to power issues of my laptop)

Maybe it's something obvious and i just can't see it, but i already spent +16h debugging, so help would be really appreciated.

1

This code looks wrong:

  command = malloc(26);
  command = "AT+CIPSSEND";
  strcat(command, number);
  strcat(command, ",");
  strcat(command, length_of_payload);
  send_wlan_chip_command(command);

First you allocate 26 bytes, then a new string is created, which you strcat to it. This happens in memory that is not allocated (or overwrites other data).

Instead of

  command = "AT+CIPSSEND";

use

  strcpy(command, "AT+CIPSSEND");

Also check that 26 bytes is enough, change it to 128 bytes to be sure (check the correct amount you need later).

| improve this answer | |
  • If you choose to use malloc() and strings, be sure to initialize the memory to zeros, or strcat will not function as expected. – jose can u c Aug 22 '17 at 19:33
  • 1
    Not "suspicious". It's "wrong". One can't append to a string constant....Also, you want strcpy, not strcat in your correction. – Johnny Mopp Aug 22 '17 at 19:35
  • 1
    @KoKIA are you sure the function was not called? The easiest way is to add a print statement before and after the wrong code ... and preferably add a bit after each print command to be sure the information got flushed (not sure if the delay is absolutely necessary). But print statements help a lot (if debugging is not possible like in Arduino). – Michel Keijzers Aug 22 '17 at 20:01
  • 2
    @KoKlA Also, even if your code worked, you would end up with a memory leak as you immediately re-assign the value returned from malloc. That memory is lost. Also because of the reassignment, you would error on the free(). – Johnny Mopp Aug 22 '17 at 20:02
  • 1
    Consider using alloca() instead of malloc(). It allocates on the stack instead of the heap and is automatically freed when the function exits and the stack frame is discarded. – Majenko Aug 22 '17 at 20:17
1

You are almost certainly running out of memory and have a stack collision with the heap. Dynamic memory allocation and de-allocation is not a good idea when you have less than 2K RAM to work with. If you use malloc() use it only to allocate buffer space and then reuse the buffers. Put your test code entirely in setup and see what happens. Also check the amount of RAM allocated at compile time it may be more than you think.

char *buf1;
char *buf2;

void setup() {
   buf1 = (char *) malloc(10);
   buf2 = (char *) malloc(10);
   .
   .
   // test code here
}
| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.