SoftwareSerial Arduino NANO

Hola; Termine de desarrollar una aplicación que trabaja como interprete LADDER-ARDUINO.

Estoy sumándole mas salidas y bloques de función para tener comunicación RS485 (halfduplex) y me tope con un gran problema; Al querer implementar SoftwareSerial en los puertos D13 y D12, no me esta funcionando. Leí en el foro varios ejemplos y la mayoría implementan los pines D10 y D11; Esto es debido a la librería?
De mi preferencia, y por una cuestión de comodidad al hacer el PCB, preferiría implementar esos puertos, pero si estoy obligado a emplear los otros puertos, arranco de cero nuevamente

Un ejemplo de como funciona la aplicación: https://www.youtube.com/watch?v=C1CCBDz9oY0

Moderador
Tema movido a documentación.

Para los interesados en probar el programa

Gracias Ricardo; En realidad me hubiera sido de mas ayuda la consulta original, pero la auto resolví y decidí no caminar en contra marea, y usar D10-D11 para Software Serial. Bien… Actualice la versión y sume bloques de funciones para poder comunicar empleando Modbus RS485… Ahora justamente estoy en el proceso de la creación de un manual y mini curso de Ladder para sumar dentro de la aplicación, y cuando termine, voy analazar los mensajes y correos para sumar mas funciones y brindar soporte para trabajarlo a elección con un NANO 328 o un ESP32. Un pequeño adelanto de la pregunta original:

Guía de uso de Modbus RS485 en uPLC v4

Descripción General

El uPLC v4 ahora incluye soporte completo para comunicación Modbus RTU sobre RS485, permitiendo comunicación con otros dispositivos industriales como PLCs, sensores, y actuadores compatibles con Modbus.

Hardware

Conexiones RS485

  • RX → D10 (SoftwareSerial)
  • TX → D11 (SoftwareSerial)
  • SE/RE → D12

Nueva Salida

  • Q6 → D13 (salida digital)

Configuración del Sistema

El Arduino NANO funciona como Modbus Master por defecto con ID=1.

Registros Modbus Disponibles

El sistema incluye 10 registros Modbus locales (MB0-MB9) que pueden ser:

  • Leídos desde dispositivos esclavos
  • Escritos hacia dispositivos esclavos
  • Usados como condiciones en la lógica ladder (MB_SLAVE)

Bloques Modbus en el Ladder

1. MB_SLAVE (Condición)

Descripción: Evalúa el valor de un registro Modbus local.

Uso:

  • Ref: MB0 a MB9 (registro a evaluar)
  • Value: Valor de comparación (0-255)

Ejemplo: Si MB0 == 100, entonces activar Q1

[MB_SLAVE:MB0=100] ────────> [COIL:Q1]

2. MB_READ (Salida)

Descripción: Lee un registro Holding (función 03) desde un dispositivo esclavo.

Uso:

  • Ref: MB0 a MB9 (registro local donde guardar el valor leído)
  • Value: ID del dispositivo esclavo (1-10)

Ejemplo: Leer registro del esclavo ID=2 y guardarlo en MB0

[NO:I1] ────────> [MB_READ:MB0, Slave=2]

3. MB_WRITE (Salida)

Descripción: Escribe un registro Single (función 06) a un dispositivo esclavo.

Uso:

  • Ref: MB0 a MB9, V0 a V9, o valor constante (dato a enviar)
  • Value: ID del dispositivo esclavo (1-10)

Ejemplo: Escribir el valor de V5 al esclavo ID=3

[NO:I2] ────────> [MB_WRITE:V5, Slave=3]

Formato del Frame Modbus

Lectura (Request):

Byte 1: ID Esclavo     (ej: 01)
Byte 2: Función        (03 = Read Holding Registers)
Byte 3: Dirección (H)  (00)
Byte 4: Dirección (L)  (00)
Byte 5: Cantidad (H)   (00)
Byte 6: Cantidad (L)   (01)
Byte 7: CRC (L)        (calculado)
Byte 8: CRC (H)        (calculado)

Respuesta (Response):

Byte 1: ID Esclavo     (01)
Byte 2: Función        (03)
Byte 3: Cantidad Bytes (02)
Byte 4: Dato (H)       (00)
Byte 5: Dato (L)       (FA = 250 decimal)
Byte 6: CRC (L)        (39)
Byte 7: CRC (H)        (93)

