1200 views|1 replies

86

Posts

0

Resources
The OP
 

Low-code IoT development board RS485 serial port and Modbus examples can be connected to Gizwits Cloud [Copy link]

1. Functional description of RS485 basic communication routine


The development board realizes communication with the computer serial port debugging assistant through UART1 interface + SP485EEN chip. And realize the following two sending and receiving example functions:
If the PC sends 5 bytes of data to the development board through 485, and the 5 bytes of data are 06 07 08 09 0A, the yellow LED1 flashes once
The development board sends 5 bytes of data to the PC through 485 every 1 second, 01 02 03 04 05


2. The purpose of this experimental teaching is to

master the following based on ShineBlink:
UART communication (occupying RX1, TX1)
GPIO controls the direction of the 485 conversion chip (D2 pin controls the direction of the 485 chip, high level)
-GPIO controls the on and off of LED1 (D8 connects to yellow LED1)


3.
The location of the module 485 interface involved in this experiment on the development board is as follows:




Note that in order to use the 485 interface, the P7 and P8 jumper caps must be shorted to connect the TX1 pin, RX1 pin and the 485 conversion chip.


4. Complete source code
The following code implements the following functions:
If the PC sends 5 bytes of data to the development board through 485, and the 5 bytes of data are 06 07 08 09 0A, the yellow LED1 flashes once.
The development board sends 5 bytes of data to the PC through 485 every 1 second, 01 02 03 04 05


  1. LIB_GpioOutputConfig("D8","STANDARD") --Initialize GPIO to control yellow LED1
  2. LIB_GpioOutputConfig("D2","STANDARD") -- Initialize GPIO control Max485 RE DE transceiver control
  3. --Configure the baud rate of Uart1 serial port to 19200 for 485 communication
  4. LIB_Uart1Config("BAUDRATE_19200")
  5. -- Enable MAX485 to send
  6. function SendEn()
  7. LIB_GpioWrite("D2",1)
  8. end
  9. --Enable MAX485 receiving
  10. function RecvEn()
  11. LIB_GpioWrite("D2",0)
  12. end
  13. -- Enable the 10 millisecond timer to start working
  14. LIB_10msTimerConfig("ENABLE")
  15. cnt_10ms = 0
  16. --Define the interrupt function of the 10 millisecond timer
  17. function LIB_10msTimerCallback()
  18. cnt_10ms = cnt_10ms + 1
  19. end
  20. --Start the big cycle
  21. while(GC(1) == true)
  22. do
  23. --Send 5 bytes of data to the PC every 1 second
  24. if cnt_10ms >= 100 then --1000ms
  25. cnt_10ms = 0
  26. send_data = {1,2,3,4,5}
  27. SendEn()
  28. LIB_Uart1BlockSend(send_data)
  29. RecvEn()
  30. end
  31. --Check whether the 5-byte data sent from the PC is received and verify
  32. recv_flag,recv_data = LIB_Uart1Recv()
  33. if recv_flag == 1 and #recv_data == 5 then
  34. if recv_data[1] == 6 and recv_data[2] == 7 and recv_data[3] == 8 and recv_data[4] == 9 and recv_data[5] == 10 then
  35. LIB_GpioToggle("D8") -- Toggle LED status
  36. end
  37. end
  38. end
Copy code



5. Experimental phenomenon

After connecting the 485 interface of the development board to the PC through the 485 to USB tool, copy the above code to the virtual TF card of the development board and start running. After that, the 5-byte data (01 02 03 04 05) sent by the development board can be received by the PC serial port debugging assistant every second, and when the debugging assistant sends it to the development board (06 07 08 09 0a), the yellow LED light of the development board will flash as shown below:


EEWORLDIMGTK1

EEWORLDIMGTK2
Note: The software needs to check "HEX display" and "HEX send".
Implementation of communication between device and host computer (Modbus host)
Introduction:
The following describes how to use ShineBlink as a device (Modbus slave) to communicate with a host computer (Modbus master), and implements the program code for function code 0x03 (read multiple holding registers) and function code 0x05 (write a single coil) on the ShineBlink device side.
1. Implementation Environment
The device acts as a Modbus slave and communicates with the host computer through the RS485 bus. We run the well-known Modbus Poll debugging software on the computer as the host computer to simulate the Modbus host. The Modbus Poll software can be downloaded from its official website.
2. Equipment Introduction
As one of the nodes in the Modbus network, the device has the following characteristics:Serial port attributes: 19200, N, 8, 1Device address: 21 (0x15)Modbus function codes supported by the device: 0x05 write a single coil 0x03 read multiple holding registersFunction introduction: 0x05, the host computer sends the 0x05 function code to the device, and when the value 0xFF00 is written to the coil with the coil address of 0x0000, the device starts running, and when the value 0x0000 is written to the coil with the coil address of 0x0000, the device stops running. 0x03, the host computer sends the 0x03 function code to the device, and reads 9 holding registers with the starting address of 0x0000 (each holding register value is 16-bit unsigned data). The data corresponding to each register is as follows:

