Skip to content

Commit 7520009

Browse files
committed
Callback API changed. Examples renamed.
1 parent 48ff2fa commit 7520009

File tree

15 files changed

+425
-280
lines changed

15 files changed

+425
-280
lines changed

API.md

Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
# Modbus Library for ESP8266/ESP32
2+
3+
## API
4+
5+
### Add [multiple] regs
6+
7+
```c
8+
bool addHreg(uint16_t offset, uint16_t value = 0, uint16_t numregs = 1);
9+
bool addCoil(uint16_t offset, bool value = false, uint16_t numregs = 1);
10+
bool addIsts(uint16_t offset, bool value = false, uint16_t numregs = 1);
11+
bool addIreg(uint16_t offset, uint16_t value = 0, uint16_t nemregs = 1);
12+
```
13+
14+
### Write regs
15+
16+
```c
17+
bool Hreg(uint16_t offset, uint16_t value);
18+
bool Coil(uint16_t offset, bool value);
19+
bool Ists(uint16_t offset, bool value);
20+
bool Ireg(uint16_t offset, uint16_t value);
21+
```
22+
23+
### Read regs
24+
25+
```c
26+
uint16_t Hreg(uint16_t offset);
27+
bool Coil(uint16_t offset);
28+
bool Ists(uint16_t offset);
29+
uint16_t Ireg(uint16_t offset);
30+
```
31+
32+
### Callbacks
33+
34+
```c
35+
void cbEnable(bool state = TRUE);
36+
void cbDisable();
37+
```
38+
39+
Callback generation control. Callback generation is enabled by default.
40+
41+
```c
42+
void onConnect(cbModbusConnect cb)
43+
```
44+
45+
*ModbusIP only.* Assign callback function on new incoming connection event.
46+
47+
```c
48+
typedef bool (*cbModbusConnect)(IPAddress ip)
49+
```
50+
51+
Connect event callback function definition. Client IP address is passed as argument.
52+
53+
```c
54+
typedef uint16_t (*cbModbus)(TRegister* reg, uint16_t val)
55+
```
56+
57+
Get/Set register callback function definition. Pointer to TRegister structure (see source for details) of the register and new value are passed as arguments.
58+
59+
60+
```c
61+
bool onSetCoil(uint16_t address, cbModbus cb = cbDefault, uint16_t numregs = 1);
62+
bool onSetHreg(uint16_t address, cbModbus cb = cbDefault, uint16_t numregs = 1);
63+
bool onSetIsts(uint16_t address, cbModbus cb = cbDefault, uint16_t numregs = 1);
64+
bool onSetIreg(uint16_t address, cbModbus cb = cbDefault, uint16_t numregs = 1);
65+
```
66+
67+
Assign callback function on register modify event. Multiple sequental registers can be affected by specifing `numregs` parameter. Call in `onSetCoil(regId)` form to disconnect callback.
68+
69+
70+
```c
71+
bool onGetCoil(uint16_t address, cbModbus cb = cbDefault, uint16_t numregs = 1);
72+
bool onGetHreg(uint16_t address, cbModbus cb = cbDefault, uint16_t numregs = 1);
73+
bool onGetIsts(uint16_t address, cbModbus cb = cbDefault, uint16_t numregs = 1);
74+
bool onGetIreg(uint16_t address, cbModbus cb = cbDefault, uint16_t numregs = 1);
75+
```
76+
77+
Assign callback function on register query event. Multiple sequental registers can be affected by specifing `numregs` parameter. Call in `onGet(regId)` form to disconnect callback.
78+
79+
### Macros
80+
81+
```c
82+
#define COIL_VAL(v)
83+
#define COIL_BOOL(v)
84+
#define ISTS_VAL(v)
85+
#define ISTS_BOOL(v)
86+
```
87+
88+
### ModBus IP specific
89+
90+
```c
91+
void begin();
92+
void task();
93+
```
94+
95+
### Callback example
96+
97+
```c
98+
ModbusIP mb;
99+
bool coil = false; // Define external variable to get/set value
100+
uint16_t cbCoilSet(TRegister* reg, uint16_t val) { // 'reg' is pointer to reg to modify, 'val' is new register value
101+
coil = COIL_BOOL(val);
102+
return val; // Returns value to be saved to TRegister structure
103+
}
104+
uint16_t cbCoilGet(TRegister* reg, uint16_t val) {
105+
return COIL_VAL(coil); // Returns value to be returned to ModBus master as reply for current request
106+
}
107+
bool cbConn(IPAddress ip) {
108+
Serial.println(ip);
109+
return true; // Return 'true' to allow connection or 'false' to drop connection
110+
}
111+
ModbusIP mb; // ModbusIP object
112+
void setup() {
113+
...
114+
mb.onConnect(cbConn); // Add callback on connection event
115+
mb.begin();
116+
mb.addCoil(COIL_NR); // Add Coil
117+
mb.onSetCoil(COIL_NR, cbCoilSet); // Add callback on Coil COIL_NR value set
118+
mb.onGetCoil(COIL_NR, cbCoilGet); // Add callback on Coil COIL_NR value get
119+
...
120+
}
121+
void loop() {
122+
...
123+
mb.task();
124+
...
125+
}
126+
```
127+
128+
129+
## Contributions
130+
131+
https://github.com/emelianov/modbus-esp8266
132+
133+
134+
135+
Original version:
136+
137+
http://github.com/andresarmento/modbus-esp8266
138+
139+
prof (at) andresarmento (dot) com
140+
141+
## License
142+
143+
The code in this repo is licensed under the BSD New License. See LICENSE.txt for more info.

