Hi!
I'm an inexperienced hobby programmer and would really like some feedback from you more experienced guys.
This is code that I will use in a grow-controller in addition to several other things I have planned for later ( Remote monitoring sensor data on a boat, battery under voltage guard, fire alarm, with SMS/phone alerts etc)
All the code is capable of now is sending back temperature and humidity, controlling relays and reading the outputs to the relays to confirm the state they are supposed to be in.
Please review my code and tell me what can be improved, maybe I did something really stupid that has to be done another way.
Positive and especially negative feedback is very much appreciated!
Code from master:
/* A sketch for controlling relays, requesting and processing sensor information over RS485
with the help of:
EasyTransfer ( REALLY great help )
Brought to you by:
Bill Porter
www.billporter.info
*/
#include <EasyTransfer.h>
#include <SoftwareSerial.h>
#define SSerialRX 10 //Serial Receive pin
#define SSerialTX 11 //Serial Transmit pin
/*-----( Declare objects )-----*/
SoftwareSerial RS485Serial(SSerialRX, SSerialTX); // RX, TX // Debug serial
EasyTransfer ETin, ETout;
struct SEND_DATA_STRUCTURE{ // Variables being sent to slaves
int address;
int id;
int port;
int highlow;
};
struct RECEIVE_DATA_STRUCTURE{ // For receiving sensor values etc.
int id;
int port;
int buttonstate;
};
RECEIVE_DATA_STRUCTURE rxdata;
SEND_DATA_STRUCTURE txdata;
//Reading ID's
int relay = 0;
int temp = 1;
int hum = 2;
int dr = 3;
int waitDelay = 100;
void setup(){
Serial.begin(115200); // Start serial for RS485
RS485Serial.begin(115200); // Debug software serial
// Start the library, pass in the data details and the name of the serial port.
ETin.begin(details(rxdata), &Serial); // Initiate easytransfer for sending
ETout.begin(details(txdata), &Serial); // Receiving
}
void loop(){
delay(waitDelay);
// RS485(ADDRESS,ID,PORT/SENSOR, H/L)
// A loop to send requests one after another to allow me to test speed and possible hickups
RS485(1, temp, 0, HIGH); // Request TemperatureSensor[0] from address 1, HIGH or LOW does nothing on temperature or humidity ID's.
delay(waitDelay);
RS485(1, hum, 0, HIGH); // Request HumidityReading[0] from address 1.
delay(waitDelay);
RS485(1, relay, 1, HIGH); // Tell address 1 to turn relay 1 HIGH.
delay(waitDelay);
RS485(1, dr , 1, LOW); // Request address 1 to digitalRead relay 1 output. HIGH/LOW does nothing, will be used to confirm if it is requested state.
delay(waitDelay);
RS485(1, relay, 1, LOW); // Tell address 1 to turn relay 1 LOW.
delay(waitDelay);
RS485(1, dr , 1, LOW);
delay(waitDelay);
RS485(1, relay, 2, HIGH);
delay(waitDelay);
RS485(1, dr , 2, LOW);
delay(waitDelay);
RS485(1, relay, 2, LOW);
delay(waitDelay);
RS485(1, dr , 2, LOW);
delay(waitDelay);
RS485(1, relay, 3, HIGH);
delay(waitDelay);
RS485(1, dr , 3, LOW);
delay(waitDelay);
RS485(1, relay, 3, LOW);
delay(waitDelay);
RS485(1, dr , 3, LOW);
delay(waitDelay);
RS485(1, relay, 4, HIGH);
delay(waitDelay);
RS485(1, dr , 4, LOW);
delay(waitDelay);
RS485(1, relay, 4, LOW);
delay(waitDelay);
RS485(1, dr , 4, LOW);
delay(waitDelay);
RS485(1, relay, 5, HIGH);
delay(waitDelay);
RS485(1, dr , 5, LOW);
delay(waitDelay);
RS485(1, relay, 5, LOW);
delay(waitDelay);
RS485(1, dr , 5, LOW);
delay(waitDelay);
RS485(1, relay, 6, HIGH);
delay(waitDelay);
RS485(1, dr , 6, LOW);
delay(waitDelay);
RS485(1, relay, 6, LOW);
delay(waitDelay);
RS485(1, dr , 6, LOW);
delay(waitDelay);
RS485(1, relay, 7, HIGH);
delay(waitDelay);
RS485(1, dr , 7, LOW);
delay(waitDelay);
RS485(1, relay, 7, LOW);
delay(waitDelay);
RS485(1, dr, 7, LOW);
}
//Function for sending and receiving data
void RS485(int address, int id, int port, int highlow){
txdata.address = address; // fill up transmit structure for request
txdata.id = id;
txdata.port = port;
txdata.highlow = highlow;
ETout.sendData(); // Send data to address
delay(10);
for(int i = 0; i < 5; i++){ // Loop to be sure to catch data// maybe not neccesary when using hardware serial?
if(ETin.receiveData()){ // Look for incoming data
if(rxdata.id == dr){ // If received ID is dr : digitalRead
RS485Serial.print(" Read port: ");
RS485Serial.print(rxdata.port); // Print what port was read
RS485Serial.print(" H/L: ");
RS485Serial.println(rxdata.buttonstate); // Print what state port was
}
if(rxdata.id == relay){ // If id == relay, print port info
RS485Serial.print("Port: ");
RS485Serial.print(rxdata.port);
RS485Serial.print(" Sent state: ");
RS485Serial.print(rxdata.buttonstate);
if(rxdata.buttonstate != txdata.highlow){ // Check to see if sent and received state matches
RS485Serial.print(" Sent and received state dont match! ");
}
}
if(rxdata.id == temp){
if(rxdata.buttonstate == true){ // If true requested sensor does not exist at node
RS485Serial.println("Sensor does not exist");
}
else{ // Print sensor data
RS485Serial.print("Reading: ");
RS485Serial.print("Temperature");
RS485Serial.print(" Sensor: ");
RS485Serial.print(txdata.port); // Sensor ID
RS485Serial.print(" Temp: ");
RS485Serial.println(rxdata.port); // Sensor reading
}
}
if(rxdata.id == hum){
if(rxdata.buttonstate == true){ // If true requested sensor does not exist at node
RS485Serial.println("Sensor does not exist");
}
else{ // Print sensor data
RS485Serial.print("Reading: ");
RS485Serial.print("Humidity");
RS485Serial.print(" Sensor: ");
RS485Serial.print(txdata.port); // ID of sensor
RS485Serial.print(" Humidity: ");
RS485Serial.println(rxdata.port); // Sensor reading
}
}
}
delay(10);
}
}
Code from slave 1:
The only problem I seem to be having is located in the master's code :
if(rxdata.buttonstate != txdata.highlow){ // Check to see if sent and received state matches
RS485Serial.print(" Sent and received state dont match! ");
}
}
txdata.highlow which is passed from the loop to the function, often says its 0, even though its actually HIGH as the led on the slave in addition to the digitalRead afterwards confirms it.
Here is my debug output:
Reading: Temperature Sensor: 0 Temp: 2000
Reading: Humidity Sensor: 0 Humidity: 2970
Port: 1 Sent state: 1 Read port: 1 H/L: 1
Port: 1 Sent state: 0 Read port: 1 H/L: 0
Port: 2 Sent state: 1 Read port: 2 H/L: 1
Port: 2 Sent state: 0 Read port: 2 H/L: 0
Port: 3 Sent state: 1 Read port: 3 H/L: 1
Port: 3 Sent state: 0 Read port: 3 H/L: 0
Port: 4 Sent state: 1 Read port: 4 H/L: 1
Port: 4 Sent state: 0 Read port: 4 H/L: 0
Port: 5 Sent state: 1 Read port: 5 H/L: 1
Port: 5 Sent state: 0 Read port: 5 H/L: 0
Port: 6 Sent state: 1 Sent and received state dont match! Read port: 6 H/L: 1
Port: 6 Sent state: 0 Read port: 6 H/L: 0
Port: 7 Sent state: 1 Read port: 7 H/L: 1
Port: 7 Sent state: 0 Read port: 7 H/L: 0
On port 6 you can see the problem occour. Where it occurs is random, and some loops it doesn't happen at all.
This is not a dealbreaker for me as I can just read the port afterwards instead of getting the info sent back right after setting the port HIGH/LOW, but it would be nice to know what may be causing the problem so I can learn something new today too.
Thanks to everyone that uses their time to review my code!