├── .gitattributes ├── .gitignore ├── ModbusESP8266_Random.ino ├── ModbusTCPSlave ├── Keywords.txt ├── ModbusTCPSlave.cpp └── ModbusTCPSlave.h ├── README.md └── extras ├── Modbus_ESP8266_Arquic_PDAControl.JPG ├── NewModbusTCPESP_ESP8266.jpg └── Test_ESP8266_ModbusTCP.jpg /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | 7 | # Standard to msysgit 8 | *.doc diff=astextplain 9 | *.DOC diff=astextplain 10 | *.docx diff=astextplain 11 | *.DOCX diff=astextplain 12 | *.dot diff=astextplain 13 | *.DOT diff=astextplain 14 | *.pdf diff=astextplain 15 | *.PDF diff=astextplain 16 | *.rtf diff=astextplain 17 | *.RTF diff=astextplain 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Windows image file caches 2 | Thumbs.db 3 | ehthumbs.db 4 | 5 | # Folder config file 6 | Desktop.ini 7 | 8 | # Recycle Bin used on file shares 9 | $RECYCLE.BIN/ 10 | 11 | # Windows Installer files 12 | *.cab 13 | *.msi 14 | *.msm 15 | *.msp 16 | 17 | # Windows shortcuts 18 | *.lnk 19 | 20 | # ========================= 21 | # Operating System Files 22 | # ========================= 23 | 24 | # OSX 25 | # ========================= 26 | 27 | .DS_Store 28 | .AppleDouble 29 | .LSOverride 30 | 31 | # Thumbnails 32 | ._* 33 | 34 | # Files that might appear in the root of a volume 35 | .DocumentRevisions-V100 36 | .fseventsd 37 | .Spotlight-V100 38 | .TemporaryItems 39 | .Trashes 40 | .VolumeIcon.icns 41 | 42 | # Directories potentially created on remote AFP share 43 | .AppleDB 44 | .AppleDesktop 45 | Network Trash Folder 46 | Temporary Items 47 | .apdisk 48 | -------------------------------------------------------------------------------- /ModbusESP8266_Random.ino: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * More information about projects PDAControl 4 | * Mas informacion sobre proyectos PDAControl 5 | * Blog PDAControl English http://pdacontrolenglish.blogspot.com.co/ 6 | * Blog PDAControl Espanol http://pdacontrol.blogspot.com.co/ 7 | * Channel Youtube https://www.youtube.com/c/JhonValenciaPDAcontrol/videos 8 | * 9 | */ 10 | #include 11 | #include 12 | #include 13 | 14 | //WIFI Settings 15 | //byte ip[] = { 192, 168, 1, 126}; 16 | //byte gateway[] = { 192, 168, 1, 1 }; 17 | //byte subnet[] = { 255, 255, 255, 0 }; 18 | 19 | Ticker Parada; 20 | ModbusTCPSlave Mb; 21 | 22 | 23 | void valor() { 24 | 25 | /// Send random - envio random 26 | Mb.MBHoldingRegister[0] = random(0,51); 27 | 28 | /// read - lectura MBHoldingRegister[0] 29 | Serial.print("MBHoldingRegister[0]"); 30 | Serial.println(Mb.MBHoldingRegister[0]); 31 | 32 | /// read - lectura MBHoldingRegister[1] 33 | Serial.print("MBHoldingRegister[1]"); 34 | Serial.println(Mb.MBHoldingRegister[1]); 35 | 36 | } 37 | 38 | void setup() 39 | { 40 | 41 | Serial.begin(115200); 42 | Mb.begin("SSID", "PASSWORD"); 43 | // Mb.begin("SSID", "PASSWORD", ip, gateway, subnet); 44 | 45 | delay(100); 46 | 47 | } 48 | 49 | void loop() 50 | { 51 | Mb.Run(); 52 | delay(10); 53 | 54 | ////Ticker Function 55 | Parada.attach_ms(25,valor); 56 | 57 | 58 | } 59 | 60 | -------------------------------------------------------------------------------- /ModbusTCPSlave/Keywords.txt: -------------------------------------------------------------------------------- 1 | ####################################### 2 | # Syntax Coloring Map For Mudbus 3 | ####################################### 4 | 5 | ####################################### 6 | # Datatypes (KEYWORD1) 7 | ####################################### 8 | 9 | ModbusTCPSlave KEYWORD1 10 | 11 | ####################################### 12 | # Methods and Functions (KEYWORD2) 13 | ####################################### 14 | 15 | Run KEYWORD2 16 | MBInputRegister KEYWORD2 17 | MBHoldingRegister KEYWORD2 18 | 19 | ####################################### 20 | # Constants (LITERAL1) 21 | ####################################### 22 | 23 | MBDebug LITERAL1 24 | MB_PORT LITERAL1 25 | -------------------------------------------------------------------------------- /ModbusTCPSlave/ModbusTCPSlave.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "ModbusTCPSlave.h" 3 | 4 | 5 | ModbusTCPSlave::ModbusTCPSlave(void): 6 | #ifdef MB_ETHERNET 7 | MBServer(MB_PORT) 8 | #endif 9 | #ifdef MB_CC3000 10 | MBClient(ADAFRUIT_CC3000_CS, ADAFRUIT_CC3000_IRQ, ADAFRUIT_CC3000_VBAT, SPI_CLOCK_DIVIDER), 11 | MBServer(MB_PORT) 12 | #endif 13 | #ifdef MB_ESP8266 14 | MBServer(MB_PORT) 15 | #endif 16 | { 17 | } 18 | #ifdef MB_ETHERNET 19 | void ModbusTCPSlave::begin(){ 20 | byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; 21 | pinMode(LED_PIN, OUTPUT); 22 | digitalWrite(LED_PIN, LOW); 23 | #ifdef MBDebug 24 | Serial1.begin(9600); 25 | Serial1.print(F("Requesting DHCP ...")); 26 | #endif 27 | if (Ethernet.begin(mac) == 0) { 28 | #ifdef MBDebug 29 | Serial1.println("failed"); 30 | #endif 31 | while (1); 32 | } 33 | #ifdef MBDebug 34 | else 35 | Serial1.println(); 36 | 37 | Serial1.print(F("Listening on ")); 38 | for (byte thisByte = 0; thisByte < 4; thisByte++) { 39 | Serial1.print(Ethernet.localIP()[thisByte], DEC); 40 | Serial1.print(thisByte < 3 ? "." : ""); 41 | } 42 | Serial1.print(":"); 43 | Serial1.print(MB_PORT); 44 | Serial1.println(" ..."); 45 | #endif 46 | digitalWrite(LED_PIN, HIGH); 47 | } 48 | void ModbusTCPSlave::begin(byte ip[4],uint8_t gateway[4],uint8_t subnet[4]){ 49 | byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; 50 | pinMode(LED_PIN, OUTPUT); 51 | digitalWrite(LED_PIN, LOW); 52 | Ethernet.begin(mac,ip,gateway,subnet); 53 | #ifdef MBDebug 54 | Serial1.begin(9600); 55 | Serial1.print(F("Listening on ")); 56 | for (byte thisByte = 0; thisByte < 4; thisByte++) { 57 | Serial1.print(ip[thisByte], DEC); 58 | Serial1.print(thisByte < 3 ? "." : ""); 59 | } 60 | Serial1.print(F(":")); 61 | Serial1.print(MB_PORT); 62 | Serial1.println(" ..."); 63 | #endif 64 | digitalWrite(LED_PIN, HIGH); 65 | } 66 | #endif 67 | #ifdef MB_CC3000 68 | void ModbusTCPSlave::begin(const char *ssid, const char *key, uint8_t secmode){ 69 | pinMode(LED_PIN, OUTPUT); 70 | digitalWrite(LED_PIN, LOW); 71 | MBClient.begin(); 72 | #ifdef MBDebug 73 | Serial1.print(F("Connecting to ")); Serial1.print(ssid); Serial1.println(F(" ...")); 74 | #endif 75 | MBClient.connectToAP(ssid, key, secmode); 76 | while (!MBClient.checkDHCP()) 77 | delay(100); 78 | uint32_t ipAddress, netmask, gateway, dhcpserv, dnsserv; 79 | MBClient.getIPAddress(&ipAddress, &netmask, &gateway, &dhcpserv, &dnsserv); 80 | #ifdef MBDebug 81 | Serial1.print(F("Listening on ")); 82 | MBClient.printIPdotsRev(ipAddress); 83 | Serial1.print(F(":")); 84 | Serial1.println(MB_PORT); 85 | #endif 86 | digitalWrite(LED_PIN, HIGH); 87 | MBServer.begin(); 88 | } 89 | #endif 90 | #ifdef MB_ESP8266 91 | void ModbusTCPSlave::begin(const char *ssid, const char *key){ 92 | pinMode(LED_PIN, OUTPUT); 93 | digitalWrite(LED_PIN, LOW); 94 | ledPinStatus = LOW; 95 | #ifdef MBDebug 96 | Serial1.begin(115200); 97 | // Connect to WiFi network 98 | Serial1.println(); 99 | Serial1.println(); 100 | Serial1.print("Connecting to "); 101 | Serial1.println(ssid); 102 | #endif 103 | 104 | WiFi.begin(ssid, key); 105 | 106 | while (WiFi.status() != WL_CONNECTED) { 107 | // Blink the LED 108 | digitalWrite(LED_PIN, ledPinStatus); // Write LED high/low 109 | ledPinStatus = (ledPinStatus == HIGH) ? LOW : HIGH; 110 | delay(100); 111 | #ifdef MBDebug 112 | Serial1.print("."); 113 | #endif 114 | } 115 | #ifdef MBDebug 116 | Serial1.println(""); 117 | Serial1.println("WiFi connected"); 118 | #endif 119 | 120 | #ifdef MBDebug 121 | Serial1.print("IP address: "); 122 | Serial1.println(WiFi.localIP()); 123 | Serial1.print("WiFi signal"); 124 | Serial1.println(WiFi.RSSI()); 125 | #endif 126 | 127 | // Start the server 128 | digitalWrite(LED_PIN, HIGH); 129 | MBServer.begin(); 130 | #ifdef MBDebug 131 | Serial1.print(F("Listening on ")); 132 | Serial1.print(MB_PORT); 133 | Serial1.println(" ..."); 134 | #endif 135 | } 136 | void ModbusTCPSlave::begin(const char *ssid, const char *key,uint8_t ip[4],uint8_t gateway[4],uint8_t subnet[4]){ 137 | pinMode(LED_PIN, OUTPUT); 138 | digitalWrite(LED_PIN, LOW); 139 | ledPinStatus = LOW; 140 | #ifdef MBDebug 141 | Serial1.begin(115200); 142 | // Connect to WiFi network 143 | Serial1.println(); 144 | Serial1.println(); 145 | Serial1.print("Connecting to "); 146 | Serial1.println(ssid); 147 | #endif 148 | 149 | WiFi.config(IPAddress(ip), IPAddress(gateway), IPAddress(subnet)); 150 | 151 | WiFi.begin(ssid, key); 152 | 153 | while (WiFi.status() != WL_CONNECTED) { 154 | // Blink the LED 155 | digitalWrite(LED_PIN, ledPinStatus); // Write LED high/low 156 | ledPinStatus = (ledPinStatus == HIGH) ? LOW : HIGH; 157 | delay(100); 158 | #ifdef MBDebug 159 | Serial1.print("."); 160 | #endif 161 | } 162 | #ifdef MBDebug 163 | Serial1.println(""); 164 | Serial1.println("WiFi connected"); 165 | #endif 166 | 167 | #ifdef MBDebug 168 | Serial1.print("IP address: "); 169 | Serial1.println(WiFi.localIP()); 170 | Serial1.print("WiFi signal"); 171 | Serial1.println(WiFi.RSSI()); 172 | #endif 173 | 174 | // Start the server 175 | digitalWrite(LED_PIN, HIGH); 176 | MBServer.begin(); 177 | #ifdef MBDebug 178 | Serial1.print(F("Listening on ")); 179 | Serial1.print(MB_PORT); 180 | Serial1.println(" ..."); 181 | #endif 182 | } 183 | #endif 184 | 185 | void ModbusTCPSlave::Run(){ 186 | boolean flagClientConnected = 0; 187 | byte byteFN = MB_FC_NONE; 188 | int Start; 189 | int WordDataLength; 190 | int ByteDataLength; 191 | int MessageLength; 192 | 193 | //****************** Read from socket **************** 194 | #ifdef MB_ETHERNET 195 | EthernetClient client = MBServer.available(); 196 | #endif 197 | #ifdef MB_CC3000 198 | Adafruit_CC3000_ClientRef client = MBServer.available(); 199 | #endif 200 | #ifdef MB_ESP8266 201 | WiFiClient client = MBServer.available(); 202 | #endif 203 | 204 | while (client.connected()) { 205 | if(client.available()) 206 | { 207 | flagClientConnected = 1; 208 | int i = 0; 209 | while(client.available()) 210 | { 211 | ByteArray[i] = client.read(); 212 | i++; 213 | } 214 | #ifdef MB_ESP8266 215 | client.flush(); 216 | #endif 217 | byteFN = ByteArray[MB_TCP_FUNC]; 218 | Start = word(ByteArray[MB_TCP_REGISTER_START],ByteArray[MB_TCP_REGISTER_START+1]); 219 | WordDataLength = word(ByteArray[MB_TCP_REGISTER_NUMBER],ByteArray[MB_TCP_REGISTER_NUMBER+1]); 220 | #ifdef MBDebug 221 | Serial1.println(); 222 | Serial1.print("RX: "); 223 | for (byte thisByte = 0; thisByte < 20; thisByte++) { 224 | Serial1.print(ByteArray[thisByte], DEC); 225 | Serial1.print("-"); 226 | } 227 | Serial1.println(); 228 | Serial1.print("Ricevuta Funzione: "); 229 | Serial1.println(byteFN); 230 | #endif 231 | } 232 | 233 | // Handle request 234 | 235 | switch(byteFN) { 236 | case MB_FC_NONE: 237 | break; 238 | 239 | case MB_FC_READ_REGISTERS: // 03 Read Holding Registers 240 | ByteDataLength = WordDataLength * 2; 241 | ByteArray[5] = ByteDataLength + 3; //Number of bytes after this one. 242 | ByteArray[8] = ByteDataLength; //Number of bytes after this one (or number of bytes of data). 243 | for(int i = 0; i < WordDataLength; i++) 244 | { 245 | ByteArray[ 9 + i * 2] = highByte(MBHoldingRegister[Start + i]); 246 | ByteArray[10 + i * 2] = lowByte(MBHoldingRegister[Start + i]); 247 | } 248 | MessageLength = ByteDataLength + 9; 249 | client.write((const uint8_t *)ByteArray,MessageLength); 250 | #ifdef MBDebug 251 | Serial1.print("TX: "); 252 | for (byte thisByte = 0; thisByte <= MessageLength; thisByte++) { 253 | Serial1.print(ByteArray[thisByte], DEC); 254 | Serial1.print("-"); 255 | } 256 | Serial1.println(); 257 | #endif 258 | byteFN = MB_FC_NONE; 259 | break; 260 | 261 | case MB_FC_READ_INPUT_REGISTERS: // 04 Read Input Registers 262 | Start = word(ByteArray[MB_TCP_REGISTER_START],ByteArray[MB_TCP_REGISTER_START+1]); 263 | WordDataLength = word(ByteArray[MB_TCP_REGISTER_NUMBER],ByteArray[MB_TCP_REGISTER_NUMBER+1]); 264 | ByteDataLength = WordDataLength * 2; 265 | ByteArray[5] = ByteDataLength + 3; //Number of bytes after this one. 266 | ByteArray[8] = ByteDataLength; //Number of bytes after this one (or number of bytes of data). 267 | for(int i = 0; i < WordDataLength; i++) 268 | { 269 | ByteArray[ 9 + i * 2] = highByte(MBInputRegister[Start + i]); 270 | ByteArray[10 + i * 2] = lowByte(MBInputRegister[Start + i]); 271 | } 272 | MessageLength = ByteDataLength + 9; 273 | client.write((const uint8_t *)ByteArray,MessageLength); 274 | #ifdef MBDebug 275 | Serial1.print("TX: "); 276 | for (byte thisByte = 0; thisByte <= MessageLength; thisByte++) { 277 | Serial1.print(ByteArray[thisByte], DEC); 278 | Serial1.print("-"); 279 | } 280 | Serial1.println(); 281 | #endif 282 | byteFN = MB_FC_NONE; 283 | break; 284 | 285 | case MB_FC_WRITE_REGISTER: // 06 Write Holding Register 286 | MBHoldingRegister[Start] = word(ByteArray[MB_TCP_REGISTER_NUMBER],ByteArray[MB_TCP_REGISTER_NUMBER+1]); 287 | ByteArray[5] = 6; //Number of bytes after this one. 288 | MessageLength = 12; 289 | client.write((const uint8_t *)ByteArray,MessageLength); 290 | #ifdef MBDebug 291 | Serial1.print("TX: "); 292 | for (byte thisByte = 0; thisByte <= MessageLength; thisByte++) { 293 | Serial1.print(ByteArray[thisByte], DEC); 294 | Serial1.print("-"); 295 | } 296 | Serial1.println(); 297 | Serial1.print("Write Holding Register: "); 298 | Serial1.print(Start); 299 | Serial1.print("="); 300 | Serial1.println(MBHoldingRegister[Start]); 301 | #endif 302 | byteFN = MB_FC_NONE; 303 | break; 304 | 305 | case MB_FC_WRITE_MULTIPLE_REGISTERS: //16 Write Holding Registers 306 | ByteDataLength = WordDataLength * 2; 307 | ByteArray[5] = ByteDataLength + 3; //Number of bytes after this one. 308 | for(int i = 0; i < WordDataLength; i++) 309 | { 310 | MBHoldingRegister[Start + i] = word(ByteArray[ 13 + i * 2],ByteArray[14 + i * 2]); 311 | } 312 | MessageLength = 12; 313 | client.write((const uint8_t *)ByteArray,MessageLength); 314 | #ifdef MBDebug 315 | Serial1.print("TX: "); 316 | for (byte thisByte = 0; thisByte <= MessageLength; thisByte++) { 317 | Serial1.print(ByteArray[thisByte], DEC); 318 | Serial1.print("-"); 319 | } 320 | Serial1.println(); 321 | Serial1.print("Write Holding Registers from: "); 322 | Serial1.print(Start); 323 | Serial1.print("="); 324 | Serial1.println(WordDataLength); 325 | #endif 326 | byteFN = MB_FC_NONE; 327 | break; 328 | } 329 | } 330 | client.stop(); 331 | 332 | if (flagClientConnected == 1){ 333 | #ifdef MBDebug 334 | Serial1.println("client disonnected"); 335 | #endif 336 | flagClientConnected = 0; 337 | } 338 | } 339 | 340 | -------------------------------------------------------------------------------- /ModbusTCPSlave/ModbusTCPSlave.h: -------------------------------------------------------------------------------- 1 | /* 2 | ModbusTCPSlave.h - an Arduino library for a Modbus TCP slave. 3 | 4 | This program is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program. If not, see . 16 | */ 17 | 18 | // Note: The Arduino IDE does not respect conditional included 19 | // header files in the main sketch so you have to select your 20 | // here. 21 | // 22 | #ifndef ModbusTCPSlave_h 23 | #define ModbusTCPSlave_h 24 | 25 | #define MB_PORT 502 26 | 27 | //#define MB_ETHERNET 28 | //#define MB_CC3000 29 | #define MB_ESP8266 30 | 31 | #define MBDebug //serial debug enable 32 | 33 | #include "Arduino.h" 34 | 35 | #ifdef MB_ETHERNET 36 | #include 37 | #define LED_PIN 13 38 | #endif 39 | #ifdef MB_CC3000 40 | #define LED_PIN 13 41 | #include 42 | #include 43 | #define ADAFRUIT_CC3000_IRQ 3 44 | #define ADAFRUIT_CC3000_VBAT 5 45 | #define ADAFRUIT_CC3000_CS 10 46 | #endif 47 | #ifdef MB_ESP8266 48 | #define LED_PIN 5 49 | #include 50 | #endif 51 | 52 | #define maxInputRegister 20 53 | #define maxHoldingRegister 20 54 | 55 | // 56 | // MODBUS Function Codes 57 | // 58 | #define MB_FC_NONE 0 59 | #define MB_FC_READ_COILS 1 60 | #define MB_FC_READ_DISCRETE_INPUT 2 61 | #define MB_FC_READ_REGISTERS 3 //implemented 62 | #define MB_FC_READ_INPUT_REGISTERS 4 //implemented 63 | #define MB_FC_WRITE_COIL 5 64 | #define MB_FC_WRITE_REGISTER 6 //implemented 65 | #define MB_FC_WRITE_MULTIPLE_COILS 15 66 | #define MB_FC_WRITE_MULTIPLE_REGISTERS 16 //implemented 67 | // 68 | // MODBUS Error Codes 69 | // 70 | #define MB_EC_NONE 0 71 | #define MB_EC_ILLEGAL_FUNCTION 1 72 | #define MB_EC_ILLEGAL_DATA_ADDRESS 2 73 | #define MB_EC_ILLEGAL_DATA_VALUE 3 74 | #define MB_EC_SLAVE_DEVICE_FAILURE 4 75 | // 76 | // MODBUS MBAP offsets 77 | // 78 | #define MB_TCP_TID 0 79 | #define MB_TCP_PID 2 80 | #define MB_TCP_LEN 4 81 | #define MB_TCP_UID 6 82 | #define MB_TCP_FUNC 7 83 | #define MB_TCP_REGISTER_START 8 84 | #define MB_TCP_REGISTER_NUMBER 10 85 | 86 | class ModbusTCPSlave 87 | { 88 | public: 89 | ModbusTCPSlave(void); 90 | #ifdef MB_ETHERNET 91 | void begin(); 92 | void begin(uint8_t ip[4],uint8_t gateway[4],uint8_t subnet[4]); 93 | #endif 94 | #ifdef MB_CC3000 95 | void begin(const char *ssid, const char *key, uint8_t secmode); 96 | #endif 97 | #ifdef MB_ESP8266 98 | void begin(const char *ssid, const char *key); 99 | void begin(const char *ssid, const char *key,uint8_t ip[4],uint8_t gateway[4],uint8_t subnet[4]); 100 | #endif 101 | void Run(); 102 | unsigned int MBInputRegister[maxInputRegister]; 103 | unsigned int MBHoldingRegister[maxHoldingRegister]; 104 | 105 | private: 106 | byte ByteArray[260]; 107 | bool ledPinStatus = LOW; 108 | 109 | 110 | #ifdef MB_ETHERNET 111 | EthernetServer MBServer; 112 | #endif 113 | 114 | #ifdef MB_CC3000 115 | Adafruit_CC3000 MBClient; 116 | Adafruit_CC3000_Server MBServer; 117 | #endif 118 | 119 | #ifdef MB_ESP8266 120 | WiFiServer MBServer; 121 | #endif 122 | }; 123 | 124 | #endif 125 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ESP8266 Actualizacion Update ESP8266 Slave Modbus TCP 2 | 3 | They have been conducted new tests with better results with ModbusTCPSlave library, solving problems as momentary disconnection of ESP8266 for updating the data. 4 | 5 | Se han realizado nuevas pruebas con mejores resultados con la libreria ModbusTCPSlave, solucionando inconvenientes como desconexion momentanea de ESP8266 para la actualizacion de los datos. 6 | 7 | ![Portada](https://github.com/JhonControl/ESP8266_Industrial_ModbusTCP_V2/blob/master/extras/NewModbusTCPESP_ESP8266.jpg) 8 | 9 | Has been implemented library Ticker routines to execute code without affecting MODBUS communication, thus creating logic, read and write I / O analog and digital is provided 10 | 11 | Se ha implementado la libreria Ticker para ejecutar rutinas de codigo sin afectar la comunicacion modbus, de este modo se facilita la creacion de logica, lectura y escritura de I/O analogas y digitales 12 | 13 | # Simulation and ESP8266 14 | 15 | This test validated the reading and writing records between ESP8266 modbus and modbus simulator configured as master. 16 | 17 | Esta prueba validara la lectura y escritura de registros modbus entre ESP8266 y un simulador modbus configurado como maestro. 18 | 19 | ![Portada](https://github.com/JhonControl/ESP8266_Industrial_ModbusTCP_V2/blob/master/extras/Test_ESP8266_ModbusTCP.jpg) 20 | 21 | 22 | # Red Industrial - Industrial network - Modbus TCP 23 | ![Portada](https://github.com/JhonControl/ESP8266_Industrial_ModbusTCP_V2/blob/master/extras/Modbus_ESP8266_Arquic_PDAControl.JPG) 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /extras/Modbus_ESP8266_Arquic_PDAControl.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JhonControl/ESP8266_Industrial_ModbusTCP_V2/5e5aac47828e84af6f1be4f339714184dfcde949/extras/Modbus_ESP8266_Arquic_PDAControl.JPG -------------------------------------------------------------------------------- /extras/NewModbusTCPESP_ESP8266.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JhonControl/ESP8266_Industrial_ModbusTCP_V2/5e5aac47828e84af6f1be4f339714184dfcde949/extras/NewModbusTCPESP_ESP8266.jpg -------------------------------------------------------------------------------- /extras/Test_ESP8266_ModbusTCP.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JhonControl/ESP8266_Industrial_ModbusTCP_V2/5e5aac47828e84af6f1be4f339714184dfcde949/extras/Test_ESP8266_ModbusTCP.jpg --------------------------------------------------------------------------------