RS485 Issues, no data being recieved

Good Morning,

I'm trying to communicate with an RS485 Device via the given documentation, but I'm getting no feedback. FYI, I'm a complete novice, so there may be a lot of mistakes. I'll try to provide as much info as possible.

Code attached -

//RS485 TA PROGRAM

int button_h_pv = 2;  //sets button as digital pin #2
int button_t_1 = 3;   // sets button as digital pin #3
int rx = 0;           //sets incoming data to pin #0 (RX Pin)

void setup() {
  pinMode(button_h_pv, INPUT_PULLUP);  // sets pintype to input with an internal pull-up resistor
  pinMode(button_t_1, INPUT_PULLUP);   // sets pintype to input with an internal pull-up resistor
  Serial.begin(9600);                  // starts comms and sets baudrate
}

void loop() {
  if (Serial.available() > 0) {
    String rx = Serial.readString();  //reads string of incoming data
    Serial.print("TOILET: ");          //inputs device name before recieved data
    Serial.println(rx);               //prints incoming rx data
  }
  if (digitalRead(button_h_pv) == HIGH) {  // Reads button state
    Serial.println("H PV");                // Should Return *AOA Factory Mode*
    delay(1000);                           //1 second delay to stop mechanical button bounce
  }
  if (digitalRead(button_t_1) == HIGH) {  // Reads button state
    Serial.println("T 1");                // Should Return *1 00 54 02*
    delay(1000);                          // 1 second delay to stop mechanical button bounce
  }
}

Documentation Attached -


I'm not receiving any data, but my code works fine when sending messages on the serial monitor.

I'm using a UNO R4 WIFI with an RS485/RS232 shield set to RS485 and UART.

Any ideas?

I'm not familiar with your board, neither your shield.
Anyway you need to setup two serials, Serial for serial monitor and Serial1 for RS485.
Also your communication parameters (7 data bits, odd parity, 2 stop bits) are different from default.
Serial1.begin(9600, SERIAL_7O2);
would be correct setup. If R4 Wifi accepts it....

2 Likes

Thanks for the advice!

How come I need to do this? I was under the assumption that the serial monitor just monitored the bus and that's it.

I was wondering about that as i couldn't find a definite answer on how to correct it. I'll sort that now.

Don't make assumptions. Look at the code! There are specific instructions that write data to the serial monitor. You need to use a totally separate serial connection for your RS-485 connection.

You code doesn't interface anyhow with the "bus". There is a difference if you are talking to yourself or to somebody else (excluding teenage kids). :wink:

1 Like

I assumed that the rs485 shield was connected to the rx and tx pins on the uno?

Why would anyone do that when they are already being used if the USB to PC connection is also connected.

Not Uno, but Uno R4.
It is connected to rx and tx pins, and that's Serial1.
Not Serial, which is connected to Usb.

Again, complete novice. 0 experience.

Right i see, so "serial" is just for usb and "serial1" is pins 0 and 1 on the UNO R4?

Set all my programs to Serial1 instead?

I still don't see why i need to setup two serials though, surely i send a message via a button and then i get a reply back? can you give me a simplified explanation on the subject or link me some useful info?

It's not so complicated. If you send something to Serial, it arrives to your computer screen (serial monitor). If you send something to Serial1, it goes to your RS485 bus.
You need them both if you want to see something on your screen. If that's not necessary, you don't need Serial.

Common usage is:
Send request to Rs485 device through Serial1.
Read response from Rs485 device on Serial1.
Print that response to Serial, to see it on serial monitor.

1 Like

That makes a lot more sense! thanks again.

  1. Now, how would i go about finding out what is Serial1, 2, 3 ,4 etc? i'm guessing this is dependant on the hardware i'm using or something?

  2. another thing i can't wrap my head around is that i also have a CANBUS 2.0B shield, will this also use Serial 1 on the UNO as this is the only UART pinouts on this specific board?

FYI - I won't be using CANBUS and RS at the same time so i'm again going to assume this is fine to do, even if they are sharing the same serial port.

