I have a NODEMCU ESP8266 LUA board with a built-in LUA interpreter. I am trying to make a device on us that the OPC server will access via MODBUS TCP / IP and interrogate it. But I have not yet met examples of the implementation of this protocol in the LUA language specifically for ESP8266 so I cannot understand how and where to start. It would be convenient to write a program in the LUA language, throw the program into the controller and that's it. But long searches on the Internet all the time lead me to ARDUINO IDE, everything is supposedly already implemented there:

http://en.trialcommand.com/blog/esp8266-slave-modbus-tcpip-no-libraries/ http://pdacontrolen.com/update-esp8266-industrial-modbus-tcp-ip/

http://pdacontroles.com/actualizacion-esp8266-industrial-modbus/

http://domoticx.com/esp8266-wifi-modbus-tcp-ip-slave/

https://github.com/andresarmento/modbus-esp8266

https://github.com/MaxKravt/WiFi-Modbus-TCPtoRTU

https://github.com/JhonControl/ESP8266_Industrial_ModbusTCP_V2

But I would like not to reflash through the ARDUINO IDE but to write the program on LUA, because it is very convenient. So far I can not understand how to do this and where to find an example. Thank.

  • What an exotic ... :-) - pepsicoca1
  • Already almost decided, it turned out to be very simple, a TCP server is going up on port 502 on NODEMCU. Now my TCP server accepts everything that comes from the master to its ip and port 502 and can respond. It remains to make the processing of received information and form the answer. As I finish, I will probably answer my own question ... - Roman

1 answer 1

I will begin with a simple way to receive a packet from a MODBUS TCP device:

arr = {} srv = net.createServer(net.TCP) srv:listen(502, function(conn) conn:on("receive", function(sck, payload) payload:gsub(".", function(c) table.insert(arr, string.byte(c)) end) print (table.concat(arr, " ")) end) end) 

Output to the terminal will be as follows:

 0 1 0 0 0 6 1 3 0 0 0 1 . . 0 30 0 0 0 6 1 3 0 0 0 1 0 31 0 0 0 6 1 3 0 0 0 1 0 32 0 0 0 6 1 3 0 0 0 1 

In my case, the OPC server, which requests information from the device using the TCP protocol, sends it to the IP address specified in it for port 502. The code that receives it above is written to the array and then output to the terminal. You can do anything with an array.

How to transfer a packet to a MODBUS TCP device? Very simple:

 arr = {0,1,0,0,0,6,1,3,0,0,0,1} srv = net.createServer(net.TCP) srv:listen(502, function(conn) conn:on("receive", function(sck, payload) buff = "" for i=1, #arr do line = string.char(arr[i]) buff = buff .. line end sck:send(buff) end) end) 

In this case, the array is transmitted in response to a request from a MODBUS TCP device. Knowing the MODBUS protocol, you can form an array of the necessary variables depending on the query.

And lastly, the code that the received packet writes to the array sends it back:

 arr = {} srv = net.createServer(net.TCP) srv:listen(502, function(conn) conn:on("receive", function(sck, payload) payload:gsub(".", function(c) table.insert(arr, string.byte(c)) end) local buff = "" for i=1, #arr do line = string.char(arr[i]) buff = buff .. line end sck:send(buff) buff = "" end) end) 

This is certainly not correct, the MODBUS TCP device will swear at the wrong answer, but in the interval between reception and transmission you can modify the array and give the correct answer, I think that those who know the MODBUS protocol will be able to understand how to answer correctly. I just debugged the reception and transmission, the basic algorithm that works, then everyone will redo it to fit their needs. There is another point to which I draw your attention. It happens that a MODBUS TCP device can send a very long packet consisting of several without waiting for an answer to them, and then the array will instantly become very large and naturally the answer will be the same and wrong. I decided it is very simple, I check the size of the received packet, if it is equal to the required number of bytes, then after receiving the code, if not, then everything is skipped and the device waits for the following request:

 if string.len(payload) == 12 then . . end 

I do this check immediately after receiving the packet and if the packet is 12 bytes, the code is executed, if not, then the next request from the MODBUS TCP device is waited. This code can be altered under MODBUS RS485, the checksum can be calculated by the module from the MODEMCU firmware.

Here you can compile the firmware with the necessary modules.