Hello. I have a requirement as follows and need your expertise in resolving the issue. I need to set up a master and two slaves on RS485, RS485 because the distance between master to first slave is 10m and another 10 mt to the other slave. The master is in the middle with the slaves on either side of the master. I will be using MAX485 modules for all the three arduinos.
Each of the slaves will be measuring (3) distances - FL_dist, FC_dist adn FR_dist. The sensors are connected to the slaves using I2C network. That part of the code is currently ommitted for simplicity and a fixed integer values assigned to the three variables.
The master on the other hand will receive the data from each slave and use it to display on a 20x4 LCD over I2C network. That part of the code is also ommitted for simplicity.
To begin with I am using only one master and one slave to set up the circuit and ensure communication and data transfer successfully.
Here is the image of the MAX485 module I am using.
I do not want to use the address selection vide external hardware set up, but would like to use one dedicated line between the master and slave 1 (pins 8 on the master and slave 1) and another dedicated line between the master and slave 2 (pins 9 on the master and slave 2). Master would make and select the dedicated line HIGH to address either the slave 1 or slave 2 and then unselect, one after the other.
I have not used any physical / External pullups or pull downs in the entire hardware.
I have shorted RE and DE pins on the MAX485 module and connected it to pins 4 of the master and slave and is called as Enable.
The Vcc and GND for the MAX485 module
I have used SoftwareSerial library to make pins 2 and 3 for RX and TX.
I have used a twisted pair Ethernet cable between the A and B of the MAX 485 module, where A goes to A and B goes to B using the green terminal block connector on the top right. There is a 120 ohm resistor between the A and B on either side of the twisted pair cable.
As I run the code, the Master is saying that the "Data Request is Sent", while the slave says "Slave Ready to Receive". The master also displays random values received from the slave as FL_dist: -8196, FC_dist: -8196 and FR_dist:-8196 in place of the intended 10, 20 and 30 as per the test codes of Master and Slave Arduinos, provided for your analysis.
Help me understand and correct where I am going wrong and why I am unable to get the set up to work as intended.
// Master_25042024
#include <SoftwareSerial.h>
#define RX_PIN 2 // Define RX pin for SoftwareSerial _ now blue - goes to RO
#define TX_PIN 3 // Define TX pin for SoftwareSerial _ now purple - goes to DI
#define Enable 4 // Define Driver Enable pin for RS485 communication_ now orange
#define ready_Slave 8 // Define pin to indicate readiness to the master
SoftwareSerial rs485(RX_PIN, TX_PIN); // RX is pin 2 and TX is pin 3
int FL_dist, FC_dist, FR_dist;
void setup()
{
pinMode(Enable, OUTPUT);
pinMode(ready_Slave, OUTPUT); // alternative way of selecting
digitalWrite(ready_Slave, LOW); // puttin TTL-RS485 Module in Receive Mode
rs485.begin(9600);
Serial.begin(9600);
}
void loop() {
digitalWrite(ready_Slave, HIGH); // Getting Slave ready
Serial.println("Slave selected");
delay(5); // Delay for slave to enter into listening mode
digitalWrite(Enable, HIGH); // Putting the RS485 module in Transmit mode
Serial.println("Ready to send data request");
delay (5);
rs485.write('S'); // Send data request command
delay(10); // Delay for slave to process the request
Serial.println("Data Request Sent"); // for troubleshooting
digitalWrite(Enable, LOW); // Putting the RS485 module in Receive Mode
// Wait for the slave to send the response
delay(100); // Adjust the delay as necessary based on the slave processing time
// Read sensor data from the slave
while (rs485.available() >= 6) {
// Read and reconstruct FL_dist
uint16_t FL_lowByte = rs485.read();
uint16_t FL_highByte = rs485.read();
FL_dist = FL_lowByte | (FL_highByte << 8);
// Read and reconstruct FC_dist
uint16_t FC_lowByte = rs485.read();
uint16_t FC_highByte = rs485.read();
FC_dist = FC_lowByte | (FC_highByte << 8);
// Read and reconstruct FR_dist
uint16_t FR_lowByte = rs485.read();
uint16_t FR_highByte = rs485.read();
FR_dist = FR_lowByte | (FR_highByte << 8);
}
digitalWrite(Enable, HIGH); // Putting the RS485 module in Transmit Mode
Serial.println("Enable put in transmit mode");
digitalWrite(ready_Slave, LOW);
Serial.println("Slave de-selected");
Serial.print("FL_dist: ");
Serial.println(FL_dist);
Serial.print("FC_dist: ");
Serial.println(FC_dist);
Serial.print("FR_dist: ");
Serial.println(FR_dist);
}
//Slave
#include <arduino.h>
#include <SoftwareSerial.h>
#define RX_PIN 2 // Define RX pin for SoftwareSerial_(goes to RO on TTL-RS485 module)
#define TX_PIN 3 // Define TX pin for SoftwareSerial_(goes to DI on TTL-RS485 module)
#define Enable 4 // Define Driver Enable pin for RS485 communication_(Pins DE & RE shorted on the TTL-RS485 module)
#define slave1 8 // Direct line between Master and Slave, this line will be pulled HIGH by the Master to initiate start of communication
SoftwareSerial rs485(RX_PIN, TX_PIN); // Create a SoftwareSerial object for RS485 communication
int FL_dist = 10; // Replace with real time Sensor data later
int FC_dist = 20;
int FR_dist = 30;
char incoming;
Serial.flush();
void setup()
{
pinMode(Enable, OUTPUT); // Set Enable as an output pin
pinMode(slave1, INPUT); // Set slave1 as an input pin
rs485.begin(9600); // Initialize SoftwareSerial with baud rate 9600
Serial.begin(9600); // Initialize Serial communication for debugging
digitalWrite (slave1, HIGH); // Putting the slave TTL-RS485 into Transmit Mode
}
void loop()
{
if (digitalRead(slave1) == HIGH)
{
digitalWrite(Enable, LOW); // put the module into receive mode
Serial.println("Slave ready to receive");
//delay(5); // changed 26042024_0843
if (Serial.available() > 0) //
{ // checking for data request from Master
incoming = Serial.read();
if (incoming == 'S')
{
Serial.println("Data Request Received");
digitalWrite(Enable, HIGH); // put the module into Transmit mode
Serial.println("Enable HIGH");
// Send sensor data
rs485.write((uint8_t*)&FL_dist, sizeof(FL_dist));
rs485.write((uint8_t*)&FC_dist, sizeof(FC_dist));
rs485.write((uint8_t*)&FR_dist, sizeof(FR_dist));
delay (5); // delete if needed
Serial.flush();
digitalWrite(Enable, LOW); // put Enable back into Receiving mode
Serial.println("Data Sent and Enable is now LOW");
}
else
{
Serial.println("mismatch");
}
}
else
{
Serial.println("Data Request NOT Received");
}
}
else
{
Serial.println("Direct line is LOW");
}
}
I must mention here that this piece of code mentioned below is NOT written by me.
// Read and reconstruct FL_dist
uint16_t FL_lowByte = rs485.read();
uint16_t FL_highByte = rs485.read();
FL_dist = FL_lowByte | (FL_highByte << 8);
// Read and reconstruct FC_dist
uint16_t FC_lowByte = rs485.read();
uint16_t FC_highByte = rs485.read();
FC_dist = FC_lowByte | (FC_highByte << 8);
// Read and reconstruct FR_dist
uint16_t FR_lowByte = rs485.read();
uint16_t FR_highByte = rs485.read();
FR_dist = FR_lowByte | (FR_highByte << 8);