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
}
}
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....
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.
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.
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?
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...
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.
The switches are also latching. currently latched to ground, they receive the internal pull-up 5v which shows HIGHwhen unlatched. They are working
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?
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
}
}
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?