-
-
Notifications
You must be signed in to change notification settings - Fork 494
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
RS485/Modbus support? #1167
Comments
I'm not sure. I've never worked with it, but it looks fairly straightforward. I'd be more inclined to try to interface directly to the Pi, rather than use an arduino, with only one intermediary IC, something like the following: https://www.sparkfun.com/products/10124 |
Hi, you can use a cheap CH340/341 serial to USB converter stick and plug it into your pi, connect the modbus wires to it. In Mycodo just write a custom Python script to read the Modbus registers and return the values to Mycodo. Works like a charm. But integration like the other interface types would have saved me quite some time for sure. Example: import minimalmodbus
import serial
instrument = minimalmodbus.Instrument('/dev/ttyUSB0', slaveaddress=1, close_port_after_each_call=True, debug=False) # port name, slave address (in decimal)
#instrument.serial.port # this is the serial port name
instrument.serial.baudrate = 9600 # Baud
instrument.serial.bytesize = 8
instrument.serial.parity = serial.PARITY_NONE
instrument.serial.stopbits = 1
instrument.serial.timeout = 1 # seconds
#print(instrument)
#instrument.address = 1 # this is the slave address number
#instrument.serial.rtscts = True
#instrumentseral.xonxoff = True
#instrument.serial.dsrdtr = True
instrument.mode = minimalmodbus.MODE_RTU # rtu or ascii mode
instrument.clear_buffers_before_each_transaction = True
## Read temperature (PV = ProcessValue) ##instrument.serial.port # this is the serial port name
#print(instrument)
ECtemp = instrument.read_register(registeraddress=2, number_of_decimals=0, functioncode=3) #read_long(1, 3) # Registernumber, function code
ECtemp = ECtemp / 10
ECms = instrument.read_long(0, 3) / 100 #instrument.read_register(registeraddress=0, number_of_decimals=2, functioncode=3)
#ECppm = instrument.read_long(2, 3)
# Store measurements in database (must specify the channel and measurement)
self.store_measurement(channel=0, measurement=ECtemp)
self.store_measurement(channel=1, measurement=ECms)
#self.store_measurement(channel=2, measurement=ECppm) |
There are also cheap UART-RS485 converters like the MAX485 module. I have just bought it, but I don't find out how to read sensors connected to the UART with mycodo. @Josuah8, is your code applicable in my case, possibly changing the |
Hi, yes, if you manage to set the max485 or whatever other solution up
outside of mycodo then you know which tty to talk to. Then you can write a
script to read the values. Once this works you only have to adapt the
script to make it return values to mycodo as described in the manual
section about custom python scripts as input module. That's it. The python
script I posted works for my case, it uses minimalmodbus. The python
library you want to use must be installed in the virtual environment of
Mycodo, otherwise it won't find it. You should be able to modify my script
to match your modbus settings and the register actions you want to perform.
In my case I really got grey hair while trying to get it running outside of
mycodo. I had one usb stick with CH340 chip that was able to read data from
one sensor but not from another one and I was not able to figure out why.
Until I tried a different CH340 stick, it worked immediately. Even without
resistors and connecting the two lines to GND and voltage. The rest was
easy because the script was already correct. I needed some testing with the
data types to get meaningful data out of the sensor and also figured out
that the documentation of the sensor was a bit misleading concerning the
register addresses. But I got it up and running and it's working well since
a year already. If we had a modbus interface in mycodo it would make it a
lot easier to change settings on the fly without having to edit the python
script.
hth
Josuah
Laurent Alebarde ***@***.***> schrieb am Di., 12. Apr. 2022,
13:46:
… There are also cheap UART-RS485 converters like the MAX485 module
<https://medium.com/raspberry-pi-and-rs485-modbus/modbus-rs485-raspberry-pi-5ccbc1996b7d>.
I have just bought it, but I don't find out how to read sensors connected
to the UART with mycodo. @Josuah8 <https://github.com/Josuah8>, is your
code applicable in my case, possibly changing the tty? Could you please
elaborate on *"just write a custom Python script to read the Modbus
registers and return the values to Mycodo"*?
—
Reply to this email directly, view it on GitHub
<#1167 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AYUEHM4K76R65ZVH3RIDNKTVEVA73ANCNFSM5SNXVALQ>
.
You are receiving this because you commented.Message ID:
***@***.***>
|
This issue has been mentioned on Radical DIY Forum. There might be relevant details there: https://forum.radicaldiy.com/t/custom-input-for-industrial-ec-with-rs485-protocol/751/2 |
Haha. You pointed the forum back to here. MODBUS would be a cool addition because a lot of solar charge controllers use MODBUS as well. And the way you've integrated MQTT to send data to/from where needed is awesome. Great project! Getting some traction on Reddit too. |
This issue has been mentioned on Radical DIY Forum. There might be relevant details there: |
I have solved it using minimalmodbus. Needed to add The following code along with installing the libraries with import minimalmodbus
import serial
import struct
# Create an instrument object
instrument = minimalmodbus.Instrument('/dev/ttyUSB0', slaveaddress=1, debug=False)
instrument.serial.baudrate = 19200
instrument.serial.bytesize = 8
instrument.serial.parity = serial.PARITY_NONE
instrument.serial.stopbits = 2
instrument.serial.timeout = 1
instrument.mode = minimalmodbus.MODE_RTU
instrument.clear_buffers_before_each_transaction = True
# Read 10 registers starting from 2090
ph_values = instrument.read_registers(2089, 10, functioncode=3)
# Read 10 registers starting from 2410
temp_values = instrument.read_registers(2409, 10, functioncode=3)
# Combine the register values to form 32-bit integers
ph_int = (ph_values[3] << 16) | ph_values[2]
temp_int = (temp_values[3] << 16) | temp_values[2]
# Convert the 32-bit integers to bytes
ph_bytes = ph_int.to_bytes(4, 'little')
temp_bytes = temp_int.to_bytes(4, 'little')
# Interpret the bytes as 32-bit floats
pH = struct.unpack('f', ph_bytes)[0]
temperature = struct.unpack('f', temp_bytes)[0]
# Store measurements
self.store_measurement(channel=0, measurement=round(pH, 2))
self.store_measurement(channel=1, measurement=round(temperature, 2)) |
I am looking at some industrial humidity/temperature sensors that use the Modbus protocol (RS485) such as this: https://www.vaisala.com/en/products/instruments-sensors-and-other-measurement-devices/instruments-industrial-measurements/hmd110-hmw110
I am wondering if there is a way to integrate Modbus sensors as a custom input?
I am considering interfacing them by using an RS485 shield https://www.hwhardsoft.de/english/projects/rs485-arduino/ and then using the Arduino to convert the data to i2c.
What do you think about this approach?
Thank you!
The text was updated successfully, but these errors were encountered: