A
A
Andrey Kovalchuk2016-05-30 08:55:06
Arduino
Andrey Kovalchuk, 2016-05-30 08:55:06

Modbus RTU how to send and process a request?

Good day. There is the following situation:
Three Android devices: 1 master-Arduino Mega, 2- slave - Arduino Nano. Everything should communicate via the Modbus Rtu protocol, why via it? Part of the graduation project, a prerequisite and all that.
RS485 interface.
Here is simple-master

#include <ModbusRtu.h>

// data array for modbus network sharing
uint16_t au16data[10];
uint8_t u8state;
#define TXEN  4 


Modbus master(0,0,TXEN); // this is master and RS-232 or USB-FTDI

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; 
}

void loop() {
  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 = 4; // start address in slave
    telegram.u16CoilsNo = 1; // 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;
  }
}

Here is simple-slave
#include <ModbusRtu.h>
#define ID   1

Modbus slave(ID, 0, 0); // this is slave ID and RS-232 or USB-FTDI
boolean led;
int8_t state = 0;
unsigned long tempus;

// data array for modbus network sharing
uint16_t au16data[9];

void setup() {
  io_setup(); // I/O settings

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


void loop() {
  // poll messages
  // blink led pin on each valid message
  state = slave.poll( au16data, 9 );
  digitalWrite( 6, HIGH);
  if (state > 4) {
    tempus = millis() + 50;
    digitalWrite(13, HIGH);
  }
  if (millis() > tempus) digitalWrite(6, LOW );

  // link the Arduino pins to the Modbus array
  io_poll();
} 

void io_setup() {
 
  pinMode(2, INPUT);
  pinMode(3, INPUT);
  pinMode(4, INPUT);
  pinMode(5, INPUT);
  pinMode(6, OUTPUT);
  pinMode(7, OUTPUT);
  pinMode(8, OUTPUT);
  pinMode(9, OUTPUT);
  pinMode(10, OUTPUT);
  pinMode(11, OUTPUT);
  pinMode(13, OUTPUT);

  digitalWrite(6, LOW );
 
  digitalWrite(13, LOW ); // this is for the UNO led pin
  
}


void io_poll() {
  au16data[4] = analogRead( 4 );
 

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

I see that the master forms a telegram of the modbus_t type. What does this slave do? More precisely, what the line does:
slave.poll( au16data, 16 );
And this block:
if (master.getState() == COM_IDLE) {
      u8state = 0;
      u32wait = millis() + 100; 
      
    }

When you work with a master client somehow everything is somehow easier.
Upd. Updated master and slave 31.05 10:19 Moscow time

Answer the question

In order to leave comments, you need to log in

1 answer(s)
O
Ocelot, 2016-05-30
@mrkovalchuk

The master sends packets. The slave listens to the line, and when it sees a packet, it processes it and responds. slave.poll() is just responsible for receiving, processing the packet and sending the response. This method needs to be periodically pulled in the main loop, on a timer or just like that. If the master hasn't sent anything, slave.poll() simply exits. All modbus registers are mapped to the slave memory (au16data[] array), you can read/write them at any time. More precisely, not quite in any, but when slave.poll () is not called.
Block

if (master.getState() == COM_IDLE) {
      u8state = 0;
      u32wait = millis() + 100;       
    }
gives a delay of 100ms before the next modbus poll. The wizard code implements a simple three-state state machine.
1) u8state == 1 Send request
2) u8state == 2 Receive response
3) u8state == 0 Delay

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question