RS-485 modbus library

The video doesn’t work for me either.
I am trying to set up a slave device that runs commands when its registers are written. I want to set up a command/register table that I can put in instructions to give to someone that wants to hook it up to their modbus master, along with other modbus slaves.
My understanding is that all they need is the slave address and the table.
Using your library, are the registers on the electron just arbitrary addresses? Or is there a construct that is specified in the library? In other words, if I have a struct with a dozen variables (byte, uint16_t, uint32_t, float), do I just give the starting address of the variable (struct address + offset)? Or do I need to specify a list of registers with library and then copy the info over? That is what I had to do with a different library in the past.

Video should be fixed. I had set it as private, thinking sharing the link would work...

The ModbusMaster library, as its name informs, is supposed to be used to manage slaves, not for a slave to be managed by a master... If you need a slave library, you will have to write your own, this one won't serve, as I already mentioned earlier...

@peergum , I see now that I forgot to thank you for your help. I think I am clear now.

1 Like

@peergum Hi Phil, I was hoping I could get some help with your library as I would love to implement it. But when I try to compile the example I am getting an error that ‘SerialLogHandler’ does not name a type. Any thoughts on what is going wrong here?

Check what system version you are targeting.
SerialLogHandler is only available since v0.6.0
https://docs.particle.io/reference/firmware/photon/#logging

1 Like

Thank you, I got that straightened out.

Maybe someone could point me in the right direction, I am unable to get any successful reads from the slave devices I am communicating with. The modbus specs are 9600 Baud, no parity, 8 data bits, 2 stop bits, no flow control, and a server address of 0x01. I have found an example of someone who was able to get successful reads using a linux modbus library ( http://larvierinehart.com/solar/sunsavermodbus.html ). Can anybody see any changes that must be made to the @peergum library in order for me to get a successful read? I am just trying to pull holding registers.

As suggested earlier in this thread, you should configure your serial right after initializing your sensor: RS-485 modbus library - #100 by peergum

I am still getting the E2 error message after configuring serial, here is the last code I ran

#include "ModbusMaster-Particle.h"

SerialLogHandler logHandler(9600,LOG_LEVEL_WARN, {
    {"app", LOG_LEVEL_TRACE},
    {"system", LOG_LEVEL_INFO}
});


void preTransmission() {
    // set interface to TX
}

void postTransmission() {
    // set interface to RX
}

void idle() {
    delay(10); // in case slave only replies after 10ms
    Particle.process(); // avoids letting the connection close if open
}

ModbusMaster sensor;

void setup() {
    sensor.begin(1, Serial1); // slaveID=1, serial=Serial1
    Serial1.begin(9600, SERIAL_8N2);
    // slave.setSpeed(9600); // same as above
    sensor.enableDebug(); // to catch the logs
    sensor.preTransmission(preTransmission);
    sensor.postTransmission(postTransmission);
    sensor.idle(idle);

    uint8_t result = sensor.readHoldingRegisters(9,1);

    if (!result) {
        uint16_t value = sensor.getResponseBuffer(0);
        Log.info("Received: %f",value);
    } else {
        Log.warn("Read error");
    }
}

void loop() {
    // do nothing 
}

This is where I’m at right now. The highlighted message in the “raw data received” box is the message that I sent to the laptop from the E Series module. This message returns an error when going to my slave device. I then copied the exact same message (as can be seen in the “modbus request” portion) and sent it to the slave from my laptop, and received accurate data from all 4 registers that were requested (as can be seen in the “registers” box). This is leading me to believe it might be a circuit issue rather than programming? I am using a max3232 converter to go from TTL to RS232. Also thinking I should maybe start another topic as I initially just wanted to ask Phil a question about the library (thanks for the configuration reminder btw) but now I am not sure that is the problem…

Hello folks,
for those that are are having pain with Modbusmaster libraries, I just found one that in my opinion is one of the most complete Libraries out there , I have tested that with particle photon, ESP32 and worked fine.
just have look here : SensorModbusMaster
cheers,

1 Like

So it turns out I was having an issue with the voltage levels coming out of my RS232 adapter, got that figured out and I was finally able to get successful reads! Does anybody have an example of publishing the returned data to the cloud? How do I get the response to publish just like it prints out on my serial?

#include "ModbusMaster.h"

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

	

void setup() {
    
    
	// initialize Modbus communication baud rate
	node.begin(9600);
	node.disableTXpin(); //disable the Tx pin
	//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.print("Starting Modbus Transaction:");
	
	Particle.function( "modbusInput", modbusInput );
	
	
}

int modbusInput(String command){
    if (command == "adc_vbterm"){
        
        
    static uint32_t i;
	uint8_t j, result;
	uint16_t data[10];

	i++;

	result = node.readHoldingRegisters(0x012,1);

	Serial.println("");
	
	// do something with data if read is successful
	if (result == node.ku8MBSuccess) {
		Serial.print("adc_vbterm: ");
		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("");
	}
	
     return 1;   
    }
    
    
    
}

void loop() {
    
    
}

Super well organized. And very nice high level utilities.

1 Like

@1bit that library works ok with arduino, mega, uno, leonardo, when I tried with Photon and ESP32 I got problems … so I had to add an small delay of 2ms somewhere in the cpp file… can’t remember where, but I may look into my other computer where I made the modification. the issue was the enable pin was going low before the entire mod-bus command end.


After I added the 2ms delay–>

Hi @failedfractal to do that i recommend you to first play the arduino Json library, so you can serialize the data in more professional manner, then you need Mqtt library like send your json to mqtt broker like mosquitto that you can install that broker in your raspberry pi for example. or you might use some free Mqtt broker online like https://www.cloudmqtt.com/plans.html

Which transceiver are you using? Are you using level shifters at all? I guess you have explicit control over the enable pin, I like that over the autoenable circuits style of breakout boards.


I want to try this BOB…It claims good Isolation and 3 to 30V power…but Automatic flow control is not to my liking…maybe I could defeat that part of the circuit…

image

@1bit … yes that works perfect… I got one of those and tested, if you use that one it will take care automatically the tx/rx flow control… but I made my own PCB designs so I want to make it simpler , I prefer to use one IO of the photon/ ESp32 for flow control of the max485.
All my test have been done with this converter: EBAY MAX485

That is the MAX485 chip, I have about 30 of those left… When I go to 3v systems like TEENSY, I use the SP3485…made for 3.3v systems. I ordered the other one just for kicks.

Max485 also works with 3.3v I am using it right now with an ESP32.