Hello,
I have made a code for a customer,long story short: it reads temperature and sends signals to a relay board and prints the values on the lcd and webpage.
My arduino MEGA somehow crashes after sometimes days, minutes or hours. there is no pattern in the crashes and i cant figure out what goes wrong, is there anyone that can help?
I have in the past implemented the watchdog timer. but no succes.
The problem is in the ethernetshield do you guys have any idea?
the code:
//Programmeur: Mike Brink |
//Project: Olthof Beton |
//© 2021, P&B Techniek |
//Uitgegeven in eigen beheer
//------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------|//
//Niets uit deze uitgave mag worden verveelvoudigd, opgeslagen in een geautomatiseerd gegevensbestand en/of openbaar gemaakt in enige vorm of op enige wijze, zonder toestemming. |//
//------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------|//
//Alle documentatie en handleidingen zijn aanwezig OP KANTOOR |
//Technische gegevens: |
//Temp sensor: DS18B20 MAX: 125C - MIN: -55C |
//LCD Display: I2C 20X4 LCD |
//Print: Arduino MEGA |
//Relay board 2 modules, en een screwshield. |
//-------------------------------------------------------------------------|
//De gebruikte libraries:
#include <Wire.h>
#include <DallasTemperature.h>
#include <OneWire.h>
#include <SPI.h>
#include <Ethernet.h>
#include <LiquidCrystal_I2C.h>
#include <SD.h>
//Ethernet shield setup:
//Het IP-ADRESS is afhankelijk van het lokale adres, check dit.
//Voer hieronder het MAC adress in van de controller en het IPADRESS.
byte mac[] = {
0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED
};
IPAddress ip(192, 168, 1, 11);
//Initialiseren van de EthernetServer library:
// (poort 80 is standaard voor HTTP, wij gebruiken een andere poort 25565!):
EthernetServer server(25565);
//LCD SETUP:
//Hieronder definiëren we het adress van de I2C Interface modules voor de displays.
//Wanneer er gebruik gemaakt word van een 16,2 scherm verander dan naar '16,2'
LiquidCrystal_I2C lcd1 = LiquidCrystal_I2C(0x27, 20, 4); //Dit is display 1
LiquidCrystal_I2C lcd2 = LiquidCrystal_I2C(0x26, 20, 4); //Dit is display 2
LiquidCrystal_I2C lcd3 = LiquidCrystal_I2C(0x25, 20, 4); //Dit is display 3
//Hieronder definiëren we de aansluitpin van de DS18B20 temperatuursensoren.
#define ONE_WIRE_BUS 3
#define TEMPERATURE_PRECISION 9
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
byte sensor1[8] = {0x28, 0x98, 0xA1, 0xBD, 0x13, 0x21, 0x01, 0x09};
byte sensor2[8] = {0x28, 0x1C, 0x6E, 0x0E, 0x00, 0x00, 0x00, 0x9E};
byte sensor3[8] = {0x28, 0xBA, 0x34, 0xFF, 0x12, 0x21, 0x01, 0xF8};
byte sensor4[8] = {0x28, 0x16, 0x0A, 0xF4, 0x12, 0x21, 0x01, 0x6B};
byte sensor5[8] = {0x28, 0xEE, 0x17, 0x58, 0x13, 0x21, 0x01, 0x38};
byte sensor6[8] = {0x28, 0xA9, 0x3F, 0x8C, 0x13, 0x21, 0x01, 0x01};
byte sensor7[8] = {0x28, 0xD9, 0x5D, 0x50, 0x13, 0x21, 0x01, 0x18};
byte sensor8[8] = {0x28, 0x05, 0x4E, 0x84, 0x13, 0x21, 0x01, 0x9C};
byte sensor9[8] = {0x28, 0xD7, 0x20, 0x96, 0x13, 0x21, 0x01, 0xBA};
byte sensor10[8] = {0x28, 0xCF, 0x7E, 0x3D, 0x13, 0x21, 0x01, 0x4A};
byte sensor11[8] = {};
byte sensor12[8] = {};
byte sensor13[8] = {};
byte sensor14[8] = {};
byte sensor15[8] = {};
byte sensor16[8] = {};
byte sensor17[8] = {};
byte sensor18[8] = {};
byte sensor[8] = {};
float tempC;
//Hieronder definiëren we de adressen van de digitale pinnen:
#define RELAY1 9
#define RELAY2 11
#define RELAY3 12
#define REQ_BUF_SZ 50
File webFile; // the web page file on the SD card
boolean SWITCH_state[4] = {0};// stores the states of the Switches
char HTTP_req[REQ_BUF_SZ] = {0};// buffered HTTP req
float arduinoVCC = 4.88; //guest stored as null terminated string
char req_index = 0; // index into HTTP_req buffer
const int TEMP_MAX = 58 ; // De grenswaarde voor de hoge temperatuur waarde.
const int TEMP_MIN = 51 ; // De grenswaarde voor de te lage temperatuur waarde.
const int TEMP_ERROR = -127 ; // De grenswaarde wanneer er een sensor in storing staat.
const int TEMP_ERRORRESET = 2; //De grenswaarde voor het automatisch resetten.
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void setup() {
Serial.begin(9600); //Begint het seriel communiceren met de serial monitor op 9600 baud
//Digitale pin defineren als uitgang.
pinMode(9, OUTPUT);
pinMode(10, OUTPUT);
pinMode(11, OUTPUT);
pinMode(12, OUTPUT);
sensors.begin();
// Ethernet connectie laten beginnen
Ethernet.begin(mac, ip); //Start de ethernet connectie en de server:
// start de server
server.begin();
Serial.print("server is op adres: ");
Serial.println(Ethernet.localIP());
// initialize SD card
Serial.println("Initializing SD card...");
if (!SD.begin(4)) {
Serial.println("ERROR - SD card initialization failed!");
return; // init failed
}
Serial.println("SUCCESS - SD card initialized.");
// check for index.html file
if (!SD.exists("index.htm")) {
Serial.println("ERROR - Can't find index.htm file!");
!SD.exists("index.htm");
!SD.exists("index.htm");
!SD.exists("index.htm");
return;// can't find index file
}
Serial.println("SUCCESS - Found index.htm file.");
lcd1.init(); //Initialiseren van display 1
lcd2.init(); //Initialiseren van display 2
lcd3.init(); //Initialiseren van display 3
lcd1.backlight(); //Zet de backlight aan voor display 1
lcd2.backlight(); //Zet de backlight aan voor display 2
lcd3.backlight(); //Zet de backlight aan voor display 3
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void loop() {
sensors.requestTemperatures();
//Ingang melding PLC:
if(sensors.getTempC(sensor3) > TEMP_MIN){
//Serial.println("HOOG Signaal verzonden naar relais");
digitalWrite(RELAY2, LOW); //Maakt de uitgang hoog
} else if(sensors.getTempC(sensor3) < TEMP_MIN){
// Serial.println("LAAG Signaal verzonden naar relais");
digitalWrite(RELAY2, HIGH); //Maakt de uitgang laag
}
if(sensors.getTempC(sensor7) > TEMP_MAX){
// Serial.println("HOOG Signaal verzonden naar relais");
digitalWrite(RELAY3, LOW); //Maakt de uitgang hoog
} else if(sensors.getTempC(sensor7) < TEMP_MAX){
// Serial.println("LAAG Signaal verzonden naar relais");
digitalWrite(RELAY3, HIGH); //Maakt de uitgang laag
}
//Storing melding Visueel:
if(sensors.getTempC(sensor7) == TEMP_ERROR){
//Serial.println("HOOG Signaal verzonden naar relais");
digitalWrite(RELAY1, HIGH); //Maakt de uitgang hoog
}
else if(sensors.getTempC(sensor7) > TEMP_ERRORRESET){
// Serial.println("LAAG Signaal verzonden naar relais");
digitalWrite(RELAY1, LOW); //Maakt de uitgang laag
}
if(sensors.getTempC(sensor3) == TEMP_ERROR){
//Serial.println("HOOG Signaal verzonden naar relais");
digitalWrite(RELAY1, HIGH); //Maakt de uitgang hoog
}
else if(sensors.getTempC(sensor3) >TEMP_ERRORRESET){
// Serial.println("LAAG Signaal verzonden naar relais");
digitalWrite(RELAY1, LOW); //Maakt de uitgang laag
}
//Resultaten van de sensor uitprinten op de LCD 1.
lcd1.setCursor (0, 0 );
lcd1.print("P&B-Techniek");
lcd1.setCursor (0, 1);
lcd1.print("--------------------");
lcd1.setCursor (0, 2);
lcd1.print("Aanvoer-Vat: ");
lcd1.print(sensors.getTempC(sensor7));
lcd1.setCursor (0, 3);
lcd1.print("Retour-Vat: ");
lcd1.print(sensors.getTempC(sensor3));
//Resultaten van de sensor uitprinten op de LCD 2.
lcd2.setCursor (0, 0 );
lcd2.print("A-1:");
lcd2.print(sensors.getTempC(sensor9));
lcd2.print("|");
lcd2.print("R-1:");
lcd2.print(sensors.getTempC(sensor1));
//Resultaten van de sensor uitprinten op de LCD 2.
lcd2.setCursor (0, 1 );
lcd2.print("A-2:");
lcd2.print(sensors.getTempC(sensor10));
lcd2.print("|");
lcd2.print("R-2:");
lcd2.print(sensors.getTempC(sensor8));
//Resultaten van de sensor uitprinten op de LCD 2.
lcd2.setCursor (0, 2 );
lcd2.print("A-3:");
lcd2.print(sensors.getTempC(sensor6));
lcd2.print("|");
lcd2.print("R-3:");
lcd2.print(sensors.getTempC(sensor4));
//Resultaten van de sensor uitprinten op de LCD 2.
lcd2.setCursor (0, 3 );
lcd2.print("A-4:");
lcd2.print(sensors.getTempC(sensor5));
lcd2.print("|");
lcd2.print("R-4:");
lcd2.print(sensors.getTempC(sensor2));
//Resultaten van de sensor uitprinten op de LCD 3.
lcd3.setCursor (0, 0 );
lcd3.print("A-5:");
lcd3.print("|");
lcd3.print("R-5:");
//Resultaten van de sensor uitprinten op de LCD 3.
lcd3.setCursor (0, 1 );
lcd3.print("A-6:");
lcd3.print("|");
lcd3.print("R-6:");
//Resultaten van de sensor uitprinten op de LCD 3.
lcd3.setCursor (0, 2 );
lcd3.print("A-7:");
lcd3.print("|");
lcd3.print("R-7:");
//Resultaten van de sensor uitprinten op de LCD 3.
lcd3.setCursor (0, 3 );
lcd3.print("A-8:");
lcd3.print("|");
lcd3.print("R-8:");
delay(10000);
EthernetClient client = server.available(); // try to get client
if (client) { // got client?
boolean currentLineIsBlank = true;
while (client.connected()) {
if (client.available()) { // client data available to read
char c = client.read(); // read 1 byte (character) from client
// buffer first part of HTTP request in HTTP_req array (string)
// leave last element in array as 0 to null terminate string (REQ_BUF_SZ - 1)
if (req_index < (REQ_BUF_SZ - 1)) {
HTTP_req[req_index] = c; // save HTTP request character
req_index++;
}
// last line of client request is blank and ends with \n
// respond to client only after last line received
if (c == '\n' && currentLineIsBlank) {
// send a standard http response header
client.println("HTTP/1.1 200 OK");
// remainder of header follows below, depending on if
// web page or XML page is requested
// Ajax request - send XML file
if (StrContains(HTTP_req, "ajax_inputs")) {
// send rest of HTTP header
client.println("Content-Type: text/xml");
client.println("Connection: keep-alive");
client.println();
// send XML file containing input states
XML_response(client);
}
else { // web page request
// send rest of HTTP header
client.println("Content-Type: text/html");
client.println("Connection: keep-alive");
client.println("Refresh: 5000");
client.println();
webFile = SD.open("index.htm"); // open web page file
if (webFile) {
while(webFile.available()) {
client.write(webFile.read()); // send web page to client
}
webFile.close();
}
}
// display received HTTP request on serial port
Serial.print(HTTP_req);
// reset buffer index and all buffer elements to 0
req_index = 0;
StrClear(HTTP_req, REQ_BUF_SZ);
break;
}
// every line of text received from the client ends with \r\n
if (c == '\n') {
// last character on line of received text
// starting new line with next character read
currentLineIsBlank = true;
}
else if (c != '\r') {
// a text character was received from client
currentLineIsBlank = false;
}
} // end if (client.available())
} // end while (client.connected())
delay(5000); // give the web browser time to receive the data
client.stop(); // close the connection
} // end if (client)
}
char StrContains(char *str, char *sfind)
// searches for the string sfind in the string str, returns 1 if string found or returns 0 if string not found.
{
char found = 0;
char index = 0;
char len;
len = strlen(str);
if (strlen(sfind) > len) {
return 0;
}
while (index < len) {
if (str[index] == sfind[found]) {
found++;
if (strlen(sfind) == found) {
return 1;
}
}
else {
found = 0;
}
index++;
}
return 0;
}
void XML_response(EthernetClient cl)
{
float tempValOne = 0.0;
float tempValTwo = 0.0;
float tempValThree = 0.0;
float tempValFour = 0.0;
float tempValFive = 0.0;
float tempValSix = 0.0;
float tempValSeven = 0.0;
float tempValEight = 0.0;
float tempValNine = 0.0;
float tempValTen = 0.0;
float tempValEleven = 0.0;
float tempValTwelf = 0.0;
float tempValThirteen = 0.0;
float tempValFourteen = 0.0;
float tempValFiveteen = 0.0;
float tempValSixteen = 0.0;
float tempValSeventeen = 0.0;
float tempValEightteen = 0.0;
float tempValNineteen = 0.0;
// Call sensor and calibration functions
tempValOne = tempCalib1();
tempValTwo = tempCalib2();
tempValThree = tempCalib3();
tempValFour = tempCalib4();
tempValFive = tempCalib5();
tempValSix = tempCalib6();
tempValSeven = tempCalib7();
tempValEight = tempCalib8();
tempValNine = tempCalib9();
tempValTen = tempCalib10();
tempValEleven = tempCalib11();
tempValTwelf = tempCalib12();
tempValThirteen = tempCalib13();
tempValFourteen = tempCalib14();
tempValFiveteen = tempCalib15();
tempValSixteen = tempCalib16();
tempValSeventeen = tempCalib17();
tempValEightteen = tempCalib18();
tempValNineteen = tempCalib19();
// Sending Gauge and Switch Values to webclient
cl.print("<?xml version = \"1.0\" ?>");
cl.print("<inputs>");
cl.print("<analog>");
cl.print(tempValOne);
cl.print("</analog>");
cl.print("<analog>");
cl.print(tempValTwo);
cl.print("</analog>");
cl.print("<analog>");
cl.print(tempValThree);
cl.print("</analog>");
cl.print("<analog>");
cl.print(tempValFour);
cl.print("</analog>");
cl.print("<analog>");
cl.print(tempValFive);
cl.print("</analog>");
cl.print("<analog>");
cl.print(tempValSix);
cl.print("</analog>");
cl.print("<analog>");
cl.print(tempValSeven);
cl.print("</analog>");
cl.print("<analog>");
cl.print(tempValEight);
cl.print("</analog>");
cl.print("<analog>");
cl.print(tempValNine);
cl.print("</analog>");
cl.print("<analog>");
cl.print(tempValTen);
cl.print("</analog>");
cl.print("<analog>");
cl.print(tempValEleven);
cl.print("</analog>");
cl.print("<analog>");
cl.print(tempValTwelf);
cl.print("</analog>");
cl.print("<analog>");
cl.print(tempValThirteen);
cl.print("</analog>");
cl.print("<analog>");
cl.print(tempValFourteen);
cl.print("</analog>");
cl.print("<analog>");
cl.print(tempValFiveteen);
cl.print("</analog>");
cl.print("<analog>");
cl.print(tempValSixteen);
cl.print("</analog>");
cl.print("<analog>");
cl.print(tempValSeventeen);
cl.print("</analog>");
cl.print("<analog>");
cl.print(tempValEightteen);
cl.print("</analog>");
cl.print("<analog>");
cl.print(tempValNineteen);
cl.print("</analog>");
// Sending SWITCH states to dashboard
// SWITCH #1
cl.print("<SW>");
if (SWITCH_state[0]) {
cl.print("checked");
}
else {
cl.print("unchecked");
}
cl.println("</SW>");
// SWITCH #2
cl.print("<SW>");
if (SWITCH_state[1]) {
cl.print("checked");
}
else {
cl.print("unchecked");
}
cl.println("</SW>");
// SWITCH #3
cl.print("<SW>");
if (SWITCH_state[2]) {
cl.print("checked");
}
else {
cl.print("unchecked");
}
cl.println("</SW>");
// SWITCH #4
cl.print("<SW>");
if (SWITCH_state[3]) {
cl.print("checked");
}
else {
cl.print("unchecked");
}
cl.println("</SW>");
cl.print("</inputs>");
}
float tempCalib1() {
float tempC = sensors.getTempC(sensor7);
return tempC;
}
float tempCalib2() {
float tempC = sensors.getTempC(sensor3);
return tempC;
}
float tempCalib3() {
float tempC = sensors.getTempC(sensor9);
return tempC;
}
float tempCalib4() {
float tempC = sensors.getTempC(sensor1);
return tempC;
}
float tempCalib5() {
float tempC = sensors.getTempC(sensor10);
return tempC;
}
float tempCalib6() {
float tempC = sensors.getTempC(sensor8);
return tempC;
}
float tempCalib7() {
float tempC = sensors.getTempC(sensor6);
return tempC;
}
float tempCalib8() {
float tempC = sensors.getTempC(sensor4);
return tempC;
}
float tempCalib9() {
float tempC = sensors.getTempC(sensor5);
return tempC;
}
float tempCalib10() {
float tempC = sensors.getTempC(sensor2);
return tempC;
}
float tempCalib11() {
float tempC = sensors.getTempC(sensor2);
}
float tempCalib12() {
float tempC = sensors.getTempC(sensor2);
}
float tempCalib13() {
float tempC = sensors.getTempC(sensor2);
}
float tempCalib14() {
float tempC = sensors.getTempC(sensor2);
}
float tempCalib15() {
float tempC = sensors.getTempC(sensor2);
}
float tempCalib16() {
float tempC = sensors.getTempC(sensor2);
}
float tempCalib17() {
float tempC = sensors.getTempC(sensor2);
}
float tempCalib18() {
float tempC = sensors.getTempC(sensor2);
}
float tempCalib19() {
float tempC = sensors.getTempC(sensor2);
}
void StrClear(char *str, char length)
// sets every element of str to 0 (clears array)
{
for (int i = 0; i < length; i++) {
str[i] = 0;
}
}
void printTemperature(DeviceAddress address) {
// Fetch the temperature in degrees Celsius for device address:
float tempC = sensors.getTempC(address);
Serial.print(tempC);
}