Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

[AVR] Problem in MODBUS RTU communication between two arduino's

Status
Not open for further replies.

Prayuktibid

Newbie level 6
Joined
Mar 30, 2017
Messages
12
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Activity points
148
I am doing a project to communicate between two arduino's using MODBUS RTU protocol. I have set One arduino as Master and Other as Slave. slave arduino connected with a potential meter to read the value analog value and store in the holding register of it. Master Arduino connected with a LED , Master read the Holding register value from Slave arduino and send PWM signal to LED according to analog value which is stored in Holding Register also show in the LCD screen. I am doing simulation on Proteous and the schematic is .. aswreswr.jpg
I am using <SimpleModbusMaster.h> and <SimpleModbusSlave.h> for Master and Slave respectevely.

Code for Master
Code:
#include <SimpleModbusMaster.h>
#include <LiquidCrystal.h>


/*
   The example will use packet1 to read a register from address 0 (the adc ch0 value)
   from the arduino slave (id=1). It will then use this value to adjust the brightness
   of an led on pin 9 using PWM.
   It will then use packet2 to write a register (its own adc ch0 value) to address 1 
   on the arduino slave (id=1) adjusting the brightness of an led on pin 9 using PWM.
*/

//////////////////// Port information ///////////////////
#define baud 115200
#define timeout 1000
#define polling 200 // the scan rate
#define retry_count 10

// used to toggle the receive/transmit pin on the driver
#define TxEnablePin 7 
#define SlaveID 1
#define LED 11

// The total amount of available memory on the master to store data
#define TOTAL_NO_OF_REGISTERS 1
LiquidCrystal lcd(12, 10, 5, 4, 3, 2);
// This is the easiest way to create new packets
// Add as many as you want. TOTAL_NO_OF_PACKETS
// is automatically updated.
enum
{
  PACKET1,
  //PACKET2,
  TOTAL_NO_OF_PACKETS // leave this last entry
};
// Create an array of Packets to be configured
Packet packets[TOTAL_NO_OF_PACKETS];

// Masters register array
unsigned int regs[TOTAL_NO_OF_REGISTERS];

void setup()
{
  Serial.begin(115200);
  lcd.begin(16, 2);
  // Initialize each packet
  modbus_construct(&packets[PACKET1], 1, READ_HOLDING_REGISTERS, 0, 1, 0); //(packet,SlaveId,Function,holdingregAdress,data,locanstartadress)
  //modbus_construct(&packets[PACKET2], 1, PRESET_MULTIPLE_REGISTERS, 1, 1, 0);

  // Initialize the Modbus Finite State Machine
  modbus_configure(&Serial, baud, SERIAL_8N2, timeout, polling, retry_count, TxEnablePin, packets, TOTAL_NO_OF_PACKETS, regs);

  pinMode(LED, OUTPUT);
}

void loop()
{
  lcd.setCursor(0, 0);
  lcd.print("MODBUS RTU");
  modbus_update();
  //regs[1] = analogRead(A0); // update data to be written to arduino slave

  analogWrite(LED, regs[0]/4);// constrain adc value from the arduino slave to 255
  lcd.setCursor(0, 1);
  lcd.print(regs[0]);
}