Ejemplos de Aplicación

Ejemplo 1: Leer sensor de temperatura remoto

Rung 1: Leer temperatura cada 1 segundo
[TON:T0=1000] ───> [MB_READ:MB0, Slave=5]

Rung 2: Si temperatura > 80°C, activar alarma
[MB_SLAVE:MB0] [CMP_GT:MB0>80] ───> [COIL:Q1]

Ejemplo 2: Controlar válvula remota

Rung 1: Si nivel alto, cerrar válvula remota
[NO:I1] ───> [SET_VAR:V0=1]
[NO:I1] ───> [MB_WRITE:V0, Slave=3]

Rung 2: Si nivel bajo, abrir válvula remota
[NC:I1] ───> [SET_VAR:V0=0]
[NC:I1] ───> [MB_WRITE:V0, Slave=3]

Ejemplo 3: Sincronización entre PLCs

Rung 1: Enviar estado de proceso al PLC principal
[NO:M0] ───> [MB_WRITE:M0, Slave=1]

Rung 2: Recibir comandos del PLC principal
[TON:T1=500] ───> [MB_READ:MB1, Slave=1]
[MB_SLAVE:MB1=1] ───> [COIL:Q2]

Librería Requerida

La librería ModbusMaster de Doc Walker debe estar instalada en el Arduino IDE:

Sketch > Include Library > Manage Libraries > Buscar "ModbusMaster"

Notas Importantes

  1. CRC Automático: La librería ModbusMaster calcula automáticamente el CRC.
  2. Timeout: Si un esclavo no responde, el registro local no se actualiza.
  3. Baudrate: Por defecto 9600 bps, modificar en setup() si es necesario.
  4. Direccionamiento: Los registros Modbus comienzan en dirección 0.
  5. Valores: Los registros MB son de 16 bits (0-65535), pero se mapean a 8 bits (0-255) para compatibilidad con Variables V.

Troubleshooting

El esclavo no responde

  • Verificar cableado RS485 (A, B, GND)
  • Verificar que el ID del esclavo es correcto
  • Verificar baudrate coincidente
  • Verificar resistencia de terminación en el bus RS485

Lecturas incorrectas

  • Verificar polaridad del bus RS485
  • Reducir longitud del cable o agregar terminación
  • Verificar que no hay interferencia electromagnética

Display muestra valores erróneos

  • Los registros MB se actualizan solo cuando hay comunicación exitosa
  • Verificar en Serial Monitor (9600 bps) los mensajes de debug

Lo vi tarde...

En teoría podrías usar los pines D8 a D13 (con la salvedad que D13 tiene conectado el LED L y puede interferir).

Hola, como estas? Gracias por sumarte….

La verdad, en algún momento me volví loco por no entender donde radicaba el problema, y mas aun cuando funcionaba con D10/11/12 :sweat_smile: ; Así que deje la comodidad del diseño del HARDWARE y reme a favor de corriente…. Estoy viendo videos, leyendo tópicos y hoja de datos. Estoy viendo la manera de integrar el ESP32 y no morir en el intento.
Pasando en limpio, el ESP32 tiene pines con funciones críticas durante el arranque que me pueden hacer que el hardware no encienda o entre en modo de error si lo conecto a periféricos externos (como relés o sensores) sin precaución.

Acá tengo un lilstado de los pines que tengo que evitar o usar con cuidado… Está mas que claro que donde me equivoque, por favor márquenmelo:

  1. Pines Prohibidos (Memoria Flash Interna): GPIO 6 al GPIO 11 (etiquetados como CLK, SD0, SD1, SD2, SD3, CMD). Por lo que interpreto, no los tengo que usar bajo ninguna circunstancia. Estos pines están conectados internamente a la memoria donde se guarda el programa, y si intento usarlos, el ESP32 se bloquea o se reiniciará constantemente...

  2. Pines Solo de Entrada (GPI): GPIO 34, 35, 36 y 39.
    Noté que a diferencia del Nano, donde casi cualquier pin es entrada/salida, estos pines no pueden ser salidas y tampoco tienen resistencias pull-up o pull-down internas; si los uso como entradas digitales externamente tengo que sumar resistencias físicas externas.

  3. Pines de Arranque (Strapping Pins): GPIO 0, GPIO 2, GPIO 12 y GPIO 15.
    No se si interprete mal, pero entiendo que estos son los más peligrosos para el hardware del uPLC; O sea, El ESP32 "lee" su estado (alto o bajo) justo en el milisegundo en que se enciende para decidir si debe ejecutar el código o entrar en modo de grabación. Si el hardware externo (ej. un relé con pull-up) cambia este estado, el hardware de uPLC no arrancaría... (No recuerdo bien, pero creo que esto lo lei de SurByte o del foro en ingles)

