for loop locks up

Hello all

I am having some trouble with a for loop and need help as i can't find any solution on line. The below code was designed to run through the for loop 100 times checking my temperatures on my solar system. After 100 times it would send the data to my data base on line.

If i run the code with a 15 times loop it works all OK and will run happily for over a day when testing. But if i increase it to 100 or more it will only send the data once then it stops sending data as if the arduino has locked up.

Any one got any idea what is happening or a work around please.

I could run the program on a 15 times loop but will have to put code into my php script to limit the amount of data coming in to MySql. I would prefer the arduino to limit this data so i can hold more long turn data on line.

thanks

#include <SPI.h>
#include <Ethernet.h>
#include<OneWire.h>
#include <DallasTemperature.h>

#define ONE_WIRE_BUS 3
#define TEMPERATURE_PRECISION 12

byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
//IPAddress ip (192, 168, 1, 74);
//IPAddress server (184,168,138,128);//ip address for my web server
char serverName[] = "88888888888";

OneWire oneWire(ONE_WIRE_BUS);
EthernetClient client;
DallasTemperature sensors(&oneWire);
 
DeviceAddress panelTemp = { 0x28, 0xB4, 0x52, 0x9D, 0x04, 0x00, 0x00, 0x31 }; 
DeviceAddress lowerCylinder = { 0x28, 0x7C, 0xB4, 0xA0, 0x04, 0x00, 0x00, 0x9C};
DeviceAddress upperCylinder  = {0x28, 0xC4, 0xB5, 0xA1, 0x04, 0x00, 0x00, 0x78 };
int panelin;// variable to store panel temperature
int lowerin;// variable to store lower cylinder temperature
int upperin;// variable to store upper cylinder
int pump = 8;
int diff;



void setup(){
  
  if (Ethernet.begin(mac) == 0) {
    Serial.println("Failed to configure Ethernet using DHCP");
    // no point in carrying on, so do nothing forevermore:
    while(true);
  }
Serial.begin(9600);
   Serial.println("Start setup");
  pinMode(pump, OUTPUT);
Serial.println ("setup end");
}
  

void loop (){
  //Serial.println ("start loop");
  for (int x=0; x<100; x++)
  {
    //Serial.println (x);
  panelin = sensors.getTempC(panelTemp);// read sensor into var panelin to send to GET function
  lowerin = sensors.getTempC(lowerCylinder);
  upperin = sensors.getTempC (upperCylinder);
  sensors.requestTemperatures ();
  //Serial.println (panelin);// serial print for fault finding
  //Serial.println (lowerin);// fault finding
  //Serial.println (upperin);
  pumpcontrol ();
  
  }
  sendGET();
}

void sendGET() //client function to send/receive GET request data.
{
  //Serial.println ("send data");
  if (client.connect(serverName, 80)) {  //starts client connection, checks for connection
    //Serial.println("connected");
    client.print("GET /88888888.php?panel=");//send panel = to server
    client.print(panelin);//add panelin temperature to above line note no println in code
    client.print("&lower=");
    client.print(lowerin);
    client.print("&upper=");
    client.print(upperin);
    client.println(" HTTP/1.0");// add to end of GET send with println
      
    client.println("Host: 8888888888");// my web host address
    client.println(); //end of get request
   // Serial.println ("end send data");
  } 
  else {
    Serial.println("connection failed"); //error message if no client connect
    Serial.println();
  }

  while(client.connected() && !client.available()) delay(1); //waits for data
  while (client.connected() || client.available()) { //connected or data available
    char c = client.read(); //gets byte from ethernet buffer
    //Serial.print(c); //prints byte to serial monitor 
  }

  //Serial.println();
  //Serial.println("disconnecting.");
  //Serial.println("==================");
  //Serial.println();
  client.stop(); //stop client
}

void pumpcontrol(){
  
  diff = lowerin + 25;
  
  if (diff < panelin){
    digitalWrite (pump, HIGH);
    delay(5000);
    digitalWrite (pump, LOW);
    delay(9000);
  }
  else{
    delay (10000);
  }
}

Can you establish exactly where the program appears to lock up from the existing Serial.prints or by adding more ?
What happens if you radically reduce the delays in the pumpcontrol() function so that the for loop does not take so long to run even with 100 iterations ?

how about this instead...

#include <SPI.h>
#include <Ethernet.h>
#include<OneWire.h>
#include <DallasTemperature.h>

#define ONE_WIRE_BUS 3
#define TEMPERATURE_PRECISION 12

byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
//IPAddress ip (192, 168, 1, 74);
//IPAddress server (184,168,138,128);//ip address for my web server
char serverName[] = "88888888888";