Don't complicate things.
Just make a communication with your RS485 device with Serial1 (rx/tx pins where your shield is connected).

I don't know if CANBUS shield is using serial or spi for communication, read the datasheet.

Only odd I see for your Rs485 communication, is parameter 7O2. You need to try it, or find some documentation for R4 wifi-board serial communication.
..Or wait until some R4 guy is responding here...

1 Like

Or, ask a clear and concise question in the R4 Category. Some members seem to stick to their own little specialty areas, for whatever reason.

3 Likes

I've done what you said, but now I'm getting this error, and I don't understand HEX at all. Do you have any ideas?

H PV


Firmware name: "C:\Users\reece\AppData\Local\Temp\arduino\sketches\54D30BEEA0D6673EE5C1BC286B6BDE1F/sketch_oct31a.ino", compiled on: Nov  1 2024
Fault on interrupt or bare metal(no OS) environment
===== Thread stack information =====
  addr: 20007ee8    data: 00010d14
  addr: 20007eec    data: 000044ef
  addr: 20007ef0    data: 00010d14
  addr: 20007ef4    data: 000079e7
  addr: 20007ef8    data: 000079dd
  addr: 20007efc    data: 00002599
====================================
=================== Registers information ====================
  R0 : 20000cd0  R1 : 20007fff  R2 : 00000002  R3 : fffffe91
  R12: 00000002  LR : ffffffe9  PC : 00005254  PSR: 61000215
==============================================================
Bus fault is caused by precise data access violation
The bus fault occurred address is 20007fff
Show more call stack info by run: addr2line -e "C:\Users\reece\AppData\Local\Temp\arduino\sketches\54D30BEEA0D6673EE5C1BC286B6BDE1F/sketch_oct31a.ino".elf -a -f 00005254 000090ba 000090ba 00008c48 00009796 0000980c 000041f4 0000a2b0 0000a2ee 000044ee 000079e6 000079dc
 

Here is my new code, IGNORE THE LCD STUFF! was just getting used to the programming as I've ordered one!

//RS485 TA TOILET PROGRAM
#include <LiquidCrystal.h>  //lcd library

LiquidCrystal lcd(12, 11, 10, 9, 8, 7);  //lcd pinout

int button_h_pv = 2;  //sets button as digital pin #2
int button_t_1 = 3;   // sets button as digital pin #3
int rx = 0;           //sets incoming data to pin #0 (RX Pin)

void setup() {                         //starts Comms, lcd and button pinouts.
  pinMode(button_h_pv, INPUT_PULLUP);  // sets pintype to input with an internal pull-up resistor
  pinMode(button_t_1, INPUT_PULLUP);   // sets pintype to input with an internal pull-up resistor
  lcd.begin(16, 2);                    // starts lcd and screen sizing
  Serial.begin(9600);                  // starts comms and sets baudrate on serial monitor/usb
  Serial1.begin(9600, SERIAL_7O2);     // starts comms and sets baudrate on RS485 BUS
}

void loop() {
  if (Serial1.available() > 0) {        //checks availability of serial1 rs485 data
    String rx1 = Serial1.readString();  //reads incoming rs485 data from rx
    Serial.print(rx1);                  //prints serial1 rs485 data to serial monitor
    lcd.println("TOILET: ");            //inputs device name on lcd before recieved data
    lcd.println(rx1);                   //prints incoming rx data to lcd
    delay(5000);                        //delays next print before clearing lcd
    lcd.clear();                        //clears lcd
  }
  if (Serial.available() > 0) {
    String rx = Serial.readString();  //reads string of incoming data
    Serial.print("TOILET: ");         //inputs device name before recieved data
    Serial.print(rx);                 //prints incoming rx data
  }
  if (digitalRead(button_h_pv) == HIGH) {  // Reads button state
    Serial.println("H PV");                //prints button press to serial monitor/usb
    Serial1.println("H PV");               // Should Return *AOA Factory Mode*
    delay(1000);                           //1 second delay to stop mechanical button bounce
  }
  if (digitalRead(button_t_1) == HIGH) {  // Reads button state
    Serial.println("T 1");                //print button press to serial monitor/usb
    Serial1.println("T 1");               // Should Return *1 00 54 02*
    delay(1000);                          // 1 second delay to stop mechanical button bounce
  }
}

