Modbus between Schneider PLC (Master) and Arduino UNO (Slave)

I want to establish Modbus RTU RS485 communication between PLC Schneider Electric TM241 (Master) and Arduino UNO (Slave). I used a MAX485 interface to make the connection. To get started I used the code I found at RS485 MODBUS Serial Communication using Arduino UNO as Slave

Since I don't use the LCD screen, I deleted this part of the code. I imported the libraries from Modbus-Master-Slave-for-Arduino/ModbusRtu.h at master · smarmengol/Modbus-Master-Slave-for-Arduino · GitHub. I created my own library named “My_Slave, renamed the .h and .cpp files the same. I also deleted some comments in the code, leaving everything else unchanged.


//RS-485 Modbus Slave (Arduino UNO)

//Circuit Digest

#include <My_Slave.h>     //Library for using Modbus and Arduino
#include <Servo.h>          //Library for using Servo Motor

#define led1 2              //Define as 2 led1 
#define led2 5              //Define as 5 led2

Servo servo;                          //Initilize servo object for class Servo
Modbus bus;                          //Define Object bus for class modbus 

uint16_t modbus_array[] = {0,0,0};    //Array initilized with three 0 values
                   
void setup()
{

  delay(5000);

  pinMode(led1,OUTPUT);           //Led1 set as OUTPUT
  pinMode(led2,OUTPUT);           //Led2 set as OUTPUT
  servo.attach(6);                //Servo PWM pin 6

  bus = Modbus(1,1,4);            //Modbus slave ID as 1 and 1 connected via RS-485 and 4 connected to DE & RE pin of RS-485 Module 
  bus.begin(9600);                //Modbus slave baudrate at 9600
}

void loop()
{
   bus.poll(modbus_array,sizeof(modbus_array)/sizeof(modbus_array[0]));       //Used to receive or write value from Master 
 
  if (modbus_array[0] == 0)    //Depends upon value in modubus_array[0] written by Master Modbus
  {
    digitalWrite(led1,LOW);    //LED OFF if 0
  }
  else
  {
     digitalWrite(led1,HIGH);  //LED ON if value other than 0
  } 

 if (modbus_array[1] == 0)    //Depends upon value in modbus_array[1] written by Master Modbus
  {
    digitalWrite(led2,LOW);   //LED OFF if 0
  }
  else
  {
     digitalWrite(led2,HIGH);  //LED ON if value other than 0
  }
 
  int pwm = modbus_array[2]; //Depends upon value in modbus_array[1] written by Master Modbus
  servo.write(pwm);          //Write Received value (0 to 180) from Modbus Master

  delay(200); 

}

The code is for writing data to the Arduino Uno, Function Code 16 "Write Multiple Registers". Everything works fine.
I myself would like to read data from the Arduino Uno (Slave), namely Function Code 03 (Read Holding Registers) and write individual pins, Function Code 05 (Write Single Coil). I can't find where in the program I should change the code to manage Function Code 03 and 05.
It would be most helpful if someone could just point me to the fix I need to put in the existing code, maybe in the .h and .cpp libraries as well, to handle the following

  • Function code 03, Register 3059 or 0x0BF3, Length 2
  • Function code 05, Register 10 or 0x0010, Length 3
    Then I myself will further study what I have to change in the existing code for Functional Code changes.
    Best regards

Maybe my question was too complicated. I'll try to simplify.
I want to use PLC Schneider as Master and Arduino Uno as Slave. Here are the settings to the Master that I want to use:
9600/none/8/1
ID 5
Read Holding Register 03
Register 0x0BF3
Length 2

I am using MAX485 module to connect between PLC and Arduino.
I am looking for the easiest code for Arduino as Slave to read value from BF3 (3059) and BF4 (3060) registers.

Best regards.

@ gusaa_01. It will be better to understand from the PLC ladder. Highlight 485 ladder section to assist write protocol.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.