I am trying to modify the Arduino RS485 library to work with Serial port 4. (number 1 is already in use). have anyone successfully manage to do it? I have tried a few of the recommendations I could find on the internet but no one seems to work.
The idea id to utilize the Arduino Modbus library at the end for some remote IO application.
Hi, thanks for the response, I have tried the defines both on top and just before the setup phase still no communication. I am including the code if it will help.
#include <wiring_private.h> // Required for pinPeripheral() function
#include <ArduinoRS485.h>
//SERCOM4 on analog pins A2 (Tx) and A3 (Rx) as Serial4
Uart Serial4 (&sercom4, A3, A2, SERCOM_RX_PAD_1, UART_TX_PAD_0);
void SERCOM4_0_Handler()
{
Serial4.IrqHandler();
}
void SERCOM4_1_Handler()
{
Serial4.IrqHandler();
}
void SERCOM4_2_Handler()
{
Serial4.IrqHandler();
}
void SERCOM4_3_Handler()
{
Serial4.IrqHandler();
}
#define RS485_SERIAL_PORT Serial4
#define RS485_CONTROL_PIN 5
void setup() {
Serial.begin(9600);
RS485.begin(9600);
// Assign pins A2 & A3 SERCOM functionality
pinPeripheral(A2, PIO_SERCOM_ALT);
pinPeripheral(A3, PIO_SERCOM_ALT);
// enable transmission, can be disabled with: RS485.endTransmission();
RS485.beginTransmission();
// enable reception, can be disabled with: RS485.noReceive();
RS485.receive();
}
void loop() {
if (Serial.available()) {
RS485.write(Serial.read());
}
if (RS485.available()) {
Serial.write(RS485.read());
}
}
Hi David, your suggestion to work with just serial4 solved the error of compiling but still no communication. To answer the question of the processor I am using a feather M4 from Adafruit.
Are you sure your test code is suitable for use with RS485? I'm no expert but I think it's not as simple as a naked UART. There are additional protocols, and if your code doesn't follow them, perhaps you won't receive any comms.
Running the following code on my hardware does give me communication, my own make shift RS485. the reason i am now trying the official lib is that the modbus library is based on this one.
#include <wiring_private.h> // Required for pinPeripheral() function
//SERCOM4 on analog pins A2 (Tx) and A3 (Rx) as Serial4
Uart Serial4 (&sercom4, A3, A2, SERCOM_RX_PAD_1, UART_TX_PAD_0);
void SERCOM4_0_Handler()
{
Serial4.IrqHandler();
}
void SERCOM4_1_Handler()
{
Serial4.IrqHandler();
}
void SERCOM4_2_Handler()
{
Serial4.IrqHandler();
}
void SERCOM4_3_Handler()
{
Serial4.IrqHandler();
}
// what's the name of the hardware serial port?
#define RS485 Serial4
//RS485.setSerial(&Serial4);
#define RS485_CONTROL_PIN 5
//#define RS485_serial(Serial4);
void setup() {
Serial.begin(9600);
RS485.begin(9600);
// Assign pins A2 & A3 SERCOM functionality
pinPeripheral(A2, PIO_SERCOM_ALT);
pinPeripheral(A3, PIO_SERCOM_ALT);
pinMode(RS485_CONTROL_PIN, OUTPUT);
digitalWrite(RS485_CONTROL_PIN, LOW); // Receive mode
}
void loop()
{
if (Serial.available())
{
digitalWrite(RS485_CONTROL_PIN, HIGH); // Transmit Mode
delay(2);
RS485.write(Serial.read());
Serial.flush(); // Wait for data to finish sending
digitalWrite(RS485_CONTROL_PIN, LOW); // Receive Mode
}
if (RS485.available())
{
Serial.write(RS485.read());
//Serial.print(RS485.read(),HEX);
//Serial.println();
}
}
Yes, that code will work, I'm sure. You are calling the Serial object "RS485" but actually it's just plain 'ol UART. You are not even #including the RS485 library.
But in the code you were testing before, you were using the RS485 library, but using it as though it was just a UART. Maybe that's why that code wasn't apparently working as you expected.
I think you need to find some other test code that is written to work with the RS485 library. Check the examples menu for the library.
I don't think you can use the same pin for DE_PIN and RE_PIN. If one is not needed, set it to a value of -1.
< edit > Looking at the library, using the same pin for both would likely work, main difference is there is an option to have a delay when changing the state of the DE pin.
Did you remove the default RS485 object in the library? There is one line declaring it as extern in the RS485.h file, and a couple of lines at the end of the RS485.cpp file with the constructor.
Is there an important reason to do that, do you think?
When I was reading the library code, my thought was that so long as RS485.begin() is not called, that object should not cause a problem and can be ignored. That's why I suggested creating the myRS485 object using the standard constructor, which allows you to specify the UART and pins you want to use.
Probably not important, it does increase the size of the code, by creating an instance of the class, but doesn't actually do anything with the serial port.