Después de caer en un vórtice espacio-tiempo (por muchas ocupaciones) vuelvo a escribir en el blog, muchos han preguntado como se usa la librería ModbusSerial
En la siguiente foto se pueden observar los elemento necesarios para hacer la prueba de la librería
El cable usb se conecta al PC en mi caso uso el ModSim para emular una Remota; este cable va conectado el conector RS232 el cual se coloca en el Protoboard para Arduino y con los cables se hace la conección final.
Se debe usar el código fuente base para usar la libreria Modbusserial.
Si no queremos que se muestre por la consola las respuesta de la remota solo se debe comentar la linea
#define VERBOSE
en la libreria modbusseriallib.h
-------------------------------------------------------------
#include <SoftwareSerial.h>
#include "modbusseriallib.h"
#define RXPIN 4
#define TXPIN 5
SoftwareSerial PLCSerialPort(RXPIN, TXPIN);
ModbusSerial ModbusSerial(&PLCSerialPort);
void setup()
{
Serial.begin(9600);
PLCSerialPort.begin(9600);
}
void loop()
{
// your program //
}
-------------------------------------------------------------
Como verán se puede cambiar el pin RX y TX de acuerdo a sus necesidades
El Objeto instanciado se llama ModbusSerial y se usa de la siguiente manera:
FC1
En caso de que deseen llamar la función fc1 de la librería deberán de tener la siguiente consideración
* Es una función de lectura por lo tanto deben declarar una variable que reciba la información de la remota.
* Si queremos ver la respuesta utilizamos un pequeño ciclo for
Veamos el siguiente ejemplo: Si queremos preguntar por 37 discrete coils desde la direccion 20 inclusive, del Device 17 (ojo viene en formato decimal), codificamos lo siguiente:
byte deviceId=17;
unsigned short start=20;
int numValues=37;
unsigned short values[numValues]; // aquí se almacena la respuesta
ModbusSerial.fc1(deviceId,start,numValues,values);
for(int i=0;i<numValues-1;i++)
{
Serial.print(values[i]);
Serial.print(",");
}
Serial.println(values[numValues-1]);
Si tomamos en cuenta las respuestas que están en la entrada anterior "http://fernandezajp.blogspot.com/2013/01/libreria-modbus-serial-para-arduino.html", obtendríamos la respuesta de la siguiente manera
MSG:11,1,0,13,0,25,E,10
10 received.
PACKET:11,1,5,CD,6B,B2,E,1B,45,E6
Read successful
1,0,1,1,0,0,1,1,1,1,0,1,0,1,1,0,0,1,0,0,1,1,0,1,0,1,1,1,0,0,0,0,1,1,0,1,1
FC2
El mismo esquema aplicaría para la función fc2, en este caso la dirección de inicio es la 10197 y leeremos solo 22 valores luego lo almacenamos en la variable values.
byte deviceId=17;
unsigned short start=10197;
int numValues=22;
unsigned short values[numValues]; // aquí se almacena la respuesta
ModbusSerial.fc2(deviceId, start, numValues,values);
for(int i=0;i<numValues-1;i++)
{
Serial.print(values[i]);
Serial.print(",");
}
Serial.println(values[numValues-1]);
Respuesta
MSG:11,2,0,C4,0,16,BA,8
8 received.
PACKET:11,2,3,CD,6B,32,45,C4
Read successful
1,0,1,1,0,0,1,1,1,1,0,1,0,1,1,0,0,1,0,0,1,1
FC3
Función fc3 (Read Holding Registers), ahora leeremos 3 valores a partir de la dirección 40108 y lo almacenaremos en la variable values.
byte deviceId=17;
unsigned short start=40108;
int numValues=3;
unsigned short values[numValues];
ModbusSerial.fc3(deviceId, start, numValues, values);
for(int i=0;i<numValues-1;i++)
{
Serial.print(values[i],HEX);
Serial.print(",");
}
Serial.println(values[numValues-1],HEX);
La respuesta que obtendríamos seria
MSG:11,3,0,6B,0,3,76,11
11 received.
PACKET:11,3,6,AE,41,56,52,43,40,49,AD
Read successful
AE41,5652,4340
FC4
Función fc4 (Read Input Registers), ahora leeremos 1 valor correspondiente a la dirección 30009 y lo almacenaremos en la variable values.
byte deviceId=17;
unsigned short start=30009;
int numValues=1;
unsigned short values[numValues];
ModbusSerial.fc4(deviceId, start, numValues, values);
for(int i=0;i<numValues-1;i++)
{
Serial.print(values[i],HEX);
Serial.print(",");
}
Serial.println(values[numValues-1],HEX);
Respuesta:
MSG:11,4,0,8,0,1,B2,7
7 received.
PACKET:11,4,2,0,A,F8,F4
10 Read successful
A
Ahora veamos ahora una de escritura
FC5
Esta función escribe un solo dato en una dirección específica por eso tiene menos parámetros
ej: escribir en la dirección 173 del DeviceId = 17 el valor de True
byte deviceId=17;
unsigned short start=173;
ModbusSerial.fc5(deviceId, start, true);
Respuesta
MSG:11,5,0,AC,0,FF,4F,8
8 received.
PACKET:11,5,0,AC,0,FF,4F,3B
Read successful
El mismo caso aplica para los analógicos
FC6
Ej: Escribir en la dirección 40002 el valor de 3
byte deviceId=17;
unsigned short start=40002;
unsigned short value=3;
ModbusSerial.fc6(deviceId, start, value);
Respuesta
MSG:11,6,0,1,0,3,9A,8
8 received.
PACKET:11,6,0,1,0,3,9A,9B
Read successful
Para escribir múltiples valores discretos utilizamos la función 15
FC15
ej: Escribir un arreglo binario de 10 valores binarios en la dirección 20 del device 17.
byte deviceId=17;
unsigned short start=20;
int numValues=10;
boolean values[numValues];
values[0] = 1;
values[1] = 1;
values[2] = 0;
values[3] = 1;
values[4] = 0;
values[5] = 0;
values[6] = 1;
values[7] = 1;
values[8] = 1;
values[9] = 0;
ModbusSerial.fc15(deviceId, start, numValues, values);
Respuesta
MSG:11,F,0,13,0,A,2,CB,1,BC,8
8 received.
PACKET:11,F,0,13,0,A,26,99
Read successful
el mismo esquema para los analógicos
FC16
Escribir un arreglo de 2 valores en la dirección 40002 del device 17.
byte deviceId=17;
unsigned short start=40002;
int numValues=2;
unsigned short values[numValues];
values[0] = 0xA;
values[1] = 0x102;
ModbusSerial.fc16(deviceId, start, numValues, values);
Respuesta
MSG:11,10,0,1,0,2,4,0,A,1,2,C6,8
8 received.
PACKET:11,10,0,1,0,2,12,98
Read successful