Arduino freezes at data transmission

Hi,

I’m new to Arduino and I bought myself an Arduino Uno with an ethernet shield. I wrote with the help of some tutorials a small program which should read humidity, temperature, light and pressure and transmits this data using a GET request into the internet. It worked very well for me for some days however now I’ve got some really random problems. After 2 - 3 transmissions (sometimes 10) the Arduino will just freeze when sending the data onto the internet. I hope anyone can give me a hint which mistake I’ve made. Currently the code isn’t very optimized.

#include <Client.h>
#include <Server.h>
#include <Ethernet.h>
#include <Print.h>

#include <SPI.h>
#include "Wire.h"
#include "Adafruit_BMP085.h"

#define HIH4030PIN 3
#define LEDr 8
#define LEDg 7
#define LICHT 2

int lichtValue = 0;
int lichtSensor = 0;
float lichtRes = 10.0;

byte mac[] = {  0x00, 0xAA, 0xBB, 0xCC, 0xDE, 0x02 };
byte ip[] = { 192, 168, 178, 254 };
byte myDNS[] = { 192, 168, 178, 1 };
char serverName[] = "www.someweather.de";

int sensorValue;         // value coming from the sensor
float supplyVolt = 5.0;  // supply voltage for the HIH-4030
float voltage;           // sensor voltage
float sensorRH;          // sensor RH (at 25 degrees C)
float trueRH;            // RH % accounting for temperature

EthernetClient client;
Adafruit_BMP085 bmp;

void setup() {
  Serial.begin(9600);
  bmp.begin();
  pinMode(LEDr, OUTPUT);
  pinMode(LEDg, OUTPUT);
  digitalWrite(LEDr, HIGH);
  digitalWrite(LEDg, HIGH);
  delay(2000);
  if (Ethernet.begin(mac)==0) {
    digitalWrite(LEDg, LOW);
    Serial.println("Could not get IP from DHCP");
  }
  else {
    digitalWrite(LEDr,LOW);
    Serial.println("Status: Operational");
    Serial.println("IP Address: ");
    Serial.print(Ethernet.localIP());
    Serial.println("");
  }
  
  delay(1000);
  digitalWrite(LEDr, LOW);
  digitalWrite(LEDg, LOW);
}

void loop() {
  
  digitalWrite(LEDr,HIGH);
  lichtSensor = analogRead(LICHT);
  float Vout0 = lichtSensor*0.0048828125;
  int Lux = 500/(lichtRes*((5-Vout0)/Vout0));
  
  sensorValue = analogRead(HIH4030PIN);
  voltage = sensorValue/1023.0 * supplyVolt;
  sensorRH = 161.0*voltage/supplyVolt - 25.8;
  trueRH = sensorRH / (1.0546 - 0.0026 * bmp.readTemperature());
    
  Serial.println(" ");
  Serial.print("Temperatur: ");
  Serial.print(bmp.readTemperature());
  Serial.println(" *C");
  Serial.print("Luftdruck: ");
  Serial.print(bmp.readPressure()/100);
  Serial.println(" Pa");
  Serial.print("Feuchtigkeit: ");
  Serial.print(trueRH);
  Serial.println("%");
  Serial.print("Helligkeit: ");
  Serial.print(Lux);
  Serial.println(" Lux");
  Serial.println("");

  if (client.connect(serverName, 80)) {
      digitalWrite(LEDg,HIGH);
      Serial.println("Connected");
      Serial.println("Sending Data...");
      client.println("GET /wetter/pushWeather.php?temp="+floatToString(bmp.readTemperature(),2)+"&luftdruck="+floatToString(bmp.readPressure(),2)+"&luftfeuchte="+floatToString(trueRH,2)+"&lux="+floatToString(Lux,2)+" HTTP/1.1");
      client.println("Host: www.someweather.de");
      client.println("User-Agent: arduino-ethernet");
      client.println("Connection: close");
      client.println("");
      while (client.connected()) {
        client.flush();
        client.stop();
        Serial.println("Disconnecting!");
      }
      Serial.println(client.status());
      Serial.println("Data sent. Closing connection.");
      digitalWrite(LEDg, LOW);
  }
  else {
    Serial.println("Connection failed");
  }
  digitalWrite(LEDr, LOW);
  delay(10000);
}

String floatToString(double number, uint8_t digits) 
{ 
  String resultString = "";
  // Handle negative numbers
  if (number < 0.0)
  {
     resultString += "-";
     number = -number;
  }

  // Round correctly so that print(1.999, 2) prints as "2.00"
  double rounding = 0.5;
  for (uint8_t i=0; i<digits; ++i)
    rounding /= 10.0;
  
  number += rounding;

  // Extract the integer part of the number and print it
  unsigned long int_part = (unsigned long)number;
  double remainder = number - (double)int_part;
  resultString += int_part;

  // Print the decimal point, but only if there are digits beyond
  if (digits > 0)
    resultString += "."; 

  // Extract digits from the remainder one at a time
  while (digits-- > 0)
  {
    remainder *= 10.0;
    int toPrint = int(remainder);
    resultString += toPrint;
    remainder -= toPrint; 
  } 
  return resultString;
}

I have to say this is the first time I actually program C or Arduino though there is probably a lot to optimize in that code.

Thanks in advance for your help.

Edit: I’ve found out it is really the HTTP request I’m doing. When I comment that part out everything works fine and the Arduino won’t freeze. Any idea what I can do? Is there some kind of timer I can use to reset the process if it is not responding?

String floatToString(double number, uint8_t digits) 
{ 
  String resultString = "";

Every day, we have a question about the Arduino hanging. And every day it turns out the sketch has the String class in it.

Example: http://arduino.cc/forum/index.php?topic=115954

It’s not your fault. The String class uses dynamic memory allocation which is, at present, buggy. Rewrite without using String and see if that fixes it.

Unless Arduino does a memory defrag with every deallocation, what should anyone expect?
I wouldn't mind as long as it could be avoided.

Perhaps the warning in the sticky could be made more prominent, or given a section of its own.

It's got the word "warning" in red type.

Perhaps the OP could explain whether he read the sticky or not. This one:

Read this before posting a programming question

Thanks for your reply. I’ve removed the function from my code from now and I’ll have a look if everything works now.

I’ll give you a note if that solved the problem for me :slight_smile:

“the function”?

You are using a C++ String Class Object named resultString. Did you completely replace that with a C character array and matching commands?

I've removed the complete floatToString as I don't really need it anymore. However it seems to work now. I already had 5 Updates from my Arduino without the need of resetting it.

Thanks for the hint.

So, did you read the sticky?

And you can still get your data out....

from this:

     client.println("GET /wetter/pushWeather.php?temp="+floatToString(bmp.readTemperature(),2)+"&luftdruck="+floatToString(bmp.readPressure(),2)+"&luftfeuchte="+floatToString(trueRH,2)+"&lux="+floatToString(Lux,2)+" HTTP/1.1");

to this:

      client.print("GET /wetter/pushWeather.php?temp=");
      client.print(bmp.readTemperature(),2);
      client.print("&luftdruck=");
      client.print(bmp.readPressure(),2);
      client.print("&luftfeuchte=");
      client.print(trueRH,2);
      client.print("&lux=");
      client.print(Lux,2);
      client.println(" HTTP/1.1");