README.md

Lines changed: 34 additions & 131 deletions
Original file line numberDiff line numberDiff line change
@@ -5,153 +5,56 @@ used in industrial automation and can be used in other areas, such as home autom
55

66
The Modbus generally uses serial RS-232 or RS-485 as physical layer (then called Modbus Serial) and TCP/IP via Ethernet or WiFi (Modbus IP).
77

8-
In the current version the library allows the ESP8266/ESP32 operate as a slave, supporting Modbus IP via wireless network. For more information about Modbus see:
8+
In the current version the library allows the ESP8266/ESP32 operate async as a slave, supporting Modbus IP via wireless network. For more information about Modbus see:
99

10-
http://pt.wikipedia.org/wiki/Modbus http://www.modbus.org/docs/Modbus_Application_Protocol_V1_1b.pdf
10+
http://pt.wikipedia.org/wiki/Modbus
11+
http://www.modbus.org/docs/Modbus_Application_Protocol_V1_1b.pdf
1112
http://www.modbus.org/docs/Modbus_Messaging_Implementation_Guide_V1_0b.pdf
1213

1314
## Features
1415

15-
<ul>
16-
<li>Operates as a slave</li>
17-
<li>Supports Modbus IP (TCP)</li>
18-
<li>Reply exception messages for all supported functions</li>
19-
<li>Modbus functions supported:</li>
20-
<ul>
21-
<li>0x01 - Read Coils</li>
22-
<li>0x02 - Read Input Status (Read Discrete Inputs)</li>
23-
<li>0x03 - Read Holding Registers</li>
24-
<li>0x04 - Read Input Registers</li>
25-
<li>0x05 - Write Single Coil</li>
26-
<li>0x06 - Write Single Register</li>
27-
<li>0x0F - Write Multiple Coils</li>
28-
<li>0x10 - Write Multiple Registers</li>
29-
</ul>
30-
<li>Callbacks for</li>
31-
<ul>
32-
<li> - Incoming IP connection</li>
33-
<li> - Read specific Register</li>
34-
<li> - Write specific Register</li>
35-
</ul>
36-
</ul>
37-
38-
<b>Notes:</b>
16+
* Supported platforms are
17+
* ESP8266
18+
* ESP32
19+
* Operates as a slave
20+
* Fully async operations. No loop locks.
21+
* Supports Modbus IP (TCP)
22+
* Reply exception messages for all supported functions
23+
* Modbus functions supported:
24+
* 0x01 - Read Coils
25+
* 0x02 - Read Input Status (Read Discrete Inputs)
26+
* 0x03 - Read Holding Registers
27+
* 0x04 - Read Input Registers
28+
* 0x05 - Write Single Coil
29+
* 0x06 - Write Single Register
30+
* 0x0F - Write Multiple Coils
31+
* 0x10 - Write Multiple Registers
32+
* Callbacks for
33+
* Incoming IP connection
34+
* Read specific Register
35+
* Write specific Register
36+
37+
## Notes:
3938

4039
1. When using Modbus IP the transport protocol is TCP (port 502).
4140

