MODBUS protocol.

Discussion in 'Programmer's Corner' started by ajitnayak, Apr 3, 2014.

  1. ajitnayak

    Thread Starter Member

    Feb 22, 2013
    36
    0
    Dear all,

    I am trying to interface modbus protcol with Arduino . I downloaded the library form Below links.How to give slave ID, address ,function code and CHeck output for program below. along with wiring diagram.



    https://code.google.com/p/simple-modbus/.

    http://code.google.com/p/arduino-modbus-slave/downloads/detail?name=MODBUS.zip&can=2&q=.



    Code ( (Unknown Language)):
    1.  
    2. #include <SimpleModbusSlave.h>
    3.  
    4. /* This example code will receive the adc ch0 value from the arduino master.
    5.    It will then use this value to adjust the brightness of the led on pin 9.
    6.    The value received from the master will be stored in address 1 in its own
    7.    address space namely holdingRegs[].
    8.    
    9.    In addition to this the slaves own adc ch0 value will be stored in
    10.    address 0 in its own address space holdingRegs[] for the master to
    11.    be read. The master will use this value to alter the brightness of its
    12.    own led connected to pin 9.
    13.    
    14.    The modbus_update() method updates the holdingRegs register array and checks
    15.    communication.
    16.  
    17.    Note:  
    18.    The Arduino serial ring buffer is 128 bytes or 64 registers.
    19.    Most of the time you will connect the arduino to a master via serial
    20.    using a MAX485 or similar.
    21.  
    22.    In a function 3 request the master will attempt to read from your
    23.    slave and since 5 bytes is already used for ID, FUNCTION, NO OF BYTES
    24.    and two BYTES CRC the master can only request 122 bytes or 61 registers.
    25.  
    26.    In a function 16 request the master will attempt to write to your
    27.    slave and since a 9 bytes is already used for ID, FUNCTION, ADDRESS,
    28.    NO OF REGISTERS, NO OF BYTES and two BYTES CRC the master can only write
    29.    118 bytes or 59 registers.
    30.  
    31.    Using a USB to Serial converter the maximum bytes you can send is
    32.    limited to its internal buffer which differs between manufactures.
    33. */
    34.  
    35. #define  LED 13  
    36.  
    37. // Using the enum instruction allows for an easy method for adding and
    38. // removing registers. Doing it this way saves you #defining the size
    39. // of your slaves register array each time you want to add more registers
    40. // and at a glimpse informs you of your slaves register layout.
    41.  
    42. //////////////// registers of your slave ///////////////////
    43. enum
    44. {    
    45.   // just add or remove registers and your good to go...
    46.   // The first register starts at address 0
    47.   ADC_VAL,    
    48.   PWM_VAL,        
    49.   HOLDING_REGS_SIZE // leave this one
    50.   // total number of registers for function 3 and 16 share the same register array
    51.   // i.e. the same address space
    52. };
    53.  
    54. unsigned int holdingRegs[HOLDING_REGS_SIZE]; // function 3 and 16 register array
    55. ////////////////////////////////////////////////////////////
    56.  
    57. void setup()
    58. {
    59.   /* parameters(HardwareSerial* SerialPort,
    60.                 long baudrate,
    61.         unsigned char byteFormat,
    62.                 unsigned char ID,
    63.                 unsigned char transmit enable pin,
    64.                 unsigned int holding registers size,
    65.                 unsigned int* holding register array)
    66.   */
    67.  
    68.   /* Valid modbus byte formats are:
    69.      SERIAL_8N2: 1 start bit, 8 data bits, 2 stop bits
    70.      SERIAL_8E1: 1 start bit, 8 data bits, 1 Even parity bit, 1 stop bit
    71.      SERIAL_8O1: 1 start bit, 8 data bits, 1 Odd parity bit, 1 stop bit
    72.      
    73.      You can obviously use SERIAL_8N1 but this does not adhere to the
    74.      Modbus specifications. That said, I have tested the SERIAL_8N1 option
    75.      on various commercial masters and slaves that were suppose to adhere
    76.      to this specification and was always able to communicate... Go figure.
    77.      
    78.      These byte formats are already defined in the Arduino global name space.
    79.   */
    80.    
    81.  
    82.   modbus_configure(9600, 1, 2, HOLDING_REGS_SIZE, holdingRegs);
    83.   pinMode(LED, OUTPUT);
    84. }
    85.  
    86. void loop()
    87. {
    88.   // modbus_update() is the only method used in loop(). It returns the total error
    89.   // count since the slave started. You don't have to use it but it's useful
    90.   // for fault finding by the modbus master.
    91.  
    92.   modbus_update();
    93.  
    94.   holdingRegs[ADC_VAL] = analogRead(A0); // update data to be read by the master to adjust the PWM
    95.  
    96.   analogWrite(LED, holdingRegs[PWM_VAL]>>2); // constrain adc value from the arduino master to 255
    97.  
    98.   /* Note:
    99.      The use of the enum instruction is not needed. You could set a maximum allowable
    100.      size for holdinRegs[] by defining HOLDING_REGS_SIZE using a constant and then access
    101.      holdingRegs[] by "Index" addressing.
    102.      I.e.
    103.      holdingRegs[0] = analogRead(A0);
    104.      analogWrite(LED, holdingRegs[1]/4);
    105.   */
    106.  
    107. }
    108.  
    109.  
    code 2
    Code ( (Unknown Language)):
    1.  
    2. #include <modbus.h>
    3. #include <modbusDevice.h>
    4. #include <modbusRegBank.h>
    5. #include <modbusSlave.h>
    6.  
    7. /*
    8. This example code shows a quick and dirty way to get an
    9. arduino to talk to a modbus master device with a
    10. device ID of 1 at 9600 baud.
    11. */
    12.  
    13. //Setup the brewtrollers register bank
    14. //All of the data accumulated will be stored here
    15. modbusDevice regBank;
    16. //Create the modbus slave protocol handler
    17. modbusSlave slave;
    18.  
    19. void setup()
    20. {  
    21.  
    22. //Assign the modbus device ID.  
    23.   regBank.setId(1);
    24.  
    25. /*
    26. modbus registers follow the following format
    27. 00001-09999  Digital Outputs, A master device can read and write to these registers
    28. 10001-19999  Digital Inputs, A master device can only read the values from these registers
    29. 30001-39999  Analog Inputs, A master device can only read the values from these registers
    30. 40001-49999  Analog Outputs, A master device can read and write to these registers
    31.  
    32. Analog values are 16 bit unsigned words stored with a range of 0-32767
    33. Digital values are stored as bytes, a zero value is OFF and any nonzer value is ON
    34.  
    35. It is best to configure registers of like type into contiguous blocks.  this
    36. allows for more efficient register lookup and and reduces the number of messages
    37. required by the master to retrieve the data
    38. */
    39.  
    40. //Add Digital Output registers 00001-00016 to the register bank
    41.   regBank.add(1);
    42.   regBank.add(2);
    43.   regBank.add(3);
    44.   regBank.add(4);
    45.   regBank.add(5);
    46.   regBank.add(6);
    47.   regBank.add(7);
    48.   regBank.add(8);
    49.   regBank.add(9);
    50.   regBank.add(10);
    51.   regBank.add(11);
    52.   regBank.add(12);
    53.   regBank.add(13);
    54.   regBank.add(14);
    55.   regBank.add(15);
    56.   regBank.add(16);
    57.  
    58. //Add Digital Input registers 10001-10008 to the register bank
    59.   regBank.add(10001);  
    60.   regBank.add(10002);  
    61.   regBank.add(10003);  
    62.   regBank.add(10004);  
    63.   regBank.add(10005);  
    64.   regBank.add(10006);  
    65.   regBank.add(10007);  
    66.   regBank.add(10008);  
    67.  
    68. //Add Analog Input registers 30001-10010 to the register bank
    69.   regBank.add(30001);  
    70.   regBank.add(30002);  
    71.   regBank.add(30003);  
    72.   regBank.add(30004);  
    73.   regBank.add(30005);  
    74.   regBank.add(30006);  
    75.   regBank.add(30007);  
    76.   regBank.add(30008);  
    77.   regBank.add(30009);  
    78.   regBank.add(30010);  
    79.  
    80. //Add Analog Output registers 40001-40020 to the register bank
    81.   regBank.add(40001);  
    82.   regBank.add(40002);  
    83.   regBank.add(40003);  
    84.   regBank.add(40004);  
    85.   regBank.add(40005);  
    86.   regBank.add(40006);  
    87.   regBank.add(40007);  
    88.   regBank.add(40008);  
    89.   regBank.add(40009);  
    90.   regBank.add(40010);  
    91.   regBank.add(40011);  
    92.   regBank.add(40012);  
    93.   regBank.add(40013);  
    94.   regBank.add(40014);  
    95.   regBank.add(40015);  
    96.   regBank.add(40016);  
    97.   regBank.add(40017);  
    98.   regBank.add(40018);  
    99.   regBank.add(40019);  
    100.   regBank.add(40020);  
    101.  
    102. /*
    103. Assign the modbus device object to the protocol handler
    104. This is where the protocol handler will look to read and write
    105. register data.  Currently, a modbus slave protocol handler may
    106. only have one device assigned to it.
    107. */
    108.   slave._device = &regBank;  
    109.  
    110. // Initialize the serial port for coms at 9600 baud  
    111.   slave.setBaud(9600);  
    112. }
    113.  
    114. void loop()
    115. {
    116. //put some data into the registers
    117.   regBank.set(1, 1);  
    118.   regBank.set(2, 1);  
    119.   regBank.set(3, 0);  
    120.   regBank.set(4, 1);  
    121.   regBank.set(5, 1);  
    122.   regBank.set(6, 0);  
    123.   regBank.set(7, 1);  
    124.   regBank.set(8, 0);  
    125.  
    126.   regBank.set(10001, 1);
    127.   regBank.set(10002, 1);  
    128.   regBank.set(10003, 1);  
    129.   regBank.set(10004, 1);  
    130.   regBank.set(10005, 0);  
    131.   regBank.set(10006, 0);  
    132.   regBank.set(10007, 0);  
    133.   regBank.set(10008, 0);  
    134.  
    135.  
    136.   regBank.set(30001,1);
    137.   regBank.set(30002,2);
    138.   regBank.set(30003,3);
    139.   regBank.set(30004,4);
    140.   regBank.set(30005,5);
    141.   regBank.set(30006,6);
    142.   regBank.set(30007,7);
    143.   regBank.set(30008,8);
    144.   regBank.set(30009,9);
    145.   regBank.set(30010,10);
    146.  
    147.   regBank.set(40001,1);
    148.   regBank.set(40002,2);
    149.   regBank.set(40003,2);
    150.   regBank.set(40004,4);
    151.   regBank.set(40005,5);
    152.   regBank.set(40006,6);
    153.   regBank.set(40007,7);
    154.   regBank.set(40008,8);
    155.   regBank.set(40009,9);
    156.   regBank.set(40010,10);
    157.  
    158.  while(1)
    159.   {
    160.     //put a random number into registers 1, 10001, 30001 and 40001
    161.     regBank.set(1, (byte) random(0, 2));
    162.     regBank.set(10001, (byte) random(0, 2));
    163.     regBank.set(30001, (word) random(0, 32767));
    164.     regBank.set(40001, (word) random(0, 32767));
    165.    
    166.      slave.run();  
    167.   }
    168. }
    169.  
     
  2. HDowns

    New Member

    Nov 24, 2010
    5
    0
    You are truing the "Slave" library. This slave code responds to all requests (with all addresses) and supports only the function code #3 (holding registers).
     
  3. ajitnayak

    Thread Starter Member

    Feb 22, 2013
    36
    0
    How to assign the value to slave address and that can be retentive from master later.
    I have
    Code ( (Unknown Language)):
    1. analog 2 : wind sensor and temperature sensor
    2. RTC signal: A4 and A5 which give date and time
    3. Some Serial value like zenith,azimuth ,Desired angle . Which are floating
    value. How can i assign to slave address.
    Can i change slave address like 40001 instead 4001???
     
Loading...