User: alciro    User
 

Microcontrolador ESP32

Share |
 ESP32 ejemplo de comunicación ModBus
 ESP32 Ejemplo de comunicación ModBus en modo AP Access Point
 Ejemplo de comunicación ModBus RTU con el ESP32 como slave RS485
 ModBus guía de referencia

Ejemplo de comunicación ModBus RTU con el ESP32 como slave RS485

/*
*  Ejemplo de comunicación ModBus RTU con el ESP32 como esclavo
*  
*  Descripción: Programa básico para utilizar una placa PCB de ESP32 como unidad remota de entradas
*  y salidas digitales y analógicas, utilizando comunicación modbus sobre RTU, con UART y RS485
*
*  Autor: Rafa Aranda
*  Fecha: 05-02-2026
*  Versión: 1.0
*/

// ------------------- Librerías -------------------
#include   // ModBus RTU de Alexander Emelianov "andresarmento/modbus-esp8266"

ModbusRTU mb; // Instancia a ModbusRTU

// ------------------- Declaraciones -------------------
#define SLAVE_ID  1             // Identificador del dispositivo
#define MODBUS_BAUD_RATE  9600  // Velocidad de comunicación para ModBus RTU


#define N_COILS  4 // Numero de bobinas
#define N_DISCRETE_INPUTS  4 // Numero de entradas discretas
#define N_INPUT_REGISTERS  2 // Numero de registros de entrada
#define N_HOLDING_REGISTERS  6 // Numero de registros de mantenimiento
/* Tabla ModBus
  Bobimas
  0   Salida digital  R/W
  1   Salida digital  R/W
  2   Salida digital  R/W
  3   Salida digital  R/W
  Entradas discretas
  0   Entrada digital  R
  1   Entrada digital  R
  2   Entrada digital  R
  3   Entrada digital  R
  Registros de entrada
  0   ADC 0            R
  1   ADC 1            R
  Registros de mantenimiento
  0   PWM 0            R/W
  1   PWM 1            R/W
  2   Configuración 1  R/W 
  3   Configuración 2  R/W 
  4   Configuración 3  R/W 
  5   Configuración 4  R/W 

  Esta tabla se ha de modificar según la aplicación, añadiendo o quitando elementos 
  y definiendo su función especifica.
*/

// ------------------- Pines -------------------
#define RS485_DE_RE 4 // Pin de control a la placa RS485
#define RXD2 16       // Pin Rx de la UART2 a la placa RS485
#define TXD2 17       // Pin Tx de la UART2 a la placa RS485

uint8_t dinPins[4]  = {32, 33, 34, 35}; // Entradas digitales
uint8_t doutPins[4] = {25, 26, 27, 14}; // Salidas digitales
uint8_t ainPins[2]  = {36, 39};         // Entradas analogicas
uint8_t pwmPins[2]  = {18, 19};         // Salidas PWM

// ------------------- Variables -------------------
uint16_t analogIn[2];
uint16_t pwmOut[2];
uint16_t configReg[4];

// ------------------- Funciones prototipo -------------------
void setupHardware();  // Inicializa pines, UART y PWM.
void setupModbus();  // Inicializa la librería Modbus y los registros.
void updateDigitalInputs();  // Actualiza entradas digitales a Modbus.
void updateDigitalOutputs(); // Actualiza salidas digitales desde Modbus.
void updateAnalogInputs(); // Lee ADC y actualiza registros Modbus.
void updatePWMOutputs(); // Escribe PWM desde registros Modbus.
void updateConfigRegisters();  // Maneja los registros de configuración.

// ------------------- Setup -------------------
void setup() {
  Serial.begin(115200);
  setupHardware();
  setupModbus();
}