EEWORLDIMGTK3


3. Modbus communication implementation code example


The following code not only implements function codes 03 and 05, but also responds to various abnormal situations to the Modbus host.
  1. --Definition of global variables used in the program
  2. Pm25Percent = 0
  3. HchoPercent = 0
  4. TvocPercent = 0
  5. MeshPercent = 0.0
  6. Temprature1 = 0.00
  7. Temprature2 = 0.00
  8. Wind485DisSpeed = 0
  9. DevIsRunning = 0 --Control device running or stopping
  10. FaultCode = 0 -- Fault code
  11. --ModBus communication function definition
  12. function ModbusProcess()
  13. local sdata = {}
  14. --Check whether the message sent by the Modbus host is received
  15. flag, data = LIB_Uart1Recv()
  16. if flag == 1 then
  17. --Determine whether the message is sent to the local machine, and only take care of it if it is sent to the local machine
  18. if data[1] == PI[2] then --PI[2], Modbus local address (1-247)
  19. --Judge Modbus function code
  20. if data[2] == 0x05 then -- 0x05 write a single coil
  21. --Here, the coil address 0x0000 is defined as the power on/off control signal
  22. if data[3] == 0x00 and data[4] == 0x00 then
  23. if data[5] == 0xff and data[6] == 0x00 then --ON
  24. DevIsRunning = 1 -- Set the global variable at startup
  25. elseif data[5] == 0x00 and data[6] == 0x00 then --OFF
  26. DevIsRunning = 0 -- Set the global variable to 0 at startup
  27. else
  28. --Here you need to reply to the illegal data 03 exception message (illegal data value), readers can complete it by themselves
  29. end
  30. --Reply OK and send back the received data intact
  31. LIB_GpioWrite("D2",1) -- Enable 485 module to send
  32. LIB_Uart1BlockSend(data)
  33. LIB_GpioWrite("D2",0) -- Enable 485 module to receive
  34. else
  35. --Reply to abnormal message (illegal data address)
  36. sdata[1] = data[1] -- local address
  37. sdata[2] = data[2]+0x80 --When an exception occurs, the function code is increased by 0x80
  38. sdata[3] = 0x02 --Exception code 0x02 means the device does not support this data address
  39. CRC = LIB_CrcCalculate("CRC16_MODBUS", sdata)
  40. sdata[4] = CRC & 0x00ff -- low byte first
  41. sdata[5] = CRC >> 8 -- high digit at the end
  42. LIB_GpioWrite("D2",1) -- Enable 485 module to send
  43. LIB_Uart1BlockSend(sdata)
  44. LIB_GpioWrite("D2",0) -- Enable 485 module to receive
  45. end
  46. --Here we use 0x03 instead of 0x04 because many hosts only support 03 06 16 instructions, so we just follow the crowd
  47. elseif data[2] == 0x03 then --0x03 Read multiple holding registers
  48. --Here, define the registers with the starting address of 0x0000 to store sensor data, and the number of registers to be read must be 9
  49. if data[3] == 0x00 and data[4] == 0x00 and data[5] == 0x00 and data[6] == 0x09 then
  50. sdata[1] = data[1] -- local address
  51. sdata[2] = data[2] -- function code
  52. sdata[3] = 18 --Number of bytes in the data field: 9 registers, a total of 18 bytes
  53. sdata[4] = Pm25Percent >> 8
  54. sdata[5] = Pm25Percent & 0x00ff
  55. sdata[6] = HchoPercent >> 8
  56. sdata[7] = HchoPercent & 0x00ff
  57. sdata[8] = TvocPercent >> 8
  58. sdata[9] = TvocPercent & 0x00ff
  59. sdata[10] = math.floor(MeshPercent) >> 8
  60. sdata[11] = math.floor(MeshPercent) & 0x00ff
  61. sdata[12] = math.floor(Temprature1) >> 8
  62. sdata[13] = math.floor(Temprature1) & 0x00ff
  63. sdata[14] = math.floor(Temprature2) >> 8
  64. sdata[15] = math.floor(Temprature2) & 0x00ff
  65. sdata[16] = Wind485DisSpeed >> 8
  66. sdata[17] = Wind485DisSpeed & 0x00ff
  67. sdata[18] = DevIsRunning >> 8
  68. sdata[19] = DevIsRunning & 0x00ff
  69. sdata[20] = FaultCode >> 8
  70. sdata[21] = FaultCode & 0x00ff
  71. CRC = LIB_CrcCalculate("CRC16_MODBUS", sdata)
  72. sdata[22] = CRC & 0x00ff -- low byte first
  73. sdata[23] = CRC >> 8 -- high digit at the end
  74. --Reply sensor data
  75. LIB_GpioWrite("D2",1) -- Enable 485 module to send
  76. LIB_Uart1BlockSend(sdata)
  77. LIB_GpioWrite("D2",0) -- Enable 485 module to receive
  78. else
  79. --Reply to abnormal message (illegal data address)
  80. sdata[1] = data[1] -- local address
  81. sdata[2] = data[2]+0x80 --When an exception occurs, the function code is increased by 0x80
  82. sdata[3] = 0x02 --Exception code 0x02 means the device does not support this data address
  83. CRC = LIB_CrcCalculate("CRC16_MODBUS", sdata)
  84. sdata[4] = CRC & 0x00ff -- low byte first
  85. sdata[5] = CRC >> 8 -- high digit at the end
  86. LIB_GpioWrite("D2",1) -- Enable 485 module to send
  87. LIB_Uart1BlockSend(sdata)
  88. LIB_GpioWrite("D2",0) -- Enable 485 module to receive
  89. end
  90. else
  91. --Reply to abnormal message (illegal function code)
  92. sdata[1] = data[1] -- local address
  93. sdata[2] = data[2]+0x80 --When an exception occurs, the function code is increased by 0x80
  94. sdata[3] = 0x01 --Exception code 0x01 means the device does not support this function code
  95. CRC = LIB_CrcCalculate("CRC16_MODBUS", sdata)
  96. sdata[4] = CRC & 0x00ff -- low byte first
  97. sdata[5] = CRC >> 8 -- high digit at the end
  98. LIB_GpioWrite("D2",1) -- Enable 485 module to send
  99. LIB_Uart1BlockSend(sdata)
  100. LIB_GpioWrite("D2",0) -- Enable 485 module to receive
  101. end
  102. end
  103. end
  104. end
  105. --Start initializing ShineBlink
  106. --Configure the baud rate of Uart1 serial port to 19200 and connect to 485 module
  107. LIB_Uart1Config("BAUDRATE_19200")
  108. --485 send and receive control pins
  109. LIB_GpioOutputConfig("D2","STANDARD")
  110. LIB_GpioWrite("D2",0) -- Enable 485 module to receive
  111. --Start the big cycle
  112. while(GC(1) == true)
  113. do
  114. --Modbus communication processing
  115. ModbusProcess()
  116. end
