Physical hardware: Uno, Ethernet card, SanDisk Class 4 4Gbyt MicroSD card(formatted as FAT32) , IDE 1.0.4
I have a data logging sketch that records info on an SD card at 10min intervals. It also serves up a web page that allows the current info to be viewed over the Ethernet. Some times it will run for weeks and other times the Ethernet shield does not respond to a GET request from the PC after a couple of hours (The Wiz 5100 does not respond to a Ping either. Ping just tells me the device is unreachable).
I have set the SD card CS pin high at the beginning of the programme, So I'm now wondering if there is a subtly in the order of the Ethernet/SD card setups that Ive got wrong. Or is a class 4 micro SD card is too slow? (does any one know if an SD card slows down when it gets warm?)
The ambient temperature where the unit is 25-28DegC The chips do warm up but you can still touch them with out going 'ouch'
The Sketch is big (30K) and FreeRam() is telling me that I've got 450 - 500 bytes of SRAM free depending where I put it in the code. And the fact that it can run some times for months suggests that there is no memory leak.
This is the 'Setup' part of the code
// Chip Select Pins
#define sdChipSelectPin 4
#define ethernetChipSelectPin 10
// Relay Output Pins
#define RelayPinDifferential 8 //limit stat defaults to 60C
#define RelayPinVariable 9 //variable stat with calculated temperature
// Define Clock Variables
volatile boolean TickTock [8]; //Used as a set of flags to control interupt output and timed events
volatile unsigned long systime = 1385798455UL; //946684800UL; //default time at start of year 2000;
long timeError; //error in systime when getting ntpEpoch
char dateTime [12] = "01 12:59:59"; //to hold dateTime
char fileName [13]; //to hold file on SD card nb the date (year&month) is overwritten each month
char fileRequest[13]; //File Client requests
const byte MAX_PAGE_NAME_LEN = 12; //max characters in page name
byte fileBufferLen = 0;
#include <SPI.h>
#include <SD.h>
#include <Ethernet.h>
#include <EthernetUdp.h>
#include <EEPROM.h>
// MAC address for controller below.
//
byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; //was ED!
const unsigned int localPort = 8888; // local port to listen for UDP packets
// list of NTP servers so we don't have to look them up again
//ntp_servers[0] timeServer(213,123,26,170); // time at BT
//ntp_servers[1] timeServer(94,44,157,90); // Europe pool
//ntp_servers[2] timeServer(192,43,244,18); // time.nist.gov NTP server US
const IPAddress ntp_server (213,123,26,170); // use BT
const IPAddress ip (192,168,1,62); //62 Fixed IP for server DCHP takes up too much space
const IPAddress localdns (192,168,1,254);
const IPAddress gateway (192,168,1,254);
const IPAddress subnet (255,255,255,0);
// setup for ethernet
// A UDP instance to let us send and receive packets over UDP
EthernetUDP Udp;
// Initialize the Ethernet server library
// HTTP defaults to port 80
EthernetServer server(80);
EthernetClient client;
const byte BUFFER_LEN = 48; //TC/IP Output buffer
byte Buffer[BUFFER_LEN];
//setup for temperature measurement N.B. arrays are zero indexed
unsigned int readings[6]; // accumulates the readings from the analog inputs
// NB these numbers are 16 times A/D conversion figures
boolean temperatureRising[6]; // HIGH indicates thermostat has switched OFF on temperature rise
int TCTemps[24]; // set points for transfer curve 0-5 for used figures,6-11 default,
// 12-17 for max 18- 23 for min
int SetPoints [24]; // Temeratures which will always cause a switch OFF
// resistors in measurement bridge
const long Pullup = 4700; // 4700 measured value
const long VoltDiv1 = 4690; // 4700 measured value
const long VoltDiv2 = 1426; // 1436 measured value in parallel with internal resistor
int counter;
//DEFINITION for bottom of 'convert2temp' just so it does not have to be calulated every time and we dont have to divide the toals either
const long VoltDivider = (VoltDiv1+VoltDiv2)*1024*16/VoltDiv2;
//SETUP
void setup()
{
// flip the relays so we know its all connected
pinMode(RelayPinDifferential, OUTPUT); //Set relay driver pins to OUTPUT
pinMode(RelayPinVariable, OUTPUT); //ie Digital pins 8 & 9
digitalWrite(RelayPinDifferential, HIGH);//Set them HIGH so inital state of relays
digitalWrite(RelayPinVariable, HIGH); //is power off
// Set up CS pins for SD card and Ethernet
pinMode (ethernetChipSelectPin,OUTPUT); // make sure its OUTPUT
pinMode (sdChipSelectPin,OUTPUT); // make sure its OUTPUT
digitalWrite(sdChipSelectPin, HIGH); // make sure its off
digitalWrite(ethernetChipSelectPin,HIGH); // make sure its off
/////////////////////////
// Serial.begin(9600); // for debuging
/////////////////////////
//Get other info from EEPROM
for (byte i = 0; i<=23; i++){
SetPoints[i] = Byte2Int(EEPROM.read(i));
TCTemps[i] = Byte2Int(EEPROM.read(i+24));
}
//Set up reference for Analog input
analogReference (EXTERNAL);//Use External to avoid any dependancy on Vcc
analogRead (A0); //force the procesor to listen
// use fixed IP address (DHCP seem to add 4k to sketch)
Ethernet.begin(mac,ip,localdns,gateway,subnet);
digitalWrite(ethernetChipSelectPin,HIGH); // make sure its off
// line start the Ethernet server
server.begin();
Udp.begin(localPort);
//Check presence of SD card
if (!SD.begin(sdChipSelectPin)) { //card initialized.
// don't do anything more:
return;
}
///////////////////////////////////
// initialize timer1
noInterrupts(); // disable all interrupts
TCCR1A = 0;
TCCR1B = 0;
TCNT1 = 0;
// runs slow @ 15624 fast @ 15563 try 15601which is slightly too
// fast and causes double dipping for time stamp after 24hours
OCR1A = 15602; //0x3CF2; // compare match register for 1Hz output
TCCR1B |= (1 << WGM12); // CTC mode
TCCR1B |= (1 << CS10);
TCCR1B |= (1 << CS12); // 1024 prescaler
TIMSK1 |= (1 << OCIE1A); // enable timer compare interrupt
interrupts(); // enable all interrupts
//Get start time from NTP
TickTock[4] = true; // Flag start up for record in data file
sendNTPpacket(); // send an NTP packet to a time server using a range of addresses it could still come back
// with zero but its unlikely It will be flaged and try again on first 10min cycle
breakTime(systime); // So make up the file name for the current data This gets updated automatically
// but we might not want to wait after a restart
//get initial fill of average temperature data from each sensor
for (byte j = 0; j<128; j++){ //use 128 lots of readings for the first load of the array
GetReadings();
}
// Serial.print (systime);
} //end 'setup'
Interestingly the sketch continues to loop and do all the things It's supposed to even when it stops talking to the pc on the other end of the local network.
This has been bugging me for a year now, I've already tried Surfer-Tim's Timeout trick, in case it was a hardware/Ethernet wiring problem, to no avail. I've also tried to introduce several Serial.print(... statements to debug and find if any of the code stops working but usually the serial monitor overflows and crashes before the communication with the network falls over