OneWire oneWire(ONE_WIRE_BUS);
EthernetClient client;
DallasTemperature sensors(&oneWire);
 
DeviceAddress panelTemp = { 0x28, 0xB4, 0x52, 0x9D, 0x04, 0x00, 0x00, 0x31 }; 
DeviceAddress lowerCylinder = { 0x28, 0x7C, 0xB4, 0xA0, 0x04, 0x00, 0x00, 0x9C};
DeviceAddress upperCylinder  = {0x28, 0xC4, 0xB5, 0xA1, 0x04, 0x00, 0x00, 0x78 };
byte Counter = 0;
int panelin;// variable to store panel temperature
int lowerin;// variable to store lower cylinder temperature
int upperin;// variable to store upper cylinder
int pump = 8;
int diff;



void setup(){
  
  if (Ethernet.begin(mac) == 0) {
    Serial.println("Failed to configure Ethernet using DHCP");
    // no point in carrying on, so do nothing forevermore:
    while(true);
  }
Serial.begin(9600);
   Serial.println("Start setup");
  pinMode(pump, OUTPUT);
Serial.println ("setup end");
}
  

void loop (){
  
  //Serial.println ("start loop");
    //Serial.println (x);
  Counter++;
  panelin = sensors.getTempC(panelTemp);// read sensor into var panelin to send to GET function
  lowerin = sensors.getTempC(lowerCylinder);
  upperin = sensors.getTempC (upperCylinder);
  sensors.requestTemperatures ();
  //Serial.println (panelin);// serial print for fault finding
  //Serial.println (lowerin);// fault finding
  //Serial.println (upperin);
  pumpcontrol (); 
  if (Counter==100)
    { 
     Counter=0;
     sendGET();
    } 
}

void sendGET() //client function to send/receive GET request data.
{
  //Serial.println ("send data");
  if (client.connect(serverName, 80))
   {  //starts client connection, checks for connection
    //Serial.println("connected");
    client.print("GET /88888888.php?panel=");//send panel = to server
    client.print(panelin);//add panelin temperature to above line note no println in code
    client.print("&lower=");
    client.print(lowerin);
    client.print("&upper=");
    client.print(upperin);
    client.println(" HTTP/1.0");// add to end of GET send with println
      
    client.println("Host: 8888888888");// my web host address
    client.println(); //end of get request
   // Serial.println ("end send data");
  } 
  else {
    Serial.println("connection failed"); //error message if no client connect
    Serial.println();
  }

  while(client.connected() && !client.available()) delay(1); //waits for data
  while (client.connected() || client.available()) { //connected or data available
    char c = client.read(); //gets byte from ethernet buffer
    //Serial.print(c); //prints byte to serial monitor 
  }

  //Serial.println();
  //Serial.println("disconnecting.");
  //Serial.println("==================");
  //Serial.println();
  client.stop(); //stop client
}

void pumpcontrol(){
  
  diff = lowerin + 25;
  
  if (diff < panelin){
    digitalWrite (pump, HIGH);
    delay(5000);
    digitalWrite (pump, LOW);
    delay(9000);
  }
  else{
    delay (10000);
  }
}

I'm thinking you're maybe low on memory but it should have worked, try this method...

If you are short on RAM, you can grab back a few bytes with the F() macro on the those constant strings: Serial.println(F("Failed to configure Ethernet using DHCP");
client.print(F("GET /88888888.php?panel=")); etc.

Thanks for the reply's.

i did think i might be running out of memory so i switched to a mega. Still due to the high count and with all the library's i might be running out of memory.

i don't know exactly where it is locking up, when i get some more time off i will see if i can find out. It seems to stop after the first GET function as i only get one set of data to Mysql. If was a memory issue then this would be when it uses more memory.

I like the count idea from cjdelphi, thanks i will give this a go when i get time.

The code seems to be fine on a lower count. so either a memory problem or it gets lost in the high count.

I've just noticed that all my sensors have dropped to zero. I seem to not be getting any readings now to MySql.

Anyone had this happen before?

i can't investigate at the moment until i get home, just wondering if any one had any pointers for me.

Would one of the sensors shorting out cause this to happen.

they cant have disconnected as i would get -127 all the time.

never had this before.

I've used this with UNO and have no reason to think it won't work on a MEGA.

int freeRam () {
  extern int __heap_start, *__brkval; 
  int v; 
  return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval); 
}

hi go GoForSmoke

thanks for reminding me I could run a memory check to see what memory I have left. From your sketch i assume i need to serial print the int v at the end of my sketch to see what memory is left.

