Help With MODBUS MASTER-SLAVE TURNING "ON" OUTPUTS

Hi all of you. (Sorry for my english)

I am trying to communicate two Arduinos, one is the Master and the other is the Slave, I am using the “ModbusRTU.h” library to communicated it, and I send and recive the correct information, but when i want to use that information i have error, can you help me ?

Here is the Sketch for the Master:

/**
 *  Modbus master example 2:
 *  The purpose of this example is to query several sets of data
 *  from an external Modbus slave device. 
 *  The link media can be USB or RS232.
 *
 *  Recommended Modbus slave: 
 *  diagslave http://www.modbusdriver.com/diagslave.html
 *
 *  In a Linux box, run 
 *  "./diagslave /dev/ttyUSB0 -b 19200 -d 8 -s 1 -p none -m rtu -a 1"
 *   This is:
 *    serial port /dev/ttyUSB0 at 19200 baud 8N1
 *    RTU mode and address @1
 */

#include <ModbusRtu.h>
#include <SoftwareSerial.h>
#define ID   0
//#define Led 3

uint16_t au16data[16]; //!< data array for modbus network sharing

uint8_t u8state; //!< machine state
uint8_t u8query; //!< pointer to message query


/**
 *  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,2); // this is master and RS-232 or USB-FTDI

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

unsigned long u32wait;

SoftwareSerial mySerial(0, 1);

void setup() {

ioset_up();
  // telegram 0: read registers
  telegram[0].u8id = 1; // slave address
  telegram[0].u8fct = 2; // function code (this one is registers read)
  telegram[0].u16RegAdd = 0; // start address in slave
  telegram[0].u16CoilsNo = 4; // number of elements (coils or registers) to read
  telegram[0].au16reg = au16data[0]; // pointer to a memory array in the Arduino
 

  // telegram 1: write a single register
  //telegram[1].u8id = 2; // slave address
  //telegram[1].u8fct = 2; // function code (this one is write a single register)
  //telegram[1].u16RegAdd = 0; // start address in slave
  //telegram[1].u16CoilsNo = 4; // number of elements (coils or registers) to read
  //telegram[1].au16reg = au16data[0]; // pointer to a memory array in the Arduino

  Serial.begin( 19200);
  master.begin( 19200 ); // baud-rate at 19200
  master.begin( &mySerial, 19200 ); 
  master.setTimeOut( 5000 ); // if there is no answer in 5000 ms, roll over
  u32wait = millis() + 1000;
  u8state = u8query = 0; 

  pinMode(6, OUTPUT);
  pinMode(7, OUTPUT);
  pinMode(8, OUTPUT);
  pinMode(9, OUTPUT);



 
}

void loop() {
  io_poll();

  switch( u8state ) {
  case 0: 
    if (millis() > u32wait) u8state++; // wait state
    break;
  case 1: 
    master.query( telegram[u8query] ); // send query (only once)
    u8state++;
  u8query++;
  if (u8query > 2) u8query = 0;
    break;
  case 2:
    master.poll(); // check incoming messages
    if (master.getState() == COM_IDLE) {
      u8state = 0;
      u32wait = millis() + 1000; 

    
   Serial.print(au16data[0]);
 


    }
    break;

  // set digital outputs -> au16data[0]
  digitalWrite( 6, bitRead( au16data[0], 0 ));
  digitalWrite( 7, bitRead( au16data[0], 1 ));
  digitalWrite( 8, bitRead( au16data[0], 2 ));
  digitalWrite( 9, bitRead( au16data[0], 3 ));
 
  }

  

  }

What i want to do is get the INPUTS in the Slave and show these INPUTS like OUTPUTS in the Master device

Here is the code for de Slave.

/**
 *  Modbus slave example 2:
 *  The purpose of this example is to link the Arduino digital and analog
 *  pins to an external device.
 *
 *  Recommended Modbus Master: QModbus
 *  http://qmodbus.sourceforge.net/
 */

#include <ModbusRtu.h>
#include <SoftwareSerial.h>
#define ID   1

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

// data array for modbus network sharing
uint16_t au16data[9];
SoftwareSerial mySerial(0, 1);//
/**
 *  Setup procedure
 */
void setup() {
  io_setup(); // I/O settings

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

/**
 *  Loop procedure
 */
void loop() {
  // poll messages
  // blink led pin on each valid message
  state = slave.poll( au16data, 9 );

  if (state > 4) {
    u32wait = millis() + 50;
    digitalWrite(13, HIGH);
  }
  if (millis() > u32wait) digitalWrite(13, LOW );

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

/**
 * pin maping:
 * 2 - digital input
 * 3 - digital input
 * 4 - digital input
 * 5 - digital input
 * 6 - digital output
 * 7 - digital output
 * 8 - digital output
 * 9 - digital output
 * 10 - analog output
 * 11 - analog output
 * 14 - analog input
 * 15 - analog input
 *
 * pin 13 is reserved to show a successful query
 */
void io_setup() {
  // define i/o
  pinMode(3, INPUT);
  pinMode(4, INPUT);
  pinMode(5, INPUT);
  pinMode(6, INPUT);



  digitalWrite(13, HIGH ); // this is for the UNO led pin

}

/**
 *  Link between the Arduino pins and the Modbus array
 */
void io_poll() {
  // get digital inputs -> au16data[0]
  bitWrite( au16data[0], 0, digitalRead( 3 ));
  bitWrite( au16data[0], 1, digitalRead( 4 ));
  bitWrite( au16data[0], 2, digitalRead( 5 ));
  bitWrite( au16data[0], 3, digitalRead( 6 ));


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

I am using a TTL to RS485 module to transmit the data betwen diveces

campaul22 wrote:

and I send and recive the correct information

Great, so the Modbus side works, is that correct ?

but when i want to use that information i have error, can you help me ?

What error, I am having trouble seeing it, maybe you can, so we can not help, correct ?

Also, try to remember to provide links to any libraries or specific hardware you use, so we do not try to fry our brains guessing all the time.


Paul - VK7KPA

SoftwareSerial mySerial(0, 1);

You cannot have a SoftwareSerial connected to the hardware serial pins and use Serial at the same time.

BTW: if ever possible don't use SoftwareSerial for the main communication. Use it for debugging as there it's not so critical if you loose some bytes. I've never seen SoftwareSerial communicating reliably at speeds over 9600 baud. And even if you're lucky and the serial communication works, you're Arduino is doing almost nothing else than handling the emulated serial communication during a transfer because the emulation stops all interrupts and blocks the complete processor during the transfer of a complete byte.

If you want to have a debugging possibility and still get some processor runtime, use AltSoftSerial for debugging (it uses fixed pins for that) and do the RS-485 communication using the hardware serial interface.