Copy code


4. Modbus Poll Host Computer Experiment Process
(1) Configure 0x03 Read Holding Register Function (Setup)





(2) Establishing a Modbus serial communication connection (Connectiong)





(3) Data communication after establishing a connection
1. The host computer automatically sends a 0x03 command every second to read the values of the 9 holding registers of the device with the starting address of 0x0000





Communication data log:



The 23 bytes of data replied by the device above are given as an example:
For example: 15 03 12 00 06 00 00 00 01 00 00 00 16 00 16 00 00 00 00 00 00 D5 16
The CRC algorithm at the end of the data uses Modbus CRC16
  1. Local address: 0x15
  2. Function code: 0x03
  3. Number of bytes: 18 bytes (9 16-bit unsigned registers)
  4. Register 1: 0x0006 means pm25=6
  5. Register 2: 0x0000 means hch0=0
  6. Register 3: 0x0001 means tvoc=1
  7. Register 4: 0x0000 means mesh=6
  8. Register 5: 0x0016 indicates temprature1 = 21 degrees
  9. Register 6: 0x0016 indicates temprature2 = 21 degrees
  10. Register 7: 0x0000 means windspeed = 0
  11. Register 8: 0x0000 means running = 0
  12. Register 9: 0x0000 means faultcode=0
  13. CRC_L:0xD5
  14. CRC_H:0x16
Copy code
2. The host computer sends a power-on command (function code 0x05, write a single coil value 0xFF00 to the coil address 0x0000)
Communication data log:
3. The host computer sends a stop command (function code 0x05, write a single coil value 0x0000 to the coil address 0x0000)
The host computer sends: 15 05 00 00 00 00 CE DE The device should reply: 15 05 00 00 00 00 CE DE
https://club.gizwits.com/forum.php?mod=post&action=reply&fid=247&tid=169449&fromvf=1&extra=page=1&replysubmit=yes&infloat=yes&handlekey=vfastpost" onsubmit="this.message.value = parseurl(this.message .value);ajaxpost('vfastpostform', 'return_reply', 'return_reply', 'onerror');return false;" style="overflow-wrap:break-word; padding:0px">
This post is from RF/Wirelessly

Latest reply

[attach]706224[/attach] What's missing? The host has a look.   Details Published on 2023-6-17 14:19
 

6593

Posts

0

Resources
2
 

What's missing? The host has a look.

This post is from RF/Wirelessly
 
 

Guess Your Favourite
Just looking around
Find a datasheet?

EEWorld Datasheet Technical Support

快速回复 返回顶部 Return list