Allora, non so se ho capito bene le tue esigenze.
Tu vuoi comunicare ad arduino uno o più valori analogici.
Questo viene fatto con la funzione di scrittura degli holding registers (FC06 oppure FC16).
Se prendi l'esempio ModbusRTUSlaveExample, devi fare riferimento alle righe che contengono la scritt HoldingRegisters.
Hai:
- la definizione del numero di registri da gestire (ogni registro è un valore a 16 bit)
- l'array che conterrà la definizione
- il setup della libreria, dove indichi l'array
- la chiamata periodica a modbus.poll()
- l'utilizzo dei valori letti.
- l'identificativo dello slave modbus, in questo caso "1":
#define MODBUS_UNIT_ID 1
Nell'esempio, due valori vengono utilizzati per variare la luminosità del led, comandato in analogico in PWM.
Qui ti riporto l'esempio in cui ho cancellato le altre funzioni (ingressi uscite digitali e ingressi analogici).
Ti ho lasciato solamente le uscite analogiche.
Per essere sicuro del funzionamento, ho testato il programma con un master modbus generico.
Codice: Seleziona tutto
/*
ModbusRTUSlaveExample
This example demonstrates how to setup and use the ModbusRTUSlave library (https://github.com/CMB27/ModbusRTUSlave).
See README.md (https://github.com/CMB27/ModbusRTUMaster/blob/main/examples/ModbusRTUSlaveExample/README.md) for hardware setup details.
Created: 2023-07-22
By: C. M. Bulliner
Last Modified: 2024-10-26
By: C. M. Bulliner
*/
#include <ModbusRTUSlave.h>
#if defined(__AVR_ATmega328P__) || defined(__AVR_ATmega168__) || defined(__AVR_ATmega2560__) || defined(__AVR_ATmega1280__) || defined(ARDUINO_SAM_DUE)
// The ATmega328P and ATmega168 are used in the Ardunino UNO and similar boards.
// The ATmega2560 and ATmega1280 are used in the Arduino Mega and similar.
#define MODBUS_SERIAL Serial
#elif defined(ARDUINO_NANO_ESP32)
// On the Arduino Nano ESP32, the HardwareSerial port on pins 0 and 1 is Serial0.
#define MODBUS_SERIAL Serial0
#else
// On the majority of Arduino boards, the HardwareSerial port on pins 0 and 1 is Serial1.
// On the Arduino Mega and Adruino Due, Serial1 is on pins 18 and 19.
#define MODBUS_SERIAL Serial1
#endif
// You can change the baud, config, and unit id values if you like.
// Just make sure they match the settings you use in ModbusRTUMasterExample.
#define MODBUS_BAUD 38400
#define MODBUS_CONFIG SERIAL_8N1
#define MODBUS_UNIT_ID 1
#if (defined(ARDUINO_NANO_RP2040_CONNECT) && !defined(ARDUINO_ARCH_MBED)) || defined(ARDUINO_NANO_ESP32)
// These boards operate unsing GPIO numbers that don't correspond to the numbers on the boards.
// However they do have D# values #defined to correct this.
const int8_t buttonPins[2] = {D2, D3};
const int8_t ledPins[4] = {D5, D6, D7, D8};
const int8_t dePin = D13;
#else
// Other boards do not have D# values, and will throw an error if you try to use them.
const int8_t buttonPins[2] = {2, 3};
const int8_t ledPins[4] = {5, 6, 7, 8};
const int8_t dePin = 13;
#endif
const int8_t knobPins[2] = {A0, A1};
ModbusRTUSlave modbus(MODBUS_SERIAL, dePin);
const uint8_t numHoldingRegisters = 4;
uint16_t holdingRegisters[numHoldingRegisters];
void setup() {
pinMode(knobPins[0], INPUT);
pinMode(knobPins[1], INPUT);
pinMode(buttonPins[0], INPUT_PULLUP);
pinMode(buttonPins[1], INPUT_PULLUP);
pinMode(ledPins[0], OUTPUT);
pinMode(ledPins[1], OUTPUT);
pinMode(ledPins[2], OUTPUT);
pinMode(ledPins[3], OUTPUT);
#if defined(ARDUINO_NANO_ESP32)
analogReadResolution(10);
#endif
modbus.configureHoldingRegisters(holdingRegisters, numHoldingRegisters);
MODBUS_SERIAL.begin(MODBUS_BAUD, MODBUS_CONFIG);
modbus.begin(MODBUS_UNIT_ID, MODBUS_BAUD, MODBUS_CONFIG);
}
void loop() {
modbus.poll();
analogWrite(ledPins[0], holdingRegisters[0]);
analogWrite(ledPins[1], holdingRegisters[1]);
}