ESP8266 WiFi – Modbus TCP/IP Slave
Hardware: ESP8266 WiFi
Het is mogelijk om een Modbus TCP/IP Slave te maken met de ESP8266 chip op diverse platformen, hieronder een aantal voorbeelden.
Voorbeeld ZONDER bibliotheek
Bron:Â trialcommand.com
Info (ENG):
We performed numerous tests of the modbus library which used the Tinker library, with the result that certain applications that use delay’s affect communication, in that case we take the library and select the connection routines, master frame reading, frame creation, Reading and writing functions.
This routine created in Arduino IDE for ESP8266 performs master – slave communication without adding extra libraries, since the communication is done step by step.
Tests:
The following addresses have been configured in the ESP8266 module:
- 10 Holding Read Registers for display on the ESP8266 serial terminal.
- 10 Holding Writing Registers in which we will send Random values to validate the changes in the Modbus Master (Simulator).
- Additionally from Holding register [14] we will activate the 14 – pin GPIO (D5)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 |
#include <ESP8266WiFi.h> const char* ssid = "SSID"; const char* password = "WACHTWOORD"; int ModbusTCP_port = 502; //////// Required for Modbus TCP / IP /// Requerido para Modbus TCP/IP ///////// #define maxInputRegister 20 #define maxHoldingRegister 20 #define MB_FC_NONE 0 #define MB_FC_READ_REGISTERS 3 //implemented #define MB_FC_WRITE_REGISTER 6 //implemented #define MB_FC_WRITE_MULTIPLE_REGISTERS 16 //implemented // // MODBUS Error Codes // #define MB_EC_NONE 0 #define MB_EC_ILLEGAL_FUNCTION 1 #define MB_EC_ILLEGAL_DATA_ADDRESS 2 #define MB_EC_ILLEGAL_DATA_VALUE 3 #define MB_EC_SLAVE_DEVICE_FAILURE 4 // // MODBUS MBAP offsets // #define MB_TCP_TID 0 #define MB_TCP_PID 2 #define MB_TCP_LEN 4 #define MB_TCP_UID 6 #define MB_TCP_FUNC 7 #define MB_TCP_REGISTER_START 8 #define MB_TCP_REGISTER_NUMBER 10 byte ByteArray[260]; unsigned int MBHoldingRegister[maxHoldingRegister]; ////////////////////////////////////////////////////////////////////////// WiFiServer MBServer(ModbusTCP_port); void setup() { pinMode(14, OUTPUT); Serial.begin(9600); delay(100); WiFi.begin(ssid, password); delay(100); Serial.println("."); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } MBServer.begin(); Serial.println("Connected "); Serial.print("ESP8266 Slave Modbus TCP/IP "); Serial.print(WiFi.localIP()); Serial.print(":"); Serial.println(String(ModbusTCP_port)); Serial.println("Modbus TCP/IP Online"); } void loop() { // Check if a client has connected // Modbus TCP/IP WiFiClient client = MBServer.available(); if (!client) { return; } boolean flagClientConnected = 0; byte byteFN = MB_FC_NONE; int Start; int WordDataLength; int ByteDataLength; int MessageLength; // Modbus TCP/IP while (client.connected()) { if(client.available()) { flagClientConnected = 1; int i = 0; while(client.available()) { ByteArray[i] = client.read(); i++; } client.flush(); ///// code here --- codigo aqui ///////// Holding Register [0] A [9] = 10 Holding Registers Escritura ///////// Holding Register [0] A [9] = 10 Holding Registers Writing MBHoldingRegister[0] = random(0,12); MBHoldingRegister[1] = random(0,12); MBHoldingRegister[2] = random(0,12); MBHoldingRegister[3] = random(0,12); MBHoldingRegister[4] = random(0,12); MBHoldingRegister[5] = random(0,12); MBHoldingRegister[6] = random(0,12); MBHoldingRegister[7] = random(0,12); MBHoldingRegister[8] = random(0,12); MBHoldingRegister[9] = random(0,12); ///////// Holding Register [10] A [19] = 10 Holding Registers Lectura ///// Holding Register [10] A [19] = 10 Holding Registers Reading int Temporal[10]; Temporal[0] = MBHoldingRegister[10]; Temporal[1] = MBHoldingRegister[11]; Temporal[2] = MBHoldingRegister[12]; Temporal[3] = MBHoldingRegister[13]; Temporal[4] = MBHoldingRegister[14]; Temporal[5] = MBHoldingRegister[15]; Temporal[6] = MBHoldingRegister[16]; Temporal[7] = MBHoldingRegister[17]; Temporal[8] = MBHoldingRegister[18]; Temporal[9] = MBHoldingRegister[19]; /// Enable Output 14 digitalWrite(14, MBHoldingRegister[14] ); //// debug for (int i = 0; i < 10; i++) { Serial.print("["); Serial.print(i); Serial.print("] "); Serial.print(Temporal[i]); } Serial.println(""); //// end code - fin //// routine Modbus TCP byteFN = ByteArray[MB_TCP_FUNC]; Start = word(ByteArray[MB_TCP_REGISTER_START],ByteArray[MB_TCP_REGISTER_START+1]); WordDataLength = word(ByteArray[MB_TCP_REGISTER_NUMBER],ByteArray[MB_TCP_REGISTER_NUMBER+1]); } // Handle request switch(byteFN) { case MB_FC_NONE: break; case MB_FC_READ_REGISTERS: // 03 Read Holding Registers ByteDataLength = WordDataLength * 2; ByteArray[5] = ByteDataLength + 3; //Number of bytes after this one. ByteArray[8] = ByteDataLength; //Number of bytes after this one (or number of bytes of data). for(int i = 0; i < WordDataLength; i++) { ByteArray[ 9 + i * 2] = highByte(MBHoldingRegister[Start + i]); ByteArray[10 + i * 2] = lowByte(MBHoldingRegister[Start + i]); } MessageLength = ByteDataLength + 9; client.write((const uint8_t *)ByteArray,MessageLength); byteFN = MB_FC_NONE; break; case MB_FC_WRITE_REGISTER: // 06 Write Holding Register MBHoldingRegister[Start] = word(ByteArray[MB_TCP_REGISTER_NUMBER],ByteArray[MB_TCP_REGISTER_NUMBER+1]); ByteArray[5] = 6; //Number of bytes after this one. MessageLength = 12; client.write((const uint8_t *)ByteArray,MessageLength); byteFN = MB_FC_NONE; break; case MB_FC_WRITE_MULTIPLE_REGISTERS: //16 Write Holding Registers ByteDataLength = WordDataLength * 2; ByteArray[5] = ByteDataLength + 3; //Number of bytes after this one. for(int i = 0; i < WordDataLength; i++) { MBHoldingRegister[Start + i] = word(ByteArray[ 13 + i * 2],ByteArray[14 + i * 2]); } MessageLength = 12; client.write((const uint8_t *)ByteArray,MessageLength); byteFN = MB_FC_NONE; break; } } } |
Algemeen voorbeeld uitlezen met Python op Raspberry Pi
1 2 3 4 5 6 7 8 |
#!/usr/bin/env python from pyModbusTCP.client import ModbusClient client = ModbusClient(host="192.168.2.28", port=502, auto_open=True, auto_close=True, timeout=10) data2 = client.write_single_register(14, 1) # FUNCTIE 06 - Schrijven (enkele register) (register=14, waarde=1) data = client.read_holding_registers(14, 1) # FUNCTIE 03 - Lees register (enkele register) (register=14, lengte=1) print "Waarde register: ", data[0] client.close() |