"Introduzione a Finder Opta e ai contatori di energia Finder serie 7M"

"Impara a leggere i registri del 7M utilizzando il protocollo Modbus su Finder Opta."

Guide and Tutorial | "Introduzione a Finder Opta e ai contatori di energia Finder serie 7M"

Panoramica

Tra i protocolli supportati da Finder Opta, troviamo Modbus RTU. In questo tutorial impareremo a implementare la comunicazione Modbus RTU su RS-485 tra Finder Opta e un contatore di energia Finder serie 7M. In particolare, impareremo a convertire i valori letti dai registri del 7M in valori floating point e a caricarli su Arduino Cloud.

Obiettivi

  • Imparare a stabilire la connettività dell'interfaccia RS-485 tra i dispositivi Finder Opta e Finder serie 7M.
  • Imparare a utilizzare il protocollo di comunicazione Modbus RTU per leggere i registri del 7M.
  • Imparare a convertire i valori codificati in floating point.
  • Imparare a caricare le letture di energia del 7M su Arduino Cloud.

Requisiti Hardware e Software

Requisiti Hardware

  • PLC Finder Opta con supporto RS-485 (x1).
  • Contatore di energia Finder serie 7M (x1).
  • Alimentatore DIN rail 12VDC/1A (x1).
  • Cavo USB-C® (x1).
  • Cavo per la connettività RS-485 con una delle seguenti specifiche (x3):
    • STP/UTP 24-18AWG (non terminato) con resistenza di 100-130Ω
    • STP/UTP 22-16AWG (terminato) con resistenza di 100-130Ω

Requisiti Software

  • Arduino IDE 1.8.10+, Arduino IDE 2.0+ o Arduino Web Editor.
  • Se si utilizza Arduino IDE offline, è necessario installare le librerie ArduinoRS485 e ArduinoModbus utilizzando il Library Manager di Arduino IDE.
  • Sarà necessario utilizzare Arduino Cloud per memorizzare le letture dell'energia del 7M tramite Wi-Fi®, utilizzando lo sketch fornito nella sezione successiva. È anche possibile utilizzare una connessione Ethernet per sfruttare le applicazioni Arduino Cloud. Per accedere alle funzionalità Arduino Cloud è necessario creare un account gratuito.
  • Codice di esempio.

Finder serie 7M e il protocollo Modbus

I contatori di energia Finder serie 7M forniscono accesso a una serie di input registers (registri in sola lettura) tramite il protocollo di comunicazione Modbus RTU su connessione seriale RS-485.

Come specificato nel documento Modbus communication protocol 7M, qualsiasi misura accessibile dal display del 7M è disponibile anche su Modbus tramite una serie di letture a 16 bit: ad esempio, il contatore di energia E1 è disponibile come un valore a 32 bit ottenuto combinando la lettura dei due registri a 16 bit situati agli offset 406 e 407. Si noti che tutti gli offset sono register offset e non byte offset.

Per ulteriori informazioni sul protocollo di comunicazione Modbus, dai un'occhiata a questo articolo su Modbus: tutte le funzionalità fornite dalla libreria ArduinoModbus sono supportate da Finder Opta.

Istruzioni

Configurazione dell'Arduino IDE

Per seguire questo tutorial, sarà necessaria l'ultima versione dell'Arduino IDE. Se è la prima volta che configuri il Finder Opta, dai un'occhiata al tutorial Getting Started with Opta.

Assicurati di installare l'ultima versione delle librerie ArduinoModbus e ArduinoRS485, poiché verranno utilizzate per implementare il protocollo di comunicazione Modbus RTU. Inoltre, installa la libreria ArduinoIoTCloud, necessaria per caricare i dati su Arduino Cloud.

Connessione tra Finder Opta e Finder serie 7M

Per avere dei dati da caricare su Arduino Cloud, è necessario collegare il contatore di energia Finder serie 7M alla rete elettrica e fornire un carico adeguato ad essere alimentato tramite i connettori di uscita a 240V (ad esempio una lampada). Utilizza l'alimentatore da 12VDC/1A per alimentare il Finder Opta e assicurati di configurare correttamente la connessione seriale RS-485 tra il Finder Opta e il 7M. Durante la connessione tramite interfaccia RS-485 del tuo dispositivo Finder Opta al contatore di energia Finder serie 7M puoi fare riferimento al diagramma sottostante.

