Skip to content

Instantly share code, notes, and snippets.

@xandfury
Last active August 26, 2021 02:06
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save xandfury/626e7849422e8757e8fa1c16403e22ee to your computer and use it in GitHub Desktop.
Save xandfury/626e7849422e8757e8fa1c16403e22ee to your computer and use it in GitHub Desktop.
A simple modbus rtu slave device that works with Arduino Uno. For testing purposes.
/*
Before you begin, make sure that you have the correct libraries installed.
You must install Modbus Library given here: https://code.google.com/archive/p/arduino-modbus-slave/downloads
This is just an example taken from that library. I have written no part of this code. All credit goes to the original authors.
- xandfury
*/
#include <modbus.h>
#include <modbusDevice.h>
#include <modbusRegBank.h>
#include <modbusSlave.h>
/*
This example code shows a quick and dirty way to get an
arduino to talk to a modbus master device with a
device ID of 1 at 9600 baud.
*/
//Setup the brewtrollers register bank
//All of the data accumulated will be stored here
modbusDevice regBank;
//Create the modbus slave protocol handler
modbusSlave slave;
void setup()
{
//Assign the modbus device ID.
regBank.setId(1);
/*
modbus registers follow the following format
00001-09999 Digital Outputs, A master device can read and write to these registers
10001-19999 Digital Inputs, A master device can only read the values from these registers
30001-39999 Analog Inputs, A master device can only read the values from these registers
40001-49999 Analog Outputs, A master device can read and write to these registers
Analog values are 16 bit unsigned words stored with a range of 0-32767
Digital values are stored as bytes, a zero value is OFF and any nonzer value is ON
It is best to configure registers of like type into contiguous blocks. this
allows for more efficient register lookup and and reduces the number of messages
required by the master to retrieve the data
*/
//Add Digital Output registers 00001-00016 to the register bank
regBank.add(1);
regBank.add(2);
regBank.add(3);
regBank.add(4);
regBank.add(5);
regBank.add(6);
regBank.add(7);
regBank.add(8);
regBank.add(9);
regBank.add(10);
regBank.add(11);
regBank.add(12);
regBank.add(13);
regBank.add(14);
regBank.add(15);
regBank.add(16);
//Add Digital Input registers 10001-10008 to the register bank
regBank.add(10001);
regBank.add(10002);
regBank.add(10003);
regBank.add(10004);
regBank.add(10005);
regBank.add(10006);
regBank.add(10007);
regBank.add(10008);
//Add Analog Input registers 30001-10010 to the register bank
regBank.add(30001);
regBank.add(30002);
regBank.add(30003);
regBank.add(30004);
regBank.add(30005);
regBank.add(30006);
regBank.add(30007);
regBank.add(30008);
regBank.add(30009);
regBank.add(30010);
//Add Analog Output registers 40001-40020 to the register bank
regBank.add(40001);
regBank.add(40002);
regBank.add(40003);
regBank.add(40004);
regBank.add(40005);
regBank.add(40006);
regBank.add(40007);
regBank.add(40008);
regBank.add(40009);
regBank.add(40010);
regBank.add(40011);
regBank.add(40012);
regBank.add(40013);
regBank.add(40014);
regBank.add(40015);
regBank.add(40016);
regBank.add(40017);
regBank.add(40018);
regBank.add(40019);
regBank.add(40020);
/*
Assign the modbus device object to the protocol handler
This is where the protocol handler will look to read and write
register data. Currently, a modbus slave protocol handler may
only have one device assigned to it.
*/
slave._device = &regBank;
// Initialize the serial port for coms at 9600 baud
slave.setBaud(9600);
}
void loop()
{
//put some data into the registers
regBank.set(1, 1);
regBank.set(2, 1);
regBank.set(3, 0);
regBank.set(4, 1);
regBank.set(5, 1);
regBank.set(6, 0);
regBank.set(7, 1);
regBank.set(8, 0);
regBank.set(10001, 1);
regBank.set(10002, 1);
regBank.set(10003, 1);
regBank.set(10004, 1);
regBank.set(10005, 0);
regBank.set(10006, 0);
regBank.set(10007, 0);
regBank.set(10008, 0);
regBank.set(30001,1);
regBank.set(30002,2);
regBank.set(30003,3);
regBank.set(30004,4);
regBank.set(30005,5);
regBank.set(30006,6);
regBank.set(30007,7);
regBank.set(30008,8);
regBank.set(30009,9);
regBank.set(30010,10);
regBank.set(40001,1);
regBank.set(40002,2);
regBank.set(40003,2);
regBank.set(40004,4);
regBank.set(40005,5);
regBank.set(40006,6);
regBank.set(40007,7);
regBank.set(40008,8);
regBank.set(40009,9);
regBank.set(40010,10);
while(1)
{
//put a random number into registers 1, 10001, 30001 and 40001
regBank.set(1, (byte) random(0, 2));
regBank.set(10001, (byte) random(0, 2));
regBank.set(30001, (word) random(0, 32767));
regBank.set(40001, (word) random(0, 32767));
slave.run();
}
}
@desh124
Copy link

desh124 commented Oct 1, 2018

i am beginner in modbus , how we write analog value on PLC as master

@AIMSTEC24
Copy link

please share schematic regarding this Code , RS 485 module connection to arduino ?
aimstec24@gmail.com i want send 16 keys push to on data from arduino (as slave) to PLC/ Simply nodebus Software (as MASTER) and want receive error msg to arduino LCD 20x4 , please help

@dude001
Copy link

dude001 commented Apr 6, 2020

Hi.
When calling 300001 and 400001 the information is swapped around? Anybody sitting with the same problem?

@dodisuwardi
Copy link

hi , how to Add Digital Input registers more than 8 (100001-19999 )??
just trying with 20 digital input on mega2560, not work !! only 8 digital input can get data, after adress 100008 ,slave only gave data zero.

@Krialro
Copy link

Krialro commented Jun 28, 2021

Dear, I need to know how to do so that with this library I can send modbus float. Thank you best regards

@trKizmeth
Copy link

one simple way that works in every case is:

struct modbusLongReg{
uint16_t lsw;
uint16_t msw;
}* mbSplit;

double f = 0.3;

mbSplit = &f;

regBank.set(40001,mbSplit->lsw);
regBank.set(40002,mbSplit->msw);

you can configure word order as you need on the other side.

@eklavyainfo
Copy link

can you plz share the connections

@AIMSTEC24
Copy link

AIMSTEC24 commented Aug 3, 2021 via email

@akirasamma
Copy link

What's UP Man.
About serial config (slave.setBaud),
How Can I change to 8N2?
And Can I use Serial2 to modbus conection?

Thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment