We are building a circuit based on ATMega328* that :

  1. Reads 32 current transducers, multiplexed into one Analog Input,
  2. Reads 12 voltage transducers, multiplexed into one Analog Input,
  3. Reads 6 temperature sensors, multiplexed into one Analog Input,
  4. Manipulates all the readings with some math (like scaling, averaging etc.),
  5. Calculates new variables (power, crest factor, etc.),
  6. Tracks trends (max/min/avg) of certain (calculated) readings,
  7. Stores some events (peaks/dips - max/min values) etc. with time stamps from RTC,
  8. Generates Alarm Flags (by comparing readings to software-set thresholds),

The circuit should be connected as a ModBus Device (Slave) to an existing Modbus network with several other devices on an RS485 interface.

The circuit should communicate all these calculated values and alarms as well as some other info, like peak/max values with date and time stamps that were recorded at their time of occurrence, to the Modbus Master. We have the freedom of allocating the register numbers and their formats etc. (Modbus Map) to the controller's vendor (SAUTER). For example we tell them Register 30001 is the current sensor x, 30002 is voltage sensor y, etc.

We think that sending time stamps (of certain events) will be based on "agreed-upon" coding of register values (MM, DD, YYYY, etc.) and the same for alarms (to be sent as hex codes).

We have searched for libraries and got really confused from the multitude of libraries out there, as well as the lack of documentation -:)

Can you please kindly help us : select the proper Arduino Modbus Slave Library that :

  1. Has MAX485 support,
  2. Assigns Modbus registers to any arbitrary variables,
  3. Issues Exception Responses to Modbus requests (e.g. non-existing registers or un-supported Function Codes.
  4. Complies to Modbus Standards
  5. Has a manual !!

We found the "yaacov" library on Github but it assigns registers directly to "Pins". Also we looked at its "issues" and one of them was very serious : in which frames coming from the Master with corrupted CRC gets responded to and causes collision with other slaves. We dont like that ! as it indicates that the library was not tested in true industrial environment.

We also found that the Library at :


somewhat fits to our requirements, however it lacks the RS485 support, and more important, it has no documentation.

We really appreciate any kind support.

  • The ATmega328 will be probably replaced with a larger CPU, but we are still in development phase.

Thank you.

  • The ATmega328 will be probably replaced with a larger CPU ... then you will back to searching for a livrary
    – jsotola
    Jul 21, 2020 at 18:34

2 Answers 2


With my post approaching one month without a single reply :smiley-confuse: ! (for whichever reason) I would like to post for those who may need this library :


The library is based on the original one written by Jason Vreeland [CodeRage] Released 3/7/2010 under GNU license

and was used (and possibly modified) by "jhottell" on electronhacks.com :


The major difference is the use of RS485.

I have written code and tested it on an "UNO" which worked perfectly with more than one ModBus Slave Simulator under windows, including DAQ Factory which is a professional package used in actual industry.


This is an awesome Modbus slave and Master Library

Required this library <ModbusRtu.h>

#include <ModbusRtu.h>
unsigned long TIME = 0;
unsigned long LASTTIME = 0;
unsigned long INTERVAL = 5000; 

int i = 0;
// data array for modbus network sharing
uint16_t au16data[16] = {
  3, 1415, 9265, 4, 2, 7182, 28182, 8, 0, 0, 0, 0, 0, 0, 1, 11 };

 *  Modbus object declaration
 *  u8id : node id = 0 for master, = 1..247 for slave
 *  port : serial port
 *  u8txenpin : 0 for RS-232 and USB-FTDI 
 *               or any pin number > 1 for RS-485
Modbus slave(1,Serial,0); // this is slave @1 and RS-232 or USB-FTDI

void setup() {
  Serial.begin( 19200 ); // baud-rate at 19200
  Serial1.begin( 19200 );

void loop() {

  if ((millis() - TIME) > INTERVAL) { 

    if(i == 16){
      i = 0;

      for (int ii = 0; ii < 16; ii++)
        au16data[ii] = 0;

    au16data[i] = 1;

    TIME = millis();

  slave.poll( au16data, 16 );

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.