Connessione tra Opta e Finder 7M

Per far funzionare il codice di esempio, è necessario configurare i seguenti parametri di comunicazione del 7M:

  • Indirizzo Modbus 2.
  • Baudrate 19200.
  • Configurazione seriale 8-N-1.

Ciò può essere fatto con facilità con il tuo smartphone utilizzando l'applicazione Finder Toolbox tramite NFC.

Panoramica del codice

Lo scopo del seguente esempio è leggere alcuni valori dal Finder serie 7M tramite Modbus e stamparli su console seriale per il debug. Inoltre, il valore del contatore di energia E1 verrà caricato su Arduino Cloud.

Il codice completo dell'esempio è disponibile qui: dopo aver estratto i file, lo sketch può essere compilato e caricato sul Finder Opta.

Si noti che il file thingProperties.h, generato da Arduino Cloud durante la configurazione del pannello di controllo, è stato leggermente modificato per leggere l'SSID e la password WiFi dal file config.h:

#define WIFI_SECRET_SSID      "YOUR SSID"
#define WIFI_SECRET_PASSWORD  "YOUR PASSWORD"

// Read from the 7M every 10 seconds
#define READ_INTERVAL_SECONDS 10

// Use WiFi to connect to Arduino Cloud
#define ARDUINO_CLOUD_USE_WIFI    1

Lettura dal 7M

I seguenti header sono necessari per abilitare il protocollo Modbus RTU, la connessione con Arduino Cloud e per importare la funzione matematica pow() di cui avremo bisogno in seguito.

Il file finder-7m.h contiene tutte le definizioni necessarie, come i parametri Modbus e gli offset dei registri.

#include <ArduinoModbus.h>
#include <ArduinoRS485.h>
#include <ArduinoIoTCloud.h>
#include <math.h>
#include "finder-7m.h"
#include "config.h"
#include "thingProperties.h"

const uint8_t MODBUS_7M_ADDRESS = 2;

void setup()
{
    Serial.begin(9600);

    digitalWrite(LEDG, HIGH);
    digitalWrite(LEDB, HIGH);
    digitalWrite(LED_D0, HIGH);
    digitalWrite(LED_D1, HIGH);
    digitalWrite(LED_D2, HIGH);
    digitalWrite(LED_D3, HIGH);

    delay(2000);

    digitalWrite(LEDG, LOW);
    digitalWrite(LEDB, LOW);
    digitalWrite(LED_D0, LOW);
    digitalWrite(LED_D1, LOW);
    digitalWrite(LED_D2, LOW);
    digitalWrite(LED_D3, LOW);

    Serial.println("Finder Opta + 7M example: setup");

    RS485.setDelays(MODBUS_PRE_DELAY_BR, MODBUS_POST_DELAY_BR);

    ModbusRTUClient.setTimeout(200);

    if (ModbusRTUClient.begin(MODBUS_BAUDRATE, MODBUS_SERIAL_PARAMETERS))
    {
        Serial.println("Modbus RTU client started");
    }
    else
    {
        Serial.println("Failed to start Modbus RTU client: reset board to restart.");
        while (1) {}
    }
}

I led sul Finder Opta lampeggiano per indicare che stiamo eseguendo la funzione setup(), quindi la connessione RS-485 viene configurata con i parametri Modbus secondo la guida Modbus over serial line. Il Baudrate viene impostato a 19200, mentre la configurazione seriale è 8-N-1.

La funzione loop() contiene il codice che legge alcuni registri del 7M e stampa i valori su console seriale per il debug:

