[MODBUS] Proper Solution for Modbus


The TX light is of concern @jstobaugh. I am confident that the TTL -> 485 system I have is 100% working, as have used it with other modbus/RS485 devices.


Your problem appears to be between the Photon and the TTL converter if you remove the connection between the Photon and it and the TX led goes out. If you do that and it goes out the polarity coming out of the Photon needs to be reversed. As long as you have a constant TX led lit the RS485 buss is disabled for two way communication. It can’t receive from the other direction.


Hi @jstobaugh, just to confirm, the Photon -> TTL -> Modbus hardware is confirmed working, as I have used it with other systems.


Do you recall when using on other systems the TX lit all the time?


No, but it cannot be a hardware fault, as I’m literally swapping over modbus device and loading new firmware, when I read the SDM120, and that works fine. I have everything wired up permanently.


I agree at this point it isn’t hardware. If you remove the phone connector on the front of the TTL to RS485 converter does the TX led go out?


Yes, light goes out :slight_smile:


2 wire RS485 is half duplex so if you have constant TX out of the Photon the modbuss end can’t respond. It appears to be a programming issue in the Photon.


Below is a link to the Modbus master program that I was tinkering with some time ago.

As mentiond before, I would first try to read the registers of your Digi from your computer to ensure your addressing and function codes are correct.

I do not recall if the library I used will automatically change the desired address to a 3x or 4x register when performing function code 4 or 3 respectively. I only attempted to read holding registers (4x) and did not read input registers (3x). As I am sure you are aware, modbus addressing can be either 0 based or 1 based, so you may need to add 1 to the first register you are trying to read.

Also, it looks like you are receiving an error code 2 by the looks of the response (E2). Error code 2 is “Illegal Data Address”. This generally means you have established communication, but the address being queried in the slave does not exist or the requested number of registers is incorrect.

Edit: This is another good piece of free software for troubleshooting modbus.
It allows you to see incoming and outgoing telegrams. NOTE: It doesn’t work well with com ports above 9, so keep that in mind!


One more thing I thought of. When reading the input registers, you are using “node.readInputRegisters(0x0000, 1)”. If they are using PLC addressing, you may need to start at 30001 (decimal).


I completely agree with adamg. That is why it is so important to have a Modbus test program. I use Modbus Tester by Omni - freeware (Oil and Gas Measurement company). You can verify that you are sending the correct information, and actually VIEW the raw bytes which are being sent between the devices. I recommend an RS485 - RS232 converter module so that you can sniff the data passed between the devices from your computer.

I am attaching a screenshot which shows the Transmit Message and the Receive Message. You can also use the Communications Log to Sniff external messages.
In this way, you can check to see if you are sending a valid request. If my photon sends my rpi Modbus simulator the message: 0B 03 00 65 00 16 D4 B1
I know that the simulator should respond, because it responds when my test program sends that exact message. Along the same lines, if I’m sniffing the messages that my photon is sending my rpi Modbus simulator, and I’m not sending the same message, then I know I have a potential problem with my photon Modbus configuration. Address offset as adamg mentions, or something else.

I hope the message poster and others don’t find this condescending, it is not intended that way. I just wanted to illustrate a very clear way to verify A) Figuring out exactly what works and B) Verifying EXACTLY what you are sending the device.

I am working on my own Modbus / Other Serial Protocol library and will likely need some help with that in the future, but I know that being able to see the raw data between the two devices is imperative for working with Serial Protocols.

(Also, as a final thought, if you can’t parse through raw HEX Modbus requests and responses, you might work through that. I always have to pull up the Modbus protocol spec as a refresher when I start messing with this stuff…)


Hi all. Thanks for the detailed explaination @ThereIsNoSky, truly appreciated.

Ok I’ve been successfully talking to my modbus device from my PC, using QModMaster:

I’m making the following query:

Read Input Register (0x04)
Start Address: 0
Number of Registers: 1

This is set via the GUI:

QModMaster has a 'Bus Monitor; so I can see the TX and RX:

[RTU]>Tx > 14:21:43:215 - F5  04  00  00  00  01  24  BE  
[RTU]>Rx > 14:21:43:238 - F5  04  02  78  96  AA  8B  

Again, in the GUI, it shows these messages quite nicely:



