Closed legaxus-mis closed 2 years ago
It's pretty much the same as ESP client example
uint16_t res[10];
uint8_t show = LOOP_COUNT;
void loop() {
if (mb.isConnected(remote)) { // Check if connection to Modbus Slave is established
mb.readHreg(remote, REG, &res, 10); // Initiate Read Hregs from Modbus Server
// or
mb.writeHreg(remote, REG, &res, 10); // Initiate Write to Modbus Server
} else {
mb.connect(remote); // Try to connect if no connection
}
mb.task(); // Common local Modbus task
delay(100); // Pulling interval
if (!show--) { // Display Slave register value one time per second (with default settings)
Serial.println(res);
show = LOOP_COUNT;
}
}
It's pretty much the same as ESP client example
uint16_t res[10]; uint8_t show = LOOP_COUNT; void loop() { if (mb.isConnected(remote)) { // Check if connection to Modbus Slave is established mb.readHreg(remote, REG, &res, 10); // Initiate Read Hregs from Modbus Server // or mb.writeHreg(remote, REG, &res, 10); // Initiate Write to Modbus Server } else { mb.connect(remote); // Try to connect if no connection } mb.task(); // Common local Modbus task delay(100); // Pulling interval if (!show--) { // Display Slave register value one time per second (with default settings) Serial.println(res); show = LOOP_COUNT; } }
Hi Eemelianov, Thanks for replying. My current situation is client request to my side, and my side will be TCP server waiting for request and then response to the client. I've attached example 1 for Multiple registers and example 2 for Holding register. Appreciate if you could guide me with some examples. Thanks.
If you need you device act as a server it's even simpler: Server -- you may add as many registers as needed. Analog read -- just replace Ireg with Hreg.
All requests (read/write/single/multiple) defined by Modbus specification are processed by the library internal code.
If you facing any issue please provide code snipped and detailed information on how to reproduce the issue.
If you need you device act as a server it's even simpler: Server -- you may add as many registers as needed. Analog read -- just replace Ireg with Hreg.
All requests (read/write/single/multiple) defined by Modbus specification are processed by the library internal code.
If you facing any issue please provide code snipped and detailed information on how to reproduce the issue.
Hi Eemelianov, Alright, I'll try it out first and update the result here, thanks.
Hi, first of all I'd like to thank you for this wonderfull library, i'm facing a strange issue, I do use a simple program to control an equipment, using this library as server AP mode in the ESP32, as soon as I connect the program to the server IP I receive a strange message "modbus says error: Connection is lost ! and doesn't work, Trying a more "complex " library this error doesn't happen, also, when I use a tester from the "easymodbustcpdotnet" the program works.
I'm using the server example with the exception that i'm using the esp32 as a acess point.
` /* Modbus-Arduino Example - Test Holding Register (Modbus IP ESP8266) Configure Holding Register (offset 100) with initial value 0xABCD You can get or set this holding register Original library Copyright by André Sarmento Barbosa http://github.com/andresarmento/modbus-arduino
Current version (c)2017 Alexander Emelianov (a.m.emelianov@gmail.com) https://github.com/emelianov/modbus-esp8266 */
// Modbus Registers Offsets const int TEST_HREG = 100;
//ModbusIP object ModbusIP mb;
void setup() { Serial.begin(115200);
WiFi.mode(WIFI_AP); WiFi.softAP("esp32", "12345678"); delay(100);
Serial.println("Set softAPConfig"); IPAddress Ip(192, 168, 1, 1); IPAddress NMask(255, 255, 255, 0); WiFi.softAPConfig(Ip, Ip, NMask);
IPAddress myIP = WiFi.softAPIP(); Serial.print("AP IP address: "); Serial.println(myIP);
mb.server(); mb.addHreg(TEST_HREG, 0xABCD); }
void loop() { //Call once inside loop() - all magic here mb.task(); delay(10); } `
If you need you device act as a server it's even simpler: Server -- you may add as many registers as needed. Analog read -- just replace Ireg with Hreg.
All requests (read/write/single/multiple) defined by Modbus specification are processed by the library internal code.
If you facing any issue please provide code snipped and detailed information on how to reproduce the issue.
Hi Eemelianov, I still confuse on some logic of communication between server and client. The example code below, how can I perform like, if receive client query message string "$01M" from Multiple registers 16 in hex as below. (0x01, 0x10, 0x27, 0x0F, 0x00, 0x03, 0x06, 0x24, 0x30, 0x31, 0x4D, 0x0D) then only server response with the SENSOR_HREG1 to client? If another message string query from client like "$02M" then server response SENSOR_HREG2 to client?
Appreciate if you could guide me on some examples, thanks.
Examples code: mb.server(); //Start Modbus IP // Add SENSOR_IREG register - Use addHreg() for analog Inputs mb.addHreg(SENSOR_HREG1); mb.addHreg(SENSOR_HREG2); mb.addHreg(SENSOR_HREG2);
ts = millis();
}
void loop() { //Call once inside loop() - all magic here mb.task();
//Read each two seconds if (millis() > ts + 2000) { ts = millis(); //Setting raw value (0-1024) mb.Hreg(SENSOR_HREG1, analogRead(A0)); } delay(10); }
I'm not sure that understand you idea correctly. In general Modbus protocol can only read and write registers. For sure you can use multiple registers to store some text across them and use the text value on server side. As the library is focused on standard Modbus data processing for this particular task code will be slightly more complex. Something like (it's just an idea):
union {
uint16_t reg[MESSAGE_REGS_COUNT];
char symbol[MESSAGE_REGS_COUNT * 2 + 1];
} message;
// Callback is called for each register individually
uint16_t cbMessageReg(TRegister* reg, uint16_t val) {
if (reg->address.address == MESSAGE_REG) // Clear message on first register write
for (uint8_t i = 0; i < MESSAGE_REGS_COUNT + 1; i++)
message.symbol[i] = '/0';
message.reg[reg->address.address - MESSAGE_REG] = val; // or __swap_16(val);
return val;
}
void setup() {
//...
mb.addHreg(MESSAGE_REG, 0, MESSAGE_REGS_COUNT);
mb.onSetHreg(MESSAGE_REG, cbMessageReg, MESSAGE_REGS_COUNT);
//...
}
uint32_t ts = 0;
void loop() {
mb.task();
if (millis() > ts + 2000) {
ts = millis();
if (String(reinterpret_cast<char*>(message.symbol)) == "$01M") {
mb.Hreg(SENSOR_HREG1, analogRead(A0));
}
}
delay(10);
}
I'm not sure that understand you idea correctly. In general Modbus protocol can only read and write registers. For sure you can use multiple registers to store some text across them and use the text value on server side. As the library is focused on standard Modbus data processing for this particular task code will be slightly more complex. Something like (it's just an idea):
union { uint16_t reg[MESSAGE_REGS_COUNT]; char symbol[MESSAGE_REGS_COUNT * 2 + 1]; } message; // Callback is called for each register individually uint16_t cbMessageReg(TRegister* reg, uint16_t val) { if (reg->address.address == MESSAGE_REG) // Clear message on first register write for (uint8_t i = 0; i < MESSAGE_REGS_COUNT + 1; i++) message.symbol[i] = '/0'; message.reg[reg->address.address - MESSAGE_REG] = val; // or __swap_16(val); return val; } void setup() { //... mb.addHreg(MESSAGE_REG, 0, MESSAGE_REGS_COUNT); mb.onSetHreg(MESSAGE_REG, cbMessageReg, MESSAGE_REGS_COUNT); //... } uint32_t ts = 0; void loop() { mb.task(); if (millis() > ts + 2000) { ts = millis(); if (String(reinterpret_cast<char*>(message.symbol)) == "$01M") { mb.Hreg(SENSOR_HREG1, analogRead(A0)); } } delay(10); }
Hi Eemelianov, Thanks for the explanation. What means by (reinterpret_cast<char*>(message.symbol), what will this line perform? Thanks.
What means by (reinterpret_cast<char*>(message.symbol), what will this line perform? Thanks.
It's close to (char): instructs compiler to interpret pinter as char not char[].
What means by (reinterpret_cast<char*>(message.symbol), what will this line perform? Thanks.
It's close to (char): instructs compiler to interpret pinter as char not char[].
Hi Eemelianov, Thanks for the explanation. From the condition as below if (String(reinterpret_cast<char*>(message.symbol)) == "$01M") { ----> mb.Hreg(SENSOR_HREG1, analogRead(A0)); <----
if after receive and compare correctly the message is "$01M" , I would like to send an "$02ACK" before sending the analogRead data. Appreciate if you could guide me on some examples, thanks.
It's some kind of overengineering in my opinion. If you really need to implement protocol on top of Modbus it's better to use Ciols/Ists for ACK flagging in my opinion. Anyway this out of the library usage scope questions.
Sir.... my slave device communication is Communication : RS232 Transmation Mode : ASCII Baud rate : 57600 Word lenth : 7 Parity : EVEN Stop Bits : 1
Not communicating the ModbusRTU program . Please help for communication.
The library doesn't support ASCII mode.
Dear sir,
Is there a library that supports it?
Please give me a library...
Thanks & regards
Manikyalarao k Mob:9885898897
On Sat, Oct 14, 2023, 9:29 AM Alexander Emelianov @.***> wrote:
The library doesn't support ASCII mode.
— Reply to this email directly, view it on GitHub https://github.com/emelianov/modbus-esp8266/issues/204#issuecomment-1762551060, or unsubscribe https://github.com/notifications/unsubscribe-auth/AZPIRDJKLSLHWGQ2FIFBSPLX7IE2NAVCNFSM5UEK5KE2U5DIOJSWCZC7NNSXTN2JONZXKZKDN5WW2ZLOOQ5TCNZWGI2TKMJQGYYA . You are receiving this because you commented.Message ID: @.***>
Hi Eemelianov, Appreciate if you could offer some examples for Modbus TCP write multiple registers and read holding registers using ModbusIP library, thanks. Hope to hear from you soon. Thanks.