First commit
This commit is contained in:
2641
firmware/Modbus-Serial/Doxyfile
Normal file
2641
firmware/Modbus-Serial/Doxyfile
Normal file
File diff suppressed because it is too large
Load Diff
27
firmware/Modbus-Serial/LICENSE
Normal file
27
firmware/Modbus-Serial/LICENSE
Normal file
@@ -0,0 +1,27 @@
|
||||
Copyright (c) 2015, Andr<64> Sarmento Barbosa
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice, this
|
||||
list of conditions and the following disclaimer in the documentation and/or other
|
||||
materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder nor the names of its contributors may
|
||||
be used to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
140
firmware/Modbus-Serial/README.md
Normal file
140
firmware/Modbus-Serial/README.md
Normal file
@@ -0,0 +1,140 @@
|
||||
# Modbus Serial Library for Arduino
|
||||
Over Serial Line Implementation RTU (OSI 2/OSI 1)
|
||||
|
||||
[](https://github.com/epsilonrt/modbus-serial/releases)
|
||||
[](https://registry.platformio.org/libraries/epsilonrt/modbus-serial)
|
||||
[](https://www.arduinolibraries.info/libraries/modbus-serial)
|
||||
|
||||
[](https://www.arduino.cc/)
|
||||
[](https://github.com/epsilonrt/modbus-serial/actions/workflows/build_uno.yml)
|
||||
[](https://github.com/epsilonrt/modbus-serial/actions/workflows/build_due.yml)
|
||||
[](https://github.com/epsilonrt/modbus-serial/actions/workflows/build_mega.yml)
|
||||
[](https://github.com/epsilonrt/modbus-serial/actions/workflows/build_nano33iot.yml)
|
||||
[](https://github.com/epsilonrt/modbus-serial/actions/workflows/build_teensy.yml)
|
||||
[](https://github.com/epsilonrt/modbus-serial/actions/workflows/build_esp8266.yml)
|
||||
[](https://github.com/epsilonrt/modbus-serial/actions/workflows/build_esp32.yml)
|
||||
|
||||
|
||||
---
|
||||
|
||||
This library allows your Arduino to communicate via Modbus protocol. The Modbus is a master-slave protocol
|
||||
used in industrial automation and can be used in other areas, such as home automation.
|
||||
|
||||
In the current version the library allows the Arduino operate **as a slave**, supporting Modbus over Serial Line RTU.
|
||||
|
||||
## How to
|
||||
|
||||
There are four classes corresponding to five headers that may be used:
|
||||
|
||||
* [Modbus-Arduino](http://github.com/epsilonrt/modbus-arduino ) - Base Library
|
||||
* Modbus-Serial - Modbus Serial RTU Library (this repository)
|
||||
* [Modbus-Ethernet](https://github.com/epsilonrt/modbus-ethernet) - Modbus TCP Library (standard Ethernet Shield)
|
||||
* [Modbus-EtherCard](https://github.com/epsilonrt/modbus-ethercard) - Modbus TCP Library (for ENC28J60 chip)
|
||||
* [Modbus-Esp8266AT](https://github.com/epsilonrt/modbus-esp8266at) - Modbus IP Library (for ESP8266 chip with AT firmware)
|
||||
|
||||
By opting for Modbus Serial or Modbus TCP you must include in your sketch the corresponding header, eg:
|
||||
|
||||
#include <ModbusSerial.h>
|
||||
|
||||
## Modbus-Serial
|
||||
|
||||
There are five examples that can be accessed from the Arduino IDE or Visual
|
||||
Studio Code with Platformio, once you have installed the library.
|
||||
Let's look at the example Lamp.ino (only the parts concerning Modbus will be commented):
|
||||
|
||||
#include <ModbusSerial.h>
|
||||
|
||||
Inclusion of the necessary header.
|
||||
|
||||
const int Lamp1Coil = 0;
|
||||
|
||||
Sets the Modbus register to represent a lamp or LED. This value is the offset (0-based) to be placed in its supervisory or testing software.
|
||||
Note that if your software uses offsets 1-based the set value there should be 1, for this example.
|
||||
|
||||
ModbusSerial mb (Serial, SlaveId);
|
||||
|
||||
Create the mb instance (ModbusSerial) to be used with the serial port `Serial`.
|
||||
Note that the serial port is passed as reference, which permits the use of other
|
||||
serial ports in other Arduino models, also ets the slave Id.
|
||||
|
||||
If you are using RS-485 driver, the configuration of another pin to control
|
||||
transmission/reception is required, this pin would be connected to the DE and
|
||||
/RE pins of the driver. This is done as follows:
|
||||
|
||||
const int TxenPin = 4;
|
||||
// ....
|
||||
ModbusSerial mb (Serial, SlaveId, TxenPin);
|
||||
|
||||
In this case, the pin 4 will be used to control TX/RX (DE must be connected with /RE).
|
||||
|
||||
Serial.begin (Baudrate, MB_PARITY_EVEN);
|
||||
while (! Serial)
|
||||
;
|
||||
|
||||
Configure the serial port and wait for it to be ready.
|
||||
|
||||
To simplify the modification of the port, you can define a macro in the following way :
|
||||
|
||||
#define MySerial Serial // define serial port used, Serial most of the time, or Serial1, Serial2 ... if available
|
||||
|
||||
Then the block above can be written as follows :
|
||||
|
||||
ModbusSerial mb (MySerial, SlaveId, TxenPin);
|
||||
|
||||
void setup() {
|
||||
|
||||
MySerial.begin (Baudrate, MB_PARITY_EVEN); // prefer this line in accordance with the modbus standard.
|
||||
while (! MySerial)
|
||||
;
|
||||
|
||||
mb.config (Baudrate);
|
||||
|
||||
The last line configures the ModbusSerial object.
|
||||
|
||||
mb.addCoil (Lamp1Coil);
|
||||
|
||||
Adds the register type Coil (digital output) that will be responsible for
|
||||
activating the LED or lamp and verify their status.
|
||||
The library allows you to set an initial value for the register:
|
||||
|
||||
mb.addCoil (Lamp1Coil, true);
|
||||
|
||||
In this case the register is added and set to true. If you use the first form
|
||||
the default value is false.
|
||||
|
||||
mb.task ();
|
||||
|
||||
This method makes all magic, answering requests and changing the registers if
|
||||
necessary, it should be called only once, early in the loop.
|
||||
|
||||
digitalWrite (LedPin, mb.coil (Lamp1Coil));
|
||||
|
||||
Finally the value of Lamp1Coil register is used to drive the lamp or LED.
|
||||
|
||||
In much the same way, the other examples show the use of other methods available in the library:
|
||||
|
||||
void addCoil (offset word, bool value)
|
||||
void addHreg (offset word, word value)
|
||||
void addIsts (offset word, bool value)
|
||||
void addIreg (offset word, word value)
|
||||
|
||||
Adds registers and configures initial value if specified.
|
||||
|
||||
bool setCoil (offset word, bool value)
|
||||
bool setHreg (offset word, word value)
|
||||
bool setIsts (offset word, bool value)
|
||||
bool setIReg (offset word, word value)
|
||||
|
||||
Sets a value to the register.
|
||||
|
||||
bool coil (offset word)
|
||||
word hreg (word offset)
|
||||
bool ists (offset word)
|
||||
word ireg (word offset)
|
||||
|
||||
Returns the value of a register.
|
||||
|
||||
License
|
||||
=======
|
||||
The code in this repo is licensed under the BSD New License. See LICENSE for more info.
|
||||
|
47
firmware/Modbus-Serial/examples/Lamp/Lamp.ino
Normal file
47
firmware/Modbus-Serial/examples/Lamp/Lamp.ino
Normal file
@@ -0,0 +1,47 @@
|
||||
/**
|
||||
@file Lamp.ino
|
||||
Modbus-Arduino Example - Lamp (Modbus Serial)
|
||||
Copyright (C) 2023 Pascal JEAN aka epsilonrt
|
||||
Copyright (C) 2014 André Sarmento Barbosa
|
||||
https://github.com/epsilonrt/modbus-serial
|
||||
*/
|
||||
|
||||
#include <ModbusSerial.h>
|
||||
|
||||
// Used Pins
|
||||
const int LedPin = 13; // Change that to match your led
|
||||
const int TxenPin = -1; // -1 disables the feature, change that if you are using an RS485 driver, this pin would be connected to the DE and /RE pins of the driver.
|
||||
|
||||
const byte SlaveId = 10;
|
||||
// Modbus Registers Offsets (0-9999)
|
||||
const int Lamp1Coil = 0;
|
||||
|
||||
#define MySerial Serial // define serial port used, Serial most of the time, or Serial1, Serial2 ... if available
|
||||
const unsigned long Baudrate = 38400;
|
||||
|
||||
// ModbusSerial object
|
||||
ModbusSerial mb (MySerial, SlaveId, TxenPin);
|
||||
|
||||
void setup() {
|
||||
|
||||
MySerial.begin (Baudrate); // works on all boards but the configuration is 8N1 which is incompatible with the MODBUS standard
|
||||
// prefer the line below instead if possible
|
||||
// MySerial.begin (Baudrate, MB_PARITY_EVEN);
|
||||
|
||||
mb.config (Baudrate);
|
||||
mb.setAdditionalServerData ("LAMP"); // for Report Server ID function (0x11)
|
||||
|
||||
// Set LedPin mode
|
||||
pinMode (LedPin, OUTPUT);
|
||||
// Add Lamp1Coil register - Use addCoil() for digital outputs
|
||||
mb.addCoil (Lamp1Coil);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
|
||||
// Call once inside loop() - all magic here
|
||||
mb.task();
|
||||
|
||||
// Attach LedPin to Lamp1Coil register
|
||||
digitalWrite (LedPin, mb.Coil (Lamp1Coil));
|
||||
}
|
83
firmware/Modbus-Serial/examples/LampDimmer/LampDimmer.ino
Normal file
83
firmware/Modbus-Serial/examples/LampDimmer/LampDimmer.ino
Normal file
@@ -0,0 +1,83 @@
|
||||
/**
|
||||
@file LampDimmer.ino
|
||||
Modbus-Arduino Example - Lamp dimmer (Modbus Serial)
|
||||
Copyright (C) 2023 Pascal JEAN aka epsilonrt
|
||||
https://github.com/epsilonrt/modbus-serial
|
||||
*/
|
||||
|
||||
#include <ModbusSerial.h>
|
||||
|
||||
// Used Pins
|
||||
const int LedPin = 3; // Must be PWM output !
|
||||
const int TxenPin = -1; // -1 disables the feature, change that if you are using an RS485 driver, this pin would be connected to the DE and /RE pins of the driver.
|
||||
|
||||
const byte SlaveId = 11; // our Modbus slave address (1-247)
|
||||
// Modbus Registers Offsets (0-9999), PDU adressing ! from the data model we have to add 1
|
||||
const int Lamp1Coil = 0;
|
||||
const int Lamp1Hreg = 0;
|
||||
|
||||
#define MySerial Serial // define serial port used, Serial most of the time, or Serial1, Serial2 ... if available
|
||||
const unsigned long Baudrate = 38400;
|
||||
|
||||
// ModbusSerial object
|
||||
ModbusSerial mb (MySerial, SlaveId, TxenPin);
|
||||
|
||||
// Lamp status variables
|
||||
bool lampOn = true;
|
||||
word lampDimming = 128;
|
||||
|
||||
void setup() {
|
||||
|
||||
MySerial.begin (Baudrate); // works on all boards but the configuration is 8N1 which is incompatible with the MODBUS standard
|
||||
// prefer the line below instead if possible
|
||||
// MySerial.begin (Baudrate, MB_PARITY_EVEN);
|
||||
|
||||
mb.config (Baudrate);
|
||||
mb.setAdditionalServerData ("LDIMMER"); // for Report Server ID function (0x11)
|
||||
|
||||
// Set LedPin
|
||||
pinMode (LedPin, OUTPUT);
|
||||
mb.addCoil (Lamp1Coil, lampOn);
|
||||
mb.addHreg (Lamp1Hreg, lampDimming);
|
||||
|
||||
// The led flashes 20 times to signal the end of setup,
|
||||
// then it is set to its default state.
|
||||
for (int i = 0; i < 20; i++) {
|
||||
|
||||
digitalWrite (LedPin, HIGH);
|
||||
delay (50);
|
||||
digitalWrite (LedPin, LOW);
|
||||
delay (100);
|
||||
}
|
||||
analogWrite (LedPin, (lampOn ? lampDimming : 0));
|
||||
}
|
||||
|
||||
void loop() {
|
||||
|
||||
// Call once inside loop() - all magic here
|
||||
mb.task();
|
||||
|
||||
if (mb.Coil (Lamp1Coil) != lampOn) {
|
||||
// If coil was modified
|
||||
|
||||
lampOn = mb.Coil (Lamp1Coil);
|
||||
if (lampOn) {
|
||||
|
||||
analogWrite (LedPin, lampDimming);
|
||||
}
|
||||
else {
|
||||
|
||||
analogWrite (LedPin, 0);
|
||||
}
|
||||
}
|
||||
|
||||
if ( (mb.Hreg (Lamp1Hreg) & 0x00FF) != lampDimming) {
|
||||
// If holding register was modified (only LSB will used)
|
||||
|
||||
lampDimming = (mb.Hreg (Lamp1Hreg) & 0x00FF);
|
||||
if (lampOn) {
|
||||
|
||||
analogWrite (LedPin, lampDimming);
|
||||
}
|
||||
}
|
||||
}
|
54
firmware/Modbus-Serial/examples/Servo/Servo.ino
Normal file
54
firmware/Modbus-Serial/examples/Servo/Servo.ino
Normal file
@@ -0,0 +1,54 @@
|
||||
/**
|
||||
@file Servo.ino
|
||||
Copyright (C) 2023 Pascal JEAN aka epsilonrt
|
||||
Copyright (C) 2014 André Sarmento Barbosa
|
||||
https://github.com/epsilonrt/modbus-serial
|
||||
|
||||
Use Servo lib
|
||||
This library only supports boards with an AVR, SAM, SAMD, NRF52 or STM32F4 processor.
|
||||
https://registry.platformio.org/libraries/arduino-libraries/Servo
|
||||
*/
|
||||
|
||||
#include <ModbusSerial.h>
|
||||
#include <Servo.h>
|
||||
|
||||
// Used Pins
|
||||
const int servoPin = 9;
|
||||
const int TxenPin = -1; // -1 disables the feature, change that if you are using an RS485 driver, this pin would be connected to the DE and /RE pins of the driver.
|
||||
|
||||
const byte SlaveId = 12;
|
||||
// Modbus Registers Offsets (0-9999)
|
||||
const int ServoHreg = 0;
|
||||
|
||||
#define MySerial Serial // define serial port used, Serial most of the time, or Serial1, Serial2 ... if available
|
||||
const unsigned long Baudrate = 38400;
|
||||
|
||||
// ModbusSerial object
|
||||
ModbusSerial mb (MySerial, SlaveId, TxenPin);
|
||||
// Servo object
|
||||
Servo servo;
|
||||
|
||||
void setup() {
|
||||
|
||||
MySerial.begin (Baudrate); // works on all boards but the configuration is 8N1 which is incompatible with the MODBUS standard
|
||||
// prefer the line below instead if possible
|
||||
// MySerial.begin (Baudrate, MB_PARITY_EVEN);
|
||||
|
||||
mb.config (Baudrate);
|
||||
mb.setAdditionalServerData ("SWITCH"); // for Report Server ID function (0x11)
|
||||
|
||||
// Attaches the servo pin to the servo object
|
||||
servo.attach (servoPin);
|
||||
// Add ServoHreg register - Use addHreg() for analog outpus or to store values in device
|
||||
mb.addHreg (ServoHreg, 127);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
|
||||
//Call once inside loop() - all magic here
|
||||
mb.task();
|
||||
|
||||
//Attach switchPin to SWITCH_ISTS register
|
||||
servo.write (mb.Hreg (ServoHreg));
|
||||
delay (15);
|
||||
}
|
46
firmware/Modbus-Serial/examples/Switch/Switch.ino
Normal file
46
firmware/Modbus-Serial/examples/Switch/Switch.ino
Normal file
@@ -0,0 +1,46 @@
|
||||
/**
|
||||
@file Switch.ino
|
||||
Modbus-Arduino Example - Switch (Modbus Serial)
|
||||
Copyright (C) 2023 Pascal JEAN aka epsilonrt
|
||||
Copyright (C) 2014 André Sarmento Barbosa
|
||||
https://github.com/epsilonrt/modbus-serial
|
||||
*/
|
||||
|
||||
#include <ModbusSerial.h>
|
||||
|
||||
// Used Pins
|
||||
const int SwitchPin = 3;
|
||||
const int TxenPin = -1; // -1 disables the feature, change that if you are using an RS485 driver, this pin would be connected to the DE and /RE pins of the driver.
|
||||
|
||||
const byte SlaveId = 13;
|
||||
// Modbus Registers Offsets (0-9999)
|
||||
const int SwitchIsts = 0;
|
||||
|
||||
#define MySerial Serial // define serial port used, Serial most of the time, or Serial1, Serial2 ... if available
|
||||
const unsigned long Baudrate = 38400;
|
||||
|
||||
// ModbusSerial object
|
||||
ModbusSerial mb (MySerial, SlaveId, TxenPin);
|
||||
|
||||
void setup() {
|
||||
|
||||
MySerial.begin (Baudrate); // works on all boards but the configuration is 8N1 which is incompatible with the MODBUS standard
|
||||
// prefer the line below instead if possible
|
||||
// MySerial.begin (Baudrate, MB_PARITY_EVEN);
|
||||
|
||||
mb.config (Baudrate);
|
||||
mb.setAdditionalServerData ("SWITCH"); // for Report Server ID function (0x11)
|
||||
|
||||
// Set SwitchPin mode
|
||||
pinMode (SwitchPin, INPUT);
|
||||
// Add SwitchIsts register - Use addIsts() for digital inputs
|
||||
mb.addIsts (SwitchIsts);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
//Call once inside loop() - all magic here
|
||||
mb.task();
|
||||
|
||||
//Attach SwitchPin to SwitchIsts register
|
||||
mb.Ists (SwitchIsts, digitalRead (SwitchPin));
|
||||
}
|
55
firmware/Modbus-Serial/examples/TempSensor/TempSensor.ino
Normal file
55
firmware/Modbus-Serial/examples/TempSensor/TempSensor.ino
Normal file
@@ -0,0 +1,55 @@
|
||||
/**
|
||||
@file TempSensor.ino
|
||||
Modbus-Arduino Example - TempSensor (Modbus Serial)
|
||||
Copyright (C) 2023 Pascal JEAN aka epsilonrt
|
||||
Copyright (C) 2014 André Sarmento Barbosa
|
||||
https://github.com/epsilonrt/modbus-serial
|
||||
*/
|
||||
|
||||
#include <ModbusSerial.h>
|
||||
|
||||
// Used Pins
|
||||
const int SensorPin = A0;
|
||||
const int TxenPin = -1; // -1 disables the feature, change that if you are using an RS485 driver, this pin would be connected to the DE and /RE pins of the driver.
|
||||
|
||||
const byte SlaveId = 14;
|
||||
// Modbus Registers Offsets (0-9999)
|
||||
const int SensorIreg = 0;
|
||||
|
||||
#define MySerial Serial // define serial port used, Serial most of the time, or Serial1, Serial2 ... if available
|
||||
const unsigned long Baudrate = 38400;
|
||||
|
||||
// ModbusSerial object
|
||||
ModbusSerial mb (MySerial, SlaveId, TxenPin);
|
||||
|
||||
long ts;
|
||||
|
||||
void setup() {
|
||||
|
||||
MySerial.begin (Baudrate); // works on all boards but the configuration is 8N1 which is incompatible with the MODBUS standard
|
||||
// prefer the line below instead if possible
|
||||
// MySerial.begin (Baudrate, MB_PARITY_EVEN);
|
||||
|
||||
mb.config (Baudrate);
|
||||
mb.setAdditionalServerData ("TEMP_SENSOR"); // for Report Server ID function (0x11)
|
||||
|
||||
|
||||
// Add SensorIreg register - Use addIreg() for analog Inputs
|
||||
mb.addIreg (SensorIreg);
|
||||
|
||||
ts = millis();
|
||||
}
|
||||
|
||||
void loop() {
|
||||
|
||||
// Call once inside loop() - all magic here
|
||||
mb.task();
|
||||
|
||||
// Read each two seconds
|
||||
if (millis() > ts + 2000) {
|
||||
|
||||
ts = millis();
|
||||
// Setting raw value (0-1024)
|
||||
mb.Ireg (SensorIreg, analogRead (SensorPin));
|
||||
}
|
||||
}
|
BIN
firmware/Modbus-Serial/extras/images/modbus.png
Normal file
BIN
firmware/Modbus-Serial/extras/images/modbus.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 17 KiB |
15
firmware/Modbus-Serial/keywords.txt
Normal file
15
firmware/Modbus-Serial/keywords.txt
Normal file
@@ -0,0 +1,15 @@
|
||||
# Syntax Coloring Map For ModbusSerial
|
||||
|
||||
# Datatypes (KEYWORD1)
|
||||
ModbusSerial KEYWORD1
|
||||
|
||||
# Methods and Functions (KEYWORD2)
|
||||
setSlaveId KEYWORD2
|
||||
getSlaveId KEYWORD2
|
||||
config KEYWORD2
|
||||
task KEYWORD2
|
||||
|
||||
# Constants (LITERAL1)
|
||||
MB_PARITY_NONE LITERAL1
|
||||
MB_PARITY_EVEN LITERAL1
|
||||
MB_PARITY_ODD LITERAL1
|
33
firmware/Modbus-Serial/library.json
Normal file
33
firmware/Modbus-Serial/library.json
Normal file
@@ -0,0 +1,33 @@
|
||||
{
|
||||
"name": "Modbus-Serial",
|
||||
"version": "2.0.6",
|
||||
"keywords": "modbus, server, slave, rtu, serial",
|
||||
"description": "A library that allows your Arduino to communicate via Modbus protocol, acting as a slave. Over serial line implementation (OSI 2/OSI 1)",
|
||||
"homepage": "https://epsilonrt.github.io/modbus-serial",
|
||||
"authors":
|
||||
[
|
||||
{
|
||||
"name": "Pascal JEAN aka epsilonrt",
|
||||
"url": "https://github.com/epsilonrt",
|
||||
"maintainer": true
|
||||
},
|
||||
{
|
||||
"name": "André Sarmento Barbosa",
|
||||
"url": "https://github.com/andresarmento"
|
||||
}
|
||||
],
|
||||
"repository":
|
||||
{
|
||||
"type": "git",
|
||||
"url": "https://github.com/epsilonrt/modbus-serial.git"
|
||||
},
|
||||
"license": "BSD-3-Clause",
|
||||
"examples":[
|
||||
"examples/*/*.ino"
|
||||
],
|
||||
"dependencies": {
|
||||
"epsilonrt/Modbus-Arduino": "^1.2.0"
|
||||
},
|
||||
"frameworks": "arduino",
|
||||
"platforms": "*"
|
||||
}
|
101
firmware/Modbus-Serial/library.project
Normal file
101
firmware/Modbus-Serial/library.project
Normal file
@@ -0,0 +1,101 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<CodeLite_Project Name="library" Version="10.0.0" InternalType="">
|
||||
<VirtualDirectory Name=".github">
|
||||
<VirtualDirectory Name="workflows">
|
||||
<File Name=".github/workflows/build_teensy.yml"/>
|
||||
<File Name=".github/workflows/build_due.yml"/>
|
||||
<File Name=".github/workflows/build_mega.yml"/>
|
||||
<File Name=".github/workflows/build_nano33iot.yml"/>
|
||||
<File Name=".github/workflows/build_uno.yml"/>
|
||||
<File Name=".github/workflows/build_esp32.yml"/>
|
||||
<File Name=".github/workflows/build_esp8266.yml"/>
|
||||
<File Name=".github/workflows/doxygen-gh-pages.yml"/>
|
||||
</VirtualDirectory>
|
||||
<File Name=".github/stale.yml"/>
|
||||
</VirtualDirectory>
|
||||
<VirtualDirectory Name="examples">
|
||||
<VirtualDirectory Name="Lamp">
|
||||
<File Name="examples/Lamp/Lamp.ino"/>
|
||||
</VirtualDirectory>
|
||||
<VirtualDirectory Name="LampDimmer">
|
||||
<File Name="examples/LampDimmer/LampDimmer.ino"/>
|
||||
</VirtualDirectory>
|
||||
<VirtualDirectory Name="Servo">
|
||||
<File Name="examples/Servo/Servo.ino"/>
|
||||
</VirtualDirectory>
|
||||
<VirtualDirectory Name="Switch">
|
||||
<File Name="examples/Switch/Switch.ino"/>
|
||||
</VirtualDirectory>
|
||||
<VirtualDirectory Name="TempSensor">
|
||||
<File Name="examples/TempSensor/TempSensor.ino"/>
|
||||
</VirtualDirectory>
|
||||
</VirtualDirectory>
|
||||
<Description/>
|
||||
<Dependencies/>
|
||||
<Settings Type="Executable">
|
||||
<GlobalSettings>
|
||||
<Compiler Options="" C_Options="" Assembler="">
|
||||
<IncludePath Value="."/>
|
||||
</Compiler>
|
||||
<Linker Options="">
|
||||
<LibraryPath Value="."/>
|
||||
</Linker>
|
||||
<ResourceCompiler Options=""/>
|
||||
</GlobalSettings>
|
||||
<Configuration Name="Debug" CompilerType="gnu gcc" DebuggerType="GNU gdb debugger" Type="Executable" BuildCmpWithGlobalSettings="append" BuildLnkWithGlobalSettings="append" BuildResWithGlobalSettings="append">
|
||||
<Compiler Options="-g -Wall" C_Options="" Assembler="" Required="yes" PreCompiledHeader="" PCHInCommandLine="no" PCHFlags="" PCHFlagsPolicy="0">
|
||||
<IncludePath Value="."/>
|
||||
</Compiler>
|
||||
<Linker Options="-O0" Required="yes">
|
||||
<LibraryPath Value="."/>
|
||||
<LibraryPath Value="Debug"/>
|
||||
</Linker>
|
||||
<ResourceCompiler Options="" Required="no"/>
|
||||
<General OutputFile="$(IntermediateDirectory)/$(ProjectName)" IntermediateDirectory="./Debug" Command="./$(ProjectName)" CommandArguments="" UseSeparateDebugArgs="no" DebugArguments="" WorkingDirectory="./Debug" PauseExecWhenProcTerminates="no" IsGUIProgram="no" IsEnabled="yes"/>
|
||||
<BuildSystem Name="Default"/>
|
||||
<Environment EnvVarSetName="<Use Workspace Settings>" DbgSetName="<Use Global Settings>">
|
||||
<![CDATA[]]>
|
||||
</Environment>
|
||||
<Debugger IsRemote="no" RemoteHostName="" RemoteHostPort="" DebuggerPath="" IsExtended="no">
|
||||
<DebuggerSearchPaths/>
|
||||
<PostConnectCommands/>
|
||||
<StartupCommands/>
|
||||
</Debugger>
|
||||
<PreBuild/>
|
||||
<PostBuild/>
|
||||
<CustomBuild Enabled="no">
|
||||
<RebuildCommand/>
|
||||
<CleanCommand/>
|
||||
<BuildCommand/>
|
||||
<PreprocessFileCommand/>
|
||||
<SingleFileCommand/>
|
||||
<MakefileGenerationCommand/>
|
||||
<ThirdPartyToolName/>
|
||||
<WorkingDirectory/>
|
||||
</CustomBuild>
|
||||
<AdditionalRules>
|
||||
<CustomPostBuild/>
|
||||
<CustomPreBuild/>
|
||||
</AdditionalRules>
|
||||
<Completion EnableCpp11="no" EnableCpp14="no">
|
||||
<ClangCmpFlagsC/>
|
||||
<ClangCmpFlags/>
|
||||
<ClangPP/>
|
||||
<SearchPaths/>
|
||||
</Completion>
|
||||
</Configuration>
|
||||
</Settings>
|
||||
<VirtualDirectory Name="src">
|
||||
<File Name="src/ModbusSerial.cpp"/>
|
||||
<File Name="src/ModbusSerial.h"/>
|
||||
</VirtualDirectory>
|
||||
<VirtualDirectory Name="modbus-serial">
|
||||
<File Name=".gitignore"/>
|
||||
<File Name="library.json"/>
|
||||
<File Name="LICENSE"/>
|
||||
<File Name="README.md"/>
|
||||
<File Name="keywords.txt"/>
|
||||
<File Name="library.properties"/>
|
||||
<File Name="Doxyfile"/>
|
||||
</VirtualDirectory>
|
||||
</CodeLite_Project>
|
10
firmware/Modbus-Serial/library.properties
Normal file
10
firmware/Modbus-Serial/library.properties
Normal file
@@ -0,0 +1,10 @@
|
||||
name=Modbus-Serial
|
||||
version=2.0.6
|
||||
author=Pascal Jean aka epsilonrt,André Sarmento Barbosa
|
||||
maintainer=epsilonrt
|
||||
sentence=A library that allows your Arduino to communicate via Modbus protocol, acting as a slave.
|
||||
paragraph=Over serial line implementation (OSI 2/OSI 1)
|
||||
category=Communication
|
||||
url=https://epsilonrt.github.io/modbus-serial
|
||||
architectures=*
|
||||
license=BSD-3-Clause
|
14
firmware/Modbus-Serial/modbus-serial.workspace
Normal file
14
firmware/Modbus-Serial/modbus-serial.workspace
Normal file
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<CodeLite_Workspace Name="modbus-serial" Database="" Version="10.0.0">
|
||||
<Project Name="library" Path="library.project" Active="Yes"/>
|
||||
<BuildMatrix>
|
||||
<WorkspaceConfiguration Name="Debug" Selected="yes">
|
||||
<Environment/>
|
||||
<Project Name="library" ConfigName="Debug"/>
|
||||
</WorkspaceConfiguration>
|
||||
<WorkspaceConfiguration Name="Release" Selected="yes">
|
||||
<Environment/>
|
||||
<Project Name="library" ConfigName="Debug"/>
|
||||
</WorkspaceConfiguration>
|
||||
</BuildMatrix>
|
||||
</CodeLite_Workspace>
|
239
firmware/Modbus-Serial/src/ModbusSerial.cpp
Normal file
239
firmware/Modbus-Serial/src/ModbusSerial.cpp
Normal file
@@ -0,0 +1,239 @@
|
||||
/*
|
||||
ModbusSerial.cpp - Source for Modbus Serial Library
|
||||
Copyright (C) 2023 Pascal JEAN aka epsilonrt
|
||||
Copyright (C) 2014 André Sarmento Barbosa
|
||||
*/
|
||||
#include "ModbusSerial.h"
|
||||
|
||||
ModbusSerial::ModbusSerial(Stream & port, byte slaveId, int txenPin) :
|
||||
m_stream(&port), m_txenPin(txenPin), m_slaveId(slaveId)
|
||||
{}
|
||||
|
||||
void ModbusSerial::config (unsigned long baud) {
|
||||
|
||||
if (m_txenPin >= 0) {
|
||||
|
||||
pinMode (m_txenPin, OUTPUT);
|
||||
digitalWrite (m_txenPin, LOW);
|
||||
}
|
||||
|
||||
if (baud > 19200) {
|
||||
m_t15 = 750;
|
||||
m_t35 = 1750;
|
||||
}
|
||||
else {
|
||||
m_t15 = 16500000UL / baud; // 1T * 1.5 = T1.5, 1T = 11 bits
|
||||
m_t35 = 38500000UL / baud; // 1T * 3.5 = T3.5, 1T = 11 bits
|
||||
}
|
||||
}
|
||||
|
||||
void ModbusSerial::task() {
|
||||
_len = 0;
|
||||
|
||||
while ( m_stream->available() > _len) {
|
||||
|
||||
_len = m_stream->available();
|
||||
delayMicroseconds (m_t15);
|
||||
}
|
||||
|
||||
if (_len == 0) {
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
byte i;
|
||||
_frame = (byte*) malloc (_len);
|
||||
|
||||
for (i = 0 ; i < _len ; i++) {
|
||||
|
||||
_frame[i] = m_stream->read();
|
||||
}
|
||||
|
||||
if (receive (_frame)) {
|
||||
|
||||
if (_reply == MB_REPLY_NORMAL) {
|
||||
|
||||
sendPDU (_frame);
|
||||
}
|
||||
else if (_reply == MB_REPLY_ECHO) {
|
||||
|
||||
send (_frame);
|
||||
}
|
||||
}
|
||||
|
||||
free (_frame);
|
||||
_len = 0;
|
||||
}
|
||||
|
||||
void ModbusSerial::setSlaveId (byte slaveId) {
|
||||
|
||||
m_slaveId = slaveId;
|
||||
}
|
||||
|
||||
byte ModbusSerial::getSlaveId() {
|
||||
|
||||
return m_slaveId;
|
||||
}
|
||||
|
||||
// protected
|
||||
bool ModbusSerial::receive (byte* frame) {
|
||||
|
||||
//first byte of frame = address
|
||||
byte address = frame[0];
|
||||
|
||||
//Last two bytes = crc
|
||||
word crc = ( (frame[_len - 2] << 8) | frame[_len - 1]);
|
||||
|
||||
//Slave Check
|
||||
if (address != BroadcastAddress && address != getSlaveId()) {
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//CRC Check
|
||||
if (crc != calcCrc (_frame[0], _frame + 1, _len - 3)) {
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//PDU starts after first byte
|
||||
//framesize PDU = framesize - address(1) - crc(2)
|
||||
receivePDU (frame + 1);
|
||||
|
||||
//No reply to Broadcasts
|
||||
if (address == BroadcastAddress) {
|
||||
|
||||
_reply = MB_REPLY_OFF;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// protected
|
||||
bool ModbusSerial::send (byte* frame) {
|
||||
byte i;
|
||||
|
||||
if (m_txenPin >= 0) {
|
||||
|
||||
digitalWrite (m_txenPin, HIGH);
|
||||
delay (1);
|
||||
}
|
||||
|
||||
for (i = 0 ; i < _len ; i++) {
|
||||
|
||||
m_stream->write (frame[i]);
|
||||
}
|
||||
|
||||
m_stream->flush();
|
||||
delayMicroseconds (m_t35);
|
||||
|
||||
if (m_txenPin >= 0) {
|
||||
|
||||
digitalWrite (m_txenPin, LOW);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// protected
|
||||
bool ModbusSerial::sendPDU (byte* pduframe) {
|
||||
|
||||
if (m_txenPin >= 0) {
|
||||
|
||||
digitalWrite (m_txenPin, HIGH);
|
||||
delay (1);
|
||||
}
|
||||
|
||||
//Send slaveId
|
||||
m_stream->write (m_slaveId);
|
||||
|
||||
//Send PDU
|
||||
byte i;
|
||||
|
||||
for (i = 0 ; i < _len ; i++) {
|
||||
|
||||
m_stream->write (pduframe[i]);
|
||||
}
|
||||
|
||||
//Send CRC
|
||||
word crc = calcCrc (m_slaveId, _frame, _len);
|
||||
m_stream->write (crc >> 8);
|
||||
m_stream->write (crc & 0xFF);
|
||||
|
||||
m_stream->flush();
|
||||
delayMicroseconds (m_t35);
|
||||
|
||||
if (m_txenPin >= 0) {
|
||||
|
||||
digitalWrite (m_txenPin, LOW);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// protected
|
||||
void ModbusSerial::reportServerId() {
|
||||
|
||||
Modbus::reportServerId();
|
||||
_frame[2] = getSlaveId(); // Server ID
|
||||
}
|
||||
|
||||
// private
|
||||
|
||||
/* Table of CRC values for highorder byte */
|
||||
const byte _auchCRCHi[] = {
|
||||
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81,
|
||||
0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
|
||||
0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01,
|
||||
0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
|
||||
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81,
|
||||
0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
|
||||
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01,
|
||||
0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
|
||||
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81,
|
||||
0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
|
||||
0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01,
|
||||
0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
|
||||
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81,
|
||||
0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
|
||||
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01,
|
||||
0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
|
||||
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81,
|
||||
0x40
|
||||
};
|
||||
|
||||
/* Table of CRC values for loworder byte */
|
||||
const byte _auchCRCLo[] = {
|
||||
0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06, 0x07, 0xC7, 0x05, 0xC5, 0xC4,
|
||||
0x04, 0xCC, 0x0C, 0x0D, 0xCD, 0x0F, 0xCF, 0xCE, 0x0E, 0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09,
|
||||
0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9, 0x1B, 0xDB, 0xDA, 0x1A, 0x1E, 0xDE, 0xDF, 0x1F, 0xDD,
|
||||
0x1D, 0x1C, 0xDC, 0x14, 0xD4, 0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3,
|
||||
0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3, 0xF2, 0x32, 0x36, 0xF6, 0xF7,
|
||||
0x37, 0xF5, 0x35, 0x34, 0xF4, 0x3C, 0xFC, 0xFD, 0x3D, 0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A,
|
||||
0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38, 0x28, 0xE8, 0xE9, 0x29, 0xEB, 0x2B, 0x2A, 0xEA, 0xEE,
|
||||
0x2E, 0x2F, 0xEF, 0x2D, 0xED, 0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26,
|
||||
0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60, 0x61, 0xA1, 0x63, 0xA3, 0xA2,
|
||||
0x62, 0x66, 0xA6, 0xA7, 0x67, 0xA5, 0x65, 0x64, 0xA4, 0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F,
|
||||
0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB, 0x69, 0xA9, 0xA8, 0x68, 0x78, 0xB8, 0xB9, 0x79, 0xBB,
|
||||
0x7B, 0x7A, 0xBA, 0xBE, 0x7E, 0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5,
|
||||
0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71, 0x70, 0xB0, 0x50, 0x90, 0x91,
|
||||
0x51, 0x93, 0x53, 0x52, 0x92, 0x96, 0x56, 0x57, 0x97, 0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C,
|
||||
0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E, 0x5A, 0x9A, 0x9B, 0x5B, 0x99, 0x59, 0x58, 0x98, 0x88,
|
||||
0x48, 0x49, 0x89, 0x4B, 0x8B, 0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C,
|
||||
0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42, 0x43, 0x83, 0x41, 0x81, 0x80,
|
||||
0x40
|
||||
};
|
||||
|
||||
word ModbusSerial::calcCrc (byte address, byte* pduFrame, byte pduLen) {
|
||||
byte CRCHi = 0xFF, CRCLo = 0x0FF, Index;
|
||||
|
||||
Index = CRCHi ^ address;
|
||||
CRCHi = CRCLo ^ _auchCRCHi[Index];
|
||||
CRCLo = _auchCRCLo[Index];
|
||||
|
||||
while (pduLen--) {
|
||||
Index = CRCHi ^ *pduFrame++;
|
||||
CRCHi = CRCLo ^ _auchCRCHi[Index];
|
||||
CRCLo = _auchCRCLo[Index];
|
||||
}
|
||||
|
||||
return (CRCHi << 8) | CRCLo;
|
||||
}
|
111
firmware/Modbus-Serial/src/ModbusSerial.h
Normal file
111
firmware/Modbus-Serial/src/ModbusSerial.h
Normal file
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
ModbusSerial.h - Header for ModbusSerial Library
|
||||
Copyright (C) 2023 Pascal JEAN aka epsilonrt
|
||||
Copyright (C) 2014 André Sarmento Barbosa
|
||||
*/
|
||||
#include <Arduino.h>
|
||||
#include <Modbus.h>
|
||||
|
||||
#pragma once
|
||||
|
||||
/**
|
||||
* @enum MB_PARITY
|
||||
* @brief Parity
|
||||
*
|
||||
* See paragraph [2.5.1 RTU Transmission Mode] from
|
||||
* MODBUS over serial line specification and implementation guide V1.02
|
||||
* http://www.modbus.org/docs/Modbus_over_serial_line_V1_02.pdf
|
||||
*
|
||||
* The format (11 bits) for each byte in RTU mode is :
|
||||
* Coding System:
|
||||
*
|
||||
* * 8–bit binary
|
||||
*
|
||||
* Bits per Byte:
|
||||
*
|
||||
* * 1 start bit
|
||||
* * 8 data bits, least significant bit sent first
|
||||
* * 1 bit for parity completion
|
||||
* * 1 stop bit
|
||||
* .
|
||||
*
|
||||
* Even parity is required, other modes ( odd parity, no parity )
|
||||
* may also be used. In order to ensure a maximum compatibility with
|
||||
* other products, it is recommended to support also No parity mode.
|
||||
* The default parity mode must be even parity.
|
||||
* Remark : the use of no parity requires 2 stop bits.
|
||||
*/
|
||||
enum MB_PARITY {
|
||||
MB_PARITY_NONE = SERIAL_8N2, ///< No parity
|
||||
MB_PARITY_EVEN = SERIAL_8E1, ///< Even parity
|
||||
MB_PARITY_ODD = SERIAL_8O1 ///< Odd parity
|
||||
};
|
||||
|
||||
/**
|
||||
* @class ModbusSerial
|
||||
* @brief Modbus over serial line Class
|
||||
*/
|
||||
class ModbusSerial : public Modbus {
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief Constructor
|
||||
* @param port serial port to use
|
||||
* @param txenPin if an RS485 circuit is used, this corresponds to the
|
||||
* pin number connected to the transmit enable (DE) and receive disable (/RE) pin.
|
||||
* -1 if not used.
|
||||
*/
|
||||
ModbusSerial (Stream & port, byte slaveId, int txenPin = -1);
|
||||
|
||||
/**
|
||||
* @brief Configure ModbusSerial object
|
||||
*
|
||||
* configures txenPin on output if necessary and calculates the times of the RTU frame.
|
||||
*
|
||||
* @warning the \c begin() function of the serial port passed to the constructor
|
||||
* must be called **BEFORE** calling this function.
|
||||
*
|
||||
* @param baud baudrate in accordance with that used by the serial port
|
||||
*/
|
||||
void config (unsigned long baud);
|
||||
|
||||
/**
|
||||
* @brief Task that performs all operations on MODBUS
|
||||
*
|
||||
* Call once inside loop(), all magic here !
|
||||
*/
|
||||
void task();
|
||||
|
||||
/**
|
||||
* @brief Change the value of slave identifier
|
||||
* @param slaveId identifier 1-247
|
||||
*/
|
||||
void setSlaveId (byte slaveId);
|
||||
|
||||
/**
|
||||
* @brief Return slave identifier
|
||||
*/
|
||||
byte getSlaveId();
|
||||
|
||||
/**
|
||||
* @brief Broadcast address
|
||||
*/
|
||||
static const byte BroadcastAddress = 0;
|
||||
|
||||
protected:
|
||||
bool receive (byte * frame);
|
||||
bool sendPDU (byte * pduframe);
|
||||
bool send (byte * frame);
|
||||
void reportServerId();
|
||||
|
||||
private:
|
||||
Stream * m_stream;
|
||||
int m_txenPin;
|
||||
byte m_slaveId;
|
||||
|
||||
unsigned int m_t15; // inter character time out (us)
|
||||
unsigned int m_t35; // frame delay (us)
|
||||
|
||||
private:
|
||||
word calcCrc (byte address, byte * pduframe, byte pdulen);
|
||||
};
|
Reference in New Issue
Block a user