user69943: My Arduino crashes after using sprintf, To reduce system ram am trying to move away from strings to char and now this happened. Loop not working properly and it's not going to webrequest, spent 2 days to find a solution nothing worked yet. My project is to send temp and humidly to my server i was using strings and after one day of use system very slow to send data to server then i realized stings are the culprit then i changed to char
char ventionoroff[6];

char Foggeronoroff[6] ;

char Exhuastonoroff[6] = "OFF";

char current[4];

char today[10];

bool running = false;
bool isFoggerRunning = false;
bool isExhaustFanRunning = false;





Time t;


void loop() {


  
 t = rtc.getTime();

  hum = dht.readHumidity();
  temp = dht.readTemperature();
  delay(1000);
  
  if (isnan(hum) || isnan(temp)) {
    Serial.println(F("Failed to read from DHT sensor!"));
    return;
  }
  val = digitalRead(powerStatus);


      byte MIN = t.hour;
      byte SEC = t.min;
     
  char timeStamp[20];
 snprintf(today, "%02d:%02d",  MIN, SEC);

   Serial.println(today);


if (millis() - lastConnectionTime > postingInterval) {
   Serial.println("reaching here2");
    httpRequest();
  }

  if (val)
  snprintf( current , "YES");
   
  else
 snprintf( current , "NO");
   
 
  if (running == false) {
    snprintf( Foggeronoroff , "WAIT");
   
  } else {
   snprintf( Foggeronoroff , "READY");
   
  }
  
    ventilationfan();
  






void httpRequest() {
Serial.println("shit reached here");
  client.stop();
  char data[10];
  const char phpScript[21]  = "";
  const char server[20]  =  ""; // also change the Host line in httpRequest()

   char strt[6];
   char str[6];
  sprintf(strt, "te=%d", temp);
  strcpy(data, strt);
  strcat (data,"&ti=");
  strcat (data,today);
   strcat (data,"&mot=");
   strcat (data,ventionoroff);
   strcat (data,",");
   strcat (data,Foggeronoroff);
    strcat (data,",");
    strcat (data,current);
     strcat (data,"&mo=");
     strcat (data,Exhuastonoroff);
      sprintf(str, "&hum=%d",hum);
      strcat (data,str);
       
 Serial.println(data);
   int len = strlen(data);
  if (client.connect(server, 80)) {
    client.print("POST ");
    client.print(phpScript);
    client.println(" HTTP/1.1");
    client.println("Host:");
    client.println("User-Agent: Arduino/1.0");
    client.println("Connection: close");
    client.println("Content-Type: application/x-www-form-urlencoded; charset=UTF-8");
    client.print("Content-Length: ");
    client.println(len);
    client.println();
    client.print(data);
    restartnet = 0;
     data[0] = 0;
     Serial.print("data after sucessfull connection");
     Serial.println(data);
     Serial.print("freeMemory after connection");
     Serial.println(freeMemory());
    lastConnectionTime = millis();
   
  } else {
    
     Serial.println(F("Failed"));
     data[0] = 0;
   
  }
}


user7508: There are quite a few points that could be improved in this code. The
main ones have already been shown in the comments:

the data buffer was not large enough to hold the whole string,
which leads to a buffer overflow, memory corruption and, ultimately,
the crash you are experiencing.

The second parameter to snprintf() should be the size of the
provided buffer.


Here I will add a few points that, although not really defects of this
program, could help improved it and save memory.
Here:
char current[4];
// ...
if (val)
    snprintf(current, "YES");
else
    snprintf(current, "NO");

you are not using the current buffer to build a string, but only to
store one of two pre-existing strings (the literals "YES" and "NO")
that are already stored in memory. Rather than making a copy, you could
instead reuse those pre-existing strings, and have current be a
pointer to the relevant one:
const char *current;
// ...
if (val)
    current = "YES";
else
    current = "NO";

This only saves two bytes (size of the buffer minus size of the
pointer), but this pattern happens multiple times in the program, and
the savings add up.
Now, another small optimization. Here:
char strt[6];
sprintf(strt, "te=%d", temp);
strcpy(data, strt);

you do not need the extra strt buffer, as you can write directly into
the data buffer. Better yet, you can write everything into the
buffer in a single call to snprintf():
snprintf(data, sizeof data,
        "te=%d&ti=%02d:%02d&mot=%s,%s,%s&mo=%s&hum=%d",
        temp, t.hour, t.min, ventionoroff, Foggeronoroff, current,
        Exhuastonoroff, hum);

If you don't like this approach, and would prefer writing the data in
separate calls to snprintf(), you can do so without using auxiliary
buffers. You have to remember (with a pointer) where within the buffer
you finished your previous write, and pass this address to the next
snprintf() call. Note that you also have to keep track of the room
that is still available, which is easy to do with a second pointer that
points to the end of the buffer:
char *p = data;                  // current writing position
char *end = data + sizeof data;  // end of the buffer
p += snprintf(p, end - p, "te=%d", temp);
p += snprintf(p, end - p, "&ti=%s", today);
// ...


69943: <p>My Arduino crashes after using sprintf, To reduce system ram am trying to move away from strings to char and now this happened. Loop not working properly and it's not going to webrequest, spent 2 days to find a solution nothing worked yet. My project is to send temp and humidly to my server i was using strings and after one day of use system very slow to send data to server then i realized stings are the culprit then i changed to char</p>
<pre><code>char ventionoroff[6];

char Foggeronoroff[6] ;

char Exhuastonoroff[6] = &quot;OFF&quot;;

char current[4];

char today[10];

bool running = false;
bool isFoggerRunning = false;
bool isExhaustFanRunning = false;





Time t;


void loop() {


  
 t = rtc.getTime();

  hum = dht.readHumidity();
  temp = dht.readTemperature();
  delay(1000);
  
  if (isnan(hum) || isnan(temp)) {
    Serial.println(F(&quot;Failed to read from DHT sensor!&quot;));
    return;
  }
  val = digitalRead(powerStatus);


      byte MIN = t.hour;
      byte SEC = t.min;
     
  char timeStamp[20];
 snprintf(today, &quot;%02d:%02d&quot;,  MIN, SEC);

   Serial.println(today);


if (millis() - lastConnectionTime &gt; postingInterval) {
   Serial.println(&quot;reaching here2&quot;);
    httpRequest();
  }

  if (val)
  snprintf( current , &quot;YES&quot;);
   
  else
 snprintf( current , &quot;NO&quot;);
   
 
  if (running == false) {
    snprintf( Foggeronoroff , &quot;WAIT&quot;);
   
  } else {
   snprintf( Foggeronoroff , &quot;READY&quot;);
   
  }
  
    ventilationfan();
  






void httpRequest() {
Serial.println(&quot;shit reached here&quot;);
  client.stop();
  char data[10];
  const char phpScript[21]  = &quot;&quot;;
  const char server[20]  =  &quot;&quot;; // also change the Host line in httpRequest()

   char strt[6];
   char str[6];
  sprintf(strt, &quot;te=%d&quot;, temp);
  strcpy(data, strt);
  strcat (data,&quot;&amp;ti=&quot;);
  strcat (data,today);
   strcat (data,&quot;&amp;mot=&quot;);
   strcat (data,ventionoroff);
   strcat (data,&quot;,&quot;);
   strcat (data,Foggeronoroff);
    strcat (data,&quot;,&quot;);
    strcat (data,current);
     strcat (data,&quot;&amp;mo=&quot;);
     strcat (data,Exhuastonoroff);
      sprintf(str, &quot;&amp;hum=%d&quot;,hum);
      strcat (data,str);
       
 Serial.println(data);
   int len = strlen(data);
  if (client.connect(server, 80)) {
    client.print(&quot;POST &quot;);
    client.print(phpScript);
    client.println(&quot; HTTP/1.1&quot;);
    client.println(&quot;Host:&quot;);
    client.println(&quot;User-Agent: Arduino/1.0&quot;);
    client.println(&quot;Connection: close&quot;);
    client.println(&quot;Content-Type: application/x-www-form-urlencoded; charset=UTF-8&quot;);
    client.print(&quot;Content-Length: &quot;);
    client.println(len);
    client.println();
    client.print(data);
    restartnet = 0;
     data[0] = 0;
     Serial.print(&quot;data after sucessfull connection&quot;);
     Serial.println(data);
     Serial.print(&quot;freeMemory after connection&quot;);
     Serial.println(freeMemory());
    lastConnectionTime = millis();
   
  } else {
    
     Serial.println(F(&quot;Failed&quot;));
     data[0] = 0;
   
  }
}
</code></pre>
 7508: <p>There are quite a few points that could be improved in this code. The
main ones have already been shown in the comments:</p>
<ol>
<li><p>the <code>data</code> buffer was not large enough to hold the whole string,
which leads to a buffer overflow, memory corruption and, ultimately,
the crash you are experiencing.</p>
</li>
<li><p>The second parameter to <code>snprintf()</code> should be the size of the
provided buffer.</p>
</li>
</ol>
<p>Here I will add a few points that, although not really defects of this
program, could help improved it and save memory.</p>
<p>Here:</p>
<pre class="lang-cpp prettyprint-override"><code>char current[4];
// ...
if (val)
    snprintf(current, &quot;YES&quot;);
else
    snprintf(current, &quot;NO&quot;);
</code></pre>
<p>you are not using the <code>current</code> buffer to build a string, but only to
store one of two pre-existing strings (the literals <code>&quot;YES&quot;</code> and <code>&quot;NO&quot;</code>)
that are already stored in memory. Rather than making a copy, you could
instead reuse those pre-existing strings, and have <code>current</code> be a
pointer to the relevant one:</p>
<pre class="lang-cpp prettyprint-override"><code>const char *current;
// ...
if (val)
    current = &quot;YES&quot;;
else
    current = &quot;NO&quot;;
</code></pre>
<p>This only saves two bytes (size of the buffer minus size of the
pointer), but this pattern happens multiple times in the program, and
the savings add up.</p>
<p>Now, another small optimization. Here:</p>
<pre class="lang-cpp prettyprint-override"><code>char strt[6];
sprintf(strt, &quot;te=%d&quot;, temp);
strcpy(data, strt);
</code></pre>
<p>you do not need the extra <code>strt</code> buffer, as you can write directly into
the <code>data</code> buffer. Better yet, you can write <em>everything</em> into the
buffer in a single call to <code>snprintf()</code>:</p>
<pre class="lang-cpp prettyprint-override"><code>snprintf(data, sizeof data,
        &quot;te=%d&amp;ti=%02d:%02d&amp;mot=%s,%s,%s&amp;mo=%s&amp;hum=%d&quot;,
        temp, t.hour, t.min, ventionoroff, Foggeronoroff, current,
        Exhuastonoroff, hum);
</code></pre>
<p>If you don't like this approach, and would prefer writing the data in
separate calls to <code>snprintf()</code>, you can do so without using auxiliary
buffers. You have to remember (with a pointer) where within the buffer
you finished your previous write, and pass this address to the next
<code>snprintf()</code> call. Note that you also have to keep track of the room
that is still available, which is easy to do with a second pointer that
points to the end of the buffer:</p>
<pre class="lang-cpp prettyprint-override"><code>char *p = data;                  // current writing position
char *end = data + sizeof data;  // end of the buffer
p += snprintf(p, end - p, &quot;te=%d&quot;, temp);
p += snprintf(p, end - p, &quot;&amp;ti=%s&quot;, today);
// ...
</code></pre>
