Arduino Modbus Master

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(&amp;packets[PACKET1], 1, READ_HOLDING_REGISTERS, 0, 4, 0);
//modbus_construct(&amp;packets[PACKET2], 1, PRESET_MULTIPLE_REGISTERS, 1, 1, 0);

//modbus_construct(&amp;packets[PACKET1], 1, READ_INPUT_STATUS, 0, 1, 0);
//modbus_construct(&amp;packets[PACKET2], 1, FORCE_SINGLE_COIL, 5, 1, 1);
//modbus_construct(&amp;packets[PACKET3], 1, FORCE_SINGLE_COIL, 5, 1, 1);

// Initialize the Modbus Finite State Machine
modbus_configure(&amp;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]&gt;&gt;2); // constrain adc value from the arduino slave to 255

unsigned long currentMillis = millis();
if (currentMillis - previousMillis &gt;= 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]);
  }

 

Deja un comentario