void loop()
{
    uint32_t data;

    Serial.println("** Reading 7M at address " + String(MODBUS_7M_ADDRESS));

    data = modbus_7m_read32(MODBUS_7M_ADDRESS, FINDER_7M_REG_ENERGY_COUNTER_XK_E1);
    Serial.println("   energy = " + (data != INVALID_DATA ? String(data) : String("read error")));

    data = modbus_7m_read32(MODBUS_7M_ADDRESS, FINDER_7M_REG_RUN_TIME);
    Serial.println("   run time = " + (data != INVALID_DATA ? String(data) : String("read error")));

    data = modbus_7m_read32(MODBUS_7M_ADDRESS, FINDER_7M_REG_FREQUENCY);
    Serial.println("   frequency = " + (data != INVALID_DATA ? String(convert_t5(data)) : String("read error")));

    data = modbus_7m_read32(MODBUS_7M_ADDRESS, FINDER_7M_REG_U1);
    Serial.println("   voltage = " + (data != INVALID_DATA ? String(convert_t5(data)) : String("read error")));

    data = modbus_7m_read32(MODBUS_7M_ADDRESS, FINDER_7M_REG_ACTIVE_POWER_TOTAL);
    Serial.println("   active power = " + (data != INVALID_DATA ? String(convert_t6(data)) : String("read error")));
}

Nell'ordine leggiamo:

  • Il contatore di energia E1 nella sua versione x1000 (con incrementi di 0,1 Wh).
  • Il tempo totale di funzionamento (s).
  • La frequenza dell'ingresso AC (Hz).
  • La tensione dell'ingresso AC (V).
  • La potenza attiva istantanea totale (W).

Tutti i valori sono su 32 bit, quindi possiamo utilizzare una singola funzione per ottenere i dati grezzi per ciascuno di essi:

uint32_t modbus_7m_read32(uint8_t addr, uint16_t reg) 
{
    uint8_t attempts = 3;

    while (attempts > 0)
    {
        digitalWrite(LED_D0, HIGH);

        ModbusRTUClient.requestFrom(addr, INPUT_REGISTERS, reg, 2);
        uint32_t data1 = ModbusRTUClient.read();
        uint32_t data2 = ModbusRTUClient.read();

        digitalWrite(LED_D0, LOW);

        if (data1 != INVALID_DATA && data2 != INVALID_DATA)
        {
            return data1 << 16 | data2;
        }
        else
        {
            attempts -= 1;
            delay(10);
        }
    }

    return INVALID_DATA;
}

La funzione modbus_7m_read32() legge dal dispositivo con indirizzo Modbus addr due registri consecutivi di 16 bit partendo dall'offset reg, e li compone in un singolo valore di 32 bit facendo uno shift a destra di 16 bit del primo valore letto. ModbusRTUClient.read() restituisce sempre un risultato di 32 bit, il valore -1 (0xFFFFFFFF) indica un errore. In caso di problemi, il codice cerca di eseguire la lettura fino a tre volte, prima di arrendersi e restituire al codice chiamante in loop() il valore di errore.

Alcuni valori, come il tempo totale di funzionamento o il contenuto del contatore E1, sono valori reali a 32 bit (indicati dai codici T2 e T3 nel documento Modbus communication protocol 7M) e possono essere utilizzati senza ulteriori elaborazioni. Purtroppo, altri valori, come la frequenza della corrente di ingresso o la sua tensione, utilizzano una codifica speciale e devono essere decodificati prima di poter essere utilizzati.

float convert_t5(uint32_t n)
{
    uint32_t s = (n & 0x80000000) >> 31;
    int32_t e = (n & 0x7F000000) >> 24;
    if (s == 1) {
        e = e - 0x80;
    }
    uint32_t m = n & 0x00FFFFFF;
    return (float)m * pow(10, e);
}

La funzione convert_t5() può essere utilizzata per convertire qualsiasi valore che utilizza la codifica T5 nel corrispondente valore float. Come spiegato nel documento Modbus communication protocol 7M, T5 indica che i 32 bit vengono suddivisi nel seguente modo:

  • Gli 8 bit più significativi sono un esponente con segno, compreso tra -128 e 127.
  • I 24 bit meno significativi sono un numero senza segno, o "mantissa".

Il codice estrae il segno s e l'esponente senza segno e, e a seconda del segno determina il valore finale con segno dell'esponente. La funzione pow() viene utilizzata per elevare la mantissa m alla potenza di e, e il risultato viene restituito come float.

Invio dei dati al cloud

