RS-485 modbus library

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

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.

Thank you for the suggestion. I have my data publishing to the cloud properly now. I am still just having issues with the data type. When I return a hex value it is “4A53” and the decimal is “19027”. The data is apparently being stored as a weird float16 number, and when I run the hex number through a float16 converter provided by the manufacture of the slave device, I get the proper result of “12.6484” which in this case refers to battery voltage. Any ideas how I can make this conversion happen inside of my code? I would rather fill my database with the already converted value than the hex value.

You can try this library for a C++ implementation of half-precission float (aka float16)

I also think there is a ModBus lib floating around in this forum that features float16 functions already.

Thank you sir, I’ve been wrestling with this all day and will hopefully get it to compile with the modbus master library for the electron. I had yet to dabble with compiling in visual studio so it’s been yet another learning experience. In the meantime if you come across that library containing float16 functions you might save me from a late night…

A post was merged into an existing topic: Particle ModbusMaster Library with two slaves

@luisgcu did you ever figure out in code where that 2ms delay was?

I’m trying out the SensorModbusMaster library for the first time today and ran into a compiler problem in Workbench. Line 612 of SensorModbusMaster.cpp reads:

int bytesRead = _stream->readBytes(responseBuffer, 135);

When trying to compile I get this error:

error: invalid conversion from 'byte* {aka unsigned char*}' to 'char*'

EDIT: fixed by changing line 612 to:

int bytesRead = _stream->readBytes((char *)responseBuffer, 135);

Still curious about the 2ms delay though. :wink:

1 Like

hi @fishmastaflex you can use these library that we forked from SensorModbusMaster and made the right corrections to work with esp32 and Particle Photon.
ModbusLibrary1
Modbus library 2