RS485 Using Mega2560

I have this RS485 to TTL converter :

I am planning to use the ArduinoModbus library and Mega2560.

What changes should I do the library header files if plan to use the TX1 / RX1 of the Mega 2560 . I studied the library but could not figure out where to define the pins. :frowning:

Thanks

The Serial pins are here: https://www.arduino.cc/reference/en/language/functions/communication/serial/.
As soon as you use Serial1, then it exists, and as soon as you call Serial1.begin(...) then the hardware is initialized.

void setup()
{
  Serial1.begin( 9600);  // activate pin 19(RX), 18(TX)
}

If the library can use another serial port, that depends on the library that you use.

Do you want to use the official ArduinoModbus library ?
That is made for the MKR 485 Shield.

The same question was asked here: https://forum.arduino.cc/t/arduino-modbus-library/602283

I think you have to look for another library.

1 Like

@Koepel

Thanks for the response.

yes I did see the ArduinoModbus library page and realized it is for MKR board. Also did a compile of one sample and found it uses quite a bit of code space and dynamic space - really the AVR is not the target.

But then I was keen to know if there is a way to hack the library to use Serial1 instead of whatever it is designed to use by default.

My actual requirement is just to read two Input Registers which hold a two byte integer value.

Let me look around for other libraries - i am sure there should be some.

OK, assuming I decide to use a MKR485 shield, what is the basic MKR board that I need to buy ?
I am not very clear on this - like if there is a WiFi shield for UNO, then I will buy both the base UNO and then the WiFi shield. But when it comes to MKR it already has some function like WiFi. Do I have to buy one of these and stack the RS485 shield on top of it ?

Sorry if this query sounds too stupid :frowning:

A RS-485 add-on board is just a line driver. There is nothing smart on it.
I think that the Arduino MKR shield can power other nodes via the RS-485. I'm not sure, I did not read everything.

The most basic MKR board I think is the MKR Zero: https://store.arduino.cc/arduino-mkr-zero-i2s-bus-sd-for-sound-music-digital-audio-data.

Sparkfun has a RS-485 module for 3.3V: https://www.kiwi-electronics.nl/transceiver-breakout-rs-485.

There is nothing wrong with the MAX485 chip: https://www.aliexpress.com/item/4000834526061.html
But with that board you don't know if it is a counterfeit MAX485.

Suppose you buy the Pro Micro: https://www.aliexpress.com/item/32768308647.html
Combine it with that cheap shield, and then you can make nodes of 10 dollar each. The Pro Micro has a spare hardware serial port. You need a power supply for each node.

1 Like

Thanks Koepel. Will check out your suggestions.

Meanwhile I located a Temperature / Humidity module ( RKI - 4879 ) that sends the values via Modbus-RTU. I tried this with another library "ModbusMaster". The provided example given below works fine. I don't know how the node.readTemperature(Slave_ID) function works even after reading the ModbusMaster.cpp and .h files.

But when I try to use a formal Read Input Register function, it fails and returns zero values. So what is wrong ?

#include <ModbusMaster.h>
#include <SoftwareSerial.h>
SoftwareSerial mySerial(2, 3);           //Software Serial port For Arduino Uno

ModbusMaster node;                      //object for ModbusMaster


uint8_t Slave_ID = 1;                   //Slave ID of the Sensor
uint16_t tempRegister = 1; 
uint16_t humidRegister = 2;
short temp, humidity ;

void setup()
{
  Serial.begin(9600);     //Baud rate is 9600 
  mySerial.begin(9600);   //Modbus Baud rate is 9600 8N1
  node.begin(mySerial);
  Serial.println("RKI-4879 XY-MD02 Temperature And Humidity Sensor");
  Serial.print("Slave ID :");
  Serial.println(Slave_ID);
}

void loop()
{
 
//  temp = node.Read_Temperature(Slave_ID);     // This original code returns the correct values. 
//  humidity = node.Read_Humidity(Slave_ID);
 temp = node.readInputRegisters(Slave_ID, tempRegister,1);  // This code returns zero... 
 humidity = node.readInputRegisters(Slave_ID, humidRegister,1);
 
  Serial.print("Temperature :"); //if value is 293 that means it is 29.3℃ temperature
  Serial.print(temp);
  Serial.print("\t\tHumidity :"); //if value is 493 that means it is 49.3% humidity
  Serial.println(humidity);

  delay(1000);             // Just to avoid too much data..
}

Ok ... after some close study of the ModbusMaster.cpp file its clear now. I have understood how the functions node.Read_Temperature(Slave_ID) is implemented. I can now modify it to suit my requirements . For all my Industrial Modbus-RTU applications I can use the ModbusLIbrary. !!

short ModbusMaster::Read_Temperature(uint8_t Slave_ID)
{
  short R1, b1; 
  R1 = readInputRegisters(Slave_ID, 1, 1);{
  b1 =  getResponseBuffer(0);
  delay(2);
  clearResponseBuffer();
  return b1;}
}

Thanks for your support Koepel !!

Did you use the *.zip file from that sensor ? The example also uses the MODBUS_DATA_TRANSACTION_PIN.

I don't know the library, but it seems that you have to get the response.
See this:

short ModbusMaster::Read_Temperature(uint8_t Slave_ID)
{
  short R1, b1; 
  R1 = readInputRegisters(Slave_ID, 1, 1);
  {
    b1 = getResponseBuffer(0);
    delay(2);
    clearResponseBuffer();
    return b1;
  }
}

Yes I am aware of that ModbusDataTransactionPin. Its nothing but an Enable for the TX and Rx pins. In the RS485-TTL module that I use ( picture in the first post ) the pins are permanently enabled and so I don't need to assign a MCU port to do that.