(SOLVED)Read Data from Temperature Controller with RS485 Modbus RTU

Hi everyone, I am starting to lose hope and would very much appreciate any help!

I am using an automation direct solo SL4845-RR Temperature controller and would like to read data from it, just a simple Process Variable to start with, I can't even get that to work. I have done so much research and tried everything possible.

I am using a MAX485 converter module which converts the RS485 communication to TTL so the Arduino can read it.

VCC -> 5v on Arduino
GND -> GND on Arduino
A -> Data+ RS485 on temp controller
B -> Data - RS485 on temp controller
RO - > Pin 2
DI - > Pin 3
RE -> Pin 4
DE -> Pin 5

According to the Temperature Controller manual: Temp Controller Manual
If you scroll down to Chapter 7 it has the Modbus Protocol information, I will provide it here as a reference as well, these are the DEFAULT values it has in the controller.

Protocol: Modbus ASCII
Network Address: 1
Baud Rate: 9600
Bit Length: 7
Parity: Even
Stop Bit: 1
Register for Process Variable I need to read from in Hexadecimal: 1000

**Please Note that I have changed the Protocol to Modbus RTU through the settings in the temperature controller

As for the library I am using, it is ModbusMaster by Doc Walker and here is the link: Modbus Library

I guess the only thing left is to show you the code!

#include <ModbusMaster.h> 
#include <SoftwareSerial.h>  

#define DE 5     //Transmit enable
#define RE 4     //Recieve enable
#define RX 2
#define TX 3

ModbusMaster node;  //instance of class
SoftwareSerial RS485Serial(RX,TX);

void preTransmission()
{
  digitalWrite(RE, 1);
  digitalWrite(DE, 1);
}

void postTransmission()
{
  digitalWrite(RE, 0);
  digitalWrite(DE, 0);
}

void setup()
{
  
  pinMode(DE, OUTPUT);    //initiate both as output
  pinMode(RE, OUTPUT);
  digitalWrite(RE, 0);     //both start at no signal for receive mode
  digitalWrite(DE, 0);

  Serial.begin(9600);
  RS485Serial.begin(9600);
 
  node.begin(1, RS485Serial);
  node.preTransmission(preTransmission);
  node.postTransmission(postTransmission);

  Serial.print("Testing");
  delay(500);
}

void loop() 
{
  uint8_t result;
  result = node.readHoldingRegisters(0x1000,1);
  Serial.println(result);
  Serial.println(node.getResponseBuffer(0));
  delay(500);
}

Now comes the issue, my output for result, is 226 which from my research means it is a communication error, usually in the form of wiring. No matter what register I try it is always giving that response which means it is time out issue?

Troubleshooting I have done

  • I have tried reversing my A and B connections on module and still no luck.
  • I have tried using the hardware serial on Arduino instead of software, still same outputs
  • I have tried replacing my RS485 to TTL Module, no luck
  • I have made sure all my settings are correct in the controller (Modbus RTU instead of ASCII, all bits, etc)
  • I can't read from any register without getting that output, which means my responsebuffer obviously won't have anything in it (hence the 0 output on response buffer).

I really do not know what else to do :confused: if someone can please help me it would mean so much and I would contribute to the community with people have similar problems.

Thank you in advance, please let me know if I can provide any more info, I have attached my serial terminal output for you to see as well. Even if my temperature controller is OFF it still gives this info so there is something going on with hardware but I really do not know what, please please help me thank you

Edit: I have attached pictures of my hardware and wiring too. I am using regular jumper wires for rs485 I’m not sure if that would cause problem. I know the temperature controller is working fine because the display shows the process variable Changing correctly. Thanks

Baud Rate: 9600
Bit Length: 7
Parity: Even
Stop Bit: 1

You cannot set 71E with SoftwareSerial. You must use a hardware serial interface to communicate with that device. If you need the Arduino just as a transceiver device (Modbus adapter) you must change the hardware to a model that has a hardware serial interface in addition to the one used for PC communication. The Leonardo/Micro is a candidate, the Mega2560 has even 3 unused hardware serial interfaces.

Hi @Pylon,

Thank you so much for your reply. I am guessing 71E refers to the bit length, stop bit, and parity? If so, when I changed from Modbus ASCII to Modbus RTU in the temperature controller settings it changes my bit length to 8. So I am 81E. I have the option to change the parity to odd if needed as well as the stop bit to 2.

Also, I have used hardware serial on my first attempt, before I tried software serial. It provided me with the same results but with more unexpected outputs such as "?" and random boxes with it. The reason I switched to softwareserial is so the Modbus communication doesn't have any errors while I am printing out to the terminal for debugging using the hardware serial. I am using Arduino uno.

