I am making an Ethernet temperature logging module that uses an RTD temperature sensor and amp, a thermocouple and amp, and an analog TMP36 sensor and sends UDP packets to a master when asked. It also creates a webpage of its history for who ever logs into the IP of the device. The issue is my code takes up roughly 90% of the Uno's program storage and 71% of its dynamic memory. This sometimes causes code instability...
Does anyone have any suggestions that could reduce my code size at all? Criticism is welcome. Thanks!
My code is as follows:
#include <Adafruit_MAX31856.h>
#include <Adafruit_MAX31865.h>
#include <SPI.h>
#include <SD.h>
#include <Ethernet2.h>
#include <EthernetUdp2.h>
//Thermocouple Amplifier Config
Adafruit_MAX31856 thermoAmp = Adafruit_MAX31856(6,7,8,9); //Creates the thermocouple instance with the pins in order: CS, DI, DO, CLK
//RTD Amplifier Config
Adafruit_MAX31865 rtdAmp = Adafruit_MAX31865(5,7,8,9); //Creates the RTD instance with the pins in order: CS, DI, DO, CLK
//Ethernet Set-Up:
byte mac[] = {0x2C, 0xF7, 0xF1, 0x08, 0x04, 0x3C}; //The MAC Address on the Ethernet Card
IPAddress ip(172, 20, 50, 120); //The static IP of this device - Only used if DHCP server doesn't assign it an IP
EthernetServer server(80); //The port that the webserver will run on (Default: 80)
unsigned int localPort = 8888; //The port that the UDP server listens on (Default: 8888)
const char* serverIP = "172.20.50.200"; //The IP Address of the computer with the server program running
//Buffers for receiving and sending data
char packetBuffer[12]; //Buffer to hold incoming packet - Set to 12 bytes, max is 24 bytes.
char ReplyBuffer[] = "Error"; //Buffer to send data back in
//EthernetUDP instance to let us send and receive packets over UDP
EthernetUDP Udp;
//Create the variables that will hold the data read from the AUX ports, set them to 0 initially
float aux1 = 0.0, aux2 = 0.0, aux3 = 0.0, aux4 = 0.0;
//The setup code is ran only one time when the arduino is first plugged in or the reset button is pressed
void setup() {
//Start the RTD amplifier instance
rtdAmp.begin(MAX31865_3WIRE);
//Start the thermocouple amplifier instance and send the "K type" command to the chip
thermoAmp.begin();
delay(50);
thermoAmp.setThermocoupleType(MAX31856_TCTYPE_K);
//Start the Ethernet, webserver, and UDP instances:
if (Ethernet.begin(mac) == 0) {
//Try to congifure the Arduino Ethernet card using a static IP address instead of DHCP:
Ethernet.begin(mac, ip);
}
Udp.begin(localPort);
server.begin();
//Wait .5 seconds for external boards to initialize
delay(500);
//Send a message to the server saying that this slave is online
Udp.beginPacket(serverIP, localPort);
Udp.write("Online");
Udp.endPacket();
//SD Card Set-Up: Make the chip select pin an output (Pin 4 is hardwired to be the SD Card CS pin)
pinMode(4, OUTPUT);
//SD Card Set-Up: Check if there is an SD Card present
SD.begin(4);
}
void loop() {
//Check if there's UDP data available - read the packet
int packetSize = Udp.parsePacket();
//Check for incoming webserver clients
EthernetClient client = server.available();
//If there is a packet availible then handle it
if (packetSize) {
handleUDP();
}
//If there is a webserver client availible then handle it
if (client) {
handleWebserverClients(client);
}
delay(10);
}
void handleUDP() {
//Read the packet into packetBufffer
Udp.read(packetBuffer, 12);
String request = String(packetBuffer);
if(request.startsWith("tmp",0)){
//Send the temperature to server
Udp.beginPacket(serverIP, localPort);
String stringReply = String(String(((thermoAmp.readThermocoupleTemperature()*1.8) + 32)) + ", " + ((rtdAmp.temperature(100, 430.0)*1.8)+32));
stringReply.toCharArray(ReplyBuffer, 50);
Udp.write(ReplyBuffer);
Udp.endPacket();
writeToLogFile(stringReply);
}else if(request.startsWith("aux",0)){
//Clear the SD card and send a completed note back to the master
handleSwitchModes(); //Updates aux1 through aux3 so we can send the data back
Udp.beginPacket(serverIP, localPort);
String stringReply = String("" + String(aux1) + "," + aux2 + "," + aux3 + "," + aux4);
stringReply.toCharArray(ReplyBuffer, 50);
Udp.write(ReplyBuffer);
Udp.endPacket();
}else if(request.startsWith("tim",0)){
//Send the runtime to server in millis
Udp.beginPacket(serverIP, localPort);
String stringReply = String(millis() / 60000) + "min";
stringReply.toCharArray(ReplyBuffer, 50);
Udp.write(ReplyBuffer);
Udp.endPacket();
}else if(request.startsWith("clr",0)){
//Clear the SD card and send a completed note back to the master
Udp.beginPacket(serverIP, localPort);
String stringReply = String(((SD.remove("log.txt") && SD.open("log.txt", FILE_WRITE)) ? "Done" : "Failed"));
stringReply.toCharArray(ReplyBuffer, 50);
Udp.write(ReplyBuffer);
Udp.endPacket();
}
}
void handleWebserverClients(EthernetClient client) {
// an http request ends with a blank line
boolean currentLineIsBlank = true;
while (client.connected()) {
if (client.available()) {
char c = client.read();
if (c == '\n' && currentLineIsBlank) {
// send a standard http response header
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
client.println("Connection: close");
client.println();
client.println("<!DOCTYPE HTML>");
client.println("<html><pre>");
//Open the log file for reading:
File myfile = SD.open("log.txt");
if (myfile)
{
//Read all the text written on the file
while (myfile.available())
{
client.write(myfile.read());
}
// close the file:
myfile.close();
} else {
// if the file didn't open, report an error:
client.println("Error opening the data file! Try cycling the power of the Arduino or take the SD card out, put in back in, and try again...");
//The SD card may have been removed and inserted again so try to reload it
SD.begin(4);
}
client.println("</pre></html>");
break;
}
if (c == '\n') {
// you're starting a new line
currentLineIsBlank = true;
}
else if (c != '\r') {
// you've gotten a character on the current line
currentLineIsBlank = false;
}
}
}
// give the web browser time to receive the data
delay(1);
// close the connection:
client.stop();
}
void writeToLogFile(String dataToWrite) {
File myfile = SD.open("log.txt", FILE_WRITE);
if (myfile)
{
myfile.print(millis() / 1000); //Print seconds since start
myfile.print(": ");
myfile.println(dataToWrite); //Print the data
myfile.close(); //close the file:
} else {
//If the file didn't open, report an error:
//The SD card may not have initialized - try again
SD.begin(4);
}
}
void handleSwitchModes() {
//Check if the switch is in the "ON" position
if(digitalRead(3) == HIGH) {
//Set up the AUX ports for a single Analog Temperature Device (TMP36)
//Set A0 pin to output 5v, set A1 pin input, and set A2 to 0v(low)
pinMode(A0, OUTPUT);
pinMode(A1, INPUT);
pinMode(A2, OUTPUT);
digitalWrite(A0, HIGH);
digitalWrite(A2, LOW);
//Convert the analog signal on pin A1 to millivolts
float voltage = analogRead(1) * 5.0;
voltage /= 1024.0;
//Read the temperature from analog pin 3 - https://learn.adafruit.com/tmp36-temperature-sensor/using-a-temp-sensor
aux4 = 0.0;
aux3 = 0.0;
aux2 = (((voltage - 0.5)*100)*1.8) + 32;
aux1 = 0.0;
}else{
//Set up the AUX ports to read analog signals in
pinMode(A0, INPUT);
pinMode(A1, INPUT);
pinMode(A2, INPUT);
pinMode(A3, INPUT);
//Read the temperature from the analog pins
aux4 = analogRead(A3);
aux3 = analogRead(A2);
aux2 = analogRead(A1);
aux1 = analogRead(A0);
}
}