Skip to content

Commit 2e8b0c7

Browse files
committed
first initial
1 parent 6162e68 commit 2e8b0c7

File tree

8 files changed

+396
-4
lines changed

8 files changed

+396
-4
lines changed

LICENSE

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
MIT License
22

3-
Copyright (c) 2025 sahin mersin
3+
Copyright (c) 2022 Christopher Bulliner
44

55
Permission is hereby granted, free of charge, to any person obtaining a copy
66
of this software and associated documentation files (the "Software"), to deal
@@ -18,4 +18,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
1818
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1919
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
2020
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21-
SOFTWARE.
21+
SOFTWARE.

README.md

Lines changed: 112 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,112 @@
1-
# ModbusRTUSlave
2-
Modbus RTU protocol (function codes `0x03` and `0x06`). This library is a slave implementation of the Modbus RTU protocol.
1+
# ModbusRTUSlave Arduino Library
2+
3+
A simple and flexible Modbus RTU slave library for Arduino.
4+
5+
## Overview
6+
7+
The `ModbusRTUSlave` library allows Arduino devices to function as Modbus RTU slaves over a serial connection. It supports reading and writing registers via Modbus function codes `0x03` (Read Holding Registers) and `0x06` (Write Single Register), with provisions for LED control based on a designated register value. The library is designed to be customizable, with configurable slave address, LED pin, LED register index, and baud rate.
8+
9+
### Features
10+
- Supports Modbus RTU protocol (function codes `0x03` and `0x06`).
11+
- Configurable slave address, LED pin, and LED register index.
12+
- Flexible baud rate setting via a variable.
13+
- LED control tied to a specific register value (turns ON when the register equals 1).
14+
- Lightweight and easy to integrate into Arduino projects.
15+
16+
### Version
17+
- **1.0.0** (Released: March 07, 2025)
18+
19+
### Author
20+
- S.Mersin (electrocoder) <[email protected]> (Assisted by Grok)
21+
22+
### License
23+
- MIT License (See [LICENSE](#license) section for details)
24+
25+
---
26+
27+
## Installation
28+
29+
1. **Download the Repository**:
30+
- Clone this repository or download it as a ZIP file:
31+
```bash
32+
git clone https://github.com/electrocoder/ModbusRTUSlave.git
33+
```
34+
35+
2. **Install to Arduino IDE**:
36+
- Move the `ModbusRTUSlave` folder to your Arduino `libraries` directory:
37+
- Windows: `Documents/Arduino/libraries/`
38+
- macOS/Linux: `~/Documents/Arduino/libraries/`
39+
- Restart the Arduino IDE.
40+
41+
3. **Include in Your Sketch**:
42+
- Add the library to your sketch with:
43+
```cpp
44+
#include <ModbusRTUSlave.h>
45+
```
46+
47+
---
48+
49+
## Usage
50+
51+
### Basic Example
52+
This example initializes a Modbus slave with default settings and controls an LED based on register 5.
53+
54+
```cpp
55+
#include <ModbusRTUSlave.h>
56+
57+
long modbusBaudRate = 9600; // Customizable baud rate
58+
ModbusRTUSlave modbus(0x01, 13, 5); // Slave address: 0x01, LED pin: 13, LED register: 5
59+
60+
void setup() {
61+
modbus.begin(modbusBaudRate);
62+
Serial.println("Modbus started");
63+
}
64+
65+
void loop() {
66+
modbus.update();
67+
}
68+
69+
70+
Modbus Commands
71+
Turn LED ON: Send 01 06 00 05 00 01 [CRC] (writes 1 to register 5).
72+
73+
Turn LED OFF: Send 01 06 00 05 00 00 [CRC] (writes 0 to register 5).
74+
75+
Read Registers: Send 01 03 00 00 00 0A [CRC] (reads 10 registers starting from 0).
76+
77+
Customization
78+
You can adjust settings at runtime:
79+
80+
modbus.setSlaveAddress(0x02); // Change slave address to 0x02
81+
modbus.setLedPin(12); // Change LED pin to 12
82+
modbus.setLedRegisterIndex(7); // Use register 7 for LED control
83+
modbus.setModbusBaudRate(115200); // Change baud rate to 115200
84+
85+
Hardware Requirements
86+
Any Arduino-compatible board with a serial interface (e.g., Uno, Mega, Nano).
87+
88+
An LED connected to the specified pin (default: pin 13, onboard LED on most Arduino boards).
89+
90+
A Modbus master device or software (e.g., Modbus Poll, QModMaster) for testing.
91+
92+
Dependencies
93+
None (uses only the Arduino core library).
94+
95+
Contributing
96+
Contributions are welcome! Feel free to:
97+
Fork this repository.
98+
99+
Create a new branch for your feature or bug fix.
100+
101+
Submit a pull request with a clear description of your changes.
102+
103+
License
104+
This project is licensed under the MIT License. See the LICENSE file for details.
105+
Acknowledgments
106+
Developed with assistance from Grok, created by xAI.
107+
108+
Inspired by the need for a simple Modbus RTU slave implementation on Arduino.
109+
110+
Contact
111+
For questions or support, open an issue on this repository or reach out to [[email protected] (mailto:[email protected])].
112+
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/*
2+
* ModbusRTUSlaveExample.ino - Example Sketch for ModbusRTUSlave Library
3+
*
4+
* Description: This sketch demonstrates the usage of the ModbusSlave library to configure
5+
* an Arduino as a Modbus RTU slave. It controls an LED based on a specific
6+
* register value and allows customization of the slave address, LED pin,
7+
* and baud rate.
8+
* Author: S.Mersin (electrocoder) <[email protected]> (Assisted by Grok)
9+
* Date: March 07, 2025
10+
* Version: 1.0.0
11+
* License: MIT License
12+
*
13+
* Hardware:
14+
* - Arduino Uno (or any compatible board)
15+
* - LED connected to pin 13 (onboard LED can be used)
16+
*
17+
* Dependencies:
18+
* - ModbusRTUSlave library (version 1.0.0 or higher)
19+
*
20+
* Usage:
21+
* - Upload this sketch to your Arduino.
22+
* - Use a Modbus master (e.g., Modbus Poll) to send commands:
23+
* - Write 1 to register 5: "01 06 00 05 00 01 [CRC]" (turns LED ON)
24+
* - Write 0 to register 5: "01 06 00 05 00 00 [CRC]" (turns LED OFF)
25+
*/
26+
27+
#include "ModbusRTUSlave.h"
28+
29+
ModbusRTUSlave modbus(0x01, 13, 0, 10); // Slave address: 0x01, LED pin: 13, LED register: 0, Register count: 10
30+
long modbusBaudRate = 9600; // If you want it can be another value like 115200, 19200
31+
32+
void setup() {
33+
34+
modbus.begin(modbusBaudRate);
35+
Serial.println("Modbus was downloaded.");
36+
37+
}
38+
39+
void loop() {
40+
41+
modbus.update();
42+
43+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# ModbusRTUSlave Arduino Library
2+
3+
A simple and flexible Modbus RTU slave library for Arduino.
4+
5+
## Usage
6+
7+
**Modbus Commands**
8+
9+
Turn LED ON: Send 01 06 00 05 00 01 [CRC] (writes 1 to register 5).
10+
11+
Turn LED OFF: Send 01 06 00 05 00 00 [CRC] (writes 0 to register 5).
12+
13+
Read Registers: Send 01 03 00 00 00 0A [CRC] (reads 10 registers starting from 0).
14+
15+
**Customization**
16+
17+
You can adjust settings at runtime:
18+
19+
```cpp
20+
modbus.setSlaveAddress(0x02); // Change slave address to 0x02
21+
modbus.setLedPin(12); // Change LED pin to 12
22+
modbus.setLedRegisterIndex(7); // Use register 7 for LED control
23+
modbus.setModbusBaudRate(115200); // Change baud rate to 115200
24+
```

keywords.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
ModbusSlave KEYWORD1
2+
begin KEYWORD2
3+
update KEYWORD2

library.properties

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
name=ModbusRTUSlave
2+
version=1.0.0
3+
author=S.Mersin (electrocoder) <[email protected]>
4+
maintainer=S.Mersin (electrocoder) <[email protected]>
5+
sentence=Modbus RTU protocol (function codes `0x03` and `0x06`). This library is a slave implementation of the Modbus RTU protocol.
6+
paragraph=The `ModbusRTUSlave` library allows Arduino devices to function as Modbus RTU slaves over a serial connection. It supports reading and writing registers via Modbus function codes `0x03` (Read Holding Registers) and `0x06` (Write Single Register), with provisions for LED control based on a designated register value. The library is designed to be customizable, with configurable slave address, LED pin, LED register index, and baud rate.
7+
category=Communication
8+
url=https://github.com/electrocoder/ModbusRTUSlave
9+
architectures=avr,esp8266,esp32
10+
license=MIT

src/ModbusRTUSlave.cpp

Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
/*
2+
* ModbusRTUSlave.cpp - Implementation of the Modbus RTU Slave Library for Arduino
3+
*
4+
* Description: This file implements the methods of the ModbusRTUSlave class.
5+
* It supports Modbus RTU protocol for register reading (0x03) and writing (0x06).
6+
* Provides LED control and flexible baud rate adjustments.
7+
* Author: S.Mersin (electrocoder) <[email protected]> (Assisted by Grok)
8+
* Date: March 07, 2025
9+
* Version: 1.0.0
10+
* License: MIT License
11+
*
12+
* Note: This library uses the Arduino Serial port to provide Modbus RTU slave functionality.
13+
* All registers except the LED register are updated with random values.
14+
*/
15+
16+
#include "ModbusRTUSlave.h"
17+
18+
ModbusRTUSlave::ModbusRTUSlave(uint8_t slaveAddress, uint8_t ledPin, uint8_t ledRegisterIndex, uint16_t registerCount) {
19+
_slaveAddress = slaveAddress;
20+
_ledPin = ledPin;
21+
_ledRegisterIndex = ledRegisterIndex;
22+
_registerCount = registerCount;
23+
_baudRate = 9600; // Default baud rate
24+
25+
// Create dynamic register array
26+
modbusRegisters = new uint16_t[_registerCount];
27+
28+
// Fill the registers with initial values
29+
modbusRegisters[0] = 0;
30+
modbusRegisters[1] = 5678;
31+
modbusRegisters[2] = 90;
32+
for (int i = 3; i < _registerCount; i++) {
33+
modbusRegisters[i] = 0;
34+
}
35+
}
36+
37+
void ModbusRTUSlave::begin(long baudRate) {
38+
_baudRate = baudRate;
39+
pinMode(_ledPin, OUTPUT);
40+
digitalWrite(_ledPin, LOW);
41+
Serial.begin(_baudRate, SERIAL_8N1);
42+
while (!Serial)
43+
;
44+
}
45+
46+
void ModbusRTUSlave::update() {
47+
// We assign random values to all registers except the LED register
48+
for (int i = 0; i < _registerCount; i++) {
49+
if (i != _ledRegisterIndex)
50+
modbusRegisters[i] = random(1, 10000);
51+
}
52+
53+
if (Serial.available() >= 8) {
54+
for (int i = 0; i < 8; i++) {
55+
requestBuffer[i] = Serial.read();
56+
}
57+
58+
if (requestBuffer[0] == _slaveAddress) {
59+
if (checkCRC(requestBuffer, 6)) {
60+
if (requestBuffer[1] == 0x03) {
61+
processReadHoldingRegisters();
62+
} else if (requestBuffer[1] == 0x06) {
63+
processWriteSingleRegister();
64+
}
65+
}
66+
}
67+
68+
while (Serial.available()) Serial.read();
69+
}
70+
71+
digitalWrite(_ledPin, modbusRegisters[_ledRegisterIndex] == 1 ? HIGH : LOW);
72+
}
73+
74+
void ModbusRTUSlave::processReadHoldingRegisters() {
75+
uint16_t startAddress = (requestBuffer[2] << 8) | requestBuffer[3];
76+
uint16_t registerCount = (requestBuffer[4] << 8) | requestBuffer[5];
77+
78+
responseBuffer[0] = _slaveAddress;
79+
responseBuffer[1] = 0x03;
80+
responseBuffer[2] = registerCount * 2;
81+
82+
for (int i = 0; i < registerCount; i++) {
83+
uint16_t regValue = modbusRegisters[startAddress + i];
84+
responseBuffer[3 + i * 2] = (regValue >> 8) & 0xFF;
85+
responseBuffer[4 + i * 2] = regValue & 0xFF;
86+
}
87+
88+
uint16_t crc = calculateCRC(responseBuffer, 3 + registerCount * 2);
89+
responseBuffer[3 + registerCount * 2] = crc & 0xFF;
90+
responseBuffer[4 + registerCount * 2] = (crc >> 8) & 0xFF;
91+
92+
Serial.write(responseBuffer, 5 + registerCount * 2);
93+
}
94+
95+
void ModbusRTUSlave::processWriteSingleRegister() {
96+
uint16_t registerAddress = (requestBuffer[2] << 8) | requestBuffer[3];
97+
uint16_t registerValue = (requestBuffer[4] << 8) | requestBuffer[5];
98+
99+
if (registerAddress < _registerCount) {
100+
modbusRegisters[registerAddress] = registerValue;
101+
}
102+
103+
for (int i = 0; i < 6; i++) {
104+
responseBuffer[i] = requestBuffer[i];
105+
}
106+
responseBuffer[6] = requestBuffer[6];
107+
responseBuffer[7] = requestBuffer[7];
108+
109+
Serial.write(responseBuffer, 8);
110+
}
111+
112+
uint16_t ModbusRTUSlave::calculateCRC(uint8_t *buffer, uint8_t length) {
113+
uint16_t crc = 0xFFFF;
114+
for (uint8_t pos = 0; pos < length; pos++) {
115+
crc ^= (uint16_t)buffer[pos];
116+
for (uint8_t i = 8; i != 0; i--) {
117+
if ((crc & 0x0001) != 0) {
118+
crc >>= 1;
119+
crc ^= 0xA001;
120+
} else {
121+
crc >>= 1;
122+
}
123+
}
124+
}
125+
return crc;
126+
}
127+
128+
bool ModbusRTUSlave::checkCRC(uint8_t *buffer, uint8_t length) {
129+
uint16_t receivedCRC = (buffer[length + 1] << 8) | buffer[length];
130+
uint16_t calculatedCRC = calculateCRC(buffer, length);
131+
return (receivedCRC == calculatedCRC);
132+
}
133+
134+
// Setter methods
135+
void ModbusRTUSlave::setSlaveAddress(uint8_t slaveAddress) {
136+
_slaveAddress = slaveAddress;
137+
}
138+
139+
void ModbusRTUSlave::setLedPin(uint8_t ledPin) {
140+
_ledPin = ledPin;
141+
pinMode(_ledPin, OUTPUT);
142+
}
143+
144+
void ModbusRTUSlave::setLedRegisterIndex(uint8_t ledRegisterIndex) {
145+
if (ledRegisterIndex < _registerCount) {
146+
_ledRegisterIndex = ledRegisterIndex;
147+
}
148+
}
149+
150+
void ModbusRTUSlave::setBaudRate(long baudRate) {
151+
_baudRate = baudRate;
152+
Serial.begin(_baudRate, SERIAL_8N1);
153+
}

0 commit comments

Comments
 (0)