I am trying to make a Nextion remote control screen with RS485. I use Nano for the RS485 control PIN. I use Arduino Mega as a master device. I'm sending data to Nextion through the SoftwareSerial library. My problem is I can send data to Nano, but I can't get data from Nano. The TX and RX pins on the mega don't flash.
Mega Sketch :
#define SSerialTxControl 28 //RS485 Direction control
#define RS485Transmit HIGH
#define RS485Receive LOW
#define Pin13LED 13
/*-----( Declare Variables )-----*/
int byteReceived;
int byteSend;
void setup() /****** SETUP: RUNS ONCE ******/
{
// Start the built-in serial port, probably to Serial Monitor
Serial.begin(38400);
Serial.println("SerialRemote"); // Can be ignored
pinMode(Pin13LED, OUTPUT);
pinMode(SSerialTxControl, OUTPUT);
digitalWrite(SSerialTxControl, RS485Receive); // Init Transceiver
// Start the software serial port, to another device
Serial2.begin(38400); // set the data rate
}//--(end setup )---
void loop() /****** LOOP: RUNS CONSTANTLY ******/
{
//Copy input data to output
if (Serial2.available())
{
byteSend = Serial2.read(); // Read the byte
digitalWrite(Pin13LED, HIGH); // Show activity
delay(10);
digitalWrite(Pin13LED, LOW);
digitalWrite(SSerialTxControl, RS485Transmit); // Enable RS485 Transmit
Serial2.write(byteSend); // Send the byte back
delay(10);
digitalWrite(SSerialTxControl, RS485Receive); // Disable RS485 Transmit
// delay(100);
}// End If RS485SerialAvailable
}//--(end main loop )---
/*-----( Declare User-written Functions )-----*/
//NONE
//*********( THE END )***********
Nano Sketch :
#include <SoftwareSerial.h>
/*-----( Declare Constants and Pin Numbers )-----*/
#define SSerialRX 10 //Serial Receive pin
#define SSerialTX 11 //Serial Transmit pin
#define SSerialTxControl 6 //RS485 Direction control
#define RS485Transmit HIGH
#define RS485Receive LOW
#define Pin13LED 13
/*-----( Declare objects )-----*/
SoftwareSerial nextion(SSerialRX, SSerialTX); // RX, TX
/*-----( Declare Variables )-----*/
int byteReceived;
int byteSend;
void setup() /****** SETUP: RUNS ONCE ******/
{
// Start the built-in serial port, probably to Serial Monitor
Serial.begin(38400);
Serial.println("YourDuino.com SoftwareSerial remote loop example");
Serial.println("Use Serial Monitor, type in upper window, ENTER");
pinMode(Pin13LED, OUTPUT);
pinMode(SSerialTxControl, OUTPUT);
digitalWrite(SSerialTxControl, RS485Receive); // Init Transceiver
// Start the software serial port, to another device
nextion.begin(38400); // set the data rate
}//--(end setup )---
void loop() /****** LOOP: RUNS CONSTANTLY ******/
{
digitalWrite(Pin13LED, HIGH); // Show activity
if (Serial.available())
{
byteReceived = Serial.read();
nextion.write(byteReceived); // Send byte to Remote Arduino
digitalWrite(Pin13LED, LOW); // Show activity
}
if (nextion.available()) //Look for data from other Arduino
{
digitalWrite(Pin13LED, HIGH); // Show activity
byteReceived = nextion.read(); // Read received byte
digitalWrite(SSerialTxControl, RS485Transmit); // Enable RS485 Transmit
Serial.write(byteReceived); // Show on Serial Monitor
delay(10);
digitalWrite(SSerialTxControl, RS485Receive); // Disable RS485 Transmit
digitalWrite(Pin13LED, LOW); // Show activity
}
}//--(end main loop )---
/*-----( Declare User-written Functions )-----*/
//NONE
//*********( THE END )***********
Hold on, what is the plan ? You've seemed to have confused things a little. I'd say the plan should be that the master sends a byte first. That is what masters do. so : in the mega Sketch
void loop()
{
if (Serial.available()) // read from the Serial monitor
{
byteSend = Serial.read(); // Read the byte
digitalWrite(Pin13LED, HIGH); // Show activity
delay(10);
digitalWrite(Pin13LED, LOW);
digitalWrite(SSerialTxControl, RS485Transmit); // Enable RS485 Transmit
Serial2.write(byteSend); // Send the byte to the Nano
delay(1); // for 1 byte at 38400, you need about a quarter of a ms.
digitalWrite(SSerialTxControl, RS485Receive); // Disable RS485 Transmit
}
if (Serial2.available()) // read from the slave
{
byteSend = Serial2.read(); // Read the byte
digitalWrite(Pin13LED, HIGH); // Show activity
delay(10);
digitalWrite(Pin13LED, LOW);
Serial.write(byteSend); // Send the byte to the Serial Monitor
// delay(1); // no need to wait for the serial buffer to clear
}
}//--(end main loop )---
and so for the Nano it should receive, send to the nextion, and echo back for now.
void loop()
{
digitalWrite(Pin13LED, HIGH); // Show activity
if (Serial.available())
{
byteReceived = Serial.read();
delay(2); // just a tad more to make sure the RS485 is in receive mode at the other end.
digitalWrite(SSerialTxControl, RS485Transmit); // Enable RS485 Transmit
Serial.write(byteReceived); // Send to the Mega
delay(1); // wait for the buffer to clear
digitalWrite(SSerialTxControl, RS485Receive); // Disable RS485 Transmit
nextion.write(byteReceived); // Send byte to Nextion
digitalWrite(Pin13LED, LOW); // Show activity
}
if (nextion.available()) //Look for data from nextion !!
{
digitalWrite(Pin13LED, HIGH); // Show activity
byteReceived = nextion.read(); // Read received byte
digitalWrite(SSerialTxControl, RS485Transmit); // Enable RS485 Transmit
Serial.write(byteReceived); // Send that to the Mega
delay(1);
digitalWrite(SSerialTxControl, RS485Receive); // Disable RS485 Transmit
digitalWrite(Pin13LED, LOW); // Show activity
}
}
That is what you said you want to do.
But in general i never really use a Max485 like that. It cumbersome. For transmission over a RS485 bus i anyway need a shielded twisted pair of wires ideally Cat 5 (or 6) UTP cable, And at the baudrate you are using we ca go a loooong way (upto 450meters !) And UTP cable has 4 pairs, i can use 3 of those (half of one as a common GND) and with 2 more transceivers i have a full-duplex system, without al the directional switching. The RS485 is meant to cover big distances, if you aren't doing that, get rid of the transceivers and hook the Arduinos straight into each other, and lower the Baud-rate until you get a reliable transmission. (9600 should get you at least 30m)
LightuC:
Can you draw a schematic of your connections with pin numbers?
Deva_Rishi:
Hello,
First of all, I apologize for the late reply. The problem was caused by software. I just discovered the problem. I can't read data from Nextion with Nano and send it to Mega.
Nano Sketch :
#include <AltSoftSerial.h>
AltSoftSerial altSerial;
/* RS485 Configurations */
#define RS485ControllerPin 6
#define RS485Transmit HIGH
#define RS485Receive LOW
void setup() {
// Open serial communications and wait for port to open:
Serial.begin(38400);
// set the data rate for the SoftwareSerial port
altSerial.begin(38400);
pinMode(RS485ControllerPin, OUTPUT);
digitalWrite(RS485ControllerPin, RS485Receive);
}
void loop() { // run over and over
static uint8_t buffer[8];
static uint8_t receivedByteCounter;
uint8_t byteHolder;
while (altSerial.available() > 0)
{
byteHolder = altSerial.read();
buffer[receivedByteCounter] = byteHolder;
if (receivedByteCounter == 7)
{
for(int i = 0; i < 8; i++) {
digitalWrite(RS485ControllerPin, RS485Transmit);
Serial.print((byte)buffer[i], HEX);
delay(1);
digitalWrite(RS485ControllerPin, RS485Receive);
}
receivedByteCounter = 0;
}
++receivedByteCounter;
}
}
Serial Monitor : Expected : A5A5A501000 | Result : A5A5A501000 The result is displayed on the serial screen as I want. But Mega seems like he doesn't understand the data type. I think there is a problem with the data type I sent to Mega.
Start with lower baudrates on software serial connection, 38400 is at the limit as far as I know
for transmit up to 115200, and both ways 57600 are reliable.
But that is not the issue. Actually the reception is as expected on the altswSerial.
You send it from the nano as a HEX representation of a byteSerial.print((byte)buffer[i], HEX); which makes it easy to read on the serial monitor, but then you try to receive it on the Mega as if they are still individual bytes (rather than their HEX representation)
byteHolder = Serial2.read();
if (byteHolder == 0xa5)
You should be trying to read what you send (or send what you want to read) which is a 14-byte char - array "A5A5A501000" So if you want to compare the first byte, you need to read the first 2 characters and compare them to "A5".
Also using while (Serial2.available() > 0) within a Serial event, chances are you will empty the buffer before the transmission is complete.
sterretje:
1)If you're talking about the LEDs, you are aware that they will only flash when communicating over USB (Serial, not Serial1 and so on?
Start with lower baudrates on software serial connection, 38400 is at the limit as far as I know.
1-) Yes, you're right. I was printing the same data on the serial monitor and Serial2. I noticed it later. It wasn't in Sketch. Sorry.
2-) I've tried sending data from Nano to Nextion via AltSoftSerial Library and it's working. AltSoftSerial Library, for an extra serial port The library does its job very well. The baudrate limit is higher than it says.
I thank you for your advice and help. But I'm sure it's about the data type. I just don't understand what kind of data I have to send.
Deva_Rishi:
for transmit up to 115200, and both ways 57600 are reliable.
But that is not the issue. Actually the reception is as expected on the altswSerial.
You send it from the nano as a HEX representation of a byteSerial.print((byte)buffer[i], HEX); which makes it easy to read on the serial monitor, but then you try to receive it on the Mega as if they are still individual bytes (rather than their HEX representation)
byteHolder = Serial2.read();
if (byteHolder == 0xa5)
You should be trying to read what you send (or send what you want to read) which is a 14-byte char - array **"A5A5A501000"** So if you want to compare the first byte, you need to read the first 2 characters and compare them to "A5".
Also using ` while (Serial2.available() > 0)` within a Serial event, chances are you will empty the buffer before the transmission is complete.
I get it, okay, I see, but would it make any difference if I sent the data with "serial.write(temp, length)" OR "serial.print((byte)temp)" ? I think I need to write the data byte by byte from the static buffer. I don't have to turn it into HEX, do I ?
As far as I know, when variable is defined with byte data type : A5 to 165 or 0xa5 all values are the same. I hope I didn't misunderstand what you wrote. Thank you.
"serial.print((byte)temp)" ? I think I need to write the data byte by byte from the static buffer. I don't have to turn it into HEX, do I ?
No you don't have to, but you did so you could read it on the Serial Monitor. if you change Serial.print((byte)buffer[i], HEX); to Serial.write((byte)buffer[i]); You won't recognize it probably since it will look like this : '¥'
As far as I know, when variable is defined with byte data type : A5 to 165 or 0xa5 all values are the same
, yes but you are calling a function which does have some overloaded versions, but print() 0xA5 as 165, and will convert that to 3 bytes being '1', '6' & 5' and converts 0xA5 to HEX if you specify that would make it "A5", which at the other end will come out as 2 bytes values 65 & 35.
write() is the function you want that actually sends the value.
Deva_Rishi:
No you don't have to, but you did so you could read it on the Serial Monitor. if you change Serial.print((byte)buffer[i], HEX); to Serial.write((byte)buffer[i]); You won't recognize it probably since it will look like this : '¥', yes but you are calling a function which does have some overloaded versions, but print() 0xA5 as 165, and will convert that to 3 bytes being '1', '6' & 5' and converts 0xA5 to HEX if you specify that would make it "A5", which at the other end will come out as 2 bytes values 65 & 35.
write() is the function you want that actually sends the value.
Hello again, I have a new problem right now. Serial2 does not trigger SerialEvent2. But serialEvent1 is running fine. I don't know why. Although I write Serial.print ("Test") in the SerialEvent2 function, I don't see anything. But it works in SerialEvent1. Only the problem seems to be in SerialEvent2.
I'm sure that's my last problem. Once we figure this out, it's gonna work. I thank you again and again for everything.
void serialEvent2() {
while (Serial2.available()) {
Serial.write(Serial2.read());
}
}
And that works
Thank you for your help. Yes, the code sample you provided worked successfully. The problem was that the MAX485's RX leg was faulty. The RX pin was pulling to LOW because it was faulty. For this reason, serialEvent2 was not triggered even though there was a signal. We noticed when we examined it with an oscilloscope. In short, the problem is not in Mega. The problem was at MAX485. I can not thank you enough.