// ------------------- Loop -------------------
void loop() {
  updateDigitalInputs();  // Leemos las entradas digitales y actulizamos en entradas modbus
  updateAnalogInputs();   // Leemos las entradas analogicas y actulizamos en registros de entrada modbus
  
  mb.task();  // Atención de Modbus

  // PROGAMA DE AUTOMATIZACIÓN DE......
  //----------------------------------------------------------------------------------------------------
  /* Aquí mi programa de automatización utilizando los datos de las bobinas y registros modbus como
    parámetros y consignas para hacer mi proyecto..... */
  /* Si queremos tener un programa estructurado es mejor poner las accines necesarias dentro de funciones "update..."
    y mantener el programa principal limpio de codigo, dejando unicamente las llamadas a las funciones */



  //----------------------------------------------------------------------------------------------------
  updateDigitalOutputs(); // Escribimos las salidas digitales de estado de bobinas modbus
  updatePWMOutputs();     // Escribimos las salidas analógicas PWM de estado de registros de mantenimiento modbus
  updateConfigRegisters();// Actualizamos los registros de configuración de estado de registros de mantenimiento modbus
  delay(10);      // Modificar para dar estabilidad el sistema (0-10), !no utilizar valores elevados¡
}

// ==================== FUNCIONES ====================

// -------- Inicialización hardware ----------
void setupHardware() {
  // RS485 UART
  Serial2.begin(MODBUS_BAUD_RATE, SERIAL_8N1, RXD2, TXD2);

  // Pines digitales
  for (int i = 0; i < 4; i++) {
    pinMode(dinPins[i], INPUT);
    pinMode(doutPins[i], OUTPUT);
  }

  // PWM
  for (int i = 0; i < 2; i++) {
    ledcSetup(i, 2000, 10);   // canal, frecuencia, resolución bits
    ledcAttachPin(pwmPins[i], i);
  }
}

// -------- Inicialización Modbus ----------
void setupModbus() {
  mb.begin(&Serial2, RS485_DE_RE);  // Iniciamos la UART2
  mb.slave(SLAVE_ID);               // Iniciamos la instancia ModBus con el ID del slave

  // Entradas digitales (Discrete Inputs)
  for (int i = 0; i < N_DISCRETE_INPUTS; i++) mb.addIsts(i);

  // Salidas digitales (Coils)
  for (int i = 0; i < N_COILS; i++) mb.addCoil(i);

  // Entradas analógicas (Input Registers)
  for (int i = 0; i < N_INPUT_REGISTERS; i++) mb.addIreg(i);

  // Salidas PWM y registros config (Holding Registers)
  for (int i = 0; i < N_HOLDING_REGISTERS; i++) mb.addHreg(i);  // 0,1 = PWM, 2–5 = Configuración
}

// -------- Actualizar entradas digitales ----------
void updateDigitalInputs() {
  for (int i = 0; i < 4; i++) {
    mb.Ists(i, digitalRead(dinPins[i]));
  }
}

// -------- Actualizar salidas digitales ----------
void updateDigitalOutputs() {
  for (int i = 0; i < 4; i++) {
    digitalWrite(doutPins[i], mb.Coil(i));
  }
}

// -------- Leer entradas analógicas ----------
void updateAnalogInputs() {
  for (int i = 0; i < 2; i++) {
    analogIn[i] = analogRead(ainPins[i]);
    mb.Ireg(i, analogIn[i]);
  }
}

// -------- Actualizar salidas PWM ----------
void updatePWMOutputs() {
  for (int i = 0; i < 2; i++) {
    pwmOut[i] = constrain(mb.Hreg(i), 0, 1023); // Limitar el valor entre 0 y 1023 (10bits)
    ledcWrite(i, pwmOut[i]);
  }
}
/* ledcWrite ESP32 equivale a analorWitre de arduino 
  const int ledChannel = 0;    // Canal PWM, puede ser de 0 a 15
  const int ledPin = 5;        // Pin al que está conectado el dispositivo
  const int frequency = 5000;  // Frecuencia en Hz
  const int resolution = 8;    // Resolución en bits (de 1 a 15)
  ledcSetup(ledChannel, frequency, resolution);

  int dutyCycle = 128; // Valor del ciclo de trabajo (0 a 255)
  ledcWrite(ledChannel, dutyCycle);
*/
// -------- Actualizar registros de configuración ----------
void updateConfigRegisters() {
  for (int i = 0; i < 4; i++) {
    configReg[i] = mb.Hreg(i + 2);  // 40003–40006
  }
}

 

Loading

copyright © 2007-2026  www.alciro.org  All rights reserved.         
Share |