3.2. Ejemplo de comunicacion ModBus
Ejemplo de comunicación modbus RTU con UART RS232 en Arduino.
Programa ejemplo de comunicación slave modbus RTU.
/*
* MicroPLCModBus. Control del microPLC con ModBus
*
* Descripción: Control de los relés de salida de la placa microPLC mediante códigos enviados
* desde el terminal serie con el protocolo ModBus.
*
* Autor: Rafa Aranda
* Fecha: 26-3-2020
* Versión: 1.0
*/
// Asignación de Pins a Salidas digitales
#define Out_1 6
#define Out_2 7
#define Out_3 8
#define Out_4 9
#define PWM_1 11
// Pins de entrada (están ordenados de forma decreciente por necesidades del PCB)
#define In_1 5
#define In_2 4
#define In_3 3
#define In_4 2
#define ADC_1 A0
// Librerías
#include <ArduinoRS485.h> // ArduinoModbus depends on the ArduinoRS485 library
#include <ArduinoModbus.h>
// Funciones prototipo
void getInputs(void);
void setOutputs(void);
// Variables globales
//Definición de las variables de trabajo
/* setup
* Tareas iniciales de preparación
*/
void setup()
{
// Iniciar las comunicaciones en serie
Serial.begin(9600);
Serial.println("MicroPLC Modbus RTU Server");
// start the Modbus RTU server, with (slave) id 2
if (!ModbusRTUServer.begin(2, 9600)) {
Serial.println("Failed to start Modbus RTU Server!");
while (1);
}
// Configurar 4 bobinas empezando en la dirección 0x00
ModbusRTUServer.configureCoils(0x00, 4);
// Configurar 4 entradas empezando en la dirección 0x00
ModbusRTUServer.configureDiscreteInputs(0x00, 4);
// Configurar 1 registro de mantenimiento empezando en la dirección 0x00
ModbusRTUServer.configureHoldingRegisters(0x00, 1);
// Configurar 6 registros de entrada empezando en la dirección 0x00
ModbusRTUServer.configureInputRegisters(0x00, 6);
// Establecer los pins de salida de los relés
pinMode(Out_1, OUTPUT);
pinMode(Out_2, OUTPUT);
pinMode(Out_3, OUTPUT);
pinMode(Out_4, OUTPUT);
// Establecer los pins de entradas digitales optoacopladas
pinMode(In_1, INPUT);
pinMode(In_2, INPUT);
pinMode(In_3, INPUT);
pinMode(In_4, INPUT);
}
/* loop
* Programa principal
*/
void loop(){
getInputs(); // Leer las entradas digitales
ModbusRTUServer.poll(); // Sondear las consultas Modbus RTU
//-------- MI PROGRAMA DE MICROPLC --------
//-----------------------------------------
setOutputs(); // Activar las salidas
delay(1); // CicloScan + 1ms, retardo para anti-rebotes
}
/* GetInputs
* Lee el estado de la entrada indicada en el parámetro y lo asigna invertido a las variables de trabajo
*/
void getInputs(void){
// Entradas digitales
// Asignar el estado de la entrada (pin físico) a la entrada asignada en ModBus
// NOTA: discreteInputWrite Retorna un 1 si ha funcionado 0 si no ha funcionado
ModbusRTUServer.discreteInputWrite(0x00, !digitalRead(In_1));
ModbusRTUServer.discreteInputWrite(0x01, !digitalRead(In_2));
ModbusRTUServer.discreteInputWrite(0x02, !digitalRead(In_3));
ModbusRTUServer.discreteInputWrite(0x03, !digitalRead(In_4));
// Entradas analogicas
ModbusRTUServer.inputRegisterWrite(0x00, analogRead(ADC_1));
/* s._1=!digitalRead(In_1);
s._2=!digitalRead(In_2);
s._3=!digitalRead(In_3);
s._4=!digitalRead(In_4);*/
}
/* setOutputs
* Asigna el estado de las variables de trabajo a las salidas digitales
*/
void setOutputs(void){
// Salidas digitales
// Escribir en la salida el valor de la bobina asignada en ModBus
// NOTA: Retorna un entero con 0,1 y -1 (error)
digitalWrite(Out_1, ModbusRTUServer.coilRead(0x00));
digitalWrite(Out_2, ModbusRTUServer.coilRead(0x01));
digitalWrite(Out_3, ModbusRTUServer.coilRead(0x02));
digitalWrite(Out_4, ModbusRTUServer.coilRead(0x03));
// Salidas analogicas
analogWrite(PWM_1, ModbusRTUServer.holdingRegisterRead(0x00));
/*digitalWrite(Out_1, k._1);
digitalWrite(Out_2, k._2);
digitalWrite(Out_3, k._3);
digitalWrite(Out_4, k._4);*/
}