I don't know about your error, just cleanup your code to start with. Add LCD codes later on.
Remove this line.

It doesn't set anything to pins, but later on you are using String rx = ...

What's the purpose of this code?

Also, you have button pins set as input with pullup, so I imagine that they are wired to GND. But in your code you look if (digitalRead(button_h_pv) == HIGH)
which it is when it's not pressed. So your code is sending H PV and T1 every few seconds.

1 Like
  1. I've now cleaned up my code a bit.

  2. The switches are also latching. currently latched to ground, they receive the internal pull-up 5v which shows HIGHwhen unlatched. They are working

  3. How does the Arduino know which pin to use as rx if it's not defined as a pin mode? is this because I've referenced Serial1 as the readstring?

  4. I've realized this error occurs when I have 'Serial1.print' in my code. If I remove the '1', the code works fine with no errors; however, it doesn't print to my RS485 bus, so it defeats the purpose. Having 'Serial1.available' doesn't cause the issue either.

//RS485 TA TOILET PROGRAM
#include <LiquidCrystal.h>  //lcd library

LiquidCrystal lcd(12, 11, 10, 9, 8, 7);  //lcd pinout

int button_h_pv = 2;  //sets button as digital pin #2
int button_t_1 = 3;   // sets button as digital pin #3

void setup() {                         //starts Comms, lcd and button pinouts.
  pinMode(button_h_pv, INPUT_PULLUP);  //sets pintype to input with an internal pull-up resistor
  pinMode(button_t_1, INPUT_PULLUP);   //sets pintype to input with an internal pull-up resistor
  lcd.begin(16, 2);                    //starts lcd and screen sizing
  Serial.begin(9600);                  //starts comms and sets baudrate on serial monitor/usb
  Serial1.begin(9600, SERIAL_7O2);     //starts comms and sets baudrate on rs485 bus
}

void loop() {
  //prints incoming data to lcd
  if (Serial1.available() > 0) {       //Check for available incoming data on Serial
    String rx = Serial1.readString();  //stores incoming data in buffer
    lcd.println("TOILET: ");           //prints device name before incoming data to lcd
    lcd.print(rx);                     //prints incoming data string to lcd
  }
  //prints incoming data to serial monitor
  if (Serial1.available() > 0) {       //Check for available incoming data on Serial
    String rx = Serial1.readString();  //stores incoming data in buffer
    Serial.print("TOILET: ");          //prints device name before incoming data to serial monitor
    Serial.print(rx);                  //prints incoming data string to serial monitor
  }
  //prints rs485 commands to both serial monitor and rs485 bus for a visual reference and data transfer
  if (digitalRead(button_h_pv) == HIGH) {  //reads button state
    Serial.println("H PV");                //prints outgoing data to serial monitor
    Serial1.println("H PV");               //prints outgoing data to rs485 bus
    delay(1000);                           //1 second delay to stop mechanical button bounce
  }
  if (digitalRead(button_t_1) == HIGH) {  //reads button state
    Serial.println("T 1");                //print outgoing data to serial monitor
    Serial1.println("T 1");               //Should Return *1 00 54 02*
    delay(1000);                          //1 second delay to stop mechanical button bounce
  }
}

Then it's ok.

It wasn't defined as pin mode. It was variable int rx=2. And right after String rx=....

Still the "Fault on interrupt or bare metal(no OS) environment"?

I know, i was just asking a general question for learning purposes.

Yes still the same, only when 'Serial1' is printing. The fault wont occur until i press the command
button.

Maybe serial and serial1 is conflicting somehow? Ive tried deleting the '1' from all the print lines and the code works fine, althought it obviously prints the command twice.

Should not.
For testing you can try Serial1 without 7O2
Serial1.begin(9600);
Like I wrote in post#2, I don't know if R4 is fine with that.
Also your shield is probably for R3. And switches and jumpers?