I have attached a photo to provide more clarity. As you can see Mdobus RTU provides a bit length of 8 when changed

Thank you so much

Modbus.PNG

HUGE thank you to pylon who gave me the basic information I needed to do research and figure out what was wrong, I can't thank you enough @pylon.

So for everyone who is curious, software serial default settings are 8N1 which is 8 bit length, no parity bit, and 1 stop bit. You can use it with ODD parity bit by typing in a line of code which people can look up. Luckily my controller lets me change all these settings so I just changed it to accept the default softwareserial of 8N1 and it works now!!

Hi everyone.

I'm trying to connect an arduino mega 2560 to an exactly the same kind of SOLO temperature controller you mention in this post but unfortunatelly I couldn't make this connection work. I'm still having the same issue (226 result).

I already performed the instructions you said it works for you but it doesn't work for me.

Is the code posting above exactly the same that you are using right now?

My hardware is an arduino mega 2560, SOLO 4848-RR-D temperature controller, and a MAX485 converter module.

Any suggestion is welcome.

Regards.

Is the code posting above exactly the same that you are using right now?

My hardware is an arduino mega 2560, SOLO 4848-RR-D temperature controller, and a MAX485 converter module.

That code is for an UNO, it makes absolutely no sense to use SoftwareSerial on a Mega2560. Change it to the hadware serial and use p.e. Serial1 in the sketch.

It that doesn't work, post the information we need: complete wiring diagram, the sketch you're using, links to your controller's manual (you don't use the same as the original poster) and your RS485 hardware!

Hi pylon

Thank for your fast answer. My hardware configuration is an Arduino mega 2560, a SOLO 4848-RR-D temperature controller wich its manual is in this link: https://www.jlab.org/accel/inj_group/vacuum/SoloTemp/solo%20manual.pdf

and a MAx485 like this: https://www.amazon.es/RS-485-Converter-transceptor-MAX485-Chip-Arduino-Raspberry/dp/B01M6BWMGH .

The wiring is the following:

VCC -> 5v on Arduino
GND -> GND on Arduino
A -> Data+ RS485 on temp controller
B -> Data - RS485 on temp controller
RO - > TX0-PIN 1
DI - > RX0-PIN 0.
DE -> Pin 2

and finally the code is below:

#include <ModbusMaster.h>
#define MAX485_DE 2


// instantiate ModbusMaster object

ModbusMaster node;

void preTransmission()
{

digitalWrite(MAX485_DE, 1);
}

void postTransmission()
{
digitalWrite(MAX485_DE, 0);
}

void setup()
{
pinMode(MAX485_DE, OUTPUT);

// Init in receive mode
digitalWrite(MAX485_DE, 0);

// Modbus communication runs at 9600 baud
Serial.begin(9600);

// Modbus slave ID 1
node.begin(1, Serial);

// Callbacks allow us to configure the RS485 transceiver correctly
node.preTransmission(preTransmission);
node.postTransmission(postTransmission);

}

void loop()
{

delay(500);
uint8_t result;
result = node.readHoldingRegisters(0x1000,1);
Serial.println(result);
Serial.println(node.getResponseBuffer(0));
delay(500);

}


So, i don't know what is exactly the problem but in the serial monitor I only can see the following infomration:

226

It would be very usefull any of your suggestiions.

If you have any other question please do not hestitate to ask.

Thanks in advance.

RO - > TX0-PIN 1
DI - > RX0-PIN 0.

On the Mega2560 you should use Serial1. But the connections are wrong anyway, you produce short-circuits using above wiring.

RO -> RX1 (18)
DI -> TX1 (19)

Then change this code line:

  // Modbus slave ID 1
    node.begin(1, Serial1);

Please edit your post and insert code tags!

aurianemami:
HUGE thank you to pylon who gave me the basic information I needed to do research and figure out what was wrong, I can't thank you enough @pylon.

So for everyone who is curious, software serial default settings are 8N1 which is 8 bit length, no parity bit, and 1 stop bit. You can use it with ODD parity bit by typing in a line of code which people can look up. Luckily my controller lets me change all these settings so I just changed it to accept the default softwareserial of 8N1 and it works now!!

aurianemami:
HUGE thank you to pylon who gave me the basic information I needed to do research and figure out what was wrong, I can't thank you enough @pylon.

So for everyone who is curious, software serial default settings are 8N1 which is 8 bit length, no parity bit, and 1 stop bit. You can use it with ODD parity bit by typing in a line of code which people can look up. Luckily my controller lets me change all these settings so I just changed it to accept the default softwareserial of 8N1 and it works now!!

can you share your code & ckt diagram