42-
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)
43-
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
44-
(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.
45-
46-
3. Early in the library Modbus.h file there is an option to limit the operation
47-
to the functions of Holding Registers, saving space in the program memory.
48-
Just comment out the following line:
49-
50-
```
51-
#define USE_HOLDING_REGISTERS_ONLY
52-
```
53-
Thus, only the following functions are supported:
54-
<ul>
55-
<li>0x03 - Read Holding Registers</li>
56-
<li>0x06 - Write Single Register</li>
57-
<li>0x10 - Write Multiple Registers</li>
58-
</ul>
59-
60-
61-
## API
62-
63-
### Add [multiple] regs
64-
```
65-
bool addReg(uint16_t address, uint16_t value = 0, uint16_t numregs = 1)
66-
bool addHreg(uint16_t offset, uint16_t value = 0, uint16_t numregs = 1)
67-
bool addCoil(uint16_t offset, bool value = false, uint16_t numregs = 1)
68-
bool addIsts(uint16_t offset, bool value = false, uint16_t numregs = 1)
69-
bool addIreg(uint16_t offset, uint16_t value = 0, uint16_t nemregs = 1)
70-
```
71-
### Write regs
72-
```
73-
bool Reg(uint16_t address, uint16_t value)
74-
bool Hreg(uint16_t offset, uint16_t value)
75-
bool Coil(uint16_t offset, bool value)
76-
bool Ists(uint16_t offset, bool value)
77-
bool Ireg(uint16_t offset, uint16_t value)
78-
```
79-
### Read regs
80-
```
81-
uint16_t Reg(uint16_t address)
82-
uint16_t Hreg(uint16_t offset)
83-
bool Coil(uint16_t offset)
84-
bool Ists(uint16_t offset)
85-
uint16_t Ireg(uint16_t offset)
86-
```
87-
### Callbacks
88-
```
89-
bool onGet(uint16_t address, cbModbus cb = cbDefault, uint16_t numregs = 1)
90-
bool onSet(uint16_t address, cbModbus cb = cbDefault, uint16_t numregs = 1)
91-
void onConnect(cbModbusConnect cb)
92-
typedef uint16_t (*cbModbus)(TRegister* reg, uint16_t val)
93-
typedef bool (*cbModbusConnect)(IPAddress ip)
94-
```
95-
### Macros
96-
```
97-
#define COIL(n)
98-
#define ISTS(n)
99-
#define IREG(n)
100-
#define HREG(n)
101-
#define COIL_VAL(v)
102-
#define COIL_BOOL(v)
103-
#define ISTS_VAL(v)
104-
#define ISTS_BOOL(v)
105-
```
106-
### ModBus IP specific
107-
```
108-
void begin()
109-
void task()
110-
```
111-
112-
### Callback example
113-
114-
```
115-
bool coil = false; // Define external variable to get/set value
116-
uint16_t cbCoilSet(TRegister* reg, uint16_t val) { // 'reg' is pointer to reg to modify, 'val' is new register value
117-
coil = COIL_BOOL(val);
118-
return val; // Returns value to be saved to TRegister structure
119-
}
120-
uint16_t cbCoilGet(TRegister* reg, uint16_t val) {
121-
return COIL_VAL(coil); // Returns value to be returned to ModBus master as reply for current request
122-
}
123-
bool cbConn(IPAddress ip) {
124-
Serial.println(ip);
125-
return true; // Return 'true' to allow connection or 'false' to drop connection
126-
}
127-
ModbusIP mb; // ModbusIP object
128-
void setup() {
129-
...
130-
mb.onConnect(cbConn); // Add callback on connection event
131-
mb.begin();
132-
mb.addCoil(COIL_NR); // Add Coil
133-
mb.onSet(COIL(COIL_NR), cbCoilSet); // Add callback on Coil COIL_NR value set
134-
mb.onGet(COIL(COIL_NR), cbCoilGet); // Add callback on Coil COIL_NR value get
135-
...
136-
}
137-
void loop() {
138-
...
139-
mb.task();
140-
...
141-
}
142-
```
41+
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)
42+
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](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.
14343

44+
For API specefication see [API.md](https://githab.com/emelianov/modbus-esp8266/API/md)
14445

14546
## Contributions
14647

147-
https://github.com/emelianov/modbus-esp8266<br>
48+
https://github.com/emelianov/modbus-esp8266
49+
14850
14951

150-
Original version:<br>
151-
http://github.com/andresarmento/modbus-esp8266<br>
52+
Original version:
53+
54+
http://github.com/andresarmento/modbus-esp8266
55+
15256
prof (at) andresarmento (dot) com
15357

15458
## License
15559

15660
The code in this repo is licensed under the BSD New License. See LICENSE.txt for more info.
157-

examples/TestAnalogInput/TestAnalogInput.ino renamed to examples/AnalogInput/AnalogInput.ino

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
Modbus-Arduino Example - Test Holding Register (Modbus IP ESP8266)
2+
Modbus-Arduino Example - Test Analog Input (Modbus IP ESP8266)
33
Read Analog sensor on Pin ADC (ADC input between 0 ... 1V)
44
Original library
55
Copyright by André Sarmento Barbosa
@@ -12,7 +12,7 @@
1212

1313
#ifdef ESP8266
1414
#include <ESP8266WiFi.h>
15-
#else
15+
#else //ESP32
1616
#include <WiFi.h>
1717
#endif
1818
#include <ModbusIP_ESP8266.h>
@@ -26,7 +26,11 @@ ModbusIP mb;
2626
long ts;
2727

2828
void setup() {
29+
#ifdef ESP8266
2930
Serial.begin(74880);
31+
#else
32+
Serial.begin(115200);
33+
#endif
3034

3135
WiFi.begin("your_ssid", "your_password");
3236
while (WiFi.status() != WL_CONNECTED) {
@@ -56,4 +60,5 @@ void loop() {
5660
//Setting raw value (0-1024)
5761
mb.Ireg(SENSOR_IREG, analogRead(A0));
5862
}
63+
delay(100);
5964
}

0 commit comments

Comments
 (0)