Go Down

Topic: Arduino freezes at data transmission (Read 1 time) previous topic - next topic

Jul 28, 2012, 09:07 am Last Edit: Jul 28, 2012, 10:10 am by KlaasTammling Reason: 1
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.

Code: [Select]

#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?

Nick Gammon

Code: [Select]
String floatToString(double number, uint8_t digits)
{
  String resultString = "";


<sigh>

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.
Please post technical questions on the forum, not by personal message. Thanks!

More info:
http://www.gammon.com.au/electronics

GoForSmoke

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

Nick Gammon on multitasking Arduinos:
1) http://gammon.com.au/blink
2) http://gammon.com.au/serial
3) http://gammon.com.au/interrupts

dxw00d

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

Nick Gammon

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
Please post technical questions on the forum, not by personal message. Thanks!

More info:
http://www.gammon.com.au/electronics

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  :)

GoForSmoke

"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?



Nick Gammon on multitasking Arduinos:
1) http://gammon.com.au/blink
2) http://gammon.com.au/serial
3) http://gammon.com.au/interrupts

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.

dxw00d


GoForSmoke

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

from this:
Code: [Select]

     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:
Code: [Select]

      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");

Nick Gammon on multitasking Arduinos:
1) http://gammon.com.au/blink
2) http://gammon.com.au/serial
3) http://gammon.com.au/interrupts

Go Up