Hey. I have multiple ESP32 boards daisy chained. I initially configured one of the ESP32 as a master device and tested the communications.
Now that I have confirmed that communications are working properly and I can write/read data thorugh MODBUS, I want to configure my raspberry PI as a master device and send a very simple messages to the selected slave devices.
This is my master code for ESP32:
I have wired 2 buttons to ESP32, and all it is doing is sending a slave with ID = 1 a message according to which button is pressed.
I have connected my raspberry PI TX/RX and direction pin to a RS485 driver module:
https://www.ti.com/lit/ds/symlink/sn75176b.pdf?ts=1603871763734&ref_url=https%3A%2F%2Fwww.google.com%2F
and connecting A/B to the ESP32.
The first library I have looked at is modbus tk. I have tried the following code with no luck :
How does the library above know what DIR pin I have connected to since I do not see any declaration in the RTU example code? How is direction pin controller by this library?
and my Slave code is :
Could someone suggest the most simple modbus library for python? I just need to be able to write/read registers to and from slave devices
Now that I have confirmed that communications are working properly and I can write/read data thorugh MODBUS, I want to configure my raspberry PI as a master device and send a very simple messages to the selected slave devices.
This is my master code for ESP32:
Code:
/*
* //masteris su lipduku
ModbusRTU ESP8266/ESP32
Read multiple coils from slave device example
(c)2019 Alexander Emelianov (a.m.emelianov@gmail.com)
https://github.com/emelianov/modbus-esp8266
modified 13 May 2020
by brainelectronics
This code is licensed under the BSD New License. See LICENSE.txt for more info.
*/
#include <ModbusRTU.h>
#define RXD2 16
#define TXD2 17
#define DIR 15
#define REG1 10
#define BUTTON1 36 //pin D5
#define BUTTON2 39 //pin D5
ModbusRTU mb;
int buttonState1 = 0; // current state of the button
int lastButtonState1 = 0; // previous state of the button
int buttonState2 = 0; // current state of the button
int lastButtonState2 = 0; // previous state of the button
uint16_t send_data = 5;
uint16_t storing_data = 0; // place holder to store data
unsigned long lastMsg = 0;
char myChar = 'A';
bool cbWrite(Modbus::ResultCode event, uint16_t transactionId, void* data) {
Serial.printf_P("Request result: 0x%02X, Mem: %d\n", event, ESP.getFreeHeap());
return true;
}
//bool cbRead(Modbus::ResultCode event, uint16_t transactionId, void* data) {
//Serial.printf_P("Request result: 0x%02X, Mem: %d\n", event, ESP.getFreeHeap());
//return true;
//}
void setup() {
pinMode(BUTTON1,INPUT);
pinMode(BUTTON2,INPUT);
Serial.begin(9600);
Serial2.begin(9600, SERIAL_8N1, RXD2, TXD2);
mb.begin(&Serial2,DIR,true);
mb.master();
}
void loop() {
mb.task();
//yield();
check_button_state(BUTTON1,BUTTON2);
unsigned long now = millis();
// no need to update when the device is in pildymas mode
if (now - lastMsg > 1000 ) {
if (!mb.slave()) {
mb.readHreg(1, REG1, &storing_data,1);
Serial.print("Value inside storing data=");
Serial.println(storing_data);
}
lastMsg=now;
}
}
void check_button_state(int pin1,int pin2){
buttonState1 = digitalRead(pin1);
buttonState2 = digitalRead(pin2);
if (buttonState1 != lastButtonState1) {
if (buttonState1 == HIGH){
Serial.println("button1 pressed");
if (!mb.slave()) {
mb.writeHreg(1, REG1, 99, cbWrite);
Serial.println("Writing 99 to REG1");
}
// if the current state is HIGH then the button went from off to on:
Serial.println("on");
}
else {
// if the current state is LOW then the button went from on to off:
Serial.println("off");
}
}
if (buttonState2 != lastButtonState2) {
if (buttonState2 == HIGH){
Serial.println("button2 pressed");
if (!mb.slave()) {
Serial.println("Writing char to REG1");
mb.writeHreg(1, REG1, myChar, cbWrite);
}
// if the current state is HIGH then the button went from off to on:
Serial.println("on");
}
else {
// if the current state is LOW then the button went from on to off:
Serial.println("off");
}
}
lastButtonState1 = buttonState1;
lastButtonState2 = buttonState2;
}
I have connected my raspberry PI TX/RX and direction pin to a RS485 driver module:
https://www.ti.com/lit/ds/symlink/sn75176b.pdf?ts=1603871763734&ref_url=https%3A%2F%2Fwww.google.com%2F
and connecting A/B to the ESP32.
The first library I have looked at is modbus tk. I have tried the following code with no luck :
Code:
#!/usr/bin/env python
# -*- coding: utf_8 -*-
"""
Modbus TestKit: Implementation of Modbus protocol in python
(C)2009 - Luc Jean - luc.jean@gmail.com
(C)2009 - Apidev - http://www.apidev.fr
This is distributed under GNU LGPL license, see license.txt
"""
import serial
import modbus_tk
import modbus_tk.defines as cst
from modbus_tk import modbus_rtu
#PORT = 1
PORT = '/dev/ttyAMA0'
def main():
"""main"""
logger = modbus_tk.utils.create_logger("console")
try:
#Connect to the slave
master = modbus_rtu.RtuMaster(
serial.Serial(port=PORT, baudrate=9600, bytesize=8, parity='N', stopbits=1, xonxoff=0)
)
master.set_timeout(5.0)
master.set_verbose(True)
logger.info("connected")
#logger.info(master.execute(1, cst.READ_HOLDING_REGISTERS, 1,5 ))
#send some queries
#logger.info(master.execute(1, cst.READ_COILS, 0, 10))
#logger.info(master.execute(1, cst.READ_DISCRETE_INPUTS, 0, 8))
#logger.info(master.execute(1, cst.READ_INPUT_REGISTERS, 100, 3))
#logger.info(master.execute(1, cst.READ_HOLDING_REGISTERS, 100, 12))
#logger.info(master.execute(1, cst.WRITE_SINGLE_COIL, 7, output_value=1))
logger.info(master.execute(1, cst.WRITE_SINGLE_REGISTER, 10, output_value=99))
#logger.info(master.execute(1, cst.WRITE_MULTIPLE_COILS, 0, output_value=[1, 1, 0, 1, 1, 0, 1, 1]))
#logger.info(master.execute(1, cst.WRITE_MULTIPLE_REGISTERS, 100, output_value=xrange(12)))
except modbus_tk.modbus.ModbusError as exc:
logger.error("%s- Code=%d", exc, exc.get_exception_code())
if __name__ == "__main__":
main()
How does the library above know what DIR pin I have connected to since I do not see any declaration in the RTU example code? How is direction pin controller by this library?
and my Slave code is :
Code:
/*
ModbusRTU ESP8266/ESP32
Simple slave example
(c)2019 Alexander Emelianov (a.m.emelianov@gmail.com)
https://github.com/emelianov/modbus-esp8266
modified 13 May 2020
by brainelectronics
This code is licensed under the BSD New License. See LICENSE.txt for more info.
*/
#include <ModbusRTU.h>
#define RXD2 16
#define TXD2 17
#define DIR 15
#define REG1 10
#define SLAVE_ID 1
#define BUTTON1 36 //pin D5
ModbusRTU mb;
uint16_t send_data = 100;
void setup() {
Serial.begin(9600, SERIAL_8N1);
Serial2.begin(9600, SERIAL_8N1, RXD2, TXD2);
mb.begin(&Serial2,DIR,true);
mb.setBaudrate(9600);
mb.slave(SLAVE_ID);//Initializng modbus slave device with ID 1
mb.addHreg(REG1); // add the register with address 1
//mb.Hreg(REG1, 0);
//mb.writeHreg(1, 100, &send_data, 1, cbWrite);
}
void loop() {
mb.task();
switch(mb.Hreg(REG1)){
case 99:
Serial.println(mb.Hreg(REG1));
mb.Hreg(REG1, 55); //PUT 55 IN REG1
break;
case 65:
Serial.println(mb.Hreg(REG1));
mb.Hreg(REG1, 155); //PUT 55 IN REG1
break;
}
}
Could someone suggest the most simple modbus library for python? I just need to be able to write/read registers to and from slave devices
Last edited: