Protocollo ABB Aurora
Ecco intanto le informazioni di base del protocollo di comunicazione RS485 ABB Aurora.
La comunicazione tra Host e processore funziona tramite un’interfaccia seriale RS485 o RS232.
I parametri di configurazione in entrambi i casi sono:
- 19200 baud (valore predefinito)
- 1 bit di stop
- nessuna parità
Il protocollo di comunicazione utilizza messaggi di trasmissione a lunghezza fissa (8Byte + 2Byte per Checksum) strutturati come segue:
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
Address | Command | B2 | B3 | B4 | B5 | B6 | B7 | CRC_L | CRC_H |
Anche la struttura della risposta ha una lunghezza fissa (6 Byte + 2 Byte per Checksum):
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
Transmission State | Global State | B2 | B3 | B4 | B5 | CRC_L | CRC_H |
Lo stato di trasmissione è codificato come segue:
0 = Va tutto bene.
51 = Il comando non è implementato
52 = La variabile non esiste
53 = Il valore della variabile è fuori intervallo
54 = EEprom non accessibile
55 = Modalità servizio non commutata
56 = Impossibile inviare il comando al micro interno
57 = Comando non eseguito
58 = La variabile non è disponibile, riprova
Global State mostra lo stato del dispositivo indirizzato, i dettagli sono specificati nella descrizione dei comandi.
Ho realizzato questa libreria per realizzare a sua volta questo Monitor Web dell’inverter Aurora
Arduino UNO e MAX485
Puoi usare un Arduino UNO e un IC MAX485, se preferisci puoi acquistare un modulo.
You can find IC on AliExpress
You can find module on AliExpress
You can ArduinoUNO on Arduino UNO - Arduino MEGA 2560 R3 - Arduino Nano - Arduino Pro Mini
Qui il semplice schema di connessione, il resistore deve essere 120Ω, ma io uso 104Ω.
Ho creato una libreria derivata da un progetto che puoi trovare nel web creato da drhack, è un lavoro fantastico (grazie a drhack) ma lo trovo abbastanza difficile da usare, con hardware specifico e non così riutilizzabile.
Quindi cerco di standardizzare la libreria e renderla semplice (le persone che usano le mie libreria sanno che “semplificare” è il mio motto.
esp8266 e MAX3485
Se vuoi usare un esp8266 (sto creando una centralina con Wemos D1 mini) devi acquistare un MAX3485 che funzioni alla giusta tensione.
You can find IC on AliExpress
You can find module on AliExpressAliExpress
You can find WeMos D1 mini on WeMos D1 mini - NodeMCU V2 V2.1 V3 - esp01 - esp01 programmer
Qui il semplice schema di connessione, il resistore deve essere 120Ω, ma io uso un 104Ω.
Come puoi vedere è abbastanza semplice connettersi.
Libreria
Puoi trovare la mia libreria qui.
Scaricare.
- Fare clic sul pulsante DOWNLOADS nell’angolo in alto a destra, rinominare la cartella non compressa ABB_Aurora_Solar_Inverter_Library.
- Verifica che la cartella ABB_Aurora_Solar_Inverter_Library contenga Aurora.cpp e Aurora.h.
- Posiziona la cartella della libreria ABB_Aurora_Solar_Inverter_Library nella tua cartella / libraries /.
- Potrebbe essere necessario creare la sottocartella delle librerie se è la tua prima libreria.
- Riavvia l’IDE.
L’elenco dei comandi è abbastanza ampio, ma proverò a spieghere tutto.
Costruttore
Come al solito cercherò di crearlo il più generico possibile, quindi potrai usarlo con HardwareSeria
l o SoftwareSerial
, sei libero di scegliere.
Come puoi vedere nella descrizione del pacchetto
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
Address | Command | B2 | B3 | B4 | B5 | B6 | B7 | CRC_L | CRC_H |
è necessario specificare un indirizzo, che normalmente è 2, ma è necessario selezionarlo nel menu dell’inverter.
È possibile creare una catena di inverter che comunicano tramite RS485. È possibile scegliere un indirizzo da 2 a 63. L’impostazione dell’indirizzo sull’inverter avviene tramite il display e la pulsantiera.
Per cambiare l’indirizzo vai a SETTINGS --> Insert password (default 0000) --> Address
.
Questo menù permette di impostare gli indirizzi delle porte seriali dei singoli inverter collegati alla linea RS485.
Gli indirizzi assegnabili sono da 2 a 63. I pulsanti UP e DOWN scorrono la scala numerica.
Al momento non è possibile utilizzare la selezione “AUTO”.
HardwareSerial
// Aurora(byte inverterAddress, HardwareSerial* serial, byte serialCommunicationControlPin)
Aurora inverter = Aurora(2, &Serial, 5);
inverterAddress
: come descritto è l’indirizzo dell’inverter impostato sul dispositivo.serial
: è l’HardwareSerial
.serialCommunicationControlPin
: è il pin che attiva la trasmissione della comunicazione seriale.
SoftwareSerial
// Aurora(byte inverterAddress, byte rxPin, byte txPin, byte serialCommunicationControlPin)
Aurora inverter = Aurora(2, 10, 11, 5);
inverterAddress
: come descritto è l’indirizzo dell’inverter impostato sul dispositivo.rxPin:
è il pin SoftwareSerial RX.txPin:
è il pin SoftwareSerial TX.serialCommunicationControlPin
: è il pin che attiva la trasmissione della comunicazione seriale.
Per il software seriale è possibile passare l’istanza SoftwareSerial esterna.
// Aurora(byte inverterAddress, SoftwareSerial* serial, byte serialCommunicationControlPin)
Utilizzo
Per prima cosa devi avviare la comunicazione con il comando begin
:
inverter.begin();
Ci sono molti comandi che puoi usare per fare query al tuo inverter:
Richiesta stato inverter
Il primo comando importante è readState per ottenere lo stato del tuo inverter:
Aurora::DataState dataState = inverter.readState();
La struttura in risposta ha 4 attributi e 4 funzioni:
byte inverterState;
byte channel1State;
byte channel2State;
byte alarmState;
String getDcDcChannel1State()
String getDcDcChannel2State()
String getInverterState()
String getAlarmState()
Naturalmente gli attributi sono il codice, la funzione è la descrizione dello stato.
Versione inverter
Con questo comando si ottiene la versione del software dell’inverter:
Aurora::DataVersion dataVersion = inverter.readVersion();
La struttura in risposta ha 4 attributi e 6 funzioni:
char par1;
char par2;
char par3;
char par4;
InverterModel getModelName()
String getIndoorOutdoorAndType()
String getGridStandard()
String getGridStandardInt()
String getTrafoOrNonTrafo()
String getWindOrPV()
InverterModel ha questa struttura:
int ID;
float multipler;
String name;
par1
identifica il modello, e così posso creare 2 funzioni di descrizione una con il modello specifico, la seconda il tipo di modello;
par2
identifico lo standard di rete e creo 2 funzioni per ottenere lo standard di rete;
par3
specifica se è trasformer less;
par4
specifica se è versione Wind o versione PV
Misura la richiesta al DSP
Con questo comando puoi ottenere la tensione, la corrente ecc. Ecc. C’è una grande lista di parametri che converto in una lista di costanti che puoi usare.
#define DSP_GRID_VOLTAGE_ALL 1 /* Grid Voltage (All) */
#define DSP_GRID_CURRENT_ALL 2 /* Grid Currrent (All) */
#define DSP_GRID_POWER_ALL 3 /* Grid Power (All) */
#define DSP_FREQUENCY_ALL 4 /* Frequency All) */
#define DSP_VBULK_WAS_ILEAK_DCDC_READING_ALL 5 /* VBulk was Ileak (Dc/Dc) reading All) */
#define DSP_ILEAK_DCDC_WAS_ILEAK_INVERTER_READING 6 /* Ileak (Dc/Dc) was Ileak (Inverter) Reading*/
#define DSP_ILEAK_INVERTER 7 /* Ileak (Inverter) */
#define DSP_PIN1_ALL 8 /* Pin 1 (All) */
#define DSP_PIN2 9 /* Pin 2 */
#define DSP_INVERTER_TEMPERATURE_GT 21 /* Inverter Temperature (Grid-Tied) */
#define DSP_BOOSTER_TEMPERATURE_GT 22 /* Booster Temperatuer (Grid-Tied) */
#define DSP_VOLTAGE_ALL 23 /* Input 1 Voltage */
#define DSP_CURRENT_ALL 25 /* Input 1 Current (All) */
#define DSP_VOLTAGE_GT 26 /* Input 2 Voltage (Grid-Tied) */
#define DSP_CURRENT_GT 27 /* Input 2 Current (Grid-Tied) */
#define DSP_GRID_VOLTAGE_DCDC_GT 28 /* Grid Voltage (Dc/Dc) (Grid-Tied) */
#define DSP_GRID_FREQUENCY_DCDC_GT 29 /* Grid Frequency (Dc/Dc) (Grid-Tied) */
#define DSP_ISOLATION_RESISTANCE_RISO_ALL 30 /* Isolation Resistance (Riso) (All) */
#define DSP_VBULK_DCDC_GT 31 /* Vbulk (Dc/Dc) (Grid-Tied) */
#define DSP_AVERAGE_GRID_VOLTAGE_VGRIDAVG_GT 32 /* Average Grid Voltage (VgridAvg) (Grid-Tied) */
#define DSP_VBULKMID_GT 33 /* Vbulk Mid (Grid-Tied) */
#define DSP_POWER_PEAK_ALL 34 /* Power Peak (All) */
#define DSP_POWER_PEAK_TODAY_ALL 35 /* Power Peak Today (All) */
#define DSP_GRID_VOLTAGE_NEUTRAL_GT 36 /* Grid Voltage neutral (Grid-Tied) */
#define DSP_WIND_GENERATOR_FREQUENCY 37 /* Wind Generator Frequency */
#define DSP_GRID_VOLTAGE_NEUTRAL_PHASE_CENTRAL 38 /* Grid Voltage neutral-phase (Central) */
#define DSP_GRID_CURRENT_PHASE_R_CENTRAL_3P 39 /* Grid Current phase r (Central & 3 Phase) */
#define DSP_GRID_CURRENT_PHASE_S_CENTRAL_3P 40 /* Grid Current phase s (Central & 3 Phase) */
#define DSP_GRID_CURRENT_PHASE_T_CENTRAL_3P 41 /* Grid Current phase t (Central & 3 Phase) */
#define DSP_FREQUENCY_PHASE_R_CENTRAL_3P 42 /* Frequency phase r (Central & 3 Phase) */
#define DSP_FREQUENCY_PHASE_S_CENTRAL_3P 43 /* Frequency phase s (Central & 3 Phase) */
#define DSP_FREQUENCY_PHASE_T_CENTRAL_3P 44 /* Frequency phase t (Central & 3 Phase) */
#define DSP_VBULK_PLUS_CENTRAL_3P 45 /* Vbulk + (Central & 3 Phase) */
#define DSP_VBULK_MINUS_CENTRAL 46 /* Vbulk - (Central) */
#define DSP_SUPERVISOR_TEMPERATURE_CENTRAL 47 /* Supervisor Temperature (Central) */
#define DSP_ALIM_TEMPERATURE_CENTRAL 48 /* Alim Temperature (Central) */
#define DSP_HEAT_SINK_TEMPERATURE_CENTRAL 49 /* Heak Sink Temperature (Central) */
#define DSP_TEMPERATURE_1_CENTRAL 50 /* Temperature 1 (Central) */
#define DSP_TEMPERATURE_2_CENTRAL 51 /* Temperature 2 (Central) */
#define DSP_TEMPERATURE_3_CENTRAL 52 /* Temperature 3 (Central) */
#define DSP_FAN_1_SPEED_CENTRAL 53 /* Fan 1 Speed (Central) */
#define DSP_FAN_2_SPEED_CENTRAL 54 /* Fan 2 Speed (Central) */
#define DSP_FAN_3_SPEED_CENTRAL 55 /* Fan 3 Speed (Central) */
#define DSP_FAN_4_SPEED_CENTRAL 56 /* Fan 4 Speed (Central) */
#define DSP_FAN_5_SPEED_CENTRAL 57 /* Fan 5 Speed (Central) */
#define DSP_POWER_SATURATION_LIMIT_DER_CENTRAL 58 /* Power Saturation limit (Der.) (Central) */
#define DSP_RIFERIMENTO_ANELLO_BULK_CENTRAL 59 /* Reference Ring Bulk (Central) */
#define DSP_VPANEL_MICRO_CENTRAL 60 /* Vpanel micro (Central) */
#define DSP_GRID_VOLTAGE_PHASE_R_CENTRAL_3P 61 /* Grid Voltage phase r (Central & 3 Phase) */
#define DSP_GRID_VOLTAGE_PHASE_S_CENTRAL_3P 62 /* Grid Voltage phase s (Central & 3 Phase) */
#define DSP_GRID_VOLTAGE_PHASE_T_CENTRAL_3P 63 /* Grid Voltage phase t (Central & 3 Phase) */
#define DSP_FAN1_SPEED_CENTRAL 95 /* Fan 1 Speed (rpm) (Central) */
#define DSP_FAN2_SPEED_RPM_CENTRAL 96 /* Fan 2 Speed (rpm) (Central) */
#define DSP_FAN3_SPEED_RPM_CENTRAL 97 /* Fan 3 Speed (rpm) (Central) */
#define DSP_FAN4_SPEED_RPM_CENTRAL 98 /* Fan 4 Speed (rpm) (Central) */
#define DSP_FAN5_SPEED_RPM_CENTRAL 99 /* Fan 5 Speed (rpm) (Central) */
#define DSP_FAN6_SPEED_RPM_CENTRAL 100 /* Fan 6 Speed (rpm) (Central) */
#define DSP_FAN7_SPEED_RPM_CENTRAL 101 /* Fan 7 Speed (rpm) (Central) */
Il comando è semplice:
Aurora::DataDSP dataDSP = inverter.readDSP(byte type, byte global)
global
se 1 richiede le misurazioni globali (solo per un master)
se 0 richiede le Misure Modulo (Master e Slave)
e anche la struttura del risultato è semplice:
float value;
OutcomeState state;
Dove valore è il valore richiesto, ha queste unità di misura:
Voltages | V |
Currents | A |
Powers | W |
Temperatures | °C |
OutcomeState è lo stato di ritorno che ha questa struttura:
byte transmissionState;
byte globalState;
bool readState;
String getTransmissionState()
String getGlobalState()
Dove lo stato di trasmissione descrive se il comando è scritto correttamente, lo stato globale è lo stato globale dell’inverter, readState è lo stato della chiamata: se vero l’inverter risponde, falso no.
Lettura ora / data
Ottieni il tempo impostato sull’Inverter in secondi ed epochTime, e aggiungo 2 funzioni una che restituisce la stringa dell’ora e un’altra che restituisce la struttura standard di Arduino.
Aurora::DataTimeDate dataTimeDate = inverter.readTimeDate();
unsigned long seconds;
unsigned long epochTime;
String getDateTimeString()
tm getDateTime()
Ultimi quattro allarmi
Questo comando restituisce i codici degli ultimi quattro allarmi, sotto forma di coda FIFO dal primo
(AL1) all’ultimo (AL4).
Quando si utilizza questo comando la coda viene svuotata (i quattro valori sono posti a zero).
Aurora::DataLastFourAlarms dataLastFourAlarms = inverter.readLastFourAlarms()
struttura di ritorno
byte alarm1;
byte alarm2;
byte alarm3;
byte alarm4;
String getAlarm1State()
String getAlarm2State()
String getAlarm3State()
String getAlarm4State()
Scatola di giunzione – Richiesta stato
Verificare il parametro e lo stato della scatola di giunzione.
Aurora::DataJunctionBoxState dataJunctionBoxState = inverter.readJunctionBoxState(byte nj)
NJ: numero scatola di giunzione
Qui il risultato della struttura
JBoxState jBoxState;
bool fuseBurnt[21] = {false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false};
bool stringCurrentUnbalanced[11] = {false,false,false,false,false,false,false,false,false,false,false} ;
OutcomeState state;
Aggiungo un JBoxState per semplificare la lettura, qui la struttura
bool burnFuseOnJBox;
bool jBoxOvertemperature;
bool jBoxOvervoltage;
bool unbalancedStringCurrent;
bool jBoxOvercurrent;
bool powerOff;
bool noCommunication;
bool jBoxNotCalibrated;
Lettura P / N (inverter Aurora)
Legge la PN dell’inverter
Aurora::DataSystemPN dataSystemPN = inverter.readSystemPN()
return a simple structure
String PN;
bool readState;
Lettura del numero di serie (inverter Aurora)
Aurora::DataSystemSerialNumber dataSystemSerialNumber = inverter.readSystemSerialNumber()
e qui la struttura di ritorno
String SerialNumber;
bool readState;
Lettura della settimana e dell’anno di produzione (inverter Aurora)
Aurora::DataManufacturingWeekYear dataManufacturingWeekYear = inverter.readManufacturingWeekYear()
e qui la struttura di ritorno
String Week;
String Year;
OutcomeState state;
Lettura della versione del firmware
Aurora::DataFirmwareRelease dataFirmwareRelease = inverter.readFirmwareRelease()
e qui la struttura di ritorno
String release;
OutcomeState state;
Letture di energia accumulata (solo inverter Aurora collegati alla rete)
Leggi l’energia accumulata del parametro che passi
Aurora::DataCumulatedEnergy dataCumulatedEnergy = inverter.readCumulatedEnergy(byte par)
qui il parametro
#define CUMULATED_DAILY_ENERGY 0 /* Daily Energy */
#define CUMULATED_WEEKLY_ENERGY 1 /* Weekly Energy */
#define CUMULATED_ENERGY_OF_LAST_7_DAYS 2 /* Energy of last 7 days */
#define CUMULATED_MONTHLY_ENERGY 3 /* Monthly Energy */
#define CUMULATED_YEARLY_ENERGY 4 /* Yearly Energy */
#define CUMULATED_TOTAL_ENERGY_LIFETIME 5 /* Total Energy (total lifetime) */
#define CUMULATED_PARTIAL_ENERGY_SINCE_RESET 6 /* Partial Energy (cumulated since reset) */
qui la struttura
unsigned long energy;
OutcomeState state;
Configurazione di sistema
Aurora::DataConfigStatus dataConfigStatus = inverter.readConfig()
qui la struttura
byte configStatus;
String getConfigStatus() {
return getConfigFlagByParams(this->configStatus);
}
OutcomeState state;
Aurora::DataTimeCounter dataTimeCounter = inverter.readTimeCounter(byte param)
qui il parametro
#define CT_TOTAL_RUN 0
#define CT_PARTIAL_RUN 1
#define CT_TOTAL_GRID 2
#define CT_RESET_PARTIAL 3
#define CT_TOTAL_RUN_DESC "Total Running Time (Lifetime)"
#define CT_PARTIAL_RUN_DESC "Partial Running Time (since reset)"
#define CT_TOTAL_GRID_DESC "Total Time With Grid Connection"
#define CT_RESET_PARTIAL_DESC "Reset of Partial (Time & Energy)"
qui la struttura di ritorno
unsigned long upTimeInSec;
int * getSecondsInDateElements() {
return getSecondsInDateElementsByParams(this->upTimeInSec);
}
OutcomeState state;
Codice di esempio
Ecco un esempio di lettura tramite Arduino.
/*
Test Arduino MAX485 Aurora ABB connection
by Mischianti Renzo <https://mischianti.org>
https://www.mischianti.org/
*/
#include "Arduino.h"
#include <Aurora.h>
#include <SoftwareSerial.h>
#include <MemoryFree.h>
//SoftwareSerial mySerial(10, 11); // RX, TX
//Aurora inverter = Aurora(2, &Serial1, 5);
Aurora inverter = Aurora(2, 10, 11, 5);
void SerialPrintData(byte *data) {
for (int i = 0; i < 8; i++) {
Serial.print((int)data[i]);
Serial.print(F(" "));
}
Serial.println(F(" "));
}
void setup()
{
Serial.begin(19200);
inverter.begin();
}
// The loop function is called in an endless loop
void loop()
{
Serial.print(F("freeMemory(1)="));Serial.println(freeMemory());
Aurora::DataCumulatedEnergy cumulatedEnergy = inverter.readCumulatedEnergy((byte)1);
Serial.println(F("------------------------------------------"));
Serial.println(F("INVERTER 2"));
Serial.print(F(" Data ROW = ")); SerialPrintData(inverter.receiveData);
Serial.print(F(" Read State = ")); Serial.println(cumulatedEnergy.state.readState);
Serial.print(F("Transmission State = ")); Serial.println(cumulatedEnergy.state.getTransmissionState());
Serial.print(F(" Global State = ")); Serial.println(cumulatedEnergy.state.getGlobalState());
Serial.print(F(" Energia = ")); Serial.print(cumulatedEnergy.energy); Serial.println(" Wh");
// free(&cumulatedEnergy);
Serial.println(F("------------------------------------------"));
Aurora::DataLastFourAlarms lastFour = inverter.readLastFourAlarms();
Serial.println(F("INVERTER 2"));
Serial.print(F(" Data ROW = ")); SerialPrintData(inverter.receiveData);
Serial.print(F(" Read State = ")); Serial.println(lastFour.state.readState);
Serial.print(F("Transmission State = ")); Serial.println(lastFour.state.getTransmissionState());
Serial.print(F(" Global State = ")); Serial.println(lastFour.state.getGlobalState());
Serial.print(F(" Alarms 1 = ")); Serial.println(lastFour.getAlarm1State());
Serial.print(F(" Alarms 2 = ")); Serial.println(lastFour.getAlarm2State());
Serial.print(F(" Alarms 3 = ")); Serial.println(lastFour.getAlarm3State());
Serial.print(F(" Alarms 4 = ")); Serial.println(lastFour.getAlarm4State());
// free(&lastFour);
Serial.println(F("------------------------------------------"));
Aurora::DataVersion version = inverter.readVersion();
Serial.println("INVERTER 2");
Serial.print(F(" Data ROW = ")); SerialPrintData(inverter.receiveData);
Serial.print(F(" Read State = ")); Serial.println(version.state.readState);
Serial.print(F("Transmission State = ")); Serial.println(version.state.getTransmissionState());
Serial.print(F(" Global State = ")); Serial.println(version.state.getGlobalState());
Serial.print(F(" Version = ")); Serial.print(version.getModelName().name); Serial.print(F(" ")); Serial.print(version.getIndoorOutdoorAndType()); Serial.print(F(" ")); Serial.print(version.getGridStandard()); Serial.print(F(" ")); Serial.print(version.getTrafoOrNonTrafo()); Serial.print(F(" ")); Serial.println(version.getWindOrPV());
Serial.println(F("------------------------------------------"));
// free(&version);
Aurora::DataConfigStatus configStatus = inverter.readConfig();
Serial.print(F(" Data ROW = ")); SerialPrintData(inverter.receiveData);
Serial.print(F(" Read State = ")); Serial.println(configStatus.state.readState);
Serial.print(F("Transmission State = ")); Serial.println(configStatus.state.getTransmissionState());
Serial.print(F(" Global State = ")); Serial.println(configStatus.state.getGlobalState());
Serial.print(F(" config = ")); Serial.println(configStatus.getConfigStatus());
Serial.println(F("------------------------------------------"));
// free(&version);
Serial.print(F("freeMemory(2)="));Serial.println(freeMemory());
Aurora::DataTimeCounter timeCounter = inverter.readTimeCounter(CT_TOTAL_RUN);
Serial.print(F(" Data ROW = ")); SerialPrintData(inverter.receiveData);
Serial.print(F(" Read State = ")); Serial.println(timeCounter.state.readState);
Serial.print(F("Transmission State = ")); Serial.println(timeCounter.state.getTransmissionState());
Serial.print(F(" Global State = ")); Serial.println(timeCounter.state.getGlobalState());
Serial.print(F(" time in sec = ")); Serial.println(timeCounter.upTimeInSec);
Serial.print(F(" time in verb = ")); Serial.print(timeCounter.getSecondsInDateElements()[0]); Serial.print(F("Y ")); Serial.print(timeCounter.getSecondsInDateElements()[1]); Serial.print(F("D "));Serial.print(timeCounter.getSecondsInDateElements()[2]);Serial.print(F("H "));Serial.print(timeCounter.getSecondsInDateElements()[3]);+Serial.print(F("M "));Serial.print(timeCounter.getSecondsInDateElements()[4]);Serial.println(F("S "));
Serial.println(F("------------------------------------------"));
// free(&version);
Serial.print(F("freeMemory(2)="));Serial.println(freeMemory());
delay(4000);
}
Come puoi vedere l’utilizzo è abbastanza semplice.
Video dimostrativo
Qui il video della chiamata dei risultati.