GPIO 0: Debe estar en ALTO para ejecución normal. Si tu sensor lo pone en BAJO al encender, el PLC se quedará esperando una carga de firmware.
GPIO 2: Debe estar en BAJO o flotante. Evita conectarlo a cargas pesadas al inicio.
GPIO 12 (MTDI): Si está en ALTO al arrancar, puede fallar el voltaje de la memoria flash.
GPIO 15: Controla la salida de mensajes de depuración por el puerto serie durante el arranque.

  1. Conflicto con el ADC y Wi-Fi
    Si implementara Wi-Fi para telemetría, tendria que evitar usar los pines del ADC2 (GPIO 0, 2, 4, 12-15, 25-27) como entradas analógicas, ya que el driver de Wi-Fi toma prioridad sobre ellos y las lecturas serán erróneas. O sea, tendria que usar solo los del ADC1 (GPIO 32 a 39) para señales analógicas seguras... eso me genera duda y pone en riesgo la versión con el ESP32...

PASANDO EN LIMPIO:

  • Uso Seguro (OK): GPIO 4, 13, 14, 16, 17, 18, 19, 21, 22, 23, 25, 26, 27, 32, 33
  • Usar con Cuidado (Arranque): GPIO 0, 2, 5, 12, 15
  • Solo Entrada (Digital/Analógica): GPIO 34, 35, 36, 39
  • Prohibidos (Flash): GPIO 6, 7, 8, 9, 10, 11
  • Comunicación I2C: GPIO 21 y 22
  • Comunicación Serial: GPIO 16 y 17

Si alguien me da una mano con este tema, creo que en semana y media, dos, sale la otra versión…

Simple respuesta

Bien, ya estoy re-mapeando todo y arrancando la próxima versión. En esta voy a ir con un poco mas de cautela y detenimiento para no cerrar nada sin antes tener varias opiniones de 3eros… El software ya llego a 1.5k de descargas y el correo esta que explota. Así que de media maquina que venia, ahora me puse a todo vapor.

El primer paso es tener soportería para varios tipos de placas. El ESP8266 es muy económico, pero no tengo la misma disponibilidad de puertos que con su par hermano mayor, el ESP32, asi que lo descarte y por el momento seria ESP32, Arduino NANO (328) y para un par de sensores RS485 que estoy trabajando para sumar, quizás Arduino micro (Intente trabajarlo con el Atinny85, pero me queda muy chico)…

En cuanto a funcionalidades; La próxima versión, la misma salida PWM va tener una función extra mas, que seria una salida para control de servo; Esto viendo la posibilidad de ver como trabajar el hardware para las entradas analógicas y trabajar los estándares 4-20mA / 0-10v.

Probé y debugue varias horas la nueva función de comunicación Modbus RS485 y aun no eh tenido problemas, pero necesita mas horas de pruebas para ver si encuentro algún error o limitante.

uPLCv4 cuenta hasta el momento:

  • 7 Entradas digitales.

  • 6 salidas relay.

  • 1 salida PWM / Digital Open Collector.

  • 2 entradas analógicas.

  • Funciones: AND/OR/Ton/Toff/Modbus/9 espacios para Marcas (memorias o relay internos)/PWM/Condicionales “Mayor que”-”Menor que”-”Igual que”/9 espacios de almacenamiento (variables).

Este es el momento en el cual, si les gusto el proyecto, pueden aportar ideas para sumar mejoras al hardware o bloques de funciones especiales para el software…

Todo aporte, por mas granito de arena o tremendo meteorito que sea, son mas que bienvenidos.

Saludos desde la Patagonia Argentina