Per inviare i dati letti dal 7M al cloud, sarà necessario creare un account Arduino Cloud, registrare il dispositivo Finder Opta, assegnarlo ad un oggetto e aggiungere una proprietà per ogni variabile che si desidera caricare.

In questo esempio, invieremo al cloud un singolo valore: il contatore di energia E1. Dopo aver aggiunto la proprietà energy, possiamo copiare il codice generato dall'IDE Cloud nel nostro sketch thingProperties.h:

#include <ArduinoIoTCloud.h>
#include <Arduino_ConnectionHandler.h>
#include "config.h"

const char SSID[] = WIFI_SECRET_SSID;
const char PASS[] = WIFI_SECRET_PASSWORD;

float energy;

void initProperties()
{
    ArduinoCloud.addProperty(energy, Permission::Read);
}

#if ARDUINO_CLOUD_USE_WIFI == 1
    WiFiConnectionHandler ArduinoIoTPreferredConnection(SSID, PASS);
#else
    EthernetConnectionHandler ArduinoIoTPreferredConnection;
#endif

Le costanti WIFI_SECRET_SSID, WIFI_SECRET_PASSWORD e ARDUINO_CLOUD_USE_WIFI sono definite in config.h e consentono di configurare il Finder Opta per una connessione di rete WiFi o Ethernet.

La funzione setup() avrà bisogno di alcune linee di codice aggiuntive per configurare correttamente la connessione a Arduino Cloud, in particolare:

    ...

    initProperties();

    setDebugMessageLevel(2);
    ArduinoCloud.begin(ArduinoIoTPreferredConnection);
    ArduinoCloud.addCallback(ArduinoIoTCloudEvent::CONNECT, iotConnect);
    ArduinoCloud.addCallback(ArduinoIoTCloudEvent::DISCONNECT, iotDisconnect);
    ArduinoCloud.printDebugInfo();
}

Utilizzo della libreria Finder7M

Per semplificare tutte le operazioni che abbiamo eseguito in questo tutorial, è possibile utilizzare la libreria Finder7M. In questo caso, il codice di setup() è molto più semplice perché la libreria stessa fornisce funzioni integrate per configurare i parametri RS-485:

Finder7M f7m;

void setup()
{
    Serial.begin(9600);

    f7m.init();

    // Arduino Cloud or other initialization code goes here.
}

Anche il codice di loop() è più semplice:

void loop()
{
    Serial.println("** Reading 7M at address " + String(MODBUS_7M_ADDRESS));

    data = f7m.modbus7MRead32(MODBUS_7M_ADDRESS, FINDER_7M_REG_ENERGY_COUNTER_XK_E1);
    Serial.println("   energy = " + (data != INVALID_DATA ? String(data) : String("read error")));

    Measure a = f7m.getMIDInActiveEnergy(MODBUS_7M_ADDRESS);
    Serial.println("   IN active energy = " + String(a.toFloat()));
}

Per saperne di più sulla libreria, visita la repository ufficiale.

Lettura da più dispositivi Finder7M

Se desideriamo leggere dai registri di più 7M, possiamo inizializzare nel nostro programma un array contenente gli indirizzi Modbus dei dispositivi con cui vogliamo interagire:

const uint8_t addresses[4] = {6, 10, 11, 13};

Nella funzione loop() possiamo iterare con un ciclo for e utilizzare la libreria Finder7M per effettuare le letture:

void loop()
{
    for (int i = 0; i < sizeof(addresses); i++)
    {
        Serial.println("** Reading 7M at address " + String(addresses[i]));

        data = f7m.modbus7MRead32((addresses[i]), FINDER_7M_REG_ENERGY_COUNTER_XK_E1);
        Serial.println("   energy = " + (data != INVALID_DATA ? String(data) : String("read error")));

        Measure a = f7m.getMIDInActiveEnergy(addresses[i]);
        Serial.println("   IN active energy = " + String(a.toFloat()));
    }
}

Conclusioni

Questo tutorial mostra come utilizzare le librerie ArduinoRS485 e ArduinoModbus per implementare il protocollo Modbus RTU tra il Finder Opta e un contatore di energia Finder serie 7M. Inoltre, mostra come sia possibile utilizzare la libreria Finder7M per leggere facilmente contatori e altri valori da un 7M.