1

I'm trying Arduino to Arduino (master-slave) communication using Modbus RTU protocol in RS-485. I am using an Arduino Mega 2560 for the project and using this library Modbus RTU. As of now, the master simply reads data slave and prints in the Serial monitor.

I tried the following code:

Slave

#include <ModbusRtu.h>
#define ID   3

Modbus slave(ID, 0, 0);
boolean led;
int8_t state = 0;
unsigned long tempus;
// data array for modbus network sharing
uint16_t au16data[9];

void setup() {
  // define i/o
  pinMode(2, INPUT);
  pinMode(3, INPUT);
  pinMode(4, INPUT);
  pinMode(5, INPUT);

  // start communication
  slave.begin(19200);
  tempus = millis() + 100;
  digitalWrite(13, HIGH);
}

void loop() {
  // poll messages
  // blink led pin on each valid message
  state = slave.poll( au16data, 9 );
  if (state > 4) {
    tempus = millis() + 50;
    digitalWrite(13, HIGH);
  }
  if (millis() > tempus) digitalWrite(13, LOW );
  // get digital inputs -> au16data[0]
  bitWrite( au16data[0], 0, digitalRead( 2 ));
  bitWrite( au16data[0], 1, digitalRead( 3 ));
  bitWrite( au16data[0], 2, digitalRead( 4 ));
  bitWrite( au16data[0], 3, digitalRead( 5 ));

  // diagnose communication
  au16data[6] = slave.getInCnt();
  au16data[7] = slave.getOutCnt();
  au16data[8] = slave.getErrCnt();
}

Master

#include <ModbusRtu.h>

// data array for modbus network sharing
uint16_t au16data[16];
uint8_t u8state;

/**
 *  Modbus object declaration
 *  u8id : node id = 0 for master, = 1..247 for slave
 *  u8serno : serial port (use 0 for Serial)
 *  u8txenpin : 0 for RS-232 and USB-FTDI 
 *               or any pin number > 1 for RS-485
 */
Modbus master(0,1,1); // this is master and RS-485

/**
 * This is an structe which contains a query to an slave device
 */
modbus_t telegram;

unsigned long u32wait;

void setup() {
  master.begin(19200); // baud-rate at 19200
  master.setTimeOut(2000); // if there is no answer in 2000 ms, roll over
  u32wait = millis() + 1000;
  u8state = 0; 
  Serial.begin(9600);
}

void loop() {
  Serial.print(u8state);
  switch(u8state) {
  case 0:
    if (millis() > u32wait) u8state++; // wait state
    break;
  case 1: 
    telegram.u8id = 1; // slave address
    telegram.u8fct = 3; // function code (this one is registers read)
    telegram.u16RegAdd = 1; // start address in slave
    telegram.u16CoilsNo = 4; // number of elements (coils or registers) to read
    telegram.au16reg = au16data; // pointer to a memory array in the Arduino
    master.query(telegram); // send query (only once)
    u8state++;
    break;
  case 2:
    master.poll(); // check incoming messages
    if (master.getState() == COM_IDLE) {
      u8state = 0;
      u32wait = millis() + 100; 
    }
    break;
  }
  Serial.println(au16data[0])
}

The output in the serial monitor is not changed when the input at Pin 2 is high in slave.

20
00

Could someone please tell me the possible cause and solution? If I've missed out anything, over- or under-emphasized a specific point, let me know in the comments.

dda
  • 6,030
  • 2
  • 25
  • 34
Nithin Varghese
  • 893
  • 1
  • 6
  • 28
  • Why are you using a 40 years old communication protocol in a new application? – Lundin Feb 08 '18 at 10:00
  • @Lundin this is bit of the topic, but can u suggest any serial protocol which can be implemented in RS485 serial channel using arduino, I to need send bit data of 40 digital pins form slave and send string to string as response, I considered mod bus because it has CRC and quite new to this – Nithin Varghese Feb 08 '18 at 10:38
  • 1
    UART-based stuff is overall stone age technology, so I wouldn't recommend any serial protocol (HDLC is as ancient as Modbus, and Profibus is nearly as bad). Why can't you use CAN instead of RS-485? – Lundin Feb 08 '18 at 10:42
  • @Lundin Thanks , CAN bus is a great choice . But, sorry, I am instructed to develop in RS485 . – Nithin Varghese Feb 08 '18 at 10:57
  • LOL, CAN bus is 10 times more complicated than a simple modbus rs485 – Ricardo Casimiro Jan 12 '22 at 15:37

0 Answers0