/*
ModbusRTU ArduinoUno
Demo unit as Slave ModbusRTU for TMR-Qsoft
by Haitham L. Sungkar, ft. Moh-Bustanul Ulum
(magang Mhsw Walisongo Semarang)
(c)2023 TESTINDO (TESTINDO.com)
created 31-Aug-2018
modified 12 Jan 2024
Library:
https://github.com/emelianov/modbus-esp8266
*/
#include <ModbusRTU.h>
#include <Servo.h>
#define SLAVE_ID 1
// Modbus Registers Offsets (0-9999)
const int Ireg_ai1 = 0; //
const int Ireg_ai2 = 1; // 4x Input Register (Analog Input)
const int Ireg_ai3 = 2; //
const int Ireg_ai4 = 3; //
const int Ists_di1 = 0; //
const int Ists_di2 = 1; // 4x Input Status (Digital Input)
const int Ists_di3 = 2; //
const int Ists_di4 = 3; //
const int Coil_do1 = 0; //
const int Coil_do2 = 1; // 4x Coil Status (Digital output)
const int Coil_do3 = 2; //
const int Coil_do4 = 3; //
#define Hreg_10 10 // 1x Sample for Holding Register
// Used Pins on ArduinoUno
const int ai_0 = A0; //Linear potensio
const int ai_1 = A1; //Rotary potensio
const int ai_2 = A2; //LDR sensor
const int ai_3 = A3; //sensor4 <GND>
const int di_0 = 5; //ldr
const int di_1 = 6; //switch / PIR
const int di_2 = 7; //digital3
const int di_3 = 8; //digital4
const int ao_pwm_9 = 9; // PWM Output
const int do_0 = 10; //led1
const int do_1 = 11; //led2
const int do_2 = 12; //led3
const int do_3 = 13; //led4
// ModbusSerial object
ModbusRTU mb;
// Servo
Servo oServo; // create servo object
int valServo;
void setup() {
// Config Serial Port (baudrate, byte format [strbit_parity_stopbit])
Serial.begin(115200, SERIAL_8N1);
// Detect if used device is ESP32 or ESP8266
#if defined(ESP32) || defined(ESP8266)
mb.begin(&Serial);
#else
mb.begin(&Serial);
//mb.begin(&Serial, RXTX_PIN); //or use RX/TX direction control pin (if required)
mb.setBaudrate(9600);
#endif
// Set the Slave ID (1-247)
mb.slave(SLAVE_ID);
oServo.attach(ao_pwm_9);
// Use Hreg for Holding Register (AO or PWM)
mb.addHreg(Hreg_10);
mb.Hreg(Hreg_10, 100); // Initilialize Register Value
valServo = mb.Hreg(Hreg_10); //map(mb.Hreg(Hreg_10),-360, -360, 360, 360); // Scale to Servo range
oServo.write(valServo);
// Use addIreg() for analog Inputs
mb.addIreg(Ireg_ai1);
mb.addIreg(Ireg_ai2);
mb.addIreg(Ireg_ai3);
mb.addIreg(Ireg_ai4);
// Set pin mode for digital inputs
pinMode(di_0, INPUT);
pinMode(di_1, INPUT);
pinMode(di_2, INPUT);
pinMode(di_3, INPUT);
// Use addIsts() for digital inputs
mb.addIsts(Ists_di1);
mb.addIsts(Ists_di2);
mb.addIsts(Ists_di3);
mb.addIsts(Ists_di4);
// Set pin mode for digital outputs
pinMode(ao_pwm_9, OUTPUT); // used for PWM output
pinMode(do_0, OUTPUT);
pinMode(do_1, OUTPUT);
pinMode(do_2, OUTPUT);
pinMode(do_3, OUTPUT);
// Use addCoil() for digital outputs
mb.addCoil(Coil_do1);
mb.addCoil(Coil_do2);
mb.addCoil(Coil_do3);
mb.addCoil(Coil_do4);
}
void loop() {
// Call once inside loop() - all magic here
mb.task();
yield();
// Raw value (0-1023)
mb.Ireg(Ireg_ai1, analogRead(ai_0));
mb.Ireg(Ireg_ai2, analogRead(ai_1)); // Read from @ Analog Input Pin
mb.Ireg(Ireg_ai3, analogRead(ai_2)); // to @ Input Register
mb.Ireg(Ireg_ai4, analogRead(ai_3));
mb.Ists(Ists_di1, digitalRead(di_0));
mb.Ists(Ists_di2, digitalRead(di_1));
mb.Ists(Ists_di3, digitalRead(di_2));
mb.Ists(Ists_di4, digitalRead(di_3));
valServo = mb.Hreg(Hreg_10); //map(mb.Hreg(Hreg_10),-360, -360, 360, 360); // Scale to Servo range
oServo.write(valServo);
digitalWrite(do_0, mb.Coil(Coil_do1));
digitalWrite(do_1, mb.Coil(Coil_do2));
digitalWrite(do_2, mb.Coil(Coil_do3));
digitalWrite(do_3, mb.Coil(Coil_do4));
delay(100);
}