So I can now be confident in the addressing I’m using to access this register, is ‘0’ (not 30001, 40001 address + 1 etc).

I’m going to keep sniffing, and will post more as I find more :slight_smile:


Using the Particle Modbus Library, I’ve commented in node.enableDebug();, so polling the modbus device with node.readInputRegisters(0x0000, 1); gives the same TX message of:

Failed, Response Code: E2
TX: F5 4 0 0 0 1 24 BE

It’s worth noting that enabling the debug messages to Serial messes with the 485 timing, so we receive nothing back. The modbus device is currently disconnected, which brings up two interesting observations:

We’re still getting modbus error 2, although the modbus slave is not responding
The TX light on my TTL->485 converter is still fairly solid.

Will continue to dig!


I’ve just sanity checked myself by uploading my SDM120 Modbus Energy Meter to the same hardware setup, moving my twisted pair from this novus unit to the SDM120, and it works fine. This confirms that the hardware setup is 100%, from Photon -> RS485


I’ve also modified the ModbusMaster.cpp file so to match the Serial config of my Modbus device:

MBSerial.begin(u16BaudRate, SERIAL_8E1);

Still nothing :cry:


Here’s the sample code I’m testing with atm:

#include "ModbusMaster.h"

ModbusMaster node(1, 245); //Novus DigiRail on Serial1 (RS485) with address 245

void setup() {
	// initialize Modbus communication baud rate

	node.enableTXpin(A5); //TX Pin of TTL-> RS485 Device (MAX 485-based DIN-rail device)
	node.begin(9600); //Novus Digirail 2A configured with baud rate of 9600

	//node.enableDebug();  //Print TX and RX frames out on Serial. Beware, enabling this messes up the timings for RS485 Transactions, causing them to fail.

	Serial.println("Starting Modbus Transaction:");

void loop() {
	uint8_t result;

	result = node.readInputRegisters(0x0000, 1); //Confirmed correct address, from Modbus Tx sniffer (using USB to 485 Adapter) F5  04  00  00  00  01  24  BE

	Serial.print("Raw Response: ");
	Serial.println(result, HEX);

	// do something with data if read is successful
	if (result == node.ku8MBSuccess) {
			Serial.print("Success, Received data: ");
			Serial.print(node.getResponseBuffer(0x00), HEX);
			Serial.print(" ");
	} else {
		Serial.print("Failed, Response Code: ");
		Serial.print(result, HEX);
		delay(5000); //if failed, wait for bit longer, before retrying!

No changes to the ModbusMaster library except for the MBSerial.begin statement as per the message above.

Link to the library (from the particle ide): https://github.com/lithiumhead/ModbusMaster


Hi all, quick update (thought it might be useful for those reading this thread in the future):

I’ve changed my modbus slave device to another known device, and I can successfully use the modbus library to access data. This uses exactly the same hardware setup (Photon, TTL-> Modbus, twisted-pair, same pullup resistors etc.) so I can therefore conclude that the problem is isolated within this particular modbus device.

Will continue to dig!


Ok, for those of us who have just joined (TLDR Anchor Point!):

There was an issue with the baud rates. Both the Novus Digirail and the TTL-> Modbus unit boast Baud Rates of 1200, 4800, 9600+…

I put the Digirail on the most basic settings, so:

Address: 1
Baud: 1200

…and hey presto! All works.

So I changed the baud to 4800 and tested again…all good!

Baud @ 9600 - Not playing ball.

At least we’re somewhere now!


@joearkay is that digirail module doing the rs485 <–> uart conversion or the MAX485 is on the CE board?


@kennethlimcp The ‘RS Pro TTL to RS485’ device is doing this:


There was no pinout available for the RJ11 connector, as I think was designed to be a plug and play solution for a pre-existing PLC system, but I opened the unit up and traced back from the MAX485 chip that this is based off of.

It’s essentially an opto-isolated MAX485 chip. The datasheet for this unit (via the RS link above) boasts ‘upto 9600 Baud’.

I’m wondering whether the EL817 Opto-couplers inside this are the bottleneck :thinking: I can’t find any ‘max operational frequency’ information for them though, and given that the unit claims to be capable of up to 9600 baud, I’m not sure this is something worth exploring.