If i can' get the sensors to start reading again i will be stuck for some time.

That's just a function you use to get the RAM value. You sketch can use it.

The snips are all the other code not shown.

.......snip............

int freeRam () 
{
  extern int __heap_start, *__brkval; 
  int v; 
  return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval); 
}

..... snip.........

Serial.print( "Free RAM = " );
Serial.println( freeRam() );

......snip..........

cheers will have a go at this

I would put the print in setup and maybe at the end of the report.

You use Strings which do havoc with the heap so expect those RAM values to change.

will hopefully have a go tonight if i can first work out why all my sensors are now reading zero.

I assume you mean the strings at the beginning of my sketch. I could work around his and reduce some of them if i have a memory problem.

Every time a String changes length, it copies itself and gets rid of the old one. Next time if the new one fits in that empty space it will be there else maybe on the heap top. So while your code is assembling Strings the value of free RAM will likely change more than what seems right. It's something to be aware of is all.

Finnaly home. connected computer to arduino serial port. under serial connection it is working again. cant explain why the sensors all went to zero today this was a first. hopefully it was a loose connection which won't happen again.

Memmory check using the code from GoForSmoke thanks.

on 15 count i get ram free at start 6873 and at end 6840

on 100 count i get ram free

start of loop 6729
before and after reading of sensors 6729
when pump is called 6722
after pump delays 6729

looking at this and running on a mega i should be ok on a 100 loop.

still not run the full 100 counts yet to see what is locking up. but memory is staying the same on every count.

just read over SurferTim's post Reconnecting to Ethernet - Networking, Protocols, and Devices - Arduino Forum and may be this is what is happening to my connection. The memory seems fine but is he is right then the connection may be getting stuck and not restarting.

I've modified my code with his sketch as below;

int noCharCount = 0;
  
  while(client.connected())
  {
    while(client.available())
    {
      inChar = client.read();
      Serial.write(inChar);
      noCharCount = 0;
    }

    delay(10);
    noCharCount++;

    // change this value to suit you. this is 10 seconds    
    if(noCharCount > 1000)
    {
      Serial.println();
      Serial.println("Timeout");
      client.stop();
    }
    
  }

and im going to run it on a 50 count to see if it locks up.

so just run the original code and the one from SurferTim and both are not working on the 50 count. the client read out is as follows

connected
HTTP/1.1 200 ok
connection: close
pragma: no-cache
cache-control : no-cache
content type :text/html
content length = 65

now most of this i do not understand but the last html line is new. not sure if this is a problem

well i think i know now this is a connection fault but not sure what to do.

the first connection gives what i put in my previous post. the connection is closed after HTTP/1.1 200 ok. this is wrong as no data is uploaded.

my second connection was as follows.

connected
HTTP/1.1 200 ok
date: fri, 09 Aug 2013 19:36:54 GMT
server: apache
vary: accept-encoding
connection close
content-type: text/html
Europe/London
Successfull

disconnecting

this time the dat was sent.

So i am assuming on a 15 count this is happening a lot and some of the data is getting sent and some not. on a longer loop this is more apparent as its a long time between data getting sent. I will run this on a short loop and see if i am loosing data on the serial monitoring.

If so then not sure were to go with this, any one have any ideas

Well i run my code last night on a 10 count and for every 50 Get functions called two would fail with the refresh command as in the 50 count test i did.

The code has now been running on a 10 count for over 15 hours, I get some missed data and the odd high reading for some reason. something to sort out later. On this count i am filling up MySql quickly. in less than a day i 500 records!

Any one under stand the loss of the GET function. It connects ok but the data does not get through. Is there a work around.

I don't have your hardware so I can't duplicate what you get but this is the place where I would be adding print lines to see what's going on in the code right down to variable values and conditional branches (if, else, for, while, etc) the code actually takes. Any that get past use, I comment out so that I can bring them back in seconds.

Arduino IDE does not have step-through-code, breakpoints, or watch windows but you could get those with another IDE if you can't make do with prints or leds (yes, some people set up leds to show execution flow, but that's tricky) in the regular IDE.

Code Blocks (free) has an Arduino version. I've seen it but I don't need it enough learn the ins and outs. It is full featured though. There are other free and pay-for compilers that will do but I don't know more than that they exist and some people like them. If you get one and like it, you will probably not want to use the official Arduino IDE again.

What do you mean by fail? Does it not connect, or lock in the while(client.connected()) loop?

edit: You should post your new code. I bet you have made some changes by now. If you use my response read code, I would be more comfortable with that.

I understand all of reply #15. This will cause the web browser to immediately reload this page.