and The Slave Code
Code:
#include <SimpleModbusSlave.h>

    /* 
       SimpleModbusSlaveV10 supports function 3, 6 & 16.

       This example code will receive the adc ch0 value from the arduino master. 
       It will then use this value to adjust the brightness of the led on pin 9.
       The value received from the master will be stored in address 1 in its own
       address space namely holdingRegs[].

       In addition to this the slaves own adc ch0 value will be stored in 
       address 0 in its own address space holdingRegs[] for the master to
       be read. The master will use this value to alter the brightness of its
       own led connected to pin 9.

       The modbus_update() method updates the holdingRegs register array and checks
       communication.

       Note:  
       The Arduino serial ring buffer is 64 bytes or 32 registers.
       Most of the time you will connect the arduino to a master via serial
       using a MAX485 or similar.

       In a function 3 request the master will attempt to read from your
       slave and since 5 bytes is already used for ID, FUNCTION, NO OF BYTES
       and two BYTES CRC the master can only request 58 bytes or 29 registers.

       In a function 16 request the master will attempt to write to your 
       slave and since a 9 bytes is already used for ID, FUNCTION, ADDRESS, 
       NO OF REGISTERS, NO OF BYTES and two BYTES CRC the master can only write
       54 bytes or 27 registers.

       Using a USB to Serial converter the maximum bytes you can send is 
       limited to its internal buffer which differs between manufactures. 
    */

    //#define  LED 3
    #define TxEnablePin 7 
    #define SlaveID 1

    // Using the enum instruction allows for an easy method for adding and 
    // removing registers. Doing it this way saves you #defining the size 
    // of your slaves register array each time you want to add more registers
    // and at a glimpse informs you of your slaves register layout.

    //////////////// registers of your slave ///////////////////
    /*enum 
    {     
      // just add or remove registers and your good to go...
      // The first register starts at address 0
      ADC_VAL,     
      PWM_VAL,        
      HOLDING_REGS_SIZE // leave this one
      // total number of registers for function 3 and 16 share the same register array
      // i.e. the same address space
    };*/

    unsigned int holdingRegs[1]; // function 3 and 16 register array
    ////////////////////////////////////////////////////////////

    void setup()
    {
      Serial.begin(115200);
      /*parameters(HardwareSerial* SerialPort,
                    long baudrate, 
            unsigned char byteFormat,
                    unsigned char ID, 
                    unsigned char transmit enable pin, 
                    unsigned int holding registers size,
                    unsigned int* holding register array)
      */

      /* Valid modbus byte formats are:
         SERIAL_8N2: 1 start bit, 8 data bits, 2 stop bits
         SERIAL_8E1: 1 start bit, 8 data bits, 1 Even parity bit, 1 stop bit
         SERIAL_8O1: 1 start bit, 8 data bits, 1 Odd parity bit, 1 stop bit

         You can obviously use SERIAL_8N1 but this does not adhere to the
         Modbus specifications. That said, I have tested the SERIAL_8N1 option 
         on various commercial masters and slaves that were suppose to adhere
         to this specification and was always able to communicate... Go figure.

         These byte formats are already defined in the Arduino global name space. 
      */

      modbus_configure(&Serial, 115200, SERIAL_8N2,SlaveID, TxEnablePin , 1, holdingRegs);

      // modbus_update_comms(baud, byteFormat, id) is not needed but allows for easy update of the
      // port variables and slave id dynamically in any function.
      modbus_update_comms(115200, SERIAL_8N2, 1);

      //pinMode(LED, OUTPUT);
    }

    void loop()
    {
      // modbus_update() is the only method used in loop(). It returns the total error
      // count since the slave started. You don't have to use it but it's useful
      // for fault finding by the modbus master.

      modbus_update();

      holdingRegs[0] = analogRead(A0); // update data to be read by the master to adjust the PWM

      //analogWrite(LED, holdingRegs[1]/4); // constrain adc value from the arduino master to 255

      /* Note:
         The use of the enum instruction is not needed. You could set a maximum allowable
         size for holdinRegs[] by defining HOLDING_REGS_SIZE using a constant and then access 
         holdingRegs[] by "Index" addressing. 
         I.e.
         holdingRegs[0] = analogRead(A0);
         analogWrite(LED, holdingRegs[1]/4);
      */

    }

When I simulate it on Proteus It does not giving me any result. I am changing the potential meter but I am getting anything LCD screen showing 0 always and LED is OFF. That's mean two arduino is not communicating properly. Is anybody can tell how I can Solve my problem then It will be very Helpful to me.
 
Last edited by a moderator:

Hi,

what did you do to debug the system?
What are the Rx and Tx signals?

Klaus
 

I didn't debug this system
Rx and Tx signal coming from arduino's 0 and 1 pins..showing in schematic
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top