Skip to content

Commit 4bd9f0b

Browse files
committed
Initial commit
0 parents  commit 4bd9f0b

File tree

12 files changed

+514
-0
lines changed

12 files changed

+514
-0
lines changed

LICENSE.txt

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
Copyright (c) 2015, Andr� Sarmento Barbosa
2+
All rights reserved.
3+
4+
Redistribution and use in source and binary forms, with or without modification,
5+
are permitted provided that the following conditions are met:
6+
7+
1. Redistributions of source code must retain the above copyright notice, this
8+
list of conditions and the following disclaimer.
9+
10+
2. Redistributions in binary form must reproduce the above copyright notice, this
11+
list of conditions and the following disclaimer in the documentation and/or other
12+
materials provided with the distribution.
13+
14+
3. Neither the name of the copyright holder nor the names of its contributors may
15+
be used to endorse or promote products derived from this software without
16+
specific prior written permission.
17+
18+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
19+
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20+
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21+
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
22+
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23+
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24+
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25+
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26+
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27+
POSSIBILITY OF SUCH DAMAGE.

README.md

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
Modbus Library for ESP8266
2+
==========================
3+
4+
This library allows your ESP8266 to communicate via Modbus protocol. The Modbus is a master-slave protocol
5+
used in industrial automation and can be used in other areas, such as home automation.
6+
7+
The Modbus generally uses serial RS-232 or RS-485 as physical layer (then called Modbus Serial) and
8+
TCP/IP via Ethernet or WiFi (Modbus IP).
9+
10+
In the current version the library allows the Arduino operate as a slave, supporting Modbus over IP. For more information about Modbus see:
11+
12+
http://pt.wikipedia.org/wiki/Modbus http://www.modbus.org/docs/Modbus_Application_Protocol_V1_1b.pdf
13+
http://www.modbus.org/docs/Modbus_Messaging_Implementation_Guide_V1_0b.pdf
14+
15+
Features
16+
========
17+
18+
<ul>
19+
<li>Operates as a slave</li>
20+
<li>Supports Modbus IP (TCP, not keep-alive)</li>
21+
<li>Reply exception messages for all supported functions</li>
22+
<li>Modbus functions supported:</li>
23+
<ul>
24+
<li>0x01 - Read Coils</li>
25+
<li>0x02 - Read Input Status (Read Discrete Inputs)</li>
26+
<li>0x03 - Read Holding Registers</li>
27+
<li>0x04 - Read Input Registers</li>
28+
<li>0x05 - Write Single Coil</li>
29+
<li>0x06 - Write Single Register</li>
30+
<li>0x0F - Write Multiple Coils</li>
31+
<li>0x10 - Write Multiple Registers</li>
32+
</ul>
33+
</ul>
34+
35+
<b>Notes:</b>
36+
37+
1. When using Modbus IP the transport protocol is TCP (port 502) and the connection is terminated to each transmitted message, that is, is not a keep-alive type connection.
38+
39+
2. The offsets for registers are 0-based. So be careful when setting your supervisory system or your testing software. For example, in ScadaBR (http://www.scadabr.com.br)
40+
offsets are 0-based, then, a register configured as 100 in the library is set to 100 in ScadaBR. On the other hand, in the CAS Modbus Scanner
41+
(http://www.chipkin.com/products/software/modbus-software/cas-modbus-scanner/) offsets are 1-based, so a register configured as 100 in library should be 101 in this software.
42+
43+
3. Early in the library Modbus.h file there is an option to limit the operation
44+
to the functions of Holding Registers, saving space in the program memory.
45+
Just comment out the following line:
46+
47+
```
48+
#define USE_HOLDING_REGISTERS_ONLY
49+
```
50+
Thus, only the following functions are supported:
51+
<ul>
52+
<li>0x03 - Read Holding Registers</li>
53+
<li>0x06 - Write Single Register</li>
54+
<li>0x10 - Write Multiple Registers</li>
55+
</ul>
56+
57+
58+
How to
59+
======
60+
61+
62+
Contributions
63+
=============
64+
http://github.com/andresarmento/modbus-esp8266<br>
65+
prof (at) andresarmento (dot) com
66+
67+
License
68+
=======
69+
The code in this repo is licensed under the BSD New License. See LICENSE.txt for more info.
70+

README_pt_BR.md

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
Biblioteca Modbus para ESP8266
2+
==============================
3+
4+
Esta biblioteca permite que seu ESP8266 se comunique através do protocolo Modbus.
5+
O Modbus é um protocolo do tipo mestre-escravo, utilizado em automação industrial,
6+
podendo ser utilizado em outras áreas, como por exemplo, na automação residencial.
7+
8+
O Modbus geralmente utiliza como meio físico as interfaces seriais RS-232 ou RS-485
9+
(quando é chamado Modbus Serial) e TCP/IP via Ethernet ou WiFi (Modbus IP).
10+
11+
Na versão atual a biblioteca permite que o arduino opere como escravo, suportando
12+
tando Modbus IP via rede wireless. Para mais informações sobre o Modbus consulte:
13+
14+
http://pt.wikipedia.org/wiki/Modbus
15+
http://www.modbus.org/docs/Modbus_Application_Protocol_V1_1b.pdf
16+
http://www.modbus.org/docs/Modbus_Messaging_Implementation_Guide_V1_0b.pdf
17+
18+
Características
19+
===============
20+
21+
<ul>
22+
<li>Opera como escravo</li>
23+
<li>Suporta Modbus IP (TCP não keep-alive)</li>
24+
<li>Responde todos os tipos de exceção para as funções suportadas</li>
25+
<li>Suporta as seguintes funções Modbus:</li>
26+
<ul>
27+
<li>0x01 - Read Coils</li>
28+
<li>0x02 - Read Input Status (Read Discrete Inputs)</li>
29+
<li>0x03 - Read Holding Registers</li>
30+
<li>0x04 - Read Input Registers</li>
31+
<li>0x05 - Write Single Coil</li>
32+
<li>0x06 - Write Single Register</li>
33+
<li>0x0F - Write Multiple Coils</li>
34+
<li>0x10 - Write Multiple Registers</li>
35+
</ul>
36+
</ul>
37+
38+
<b>Observações:</b>
39+
40+
1. Quando se usa Modbus IP o protocolo de transporte é o TCP (porta 502) e a conexão
41+
é finalizada a cada mensagem transmitida, ou seja, não é do tipo keep-alive.
42+
43+
2. Os offsets para acesso aos registradores são baseados em 0. Assim, tenha cuidado
44+
ao configurar seu seu supervisório ou utilitário de teste. Por exempo, no ScadaBR
45+
(http://www.scadabr.com.br) os offsets são baseados em 0, então, um registrador
46+
configurado como 100 na biblioteca será configurado como 100 no ScadaBR. Por outro
47+
lado, no software de teste CAS Modbus Scanner (http://www.chipkin.com/products/software/modbus-software/cas-modbus-scanner/)
48+
os offsets são baseados em 1, logo, um registrador configurado como 100 na biblioteca
49+
deverá ser 101 neste software.
50+
51+
3. No início do arquivo Modbus.h da biblioteca há uma opção para limitar o funcionamento
52+
da mesma às funções de Holding Registers, salvando espaço na memória de programa.
53+
Basta retirar o comentário da seguinte linha:
54+
55+
```
56+
#define USE_HOLDING_REGISTERS_ONLY
57+
```
58+
Dessa forma, somente as seguintes funções são suportadas:
59+
<ul>
60+
<li>0x03 - Read Holding Registers</li>
61+
<li>0x06 - Write Single Register</li>
62+
<li>0x10 - Write Multiple Registers</li>
63+
</ul>
64+
65+
Como utilizar
66+
=============
67+
68+
69+
Contribuições
70+
=============
71+
http://github.com/andresarmento/modbus-esp8266<br>
72+
prof (at) andresarmento (dot) com
73+
74+
Licença
75+
=======
76+
77+
O código neste repositório é licenciado pela BSD New License.
78+
Veja [LICENSE.txt](LICENSE.txt) para mais informações.
79+
80+

TODO.txt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
TODO
2+
====
3+
. Modbus for Expressif SDK (in development)
4+
5+
6+
7+
8+
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
/*
2+
ModbusIP_ESP8266.cpp - Source for Modbus IP ESP8266 Library
3+
Copyright (C) 2015 André Sarmento Barbosa
4+
*/
5+
#include "ModbusIP_ESP8266.h"
6+
7+
WiFiServer server(MODBUSIP_PORT);
8+
9+
ModbusIP::ModbusIP() {
10+
11+
}
12+
13+
void ModbusIP::config(const char* ssid, const char* password) {
14+
WiFi.begin(ssid, password);
15+
server.begin();
16+
}
17+
18+
void ModbusIP::task() {
19+
WiFiClient client = server.available();
20+
21+
int raw_len = 0;
22+
23+
if (client) {
24+
if (client.connected()) {
25+
for (int x = 0; x < 300; x++) { // Time to have data available
26+
if (client.available()) {
27+
while (client.available() > raw_len) { //Computes data length
28+
raw_len = client.available();
29+
delay(1);
30+
}
31+
break;
32+
}
33+
delay(10);
34+
}
35+
}
36+
37+
if (raw_len > 7) {
38+
for (int i=0; i<7; i++) _MBAP[i] = client.read(); //Get MBAP
39+
40+
_len = _MBAP[4] << 8 | _MBAP[5];
41+
_len--; // Do not count with last byte from MBAP
42+
if (_MBAP[2] !=0 || _MBAP[3] !=0) return; //Not a MODBUSIP packet
43+
if (_len > MODBUSIP_MAXFRAME) return; //Length is over MODBUSIP_MAXFRAME
44+
_frame = (byte*) malloc(_len);
45+
46+
raw_len = raw_len - 7;
47+
for (int i=0; i< raw_len; i++) _frame[i] = client.read(); //Get Modbus PDU
48+
49+
this->receivePDU(_frame);
50+
client.flush();
51+
52+
if (_reply != MB_REPLY_OFF) {
53+
//MBAP
54+
_MBAP[4] = (_len+1) >> 8; //_len+1 for last byte from MBAP
55+
_MBAP[5] = (_len+1) & 0x00FF;
56+
57+
size_t send_len = (unsigned int)_len + 7;
58+
uint8_t sbuf[send_len];
59+
60+
for (int i=0; i<7; i++) sbuf[i] = _MBAP[i];
61+
for (int i=0; i<_len; i++) sbuf[i+7] = _frame[i];
62+
63+
client.write(sbuf, send_len);
64+
}
65+
66+
client.stop();
67+
free(_frame);
68+
_len = 0;
69+
}
70+
}
71+
}
72+
/*
73+
uint8_t buffer[128] = {0};
74+
uint8_t mux_id;
75+
uint32_t len = _wifi->recv(&mux_id, buffer, sizeof(buffer), 100);
76+
77+
if (len > 0) {
78+
int i = 0;
79+
while (i < 7) {
80+
_MBAP[i] = buffer[i];
81+
i++;
82+
}
83+
84+
_len = _MBAP[4] << 8 | _MBAP[5];
85+
_len--; // Do not count with last byte from MBAP
86+
if (_MBAP[2] !=0 || _MBAP[3] !=0) return; //Not a MODBUSIP packet
87+
if (_len > MODBUSIP_MAXFRAME) return; //Length is over MODBUSIP_MAXFRAME
88+
89+
_frame = (byte*) malloc(_len);
90+
i = 0;
91+
while (i < _len){
92+
_frame[i] = buffer[7+i]; //Forget MBAP and take just modbus pdu
93+
i++;
94+
}
95+
96+
this->receivePDU(_frame);
97+
98+
if (_reply != MB_REPLY_OFF) {
99+
//MBAP
100+
_MBAP[4] = _len >> 8;
101+
_MBAP[5] = _len | 0x00FF;
102+
buffer[4] = _MBAP[4];
103+
buffer[5] = _MBAP[5];
104+
105+
i = 0;
106+
while (i < _len){
107+
buffer[i+7] = _frame[i];
108+
i++;
109+
}
110+
_wifi->send(mux_id, buffer, _len + 7);
111+
_wifi->releaseTCP(mux_id);
112+
}
113+
114+
free(_frame);
115+
_len = 0;
116+
}
117+
118+
}
119+
*/
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/*
2+
ModbusIP_ESP8266.h - Header for Modbus IP ESP8266 Library
3+
Copyright (C) 2015 André Sarmento Barbosa
4+
*/
5+
#include <Modbus.h>
6+
#include <ESP8266WiFi.h>
7+
8+
#ifndef MODBUSIP_ESP8266_H
9+
#define MODBUSIP_ESP8266_H
10+
11+
#define MODBUSIP_PORT 502
12+
#define MODBUSIP_MAXFRAME 200
13+
#define MODBUSIP_TIMEOUT 10
14+
15+
class ModbusIP : public Modbus {
16+
private:
17+
byte _MBAP[7];
18+
public:
19+
ModbusIP();
20+
void config(const char* ssid, const char* password);
21+
void task();
22+
};
23+
24+
#endif //MODBUSIP_ESP8266_H
25+
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
/*
2+
Modbus-Arduino Example - Test Holding Register (Modbus IP ESP8266)
3+
Read Analog sensor on Pin ADC (ADC input between 0 ... 1V)
4+
Copyright by André Sarmento Barbosa
5+
http://github.com/andresarmento/modbus-arduino
6+
*/
7+
8+
#include <ESP8266WiFi.h>
9+
#include <Modbus.h>
10+
#include <ModbusIP_ESP8266.h>
11+
12+
//Modbus Registers Offsets (0-9999)
13+
const int SENSOR_IREG = 100;
14+
15+
//ModbusIP object
16+
ModbusIP mb;
17+
18+
long ts;
19+
20+
void setup() {
21+
Serial.begin(115200);
22+
23+
//Config Modbus IP
24+
mb.config("your_ssid", "your_password");
25+
26+
while (WiFi.status() != WL_CONNECTED) {
27+
delay(500);
28+
Serial.print(".");
29+
}
30+
31+
Serial.println("");
32+
Serial.println("WiFi connected");
33+
Serial.println("IP address: ");
34+
Serial.println(WiFi.localIP());
35+
36+
// Add SENSOR_IREG register - Use addIreg() for analog Inputs
37+
mb.addIreg(SENSOR_IREG);
38+
39+
ts = millis();
40+
}
41+
42+
void loop() {
43+
//Call once inside loop() - all magic here
44+
mb.task();
45+
46+
//Read each two seconds
47+
if (millis() > ts + 2000) {
48+
ts = millis();
49+
//Setting raw value (0-1024)
50+
mb.Ireg(SENSOR_IREG, analogRead(A0));
51+
}
52+
}

0 commit comments

Comments
 (0)