/** * Modbus master example 1: * The purpose of this example is to query an array 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> // 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,0,0); // this is master and RS-232 or USB-FTDI /** * 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; } 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 = 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; } }
The master requires:
- A memory array, which is linked to the communication network, and this role is assigned to au16data array.
- A master object, which sends queries and receives answers through Serial port. This belongs to Modbus class and is assigned to address 0.
- An object or a set of objects to query, which are modbus_t type;
- A machine state to make queries and wait for answers in the loop section.
The modbus object
This is the master definition. As in a Modbus slave, there are some parameters to define it:- node id u8id is always 0;
- Serial port u8SerNo must be 0 in an Arduino UNO and could be 0, 1, 2 and 3 in an Arduino Mega;
- the txenpin is the pin that makes the flow control for the RS-485 transceiver, if any.
The memory array
This is the place to link the data pooled through the network with the controller program.For instance, in a network with an weather station and a cooling system, the master controller must fetch data from the weather station and send commands to the cooling system.
The machine state
The master should consider 3 states:- wait state (with no telegrams)
- send query
- wait for answer or generate a time-out event
- restart
Results
./diagslave /dev/ttyUSB0 -b 19200 -d 8 -s 1 -p none -m rtu -a 1
