[MODBUS] Proper Solution for Modbus

Hi all,

I’ve read literally every forum post on MODBUS/RS485 but I’m still at a complete loss.

I’m after a solid solution that can read a modbus device (Novus DigiRail 2A) with the following params:

Baud Rate: 4800
Parity: Even
Stop Bits: 1

READ INPUT REGISTERS - 04H

Address:
0             PV of Channel 1 in percentage. Range from 0 to 62000.
1             PV of Channel 2 in percentage. Range from 0 to 62000.
2 – 4         Reserved
5             PV of Channel 1 in engineering unit.
6             PV of Channel 2 in engineering unit.
.
.
.
etc

I’ve know got a solid TTL->485 hardware setup, using the MAX485. I know this works, as I’ve tested it using the SDM_Energy_Monitor repo that I’ve ported to Photon/Electron, alongside an SDM120 Meter and it works a charm.

However this library doesn’t use another modbus library, rather it relies on the base Serial implementation for it’s communication.

So far, I haven’t been able to find a library that let’s me specify parity, stop bits etc as well as read registers successfully.

I’ve tried using the MODBUS_Master library provided on the Web IDE, with no luck. Also tried both of @peekay123’s modbus libraries with no luck. I’d just really like an answer because I’m struggling.

Thanks all.
Joe

EDIT:

This is the example I’m currently working from, which uses the MODBUS_Master lib from the IDE:

#include "ModbusMaster.h"

// instantiate ModbusMaster object as slave ID 1
ModbusMaster node(245);


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

	node.begin(4800);
	node.enableTXpin(A5); //A1 is the pin used to control the TX enable pin of RS485 driver
	//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.begin(9600);
	Serial.println("Starting Modbus Transaction:");
}


void loop() {
	static uint32_t i;
	uint8_t j, result;
	uint16_t data[10];

	i++;

	result = node.readInputRegisters(0x0000, 1);

	Serial.println("");

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

This is how I’ve configured my device:

This is the communication manual:

@ScruffR I’ve seen your name pop up a lot for Modbus as well, any ideas? Thanks

Sorry, the nitty gritty bits of Modbus aren’t my field of expertise.

1 Like

Have you considered using the ParticleSoftSerial library for this? At 4800 baud, you should be able to use a software UART and you will have full control.

No worries, thanks though!

@bko This could be possible. I guess I’d just have to push out data in the same frame format, not actually sure how to do this though.

I’d like to be able to use one of the Modbus libraries: I can’t understand why they aren’t working for me. I’d like to have the potential to interface with higher baud rate devices if possible.

Thanks for the comment

I can’t see the advantage of using SoftSerial over the exposed Serial port though, especially when it’s capable of much higher speeds

Since you have a configuration tool, I would start with 9600 / None / 1 bit, then use the example you find in @peekay123’s library here: https://github.com/pkourany/ModBus_RS485_Slave

Some things you may have missed, because I miss them all the time:

  • Wires are crossed
  • Your TXEN pin is wired wrong or not assigned to the right port

Upload a photo of your connections.

Hi @hwestbrook - Thanks for the message. I am 100% my connections are correct, as I’ve used exactly the same setup, albeit with a different modbus device, using the SDM_120 library. Setting this with the config tool is a good idea, I’ll do this now.

Thanks

I could set 9600 / None but it forces me to then use 2 bit. Still the same response:

Failed, Response Code: E2

Some photos below. I have proven that the Particle (TTL) -> Modbus (MAX485) section is correct, as this works perfectly for the SDM120 (left most device) when using the SDM120 Library. I’ve checked the wiring schematics, and D+ maps to D1 (connection 10 on the Novus) and D- maps to D0 (connection 11 on the novus) (see bottom-most image, from the suppliers spec sheet).


Do you see the lights blink when the example firmware tries to communicated with your MODBUS device?

If you have to use 2 bits, you’ll have to modify that library here and add SERIAL_8N2 to begin, so it looks like:

port->begin(u32speed, SERIAL_8N2);

Good point, I’ll change that in the morning (1AM in the UK!). The TX light of the ttl->modbus transceiver is constantly on, from what I can see, which is odd. The TX LED flashes on the Digicom just before I get my error message.

I have had some good success with a Photon talking Modbus RS485 to a Panasonic PLC and an ControlLogix PLC (via an prosoft MCM module). I would have to dig up the code and jog my memory of the setup though.

I do remember that I used 19200 or 9600 baud. Any particular reason for the 4800?

I see Modbus quite commonly at work and these third party devices are sometimes a challenge. Have you connected the Photon to a know Modbus source and proven the comms? Have your tired reading the registers from on your Digi device with your computer via Modbus software? I generally use my computer with Modsim/Modbus Poll or something similar and first prove the registers I am reading are correct and available using the correct function code.

@adamg Thanks. I’d love to understand how you implemented it. Good plan regarding the pc software, I’ll definitely give this a go, thanks.

4800 was the default baud rate on a couple of devices, so I went with that. Thanks

You should look at the TX light issue as that should be out when no data is transmitted. If it indicates TX from the Photon it will go out when the RJ11 connector is removed. If it does go out when the RJ11 connector is removed it maybe the Photon output port needs to be reversed. Another words if no data from the Photon output port it outputs 3 volts it should be set to output 0 volts. Can you give the model of the TTL to RS485 converter? Since TTL is 5 volts the Photon output may be to low. Verify TTL to RS485 device will use 3.3 volt input.

I’m also wrestling to see how ModBus can be implemented with MAX485 that requires the hardware flow control and parity stuff.

Hope to see some progress and contribute in some way :smiley:

Please verify the orange wires on the Digirail-2a are connected to pins 10 and 11. Pin 12 is ground if the manual I looked at is correct.

Pin 10 is D1/D+ (Orange) and ion 11 is D0/D- (Orange/White)

Thanks

Pin 12 on the digital is tied to the same ground pin as the incoming dc supply, also shared by all others devices.