Primero se ha probado sobre un arduino Leonardo el siguiente Sketch:
#include <SimpleModbusMaster_DUE.h> /* The example will use packet1 to read a register from address 0 (the adc ch0 value) from the arduino slave (id=1). It will then use this value to adjust the brightness of an led on pin 9 using PWM. It will then use packet2 to write a register (its own adc ch0 value) to address 1 on the arduino slave (id=1) adjusting the brightness of an led on pin 9 using PWM. */ long previousMillis = 0; long interval = 1000; //////////////////// Port information /////////////////// #define baud 9600 #define timeout 1000 #define polling 200 // the scan rate #define retry_count 10 // used to toggle the receive/transmit pin on the driver #define TxEnablePin 2 #define LED 9 // The total amount of available memory on the master to store data #define TOTAL_NO_OF_REGISTERS 4 // This is the easiest way to create new packets // Add as many as you want. TOTAL_NO_OF_PACKETS // is automatically updated. enum { PACKET1, //PACKET2, //PACKET3, TOTAL_NO_OF_PACKETS // leave this last entry }; // Create an array of Packets to be configured Packet packets[TOTAL_NO_OF_PACKETS]; // Masters register array unsigned int regs[TOTAL_NO_OF_REGISTERS]; void setup() { Serial.begin(9600); // Initialize each packet modbus_construct(&packets[PACKET1], 1, READ_HOLDING_REGISTERS, 0, 4, 0); //modbus_construct(&packets[PACKET2], 1, PRESET_MULTIPLE_REGISTERS, 1, 1, 0); //modbus_construct(&packets[PACKET1], 1, READ_INPUT_STATUS, 0, 1, 0); //modbus_construct(&packets[PACKET2], 1, FORCE_SINGLE_COIL, 5, 1, 1); //modbus_construct(&packets[PACKET3], 1, FORCE_SINGLE_COIL, 5, 1, 1); // Initialize the Modbus Finite State Machine modbus_configure(&Serial1, baud, timeout, polling, retry_count, TxEnablePin, packets, TOTAL_NO_OF_PACKETS, regs); pinMode(LED, OUTPUT); } void loop() { modbus_update(); //regs[0] = analogRead(0); // update data to be written to arduino slave //analogWrite(LED, regs[0]>>2); // constrain adc value from the arduino slave to 255 unsigned long currentMillis = millis(); if (currentMillis - previousMillis >= interval) { previousMillis = currentMillis; Serial.println("valores"); Serial.println(regs[0]); Serial.println(regs[1]); Serial.println(regs[2]); Serial.println(regs[3]); } }
Destacar que el puerto serie que se emplea en el arduino Leonardo es Serial1, puesto que Serial se emplea para la comunicación mediante USB con el monitor serie del IDE de arduino.
Al intentar portar el Sketch anterior al desarrollo yunlogger, no funcionaba. Se debe a que el puerto RS232 de la parte leonardo del yun no está accesible sino que se emplea en la comunicación con la parte linux mediante la librería Bridge.
Por ello se ha empleado un puerto serie software, ha sido necesario evolucionar la librería Simple-Modbus para emplear este puerto serie software. Se puede descargar aquí: SimpleModbusMasterSoftSerial.zip
ACTUALIZADO (14/03/2015) se incorpora ejemplo de uso de la librería modificada, lectura de 4 registros desde la posición 0: SimpleModbusMasterArduino
Finalmente se ha incorporado la lectura de esclavo modbus a las funciones de adquisición de datos del desarrollo yunlogger, los cambios han sido los siguientes:
En la parte de declaración de variables:
// modbus #include <SimpleModbusMasterSoftSerial.h> #include <SoftwareSerial.h> SoftwareSerial mySerial(15, 16); // RX, TX //////////////////// Port information /////////////////// #define baud 9600 #define timeout 1000 #define polling 200 // the scan rate #define retry_count 10 // used to toggle the receive/transmit pin on the driver #define TxEnablePin 2 // The total amount of available memory on the master to store data #define TOTAL_NO_OF_REGISTERS 4 // This is the easiest way to create new packets // Add as many as you want. TOTAL_NO_OF_PACKETS // is automatically updated. enum { PACKET1, // PACKET2, TOTAL_NO_OF_PACKETS // leave this last entry }; // Create an array of Packets to be configured Packet packets[TOTAL_NO_OF_PACKETS]; // Masters register array unsigned int regs[TOTAL_NO_OF_REGISTERS]; // fin modbus
En la parte de setup():
// modbus modbus_construct(&packets[PACKET1], 1, READ_HOLDING_REGISTERS, 0, 4, 0); modbus_configure(&mySerial, baud, SERIAL_8N1, timeout, polling, retry_count, TxEnablePin, packets, TOTAL_NO_OF_PACKETS, regs); // fin modbus
Y finalmente en el bloque principal se ha definido una función nueva que se encarga de leer los registros modbus configurados anteriormente y devolverlos al cliente web:
void mbCommand(YunClient client){ client.println("ModBus"); modbus_update(); client.println(regs[0]); client.println(regs[1]); client.println(regs[2]); client.println(regs[3]); }