Sommario:
2025 Autore: John Day | [email protected]. Ultima modifica: 2025-01-13 06:57
SU QUESTO PROGETTO
Se vuoi davvero rendere la tua casa più smart, probabilmente vorrai partire dalle tue bollette mensili (es. energia, gas, ecc…). Come dicono alcuni, Good for Planet, The Wallet e The Bottom Line. L'hardware open source è il nostro modo per raggiungere la sostenibilità nell'ambiente domestico! Questa idea ci ha portato a costruire una soluzione semplice e sicura, facile da integrare con qualsiasi software di domotica poiché espone i dati su MQTT (nel nostro caso ti mostreremo come integrarlo in Home Assistant).
Panoramica
Per misurare il consumo di energia elettrica, abbiamo scelto di utilizzare il Finder Energy Meter, poiché è progettato per l'uso su guida DIN e si inserisce perfettamente nell'armadio principale della nostra casa. La cosa bella di questo prodotto è che ha un'interfaccia RS485 Modbus, un protocollo di comunicazione standard industriale che rende davvero facile parlare con un Arduino. Arduino ha infatti rilasciato uno shield ufficiale, il MKR485 e due librerie per decodificare il protocollo. Come scheda madre, abbiamo scelto Arduino MKR WiFi 1010, poiché condivide il fattore di forma MKR e dispone di connettività WiFi.
ConfigurazioneAttenzione! Controlla le normative del tuo paese sulla gestione dell'impianto elettrico di casa e fai molta attenzione perché può essere mortale! Se non sai come fare, chiama un elettricista. Il primo passo è installare il contatore nel tuo armadio elettrico. Per assicurarti di lavorare in un ambiente sicuro, disattiva l'alimentazione dal terminale elettrico a monte del sistema e ricontrolla con il multimetro che non vi sia tensione tra i terminali. Quindi posiziona il contatore di energia all'interno del tuo armadio e collega i fili sotto tensione e neutro dall'interruttore principale all'ingresso del contatore, ricordati di utilizzare la convenzione di colore (blu per neutro e marrone/nero/grigio per live in UE). L'uscita deve essere collegata al resto del sistema.
Collegamenti della tensione principale. I fili sopra sono input, i fili oltre sono output.
Passaggio 1: parti necessarie
Passaggio 2: esigenze software
Software
Avvia il tuo computer e apri il tuo IDE. Puoi usare l'IDE di Arduino o l'editor di creazione di Arduino. Il codice soddisfa le seguenti richieste: Comunicazione Modbus, gestione WiFi Protocollo MQTT Modbus è un protocollo open source per sensori e macchine industriali. Per far parlare Arduino Modbus, utilizzeremo la libreria Arduino Modbus. Questa libreria racchiude tutti i gestori e rende il collegamento di qualsiasi dispositivo Modbus davvero veloce. Poiché andremo a leggere i registri, seguendo la scheda tecnica del contatore, possiamo trovare tutte le informazioni di cui abbiamo bisogno come codici funzione, indirizzo del registro e dimensione del registro in parole. Ma per essere più chiari, spieghiamo come funziona Modbus: I messaggi Modbus seguono una struttura semplice: 01 03 04 00 16 00 02 25 C7 0x01 è l'indirizzo del dispositivo 0x03 è il codice funzione che dice al dispositivo se vogliamo leggere o scrivere dati *, in questo caso, leggi holding registers 0x04 per Byte Count00 16 - Inviamo 4 byte di indirizzo di registro (00 16) che dice al dispositivo cosa vogliamo leggere 00 02- poi la dimensione del registro (00 02) in parole (ogni parola è lunga 2 byte) Gli ultimi 4 byte sono codice CRC. Questo codice è generato da una funzione matematica sui byte precedenti, questo assicura che il messaggio sia stato ricevuto correttamente.
Integrazione con Home Assistant L'aggiunta del contatore a Home Assistant è piuttosto semplice. Supponendo che tu abbia un broker MQTT configurato (ecco la guida), tutto ciò che devi fare è aggiungere nuove definizioni nel file configuration.yaml. sensore: - piattaforma: mqtt nome: "Main Voltage" state_topic: "energy/main/voltage" unit_of_measurement: "V" Qui bisogna inserire il nome della misura, il topic MQTT da leggere e l'unità di misura della grandezza. Salva il file, controlla la configurazione e ricarica Home Assistant, ora le misure appariranno nella pagina principale.
Pannello dei consumi di Home Assistant che mostra le letture correnti
Home Assistant si occuperà di creare grafici e automatizzare i processi attivati dalle tue letture. Questo tutorial è terminato, ora tocca a te aggiungere funzionalità e personalizzarlo per i tuoi scopi!
Passaggio 3: assemblare
Fatto? È ora di avvitare la connessione RS485! Utilizzeremo un cavo a doppino intrecciato con la terra, tipicamente utilizzato per le linee telefoniche. Con questo cavo è possibile trasmettere a lunga distanza (1,2 km). Tuttavia, usiamo solo un cavo abbastanza lungo per uscire dall'armadio e posizionare Arduino in un luogo accessibile.
Ricerca connessione RS485
L'interfaccia RS485 nomina i suoi terminali A, B e COM. Uno standard di fatto comune è l'uso di TX+/RX+ o D+ in alternativa a B (alto per MARK, cioè inattivo), TX-/RX- o D- in alternativa per A (basso per MARK, cioè inattivo) Lo shield MKR supporta anche il Full Duplex, vedrai altri due terminali, Y e Z. Qui andremo ad avvitare l'altra estremità del cavo poiché sappiamo dal datasheet che la comunicazione half-duplex avviene solo sui terminali Y e Z. Il terminale COM deve essere collegato a ISOGND. Poiché utilizziamo una connessione half-duplex e poiché il cablaggio è peer-to-peer, dobbiamo impostare gli interruttori sullo shield MKR485 in modo che corrispondano alla nostra configurazione: impostiamo HALF (2 su off) e terminazione su YZ (3 su SU); il primo non importa. La terminazione è una resistenza che collega i due terminali dati, per smorzare i disturbi.
Questo è. Ora puoi chiudere il cabinet e concentrarti sul lato software!
Passaggio 4: codice
#includere
#include #include #include //le tue credenziali wifi const char ssid = "**********"; const char pass = "**********";
Rete client WiFi; client MQTTClient; tasso lungo senza segno = 60000; // frequenza di aggiornamento predefinita in ms unsigned long lastMillis = 0;
//connect function void connect() { Serial.print("controllo wifi…"); while (WiFi.status() != WL_CONNECTED) { Serial.print("."); ritardo(1000); } Serial.print("\nconnessione…"); while (!client.connect("device_name", "user_name", "user_pw")) { //CAMBIA PER CORRISPONDERE ALLA TUA CONFIGURAZIONE Serial.print("."); ritardo(1000); } Serial.println("\nconnesso!"); client.subscribe("energia/principale/frequenza"); //topic per impostare la frequenza di aggiornamento in remoto } //mqtt riceve la funzione di callback void messageReceived(String &topic, String &payload) { Serial.println("incoming: " + topic + " - " + payload); if(topic == "energy/main/refreshrate"){ //refresh rate handler rate = payload.toInt()*1000; Serial.println("nuovo tasso "+String(tasso)); } }
void setup() { Serial.begin(115200); WiFi.begin(ssid, pass); mentre (!Seriale); client.begin("broker_ip", net); //CAMBIA PER CORRISPONDERE ALLA TUA CONFIGURAZIONE client.onMessage(messageReceived); // avvia il client Modbus RTU if (!ModbusRTUClient.begin(9600)) { Serial.println("Impossibile avviare il client Modbus RTU!"); mentre (1); } }
void loop() { client.loop(); if (!client.connected()) { //controlla la connessione di rete connect(); } // pubblica un messaggio dopo che è trascorso l'aggiornamento (routine non bloccante) if (millis() - lastMillis > rate) { lastMillis = millis(); //effettua tutte le chiamate di lettura float volt = readVoltage(); ritardo(100); float amp = readCurrent(); ritardo(100); doppio watt = readPower(); ritardo(100); float hz = readFreq(); ritardo(100); double wh = readEnergy(); //pubblica i risultati in argomenti correlati client.publish("energy/main/voltage", String(volt, 3)); client.publish("energia/principale/corrente", String(amp, 3)); client.publish("energia/principale/potenza", String(watt, 3)); client.publish("energia/principale/frequenza", String(hz, 3)); client.publish("energia/principale/energia", String(wh, 3)); Serial.print(Stringa(volt, 3)+"V "+Stringa(amp, 3)+"A "+Stringa(watt, 3)+"W "); Serial.println(Stringa(hz, 3)+"Hz "+Stringa(wh, 3)+"kWh"); ritardo(100); } }
/* Funzioni per leggere i registri del Finder Energy Meter * * Consultare il manuale del protocollo modbus per capire il codice * https://gfinder.findernet.com/public/attachments/7E/EN/PRT_Modbus_7E_64_68_78_86EN.pdf */ float readVoltage(){ float volt = 0.; if (!ModbusRTUClient.requestFrom(0x01, HOLDING_REGISTERS, 0x000C, 2)) { //effettua la chiamata al registro Serial.print("failed to read voltage! "); Serial.println(ModbusRTUClient.lastError()); //gestore errori }else{ uint16_t word1 = ModbusRTUClient.read(); //legge i dati dal buffer uint16_t word2 = ModbusRTUClient.read(); uint32_t millivolt = word1 << 16 | parola2; //bit matematico volt = millivolt/1000.0; } volt di ritorno; } float readCurrent(){ float ampere = 0.; if (!ModbusRTUClient.requestFrom(0x01, HOLDING_REGISTERS, 0x0016, 2)) { Serial.print("Impossibile leggere la corrente! "); Serial.println(ModbusRTUClient.lastError()); }else{ uint16_t word1 = ModbusRTUClient.read(); uint16_t word2 = ModbusRTUClient.read(); int32_t milliamp = word1 << 16 | parola2; ampere = milliampere/1000,0; } ritorno ampere; }
double readPower(){ double watt = 0.; if (!ModbusRTUClient.requestFrom(0x01, HOLDING_REGISTERS, 0x0025, 3)) { Serial.print("Impossibile leggere l'alimentazione! "); Serial.println(ModbusRTUClient.lastError()); }else{ uint16_t word1 = ModbusRTUClient.read(); uint16_t word2 = ModbusRTUClient.read(); uint16_t word3 = ModbusRTUClient.read(); uint64_t milliwatt; if(parola1 >> 7 == 0){ milliwatt = parola1