I have a fully working set of Master/Slave sketch for RS485 Communications between two UNOS, using the standard MAX 485 Modems. Here below is a simplified Master sketch. Is there a charitable soul that can give me the mods to the sketch to make it work with a Zero Master? I would still use a UNO as Slave.
#include <SoftwareSerial.h>
//DECLARE CONSTANTS -
#define SSerialRX 7 //Serial Receive pin.
#define SSerialTX 8 //Serial Transmit pin.
#define SSerialTxControl 2 //Serial RS485 Rx/TX command pin.
#define RS485Transmit HIGH // When Pin 2 HIGH, Transmit.
#define RS485Receive LOW // When Pin 2 LOW, Receive.
//DECLARE OBJECTS
SoftwareSerial RS485Serial(SSerialRX, SSerialTX); //Software Comms RX & TX
//DECLARE VARIABLES
//Operating Variables
int synComm; //Sync byte generated by the Master and sent to the Slave.
int syncRec; //Sync byte read by the Slave and sent back to the Master for verification.
unsigned long k = 0; //Number of Iterations: set below.
int t = 0; //Recycle time: set below.
int inByte = 0; //Used in the SWITCH Command.
//Inputs
int sensorValue_0; //Sensor value received from the Slave.
int Vy0 = 0; //Float variable for Sensor value received from Slave.
//outputs
const int analogOutPin1 = 3; //Outputs sensorValue_0 in Analogue form.
int powerPin = 4; // Used for command of external local device.
//SETTING UP
void setup()
{
Serial.begin(115200);//Starts (USB) Serial Port & sets Data Rate.
//=============================================================
//SETTINGS: These constants to be set up prior to switch-on.
k = 100; //SET NUMBER OF ITERATIONS AT k
t = 1000; //SET RECYCLE TIME, e.g. 1000 = 1 sec.
//=============================================================
delay(200); //This delay gives time to Serial to turn-on & print labels following.
Serial.println("=========RS485 DrDAQ DATA COMMUNICATIONS=========");
Serial. println("===Stand-By/Reset = a; Start = b; press RESET to Stop===");
Serial.print(" ITERATION SETTING = ");
Serial.println(k);
delay(10);
pinMode(powerPin, OUTPUT); // Sets Digital Pin 4 as output.
digitalWrite(powerPin, LOW); //Initially sets power Pin LOW.
pinMode(SSerialTxControl, OUTPUT); //Sets Digital Pin 2 as output.
digitalWrite(SSerialTxControl, RS485Receive); //Initial setting of Pin 2: LOW for receive.
RS485Serial.begin(28800); //Starts software RS485 Serial Port & sets Data Rate.
}
//OPERATION
void loop()
{
if (Serial.available() > 0) // The Byte written in Serial Monitor starts System: see cases "a" & "b" below.
{
int inByte = Serial.read(); // Byte written in Serial Monitor
switch (inByte) // Switch operator selects alternative cases "a" or "b".
{
case 'a': // Slave reset & System St-By.
digitalWrite(4, LOW); //power Pin confirmed LOW in Stand-By.
synComm = 111;
Serial.println("=========RS485 SIX CHANNEL PICO DATA COMMUNICATIONS=========");
Serial.println("======RESET TO SLAVE // SLAVE READY // SYSTEM IN ST-BY======");
digitalWrite(SSerialTxControl, RS485Transmit); //Sets TX/RX control HIGH to transmit.
delay(20);
RS485Serial.write(synComm); //Sends the Sync Byte to Slave.
delay(300);
digitalWrite(SSerialTxControl, RS485Receive);
delay(300);
break;
case 'b': // System operation.
for (int i = 0; i < k; i++) //This is the iteration counter: number of iterations = K.
{
synComm = 123; // This is the Sync byte sent to the Slave for control.If Sync Byte received is not "123", system does not start.
float R = (t); // Calculates recycle time in mSeconds.
int S = (R * (k) / 60000); // Calculates total data acquisition time.
delay(t);
// We are in RX condition: now we transmit the Sync Byte to the Slave to start the System.
digitalWrite(SSerialTxControl, RS485Transmit); //Sets TX/RX control HIGH to transmit.
RS485Serial.write(synComm); //Sends the Sync Byte to Slave.
digitalWrite(SSerialTxControl, RS485Receive); //Sync Byte sent, now we seek data from Slave, RX/TX to receive.
if (RS485Serial.available()>0) // System carries on if it received data from the Slave.
{
syncRec = RS485Serial.read(); //Reads the Sync Byte sent back from the Slave as a check.
if(syncRec == synComm)
{
digitalWrite(powerPin, HIGH); //Turns power Pin on for external device command.
sensorValue_0 = RS485Serial.read(); //Reads the sensor data (Value_0) of Channel 0 sent by the Slave in 8 bit format 0-255.
analogWrite(analogOutPin1, sensorValue_0); // Writes Value_0 to output Pin 1 IN ANALOGUE format as PWM's duty Cycle.
float Vy0 = (sensorValue_0 * 19.8039); // Converts Value_0 to Analogue format to display on Serial Monitor.
Serial.print("SLAVE CHANNEL/0 = ");
Serial.print(sensorValue_0);
Serial.print(" - mV ");
Serial.println(Vy0);
delay(200);
}
else
{
Serial.println("ALARM - ERROR OR NO CONNECTION TO SLAVE");
delay(2000);
exit(0);
}
}
}
}
}
} //End of Iteration - Iteration re-starts.