Pages: [1]   Go Down
Author Topic: Server haulting after 4 days  (Read 2096 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Sr. Member
****
Karma: 1
Posts: 252
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I have a garage door opener server that works for 4 or so days and then stops (Firefox times out and says that it took too long). This is not installed at my house, so I thought it was the internet connection. I can ping the address without any loss. The odd thing is that I was not able to access the site a few tries, then it worked but would not reload (or when the meta refresh happened, it would time out) and then I could not access it anymore.
The sketch size is 24188 bytes, is it possible that its running out of memory?

Board is a Uno R2
Sheild is a Yourduino Ethernet shield (Wiznet W5100)
IDE is 22

Here is the code, thanks for any help!

Code:
#include <Ethernet.h>
#include <TextFinder.h>
#include "DHT.h"
#include <avr/pgmspace.h> // for progmem
#include <Dhcp.h>
#include <RF24Network.h>
#include <RF24.h>
#include <SPI.h>


#define DHTPIN 5
#define DHTTYPE DHT22
//-----------------------------------------------------------------------

// nRF24L01(+) radio attached to SPI and pins 8 & 9
RF24 radio(8,9);
// Network uses that radio
RF24Network network(radio);
// Address of our node
const uint16_t this_node = 1;
// Address of the other node
const uint16_t other_node = 0;

//-----------------------------------------------------------------------
byte mac[] = { 0x90, 0xA2, 0xDA, 0x00, 0xE3, 0xCA };//= { 0xC5, 0xA1, 0xDA, 0x00, 0xE3, 0xA3 };
//byte ip[] = { 192, 168, 1, 66 };
//byte gateway[] = { 108, 89, xx, xxx };// 108.89.xx.xxx
char buffer[8]; // buffer holding the requested page name
Server server(80);
int relayPin = 3;
int switchPin = 2;
int ledPin = 4;
int val5 = 0;
int val = 0;
int val2 = 0;
String val3 = 0;
String doorCommand;
int stat = 0;
int doorStat;
int doorStat2;
int doorStat3;
int doorNum;
int door3;
int humid;
int t;
int temp;
int t2 = 0;
int h2 = 0;
const unsigned long interval = 2000;
unsigned long last_sent;

DHT dht(DHTPIN, DHTTYPE);
//--------------------------------------------------------------------------

struct message_t
{
  uint16_t temp_reading;
  uint16_t humid_reading;
  uint16_t doorStat_reading;
  message_t(void): temp_reading(), humid_reading(), doorStat_reading() {}
};

struct door_t
{
  uint16_t door_reading;
  door_t(void): door_reading(0) {}
};
//--------------------------------------------------------------------------

void setup()
{
Serial.begin(9600);
//Ethernet.begin(mac, ip);
  while (Dhcp.beginWithDHCP(mac) != 1)
  {
    Serial.println("Error getting IP address via DHCP, trying again...");
    delay(15000);
  }    
  delay(1000);
  
Serial.println("connecting...");
Serial.println("Begin Ethernet");
server.begin();
Serial.println("Begin Server");
dht.begin();
Serial.println("Begin DHT22");
SPI.begin();
Serial.println("Begin PrintF");
radio.begin();
Serial.println("Begin NRF Radio");
network.begin(/*channel*/ 90, /*node address*/ this_node);
Serial.println("Begin Network");
delay(3000);
Serial.println("Ready");
pinMode(relayPin, OUTPUT);
pinMode(switchPin, INPUT);
pinMode(ledPin, OUTPUT);
digitalWrite(relayPin, HIGH);
digitalWrite(switchPin, HIGH);
//digitalWrite(ledPin, HIGH);

}

void loop(){
//-------------------------------------------
  humid = dht.readHumidity();
  t = dht.readTemperature();
  temp = (t * 1.8 + 32);
  
//----------------------------------------------  
  // Pump the network regularly
  network.update();

  // If it's time to send a message, send it!
  unsigned long now = millis();
  if ( now - last_sent > interval  )
  {
    last_sent = now;

    Serial.print("Sending...");

    RF24NetworkHeader header(/*to node*/ other_node);
    door_t door;
    door.door_reading += relayPin;
    bool ok = network.write(header,&door,sizeof(door));
    if (ok)
      Serial.println("ok.");
    else
      Serial.println("failed.");
      relayPin = 3;
  }
  
  
  while ( network.available() )
  {        
    message_t message;
    RF24NetworkHeader header;
    network.read(header,&message,sizeof(message));
    Serial.print("Received: ");
    t2 = (message.temp_reading * 1.8 + 32);
    h2 = (message.humid_reading);
    stat = (message.doorStat_reading);
    
    Serial.print(t2);
    Serial.print(" , ");
    Serial.println(h2);
    delay(1000);
  }
//----------------------------------------------  
  
Client client = server.available();
if (client) {
TextFinder finder(client );
int type = 0;
while (client.connected()) {
if (client.available()) {
// GET, POST, or HEAD
if(finder.getString("","/", buffer,sizeof(buffer))){
if(strcmp(buffer,"POST ") == 0){
finder.find("\n\r"); // skip to the body
// find string starting with "pin", stop on first blank line
// the POST parameters expected in the form pinDx=Y
// where x is the pin number and Y is 0 for LOW and 1 for HIGH

//------------------------------------------------
while(finder.findUntil("pinD", "\n\r")){
relayPin = finder.getValue(); // the pin number
val = finder.getValue(); // 0 or 1
digitalWrite(relayPin, val);
delay(1000);
digitalWrite(relayPin, HIGH);
}
//------------------------------------------------
//while(finder.findUntil("door", "\n\r")){
//doorNum = finder.getValue(); // the pin number
//val2 = finder.getValue(); // 0 or 1
//}
//-------------------------------------------------

Serial.println(relayPin);
Serial.println(val);
//Serial.println(val3);
//doorCommand = val2 + val3;
//Serial.println(doorCommand);



//------------------------------------------------------------
}

//client.print("<meta http-equiv=\"refresh\" content=\"10\">");
sendHeader(client,"Votto Vines Warehouse");
client.println("<h1><center>Votto Vines</center></h1>");
client.print("<center><IMG SRC='http://24.34.89.0:85/VVwh.jpg' ALT='Image'></center>");
client.println("<br />");
client.println("Warehouse 1 Temperature = "); client.print(temp); client.print("*F");
client.println(", Humidity = "); client.print(humid); client.print("% RH");
client.println("<br />");
client.println("Warehouse 2 Temperature = "); client.print(t2); client.print("*F");
client.println(", Humidity = "); client.print(h2); client.print("% RH");
//-------------------------------------------------------------------------
//Door 1
client.println("<h3>Warehouse 1</h3>");
client.print("<form action='/' method='POST'><p><input type='hidden'name='pinD3'");
client.print(" value='0'><input type='submit' value='Operate Door'/></form>");

client.print("Door is ");
if(doorStat == 1){
client.println("OPEN!");
}
else{
client.println("CLOSED");
}
//client.println("<br />");
//client.println("Warehouse 1 Temperature = "); client.print(temp); client.print("*F");
//client.println(", Humidity = "); client.print(humid); client.print("% RH");
client.println("<br />");

//--------------------------------------------------------------------------------
//Door 2

client.println("<h3>Warehouse 2</h3>");
client.print("<form action='/' method='POST'><p><input type='hidden'name='pinD4'");
client.print(" value='0'><input type='submit' value='Operate Door'/></form>");

client.print("Door is ");
if(doorStat2 == 1){
client.println("OPEN!");
}
else{
client.println("CLOSED");
}
client.println("<br />");

//--------------------------------------------------------------------------------
//Door 3

client.println("<h3>Warehouse 3</h3>");
client.print("<form action='/' method='POST'><p><input type='hidden'name='pinD5'");
client.print(" value='0'><input type='submit' value='Operate Door'/></form>");

client.print("Door is ");
if(doorStat3 == 1){
client.println("OPEN!");
}
else{
client.println("CLOSED");
}
client.println("<br />");

//--------------------------------------------------------------------------------
client.println("</body></html>");
client.stop();
}
break;
}
}
// give the web browser time to receive the data
delay(1);
client.stop();
}
//Serial.println(temp);
//Serial.println(humid);
//Serial.println(val5);
Serial.println(t2);
Serial.println(h2);


val5 = digitalRead(switchPin);   // read the input pin
digitalWrite(ledPin, val5);    // sets the LED to the button's value
if(val5 == LOW){
  doorStat = 0; // low = closed = 1
}
  else {
    doorStat = 1;
}
//------------------------------------------------------------


//----------------------------------------------

switch(stat) // If node dump reads "1" through blah is node. Need to assign Attic, Outdoor, etc.
{
case 0: // no "0" because we will hard code it in.
doorStat2 = 0;
doorStat3 = 0;
break;
case 10:
doorStat2 = 1;
doorStat3 = 0;
break;
case 01:
doorStat2 = 0;
doorStat3 = 1;
break;
case 11:
doorStat2 = 1;
doorStat3 = 1;
break;
default :
break;
}

}

//----------------------------------------------------------------

void sendHeader(Client client, char *title){
// send a standard http response header
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
client.println();
client.print("<meta http-equiv=\"refresh\" content=\"10\">");
client.print("<html><head><title>");
client.print(title);
client.println("</title><body>");
}
« Last Edit: September 27, 2012, 10:48:17 pm by RobDrizzle » Logged

0
Offline Offline
Tesla Member
***
Karma: 141
Posts: 9470
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

You can use the progmem macro F() to put static text in program memory like below.

Code:
client.println(F("<HTML><HEAD><TITLE>Arduino GET test page</TITLE></HEAD><BODY><H1>Zoomkat's simple Arduino button</H1><a href='/?on''>ON</a>&nbsp;<a href='/?off''>OFF</a></BODY></HTML>"));
Logged

Consider the daffodil. And while you're doing that, I'll be over here, looking through your stuff.   smiley-cool

Norfolk UK
Offline Offline
Edison Member
*
Karma: 65
Posts: 2451
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
String val3 = 0;
String doorCommand;
String is known to cause SRAM memory fragmentation and can lead to crashes, try coding to use char[] instead.

zoomkat's idea is also very good to help free up valuable SRAM. The F() also works with Serial.Print strings
Code:
Serial.println(F("Error getting IP address via DHCP, trying again..."));
Logged

There is no such thing as a stupid question but there are a lot of inquisitive idiots.

Miramar Beach, Florida
Offline Offline
Faraday Member
**
Karma: 138
Posts: 5846
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

The "F()" function is not available in V0022.  smiley-sad

Maybe install v1.0.1? You can run both versions if you don't like the new version.

edit: Note I said "install", not "upgrade".

« Last Edit: September 28, 2012, 07:03:47 am by SurferTim » Logged

Offline Offline
Sr. Member
****
Karma: 1
Posts: 252
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks for the help gentlemen. I can't use 1.0.1 without porting the libraries for the nRFnetwork and driver.

I will trying to cut down the use of String and see if that will make a difference first, before diving into any porting.
Logged

Switzerland
Offline Offline
Faraday Member
**
Karma: 108
Posts: 5144
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
I can't use 1.0.1 without porting the libraries for the nRFnetwork and driver.

That porting consists in most cases of the change of a few include statements and in some cases a few search and replaces. Some bugs in the Ethernet-Library have been fixed meanwhile. I won't install an old IDE to track down old bugs. BTW: have you checked if there doesn't exist a new version of these libraries which is compatible with version 1.0+?
Logged

Offline Offline
Sr. Member
****
Karma: 1
Posts: 252
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

So I changed out some of the obvious stuff that was eating up memory. The code went from 400 bytes free to 630 bytes free.

The code froze after 10 days of running. The free memory never dropped below 630 bytes (that I am aware of).

Something did come to me. I had the code running for weeks at my house. When I installed it in it's permanent location, it is connect through a AT&T gateway which requires that the code request an IP using DHCP rather than pushing one with a IP declared in the code. At my house, I did not use DHCP.

My understanding is that IDE 1.0 had included the DHCP support and there were some improvements.

Do you guys think that this could be the cause? I'm going to try to get the code working in v1.0 or v1.0.1...

Code:
#include <memoryfree.h>
#include <Ethernet.h>
#include <TextFinder.h>
#include "DHT.h"
//#include <avr/pgmspace.h> // for progmem
#include <Dhcp.h>
#include <RF24Network.h>
#include <RF24.h>
#include <SPI.h>


#define DHTPIN 5
#define DHTTYPE DHT22
//-----------------------------------------------------------------------

// nRF24L01(+) radio attached to SPI and pins 8 & 9
RF24 radio(8,9);
// Network uses that radio
RF24Network network(radio);
// Address of our node
const uint16_t this_node = 1;
// Address of the other node
const uint16_t other_node = 0;

//-----------------------------------------------------------------------
byte mac[] = { 0x90, 0xA2, 0xDA, 0x00, 0xE3, 0xCA };//= { 0xC5, 0xA1, 0xDA, 0x00, 0xE3, 0xA3 };
char buffer[8]; // buffer holding the requested page name
Server server(80);
int relayPin = 3;
int switchPin = 2;
int ledPin = 4;
int val5 = 0;
int val = 0;
int stat = 0;
int doorStat;
int doorStat2;
int doorStat3;
int humid;
//int t;
int temp;
int t2 = 0;
int h2 = 0;
const unsigned long interval = 2000;
unsigned long last_sent;

DHT dht(DHTPIN, DHTTYPE);
//--------------------------------------------------------------------------

struct message_t
{
uint16_t temp_reading;
uint16_t humid_reading;
uint16_t doorStat_reading;
message_t(void): temp_reading(), humid_reading(), doorStat_reading() {}
};

struct door_t
{
uint16_t door_reading;
door_t(void): door_reading(0) {}
};
//--------------------------------------------------------------------------

void setup()
{
//        Serial.begin(9600);
while (Dhcp.beginWithDHCP(mac) != 1)
{
delay(15000);
}
delay(1000);

server.begin();
dht.begin();
SPI.begin();
radio.begin();
network.begin(/*channel*/ 90, /*node address*/ this_node);
delay(3000);
pinMode(relayPin, OUTPUT);
pinMode(switchPin, INPUT);
pinMode(ledPin, OUTPUT);
digitalWrite(relayPin, HIGH);
digitalWrite(switchPin, HIGH);

}

void loop(){

//    Serial.print("freeMemory()=");
//    Serial.println(freeMemory());
 
//-------------------------------------------
humid = dht.readHumidity();
//t = dht.readTemperature();
temp = (dht.readTemperature() * 1.8 + 32);

//----------------------------------------------
// Pump the network regularly
network.update();

// If it's time to send a message, send it!
unsigned long now = millis();
if ( now - last_sent > interval )
{
last_sent = now;


RF24NetworkHeader header(/*to node*/ other_node);
door_t door;
door.door_reading += relayPin;
bool ok = network.write(header,&door,sizeof(door));
relayPin = 3;
}


while ( network.available() )
{
message_t message;
RF24NetworkHeader header;
network.read(header,&message,sizeof(message));
t2 = (message.temp_reading * 1.8 + 32);
h2 = (message.humid_reading);
stat = (message.doorStat_reading);

delay(1000);
}
//----------------------------------------------

Client client = server.available();
if (client) {
TextFinder finder(client );
int type = 0;
while (client.connected()) {
if (client.available()) {
// GET, POST, or HEAD
if(finder.getString("","/", buffer,sizeof(buffer))){
if(strcmp(buffer,"POST ") == 0){
finder.find("\n\r"); // skip to the body
// find string starting with "pin", stop on first blank line
// the POST parameters expected in the form pinDx=Y
// where x is the pin number and Y is 0 for LOW and 1 for HIGH

//------------------------------------------------
while(finder.findUntil("pinD", "\n\r")){
relayPin = finder.getValue(); // the pin number
val = finder.getValue(); // 0 or 1
digitalWrite(relayPin, val);
delay(1000);
digitalWrite(relayPin, HIGH);
}

//------------------------------------------------------------
}

//client.print("<meta http-equiv=\"refresh\" content=\"10\">");
sendHeader(client,"Votto Vines Warehouse");
client.println("<h1><center>Votto Vines</center></h1>");
client.print("<center><IMG SRC='http://24.34.89.0:85/VVwh.jpg' ALT='Image'></center>");
client.println("<br />");
client.println("Warehouse 1 Temperature = "); client.print(temp); client.print("*F");
client.println(", Humidity = "); client.print(humid); client.print("% RH");
client.println("<br />");
client.println("Warehouse 2 Temperature = "); client.print(t2); client.print("*F");
client.println(", Humidity = "); client.print(h2); client.print("% RH");
//-------------------------------------------------------------------------
//Door 1
client.println("<h3>Warehouse 1</h3>");
client.print("<form action='/' method='POST'><p><input type='hidden'name='pinD3'");
client.print(" value='0'><input type='submit' value='Operate Door'/></form>");

client.print("Door is ");
if(doorStat == 1){
client.println("OPEN!");
}
else{
client.println("CLOSED");
}
client.println("<br />");

//--------------------------------------------------------------------------------
//Door 2

client.println("<h3>Warehouse 2</h3>");
client.print("<form action='/' method='POST'><p><input type='hidden'name='pinD4'");
client.print(" value='0'><input type='submit' value='Operate Door'/></form>");

client.print("Door is ");
if(doorStat2 == 1){
client.println("OPEN!");
}
else{
client.println("CLOSED");
}
client.println("<br />");

//--------------------------------------------------------------------------------
//Door 3

client.println("<h3>Warehouse 3</h3>");
client.print("<form action='/' method='POST'><p><input type='hidden'name='pinD5'");
client.print(" value='0'><input type='submit' value='Operate Door'/></form>");

client.print("Door is ");
if(doorStat3 == 1){
client.println("OPEN!");
}
else{
client.println("CLOSED");
client.println("<br />");
client.println("<br />");
client.print("Memory Free =");
client.println(freeMemory());
}
client.println("<br />");

//--------------------------------------------------------------------------------
client.println("</body></html>");
client.stop();
}
break;
}
}
// give the web browser time to receive the data
delay(1);
client.stop();
}


val5 = digitalRead(switchPin); // read the input pin
digitalWrite(ledPin, val5); // sets the LED to the button's value
if(val5 == LOW){
doorStat = 0; // low = closed = 1
}
else {
doorStat = 1;
}
//------------------------------------------------------------


//----------------------------------------------

switch(stat)
{
case 0:
doorStat2 = 0;
doorStat3 = 0;
break;
case 10:
doorStat2 = 1;
doorStat3 = 0;
break;
case 01:
doorStat2 = 0;
doorStat3 = 1;
break;
case 11:
doorStat2 = 1;
doorStat3 = 1;
break;
default :
break;
}

}

//----------------------------------------------------------------

void sendHeader(Client client, char *title){
// send a standard http response header
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
client.println();
client.print("<meta http-equiv=\"refresh\" content=\"10\">");
client.print("<html><head><title>");
client.print(title);
client.println("</title><body>");
}
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 601
Posts: 48543
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
When I installed it in it's permanent location, it is connect through a AT&T gateway which requires that the code request an IP using DHCP rather than pushing one with a IP declared in the code. At my house, I did not use DHCP.
The D stands for dynamic. Dynamically assigned IP addresses are not permanent. They expire after some period of time. Once the IP address expires, it is no longer valid, and can no longer be used.

You'll need for your Arduino to be aware of that, and to request a new IP address before, or just after, the current one expires.
Logged

Miramar Beach, Florida
Offline Offline
Faraday Member
**
Karma: 138
Posts: 5846
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

If you plan on using dhcp for extended periods (>1day), you should insert a maintain call in your code.
http://arduino.cc/en/Reference/EthernetMaintain
I don't think the router dhcp server would mind too much if you called it once an hour.
Requires IDE v1.0.1

FYI: There is no guarantee you will be issued the same ip. If the router has been restarted (power fail), there is a chance you will get a new ip. I would use a static ip for a server.
« Last Edit: October 11, 2012, 08:02:03 am by SurferTim » Logged

0
Offline Offline
Tesla Member
***
Karma: 141
Posts: 9470
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

What type of gizmo are you plugging your arduino into? Some tyoe of cable modem? If so, maybe you should get a cheap router to go between the arduino and cable modem.
Logged

Consider the daffodil. And while you're doing that, I'll be over here, looking through your stuff.   smiley-cool

Offline Offline
Sr. Member
****
Karma: 1
Posts: 252
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks guys.

Tim, this is a crappy modem/router. There is no way to fix the ip as static... If I use a static IP declared in the code the router refuses to "see" the arduino, although I can ping and access it locally by typing in it's IP via a web browser.

Zoomkat, the arduino is connected to a AT&T/2 Wire Gateway DSL modem/router... AKA garbage. Are you saying that the router would be in charge of the IPs if it was between the modem and arduino?
Logged

Miramar Beach, Florida
Offline Offline
Faraday Member
**
Karma: 138
Posts: 5846
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Are you saying that the router would be in charge of the IPs if it was between the modem and arduino?
Yes, on the router localnet only. Normally a router will perform a NAT to the WAN address on the router.

Can you access the router setup? If so, you may be able to assign the Arduino a "static" dynamic address. It isn't actually a static ip, but the dhcp server will reserve an ip and assign that same ip to that mac address every time it requests one. That has worked as well for me as a static assignment.
« Last Edit: October 12, 2012, 06:55:24 am by SurferTim » Logged

0
Offline Offline
Tesla Member
***
Karma: 141
Posts: 9470
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Zoomkat, the arduino is connected to a AT&T/2 Wire Gateway DSL modem/router... AKA garbage. Are you saying that the router would be in charge of the IPs if it was between the modem and arduino?

In my mind you should not be trying to get into or directly connect to the modem/router supplied by your ISP (its normal function is to make the transistion from phone/cable signals to ethernet signals). In most customer setups another router is connected to the ISP's modem/router, and the new router is configured to do what the customer wants to do. I have my $40 netgear wireless router connected to the cable modem supplied by the cable company and every thing works well.
Logged

Consider the daffodil. And while you're doing that, I'll be over here, looking through your stuff.   smiley-cool

Pages: [1]   Go Up
Jump to: