MODBUS protocol Library

Hi There,

I am pretty new here , Kind of been popping in and out. been hunting around for answers around this
topic. Id taken youd code and thrown it on my Arduino Mega with the Ethernet R3 Shield.
The code runs and i can pick up the Modbus slave from TCP/IP. However there is some stuff I
dont understand in your code and how best to adapt it to what id like to do. In addition to this
i think i require some more assistance either in knowing how Mudbus library works in relation
to the digital input registers you have there. since i am not sure where or what my registers should
be on my Master side. Could anyone also recommend to me a good Master simulator .

What i intend to do is for the time being Run 2 DHT22 sensors with another 2 Analogue temperature
probes. I would also like to write values back to the Arduino for example PWM signal for control on
the other side . Its my first time run with some home automation and I would really like to experiment
with this. I would like to stick to Modbus as i want to use NodeRed for interaction and control with
all the sensory and ouputs .

madpenguin8:
Are you looking for Modbus over Serial or over Ethernet, I didn't see this mentioned anywhere. If you want a Modbus/TCP slave then I have included the Mudbus library. I have an Arduino Mega 2560 with all of it's pins mapped out with the exception of those required by the Ethernet shield. I have this sketch working with an industrial HMI for a home automation type system, it works quite well. Some of the pins have thermistors connected, I multiply by 10 so I can divide by 10 on the master and carry a decimal place. For diagnostics I made a holding register for the Slave's free ram as well as two holding registers that hold the 32bit millis() value split into two 16 bit words. All of the other holding registers are just raw ADC values from analogRead(). If you're using an UNO or any other Arduino with less pins then just remove the lines that map to pins you don't have.

Hope this helps.

#include <SPI.h>

#include <Ethernet.h>

#include "Mudbus.h"

Mudbus Mb;

void setup()
{
 //Setup networking
   uint8_t mac[] = { 0x90, 0xA2, 0xDA, 0x00, 0x51, 0x06 };
   IPAddress ip(10, 0, 0, 11);
   IPAddress gateway = ( 10, 0, 0, 53 );
   IPAddress subnet  = ( 255, 255, 255, 0 );
   Ethernet.begin(mac, ip, gateway, subnet);
   
   Mb.ConnectionTimeout = 100;
   pinMode(2, OUTPUT);
   pinMode(3, OUTPUT);
   pinMode(5, OUTPUT);
   pinMode(6, OUTPUT);
}

void loop()
{
   // Read the current state of the pins before calling Run()
   // This allows you to read forced pin state changes
   // Any writes after connecting to the master are written after
   Mb.C[0] = digitalRead(0);
   Mb.C[1] = digitalRead(1);
   //Mb.C[2] = digitalRead(2);
   //Mb.C[3] = digitalRead(3);
   Mb.C[4] = false;
   //Mb.C[5] = digitalRead(5);
   //Mb.C[6] = digitalRead(6);
   Mb.C[7] = digitalRead(7);
   Mb.C[8] = digitalRead(8);
   Mb.C[9] = digitalRead(9);
   Mb.C[10] = false;
   Mb.C[11] = digitalRead(11);
   Mb.C[12] = digitalRead(12);
   Mb.C[13] = digitalRead(13);
   Mb.C[14] = digitalRead(14);
   Mb.C[15] = digitalRead(15);
   Mb.C[16] = digitalRead(16);
   Mb.C[17] = digitalRead(17);
   Mb.C[18] = digitalRead(18);
   Mb.C[19] = digitalRead(19);
   Mb.C[20] = digitalRead(20);
   Mb.C[21] = digitalRead(21);
   Mb.C[22] = digitalRead(22);
   Mb.C[23] = digitalRead(23);
   Mb.C[24] = digitalRead(24);
   Mb.C[25] = digitalRead(25);
   Mb.C[26] = digitalRead(26);
   Mb.C[27] = digitalRead(27);
   Mb.C[28] = digitalRead(28);
   Mb.C[29] = digitalRead(29);
   Mb.C[30] = digitalRead(30);
   Mb.C[31] = digitalRead(31);
   Mb.C[32] = digitalRead(32);
   Mb.C[33] = digitalRead(33);
   Mb.C[34] = digitalRead(34);
   Mb.C[35] = digitalRead(35);
   Mb.C[36] = digitalRead(36);
   Mb.C[37] = digitalRead(37);
   Mb.C[38] = digitalRead(38);
   Mb.C[39] = digitalRead(39);
   Mb.C[40] = digitalRead(40);
   Mb.C[41] = digitalRead(41);
   Mb.C[42] = digitalRead(42);
   Mb.C[43] = digitalRead(43);
   Mb.C[44] = digitalRead(44);
   Mb.C[45] = digitalRead(45);
   Mb.C[46] = digitalRead(46);
   Mb.C[47] = digitalRead(47);
   Mb.C[48] = digitalRead(48);
   Mb.C[49] = digitalRead(49);
   Mb.C[50] = false;
   Mb.C[51] = false;
   Mb.C[52] = false;
   Mb.C[53] = false;
   
   //Analog inputs 0-1023
   // Temperature readings using a 3k NTC thermistor
   Mb.R[0] = int(tempFromADC(analogRead(1)) * 10); //pin A0 to Mb.R[0]
   Mb.R[1] = int(tempFromADC(analogRead(2)) * 10);
   Mb.R[2] = int(tempFromADC(analogRead(2)) * 10);
   Mb.R[3] = analogRead(A3);
   Mb.R[4] = analogRead(A4);
   // Basic light measurement using a photoresistor
   Mb.R[5] = lightScale();
   Mb.R[6] = analogRead(A6);
   Mb.R[7] = analogRead(A7);
   Mb.R[8] = analogRead(A8);
   Mb.R[9] = analogRead(A9);
   Mb.R[10] = analogRead(A10);
   Mb.R[11] = analogRead(A11);
   Mb.R[12] = analogRead(A12);
   Mb.R[13] = analogRead(A13);
   Mb.R[14] = analogRead(A14);
   Mb.R[15] = analogRead(A15);
   // Slave Memory
   Mb.R[16] = freeRam();
   // Slave uptime, 32 bits carried by two (2) 16 bit registers
   long uptime = millis();
   // High word
   Mb.R[17] = uptime >> 16 & 0xFFFF;
   // Low word
   Mb.R[18] = uptime & 0xFFFF;

// Listen for the master
   Mb.Run();
   // This delay improves stability by orders of magnitude
   delay(10);
   // Set digital outs
   digitalWrite(2, Mb.C[2]);
   digitalWrite(3, Mb.C[3]);
   digitalWrite(5, Mb.C[5]);
   digitalWrite(6, Mb.C[6]);
}

double tempFromADC(int adcVal)
{
   double temp;
   // See Thermistor - Wikipedia for explanation of formula
   temp = log(((10240000/adcVal) - 10000));
   temp = 1 / (0.001129148 + (0.000234125 * temp) + (0.0000000876741 * temp * temp * temp));
   temp = temp - 273.15;          // Convert Kelvin to Celcius
   temp = (temp * 1.8) + 32.0; // Comment this line for C instead of F
   return temp;
}

int lightScale()
{
   double val = analogRead(5) / 1023.0;
   int returnVal = int(val * 1000);
   return returnVal;
}

int freeRam()
{
   extern int __heap_start, *__brkval;
   int v;
   return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval);
}