diff --git a/doc/sphinx/stima_wifi/stimawifi_v3/esp32_flash.png b/doc/sphinx/stima_wifi/stimawifi_v3/esp32_flash.png new file mode 100644 index 000000000..fe8b59b9a Binary files /dev/null and b/doc/sphinx/stima_wifi/stimawifi_v3/esp32_flash.png differ diff --git a/doc/sphinx/stima_wifi/stimawifi_v3/sch_s3_mini_v1.0.0.png b/doc/sphinx/stima_wifi/stimawifi_v3/sch_s3_mini_v1.0.0.png new file mode 100644 index 000000000..8c8f79361 Binary files /dev/null and b/doc/sphinx/stima_wifi/stimawifi_v3/sch_s3_mini_v1.0.0.png differ diff --git a/doc/sphinx/stima_wifi/stimawifi_v3/stima_wifi_howto.rst b/doc/sphinx/stima_wifi/stimawifi_v3/stima_wifi_howto.rst index 8cf910811..dca194464 100644 --- a/doc/sphinx/stima_wifi/stimawifi_v3/stima_wifi_howto.rst +++ b/doc/sphinx/stima_wifi/stimawifi_v3/stima_wifi_howto.rst @@ -229,7 +229,10 @@ MCU - Espressif ESP32 S3 .. image:: s3_mini_v1.0.0_4_16x9.jpg :width: 50% +Questo lo schema elettrico: +.. image:: sch_s3_mini_v1.0.0.png + :width: 50% RTC and Microsd Data Logger Shield @@ -391,7 +394,7 @@ Micro SD Card Shield Questo modulo può sostituire RTC and Microsd Data Logger Shield ma non fornisce le funzionalità relative all'RTC in quanto non è presente. Necessita anche di uno specifico firmware in quanto richiede una -specifica configurazione tempo di compilazione. +specifica configurazione a tempo di compilazione. .. image:: sd_v1.2.0_1_16x16.jpg :width: 50% @@ -399,8 +402,8 @@ specifica configurazione tempo di compilazione. Micro SD(TF) card per D1 mini -Assemblaggio componenti elettroniche e sensori ----------------------------------------------- +Componenti elettroniche e sensori +--------------------------------- .. image:: stimawifi_out_of_box_mini.jpg :width: 50% @@ -425,36 +428,6 @@ Scatola Serve a proteggere l’elettronica ed alloggiare parte dei sensori. -Deve essere divisa in due sezioni principali, una ospita i componenti -elettronici, l’altra (divisa a sua volta in due camere separate) il -sensore per le polveri sottili e quello per la rilevazione della -concentrazione di CO2 - -.. image:: scatola_interno.png - :width: 50% - -Nella parte alta della foto si nota l’alloggiamento -delle componenti elettroniche principali. - -.. image:: scatola_elettronica.png - :width: 50% - -La parte bassa è divisa in due sezioni e queste sezioni sono aperte -verso l’esterno a differenza di quella superiore - -.. image:: scatola_inferiore.png - :width: 50% - -I cavi per i sensori passano attraverso piccole incisioni del -polietilene per mantere il più possibile la camera superiore stagna - - -La finestra per il monitor è ricavata incollando un riquadro di -policarbonato con della colla a caldo. - -.. image:: scatola_display.png - :width: 30% - Schermo solare -------------- @@ -472,21 +445,6 @@ umidità e temperatura * Modelli molto economici già pronti -Connessione Device -^^^^^^^^^^^^^^^^^^ - -Connettere i device necessari è semplice - -- assicurarsi che la stazione non sia alimentata -- selezionare appropriato voltaggio alimentazione -- assicurarsi che i collegamenti siano corretti (SCl -> SCl, SDA->SDA, GND -> GND, Vcc ->Vcc) - -NOTE - -- Alcuni device hanno più dei quattro pin necessari alla connessione - al bus I2C -- VCC, Vcc, Vdd e VDD sono denominazioni equivalenti - Sensori ------- @@ -544,9 +502,13 @@ Sensirion SHT85 (Sensore Umidità & Temperatura) Software -------- -FreeRtos viene utilizzato attraverso un wrapper C++. Ogni thread ha -una struttura dati utilizzata per comunicare trutture dati e dati. -Nessun dato possibilmente è definito globalmente. +FreeRtos viene utilizzato attraverso un wrapper C++: +https://github.com/michaelbecker/freertos-addons +https://michaelbecker.github.io/freertos-addons/cppdocs/html/namespacecpp__freertos.html +con qualche adattamento per ESP32. + +Ogni thread ha una struttura dati utilizzata per comunicare trutture +dati e dati. Nessun dato possibilmente è definito globalmente. Il colore del led indica lo stato di funzionamento: @@ -582,8 +544,8 @@ E' attivo un web server accessibile quando ci si connette allo stesso Wifi a cui è connessa la stazione, Sono forniti le seguenti URL/servizi: * http:// Full main page -* http:///data.json Data in json format -* http:///geo Coordinate of the station +* http:///data.json Data in formato json +* http:///geo Coordinate della statione * http:///archive.dat Dati dell'archivio da leggere con apposito tools * http:///info.dat Info file dell'archivio da leggere con apposito tools @@ -610,11 +572,17 @@ pubblicazione sul broker MQTT; se non c'è spazio vanno direttamente nella coda dbqueue per l'archiviazione su SD card. threadMeasure è attivato periodicamente. -threadPublish prova la pubblicazione MQTT. +threadPublish prova la pubblicazione MQTT attigendo da due code: +mqttquque e recoveryqueue. L prima ha priorità rispetto alla seconda, +quindi i messaggi ricevuti da recoveryqueue saranno pubblicati solo +quando non ci saranno messaggi nella coda mqttqueue. -Dopo ogni tentativo di pubblicazione al broker MQTT -i dati vengono accodati per l'archiviazione nella coda dbqueue -etichettati relativamente al risultato della pubblicazione. +Dopo ogni tentativo di pubblicazione al broker MQTT i dati vengono +accodati per l'archiviazione nella coda dbqueue etichettati +relativamente al risultato della pubblicazione, a meno che i messaggi +non siano già stati etichettati come pubblicati e ci si può +risparmiare il lavoro di riarchiviazione (sono quindi il risultato di +una richiesta di recovery). Il thread threadDb gestisce due tipi di archiviazione dati. @@ -695,8 +663,8 @@ e il secondo con i dati. Il thread threadDb viene attivato periodicamente per recuperare l'invio dei dati presenti nel DB e non ancora pubblicati -inviando un piccolo blocco di dati a mqttqueue fino a quando avanzi -sufficiente spazio nella coda di pubblicazione per altri thread. +inviando un piccolo blocco di dati a recoveryqueue fino a quando avanzi +sufficiente spazio nella coda di pubblicazione. Il thread threadDb esegue a priorità più alta degli altri per garantire l'archiviazione senza perdita di dati in tempi utili e non riempire le code. @@ -722,6 +690,15 @@ threadGps Legge i dati dal GPS se presente (porta seriale) riempiendo una struttura dati con la geolocalizzazione e un timestamp. +threadGpsI2c +^^^^^^^^^^^^ + +E' una alternativa a threadGps in cui la comunicazione con il modulo +GPS avviene tramite BUS I2C. + +La scelta tra threadGpsI2c e threadGps avviene al momento della +compilazione tramite il file di configurazione include/stimawifi_config.h + Remote Procedure Call ^^^^^^^^^^^^^^^^^^^^^ @@ -754,7 +731,7 @@ casi le operazioni richieste dalla RPC sono eseguibili dallo stesso thread ma ad esempio l'RPC "recovery" deve essere eseguite da un thread differente (threadDb). In questo ultimo caso le informazioni per eseguire l'RPC vengono inviate tramite una apposita coda -"recoveryqueue"; è una coda binaria, ossia in grado mi gestire un solo +"rpcrecoveryqueue"; è una coda binaria, ossia in grado mi gestire un solo messaggio che sarà sempre l'ultimo. L'RPC recovery sarà quindi eseguita dal threadDb; Il recupero dei dati selezionati per limite di data e su richiesta tra quelli non ancora inviati viene gestito in @@ -777,37 +754,18 @@ I dati per la ritrasmissione (vedi RPC recovery) quindi presenti in archivio vengono sempre inviati al thread per la pubblicazione con la flag di "inviato" attiva per evitare duplicati in archivio - -Messa in opera della stazione ------------------------------ - -La messa in opera della stazione può essere affrontata in più fasi: -dopo aver assemblato la scheda elettronica ed averla posizionata nel -proprio guscio bisognerà configurare la stazione, registrarla presso -il sito che raccoglierà i dati e installare la stazione nel sito -prescelto. -In queste pagine tratteremo sommariamente queste operazioni -preoccupandoci di dare delle indicazioni di massima su cosa fare, sui -materiali e strumenti necessari alla corretta esecuzione delle -procedure necessarie alla messa in opera. - - -Assemblaggio scheda elettronica --------------------------------- +Assemblaggio datalogger +----------------------- La prima fase della messa in opera presuppone l’assemblaggio del data logger, la parte della stazione che si occupa di consultare periodicamente i sensori installati e di inviare i campionamenti al server centrale. -A seconda del kit utilizzato, potrebbe essere necessario utilizzare un -saldatore a stagno per installare i connettori a pettine necessari a -collegare tra loro i vari componenti ed assemblare i cavi di -connessione (il progetto prevede che connettori e cavi siano -preassemblati ma nulla vieta, per chi avesse tra gli obiettivi di -migliorare la confidenza con la saldatura di componenti elettronici di -utilizzare il kit senza il servizio di saldatura). +E' necessario utilizzare un saldatore a stagno per installare i +connettori a pettine necessari a collegare tra loro i vari componenti +ed assemblare i cavi di connessione. I diversi moduli dovranno essere collegati tra di loro rispettando la polarità. Prima di procedere alla connessione dei sensori, bisognerà @@ -838,15 +796,8 @@ Dotazione Software * Nessuna -Caricamento firmware --------------------- - -Questa fase della messa in opera è necessaria per il funzionamento -della stazione. Dopo la prima attivazione può rendersi nuovamente -necessario in caso si voglia modificare l’utilizzo della stazione, -personalizzarne le funzionalità o cogliere l’occasione di -impratichirsi con questa operazione fondamentale nel ciclo di vita del -software per microcontrollori, +Compilazione firmware +--------------------- La stazione Stima WiFi è basata sul microcontrollore Esp32 prodotto da ExpressIf. Si tratta di una soluzione economica e affidabile che da @@ -867,21 +818,23 @@ dotazioni software adottabili successivamente per lo sviluppo di programmi che interagiscano con la stazione di monitoraggio dopo la sua installazione. -NOTA: Non tutti i cavi usb sono uguali, in special modo quelli forniti -con gli smartphone. Alcuni sono adatti solo all’alimentazione ed alla -ricarica dei dispositivi e non permettono lo scambio di dati. Se il -computer non sembra riconoscere la stazione provare a sostituire il -cavo di connessione. Se anche questa prova non sortisce effetti, ma la -stazione si accende regolarmente, è probabile che il computer in uso -non riconosca l’interfaccia seriale usb usata dalla stazione. In -questo caso bisognerà caricare l’apposito driver prima di poter -procedere. +TODO clone repository; compilazione +Upload del firmware +^^^^^^^^^^^^^^^^^^^ + +Questa fase della messa in opera è necessaria per il funzionamento +della stazione. Dopo la prima attivazione può rendersi nuovamente +necessario in caso si voglia modificare l’utilizzo della stazione, +personalizzarne le funzionalità o cogliere l’occasione di +impratichirsi con questa operazione fondamentale nel ciclo di vita del +software per microcontrollori, + +TODO Strumentazione necessaria ^^^^^^^^^^^^^^^^^^^^^^^^^ -* cavo usb C * computer Dotazione Software @@ -898,15 +851,177 @@ Ambiente grafico con IDE: * Pioarduino https://github.com/pioarduino/platform-espressif32?tab=readme-ov-file -TODO clone repository; compilazione e caricamento firmware +Upload del firmware con esptool +------------------------------- + +Questa fase della messa in opera è necessaria per il funzionamento +della stazione. Dopo la prima attivazione può rendersi nuovamente +necessario in caso si voglia modificare l’utilizzo della stazione, +personalizzarne le funzionalità o cogliere l’occasione di +impratichirsi con questa operazione fondamentale nel ciclo di vita del +software per microcontrollori, + +Salvare sul proprio COMPUTER tutti file contenuti in questa cartella +git di github: + +https://github.com/r-map/rmap/tree/master/platformio/stima_v3/stimawifi/bin/lolin_s3_mini + +dopo aver collegato al PC il datalogger tramite cavo USB impartire il comando: + +:: + + esptool --chip esp32s3 --port "/dev/ttyACM0" --baud 460800 --before default-reset --after hard-reset write-flash -z --flash-mode dio --flash-freq 80m --flash-size detect 0x0000 bootloader.bin 0x8000 partitions.bin 0xe000 boot_app0.bin 0x10000 firmware.bin + +eventualmente sostituendo a ttyACM0 la porta seriale effettivamente in uso. + +Dotazione Software +^^^^^^^^^^^^^^^^^^ + +WINDOWS + +Provvedere innanzitutto al download del pacchetto di installazione di +Python (scegliere solo tra le versioni superiori alla 3.4) presso +questo link, dopodiché installare il pacchetto. ATTENZIONE: è +assolutamente necessario che l’installazione di Python includa la voce +“Add Python to enviroment variables“. In caso non l’abbiate +selezionato durante l’installazione, è possibile correggere +rilanciando l’installer, selezionando “Modify” e, avanzando di uno +step, selezionare la voce “Add Python to enviroment variables“. NON +proseguire senza aver provveduto. + +Effettuata l’installazione, riavviare il computer. A riavvio +completato, recarsi presso prompt dei comandi ed eseguire il seguente +comando: + +:: + + pip3 install esptool + + +MAC +Provvedere innanzitutto al download del pacchetto di installazione di +Python presso questo link, dopodiché installare il pacchetto e +riavviare al termine. + +Recarsi poi presso terminale ed eseguire il seguente comando: + +:: + + python3 -m pip install esptool + + +Linux (Debian, Ubuntu) + +Eseguire, da terminale i seguenti comandi: + +:: + + sudo apt install python3-setuptools git -y + git clone https://github.com/themadinventor/esptool.git + cd esptool + sudo python3 setup.py install + + +Linux (Fedora) + +Eseguire, da terminale i seguenti comandi: + +:: + + sudo dnf install python3-setuptools git -y + git clone https://github.com/themadinventor/esptool.git + cd esptool + sudo python3 setup.py install + + +Strumentazione necessaria +^^^^^^^^^^^^^^^^^^^^^^^^^ + +* computer +* cavo USB C + + +Upload del firmware da android +------------------------------ + +Questa fase della messa in opera è necessaria per il funzionamento +della stazione. Dopo il primo caricamento i successivi aggiornamenti +potranno essere fatti in automatico dal server RMAP tramite WiFi. + +Salvare sul proprio telefono tutti file contenuti in questa cartella +git di github: + +https://github.com/r-map/rmap/tree/master/platformio/stima_v3/stimawifi/bin/lolin_s3_mini + +Eseguire dopo averla installata l'app ESP32_Flash + +e configurarla come indicato qui: + +.. image:: esp32_flash.png + :width: 50% + +collegare l'adattatore OTG al telefono e il cavo USB collegandolo al +datalogger (modulo wemos ESP32-S3) + +Avviare il microcontrollore ESP32 in modalità programmazione con la seguente procedura: + +* premere e tenere premuto il pulsante O +* premere e rilasciare il pulsante RST +* rilasciare il pulsante O + +premere il pulsante Flash sull'app ESP32_Flash sul telefono. +attendere la conferma dell'avvenuta programmazione della MCU. +Scollegare il tutto. + + +Strumentazione necessaria +^^^^^^^^^^^^^^^^^^^^^^^^^ + +* smartphone con android +* cavo OTG usb C per smatphone + +NOTA: La tecnologia USB OTG (o on-the-go) permette di leggere dati da +chiavette e altre memorie di massa USB anche da smartphone e tablet, +collegandoli direttamente alla porta microUSB / USB di tipo C del +dispositivo (per intenderci, quella che si utilizza per collegare il +caricabatterie) -Collegamento dei sensori ------------------------- +NOTA: Non tutti i cavi usb sono uguali, in special modo quelli forniti +con gli smartphone. Alcuni sono adatti solo all’alimentazione ed alla +ricarica dei dispositivi e non permettono lo scambio di dati. Se il +computer non sembra riconoscere la stazione provare a sostituire il +cavo di connessione. Se anche questa prova non sortisce effetti, ma la +stazione si accende regolarmente, è probabile che il computer in uso +non riconosca l’interfaccia seriale usb usata dalla stazione. In +questo caso bisognerà caricare l’apposito driver prima di poter +procedere. + +Dotazione Software +^^^^^^^^^^^^^^^^^^ + +* android app ESP32_Flash https://play.google.com/store/apps/details?id=com.esp_flash.esp_flash_app + + +Collegamento dei sensori e altri dispositivi +-------------------------------------------- .. video:: stimawifi_v3_board_e_pila.mp4 :width: 100% - + +Connettere i device necessari è semplice se fatto con attenzione: + +- assicurarsi che la stazione non sia alimentata +- selezionare appropriato voltaggio alimentazione +- assicurarsi che i collegamenti siano corretti (SCl -> SCl, SDA->SDA, GND -> GND, Vcc ->Vcc) + +NOTE + +- Alcuni device hanno più dei quattro pin necessari alla connessione + al bus I2C +- VCC, Vcc, Vdd e VDD sono denominazioni equivalenti + + Prima di procedere con questa fase, disalimentare la stazione di monitoraggio. @@ -958,7 +1073,6 @@ Dotazione Software * Un qualunque browser web * Accesso alla rete Wi-Fi - Censimento stazione ------------------- @@ -986,7 +1100,6 @@ sarà possibile censire una o più stazioni. Censire una stazione consiste nel dichiararne le caratteristiche: - * Coordinate * Identificativo di stazione * Altezza dal livello del suolo @@ -1072,6 +1185,37 @@ protettivo. Il sensore di temperatura, per non essere influenzato nelle sue misurazioni dal funzionamento della stazione, viene installato in un involucro separato denominato schermo solare passivo. +Deve essere divisa in due sezioni principali, una ospita i componenti +elettronici, l’altra (divisa a sua volta in due camere separate) il +sensore per le polveri sottili e quello per la rilevazione della +concentrazione di CO2 + +.. image:: scatola_interno.png + :width: 50% + +Nella parte alta della foto si nota l’alloggiamento +delle componenti elettroniche principali. + +.. image:: scatola_elettronica.png + :width: 50% + +La parte bassa è divisa in due sezioni e queste sezioni sono aperte +verso l’esterno a differenza di quella superiore + +.. image:: scatola_inferiore.png + :width: 50% + +I cavi per i sensori passano attraverso piccole incisioni del +polietilene per mantere il più possibile la camera superiore stagna + + +La finestra per il monitor è ricavata incollando un riquadro di +policarbonato con della colla a caldo. + +.. image:: scatola_display.png + :width: 30% + + Con delle forbici o un taglierino, bisognerà tagliare da un foglio di schiuma per imballaggi, che può essere riciclato, dei riquadri che permettano separare l’interno della scatola di derivazione usata come @@ -1113,6 +1257,7 @@ Dotazione Software * Nessuna + Installazione in loco --------------------- @@ -1254,7 +1399,7 @@ add attivare la riga configurata -premete il bottono con il triangolino +premete il bottone con il triangolino .. image:: gpsdRelay_principale.jpg :width: 50% @@ -1291,7 +1436,7 @@ Nel modulo inserire:: dove 430 dovrà essere sostituito dal valore di calibrazione della CO2 in ppm. E' necessario monitorare lo stato di esecuzione delle RPC alla voce -"Monitor Remote Procedure Call" dellla stazione dallla propria pagina +"Monitor Remote Procedure Call" della stazione dallla propria pagina personale sulla piattaforma RMAP. Se Status risulta "completed" il valore fornito viene utilizzato per @@ -1466,5 +1611,11 @@ Appendice E I2C resistenze di pull up | MCU - Espressif | | | | ESP32 S3 | --- | --- | +-----------------------+---------+---------+ -| Totale | 2.4K | 3.2K | + ++-----------------------+---------+---------+ +| Totale | SDA | SCL | ++=======================+=========+=========+ +| con ESP32 C3 | 2.4K | 3.2K | ++-----------------------+---------+---------+ +| con ESP32 S3 | 3.2K | 3.2K | +-----------------------+---------+---------+ diff --git a/platformio/stima_v3/stimawifi/bin/lolin_c3_mini/boot_app0.bin b/platformio/stima_v3/stimawifi/bin/lolin_c3_mini/boot_app0.bin new file mode 100644 index 000000000..13562cabb Binary files /dev/null and b/platformio/stima_v3/stimawifi/bin/lolin_c3_mini/boot_app0.bin differ diff --git a/platformio/stima_v3/stimawifi/bin/lolin_c3_mini/bootloader.bin b/platformio/stima_v3/stimawifi/bin/lolin_c3_mini/bootloader.bin new file mode 100644 index 000000000..010599354 Binary files /dev/null and b/platformio/stima_v3/stimawifi/bin/lolin_c3_mini/bootloader.bin differ diff --git a/platformio/stima_v3/stimawifi/bin/lolin_c3_mini/firmware.bin b/platformio/stima_v3/stimawifi/bin/lolin_c3_mini/firmware.bin index a6dc7c914..8c69cedcf 100644 Binary files a/platformio/stima_v3/stimawifi/bin/lolin_c3_mini/firmware.bin and b/platformio/stima_v3/stimawifi/bin/lolin_c3_mini/firmware.bin differ diff --git a/platformio/stima_v3/stimawifi/bin/lolin_c3_mini/partitions.bin b/platformio/stima_v3/stimawifi/bin/lolin_c3_mini/partitions.bin new file mode 100644 index 000000000..50189203b Binary files /dev/null and b/platformio/stima_v3/stimawifi/bin/lolin_c3_mini/partitions.bin differ diff --git a/platformio/stima_v3/stimawifi/bin/lolin_s3_mini/README.upload b/platformio/stima_v3/stimawifi/bin/lolin_s3_mini/README.upload new file mode 100644 index 000000000..e75e1450c --- /dev/null +++ b/platformio/stima_v3/stimawifi/bin/lolin_s3_mini/README.upload @@ -0,0 +1,2 @@ +esptool --chip esp32s3 --port "/dev/ttyACM0" --baud 460800 --before default-reset --after hard-reset write-flash -z --flash-mode dio --flash-freq 80m --flash-size detect 0x0000 bootloader.bin 0x8000 partitions.bin 0xe000 boot_app0.bin 0x10000 firmware.bin + diff --git a/platformio/stima_v3/stimawifi/bin/lolin_s3_mini/boot_app0.bin b/platformio/stima_v3/stimawifi/bin/lolin_s3_mini/boot_app0.bin new file mode 100644 index 000000000..13562cabb Binary files /dev/null and b/platformio/stima_v3/stimawifi/bin/lolin_s3_mini/boot_app0.bin differ diff --git a/platformio/stima_v3/stimawifi/bin/lolin_s3_mini/bootloader.bin b/platformio/stima_v3/stimawifi/bin/lolin_s3_mini/bootloader.bin new file mode 100644 index 000000000..84ae916c1 Binary files /dev/null and b/platformio/stima_v3/stimawifi/bin/lolin_s3_mini/bootloader.bin differ diff --git a/platformio/stima_v3/stimawifi/bin/lolin_s3_mini/firmware.bin b/platformio/stima_v3/stimawifi/bin/lolin_s3_mini/firmware.bin index 742c11941..6ed656cc3 100644 Binary files a/platformio/stima_v3/stimawifi/bin/lolin_s3_mini/firmware.bin and b/platformio/stima_v3/stimawifi/bin/lolin_s3_mini/firmware.bin differ diff --git a/platformio/stima_v3/stimawifi/bin/lolin_s3_mini/partitions.bin b/platformio/stima_v3/stimawifi/bin/lolin_s3_mini/partitions.bin new file mode 100644 index 000000000..50189203b Binary files /dev/null and b/platformio/stima_v3/stimawifi/bin/lolin_s3_mini/partitions.bin differ diff --git a/platformio/stima_v3/stimawifi/extra_script.py b/platformio/stima_v3/stimawifi/extra_script.py index 9240cd74b..c368bc1e9 100644 --- a/platformio/stima_v3/stimawifi/extra_script.py +++ b/platformio/stima_v3/stimawifi/extra_script.py @@ -7,9 +7,20 @@ # Custom BIN from ELF env.AddPostAction( "$BUILD_DIR/${PROGNAME}.bin", - env.VerboseAction(" ".join([ + env.VerboseAction(" ".join( + [ "mkdir", "-p", "$PROJECT_DIR/bin/${PIOENV};", "cp", "$BUILD_DIR/${PROGNAME}.bin", - "$PROJECT_DIR/bin/${PIOENV}/firmware.bin" - ]), "Building $TARGET")) + "$PROJECT_DIR/bin/${PIOENV}/firmware.bin;" + "cp", + "$BUILD_DIR/bootloader.bin", + "$PROJECT_DIR/bin/${PIOENV}/;" + "cp", + "$BUILD_DIR/partitions.bin", + "$PROJECT_DIR/bin/${PIOENV}/;" + "cp", + "$PROJECT_PACKAGES_DIR/framework-arduinoespressif32/tools/partitions/boot_app0.bin", + "$PROJECT_DIR/bin/${PIOENV}/" + ] + ), "Building $TARGET")) diff --git a/platformio/stima_v3/stimawifi/include/sensors_config.h b/platformio/stima_v3/stimawifi/include/sensors_config.h index 66fa6cfc1..2e890be10 100644 --- a/platformio/stima_v3/stimawifi/include/sensors_config.h +++ b/platformio/stima_v3/stimawifi/include/sensors_config.h @@ -28,9 +28,10 @@ along with this program. If not, see . \def SENSOR_MAX> 1 \brief Max number of sensor. Max value here is 25 for stima atmega1284 +NOTE: used to define queue len */ #if portNUM_PROCESSORS > 1 -#define SENSORS_MAX (25) +#define SENSORS_MAX (10) #else #define SENSORS_MAX (3) #endif @@ -39,10 +40,10 @@ Max value here is 25 for stima atmega1284 \def SENSOR_UNIQUE_MAX \brief Max number of unique sensor (Stima modules). unique sensors are sensors that can have more driver but only one i2c address and only one setup and prepare -Max value here is 10 +Max value here is 10 for stima atmega1284 */ #if portNUM_PROCESSORS > 1 -#define SENSORS_UNIQUE_MAX (10) +#define SENSORS_UNIQUE_MAX (5) #else #define SENSORS_UNIQUE_MAX (3) #endif diff --git a/platformio/stima_v3/stimawifi/include/stimawifi_config.h b/platformio/stima_v3/stimawifi/include/stimawifi_config.h index 88c772650..3708e00ad 100644 --- a/platformio/stima_v3/stimawifi/include/stimawifi_config.h +++ b/platformio/stima_v3/stimawifi/include/stimawifi_config.h @@ -2,8 +2,8 @@ #define STIMAWIFI_CONFIG_H_ // increment on change -#define SOFTWARE_VERSION "2026-03-31T00:00" // date and time iso format -#define MAJOR_VERSION "20260331" // date YYYYMMDD +#define SOFTWARE_VERSION "2026-04-23T00:00" // date and time iso format +#define MAJOR_VERSION "20260423" // date YYYYMMDD #define MINOR_VERSION "0" // time HHMM without leading 0 // SSID and password of WiFi for setup @@ -100,20 +100,26 @@ #define SENSORDRIVER_META_LEN 30 // define parameter for queues len and communication -//#define DATA_BURST (SENSORS_MAX*VALUES_TO_READ_FROM_SENSOR_COUNT) + # if portNUM_PROCESSORS > 1 -#define DATA_BURST (150) +#define DATA_BURST (SENSORS_MAX*VALUES_TO_READ_FROM_SENSOR_COUNT) // max burst of messages +#define DB_QUEUE_LEN (DATA_BURST*2) +#define MQTT_QUEUE_LEN (DATA_BURST*3) +#define RECOVERY_QUEUE_LEN (DATA_BURST*2) #else -#define DATA_BURST (15) +#define DATA_BURST (15) // tipic burst of messages +#define DB_QUEUE_LEN (DATA_BURST) +#define MQTT_QUEUE_LEN (DATA_BURST*2) +#define RECOVERY_QUEUE_LEN (DATA_BURST) #endif -#define DATA_BURST_RECOVERY (DATA_BURST) -#define DB_QUEUE_LEN (DATA_BURST) -#define MQTT_QUEUE_LEN (DATA_BURST*3) +#define DATA_BURST_RECOVERY (DATA_BURST) // messages in recovery packet -#define MQTT_QUEUE_SPACELEFT_MEASURE (DATA_BURST) -#define MQTT_QUEUE_SPACELEFT_PUBLISH (DATA_BURST/2) -#define MQTT_QUEUE_SPACELEFT_RECOVERY (DATA_BURST*2) +//This is mechanism that prevents a system from becoming overwhelmed +//when data arrives faster than it can be processed (queue pressure) +#define QUEUE_SPACELEFT_MEASURE (0) // limit for enqueue messages by measure thread +#define QUEUE_SPACELEFT_PUBLISH (DATA_BURST) // limit for publish thread to ignore incoming message and send it to db +#define QUEUE_SPACELEFT_RECOVERY (0) // limit for enqueue recovered messages by db thread // SD card SPI PIN assignment // Micro SD Card Shield diff --git a/platformio/stima_v3/stimawifi/src/db_thread.cpp b/platformio/stima_v3/stimawifi/src/db_thread.cpp index 0cf1c640f..b6a2389e6 100644 --- a/platformio/stima_v3/stimawifi/src/db_thread.cpp +++ b/platformio/stima_v3/stimawifi/src/db_thread.cpp @@ -456,7 +456,7 @@ bool dbThread::archive_recovery(){ case ARCHIVE_RECOVERY_PUBLISH: - if (data->mqttqueue->NumSpacesLeft() < MQTT_QUEUE_SPACELEFT_RECOVERY){ + if (data->recoveryqueue->NumSpacesLeft() <= QUEUE_SPACELEFT_RECOVERY){ data->logger->warning(F("db archive recovery no space in mqtt queue")); archive_recovery_run=false; break; @@ -464,7 +464,7 @@ bool dbThread::archive_recovery(){ data->logger->notice(F("db archive recovery queuing message for publish %s:%s"),archive_recovery_message.topic,archive_recovery_message.payload); archive_recovery_message.sent=true; // prevent publish task requeue for archive - if(!data->mqttqueue->Enqueue(&archive_recovery_message,pdMS_TO_TICKS(0))){ + if(!data->recoveryqueue->Enqueue(&archive_recovery_message,pdMS_TO_TICKS(0))){ data->logger->warning(F("db archive recovery message for publish not queued")); archive_recovery_run=false; break; @@ -655,8 +655,8 @@ bool dbThread::data_recovery(void){ // return false; //} - if (data->mqttqueue->NumSpacesLeft() < MQTT_QUEUE_SPACELEFT_RECOVERY){ - data->logger->warning(F("db recovery no space in mqtt queue")); + if (data->recoveryqueue->NumSpacesLeft() <= QUEUE_SPACELEFT_RECOVERY){ + data->logger->warning(F("db recovery no space in recovery queue")); return true; } @@ -705,7 +705,7 @@ bool dbThread::data_recovery(void){ strcpy(message.payload, (const char*)sqlite3_column_text(stmt, 2)); data->logger->notice(F("db recovery queuing message for publish %s:%s"),message.topic,message.payload); - if(!data->mqttqueue->Enqueue(&message,pdMS_TO_TICKS(0))){ + if(!data->recoveryqueue->Enqueue(&message,pdMS_TO_TICKS(0))){ data->logger->warning(F("db recovery message for publish not queued")); } } else if(rc == SQLITE_DONE) { @@ -833,8 +833,6 @@ bool dbThread::doDb(const mqttMessage_t& message) { int rc; char sql[] = "INSERT OR REPLACE INTO messages VALUES (?, strftime('%s',?), ?, ?)"; sqlite3_stmt* stmt; // will point to prepared stamement object - - data->logger->notice(F("db spaceleft in mqtt queue %d"),data->mqttqueue->NumSpacesLeft()); sqlite3_prepare_v2( db, // the handle to your (opened and ready) database @@ -901,9 +899,6 @@ bool dbThread::doDb(const mqttMessage_t& message) { sqlite_status=true; data->status->database=ok; data->logger->notice(F("db Data saved on SD %s:%s"),message.topic,message.payload); - - mqttMessage_t tmpmsg; - data->dbqueue->Dequeue(&tmpmsg, pdMS_TO_TICKS( 0 )); // all done: dequeue the message return true; } @@ -1176,12 +1171,15 @@ void dbThread::Run() { // SetPriority(basePriority); for(;;){ - + + while (data->dbqueue->Peek(&message, pdMS_TO_TICKS( 1000 ))){ // peek one message - if (!doDb(message)) return; // return and terminate task if fatal error - if (!sqlite_status) sqlite_status = db_restart(); // try to restart SD card and sqlite + if (doDb(message)){ + data->dbqueue->Dequeue(&message, pdMS_TO_TICKS( 0 )); // all done: dequeue the message + } //threadPublish.mqttDisconnect(); - if (!sqlite_status) esp_system_abort("SD do not restart; REBOOT"); + if (!sqlite_status) sqlite_status = db_restart(); // try to restart SD card and sqlite + if (!sqlite_status) esp_system_abort("SD do not restart; REBOOT"); // return and terminate task if fatal error } @@ -1192,26 +1190,18 @@ void dbThread::Run() { } // check queue for rpc recovey - if(data->recoveryqueue->Dequeue(&rpcrecovery, pdMS_TO_TICKS( 0 )))recovery(); + if(data->rpcRecoveryqueue->Dequeue(&rpcrecovery, pdMS_TO_TICKS( 0 )))recovery(); uint8_t basePriority = GetPriority(); SetPriority(TASK_BASE_PRIORITY); // slow down task; this take a long time and we do not want to freeze everything while (db_recovery()); // run one subquery (one time step) of the big recovery on DB - while (archive_recovery()); // run until the mqtt queue is full (less then MQTT_QUEUE_SPACELEFT_RECOVERY) + while (archive_recovery()); // run until the mqtt queue is full (less/equal then QUEUE_SPACELEFT_RECOVERY) SetPriority(basePriority); - while (data->dbqueue->Peek(&message, pdMS_TO_TICKS( 1000 ))){ // peek one message - if (!doDb(message)) return; // return and terminate task if fatal error - if (!sqlite_status) sqlite_status = db_restart(); // try to restart SD card and sqlite - //threadPublish.mqttDisconnect(); - if (!sqlite_status) esp_system_abort("SD do not restart; REBOOT"); - } - - if (getArchiveRecoveryState() == ARCHIVE_RECOVERY_NONE and getDbRecoveryState() == DB_RECOVERY_NONE) { // check semaphore for data recovey - if(data->recoverysemaphore->Take(0)){ + if(data->rpcRecoverysemaphore->Take(0)){ if (timeStatus() == timeSet) { if (!data_purge()) data->logger->error(F("db purge DB")); // migrate old data to archive } @@ -1219,6 +1209,9 @@ void dbThread::Run() { } } + data->logger->notice(F("db db queue space left %d"),data->dbqueue->NumSpacesLeft()); + data->logger->notice(F("db recovery queue space left %d"),data->recoveryqueue->NumSpacesLeft()); + // checks for heap and stack //data->logger->notice(F("HEAP: %l"),esp_get_minimum_free_heap_size()); if( esp_get_minimum_free_heap_size() < HEAP_MIN_WARNING){ diff --git a/platformio/stima_v3/stimawifi/src/db_thread.h b/platformio/stima_v3/stimawifi/src/db_thread.h index ae85ef86a..3066d1326 100644 --- a/platformio/stima_v3/stimawifi/src/db_thread.h +++ b/platformio/stima_v3/stimawifi/src/db_thread.h @@ -6,9 +6,9 @@ struct db_data_t { int id; frtosLogging* logger; Queue* dbqueue; - Queue* mqttqueue; - BinarySemaphore* recoverysemaphore; - BinaryQueue* recoveryqueue; + Queue* recoveryqueue; + BinarySemaphore* rpcRecoverysemaphore; + BinaryQueue* rpcRecoveryqueue; dbStatus_t* status; station_t* station; File* logFile; diff --git a/platformio/stima_v3/stimawifi/src/measure_thread.cpp b/platformio/stima_v3/stimawifi/src/measure_thread.cpp index 81fea4263..65008707f 100644 --- a/platformio/stima_v3/stimawifi/src/measure_thread.cpp +++ b/platformio/stima_v3/stimawifi/src/measure_thread.cpp @@ -160,7 +160,7 @@ void measureThread::enqueueMqttMessage(uint8_t i ) { // if there are enough space left on the publish queue send it - if (data->mqttqueue->NumSpacesLeft() > MQTT_QUEUE_SPACELEFT_MEASURE){ + if (data->mqttqueue->NumSpacesLeft() > QUEUE_SPACELEFT_MEASURE){ data->logger->notice(F("measure enqueue for mqtt: %s ; %s"), mqtt_message.topic, mqtt_message.payload); if(!data->mqttqueue->Enqueue(&mqtt_message,pdMS_TO_TICKS(0))){ data->logger->error(F("measure enqueue for mqtt: %s ; %s"), mqtt_message.topic, mqtt_message.payload); @@ -253,7 +253,7 @@ void measureThread::doMeasure() { // check queue for rpc calibrate rpcCalibrate_t rpccalibrate; - if(data->calibratequeue->Dequeue(&rpccalibrate, pdMS_TO_TICKS( 0 ))){ + if(data->rpccalibratequeue->Dequeue(&rpccalibrate, pdMS_TO_TICKS( 0 ))){ for (uint8_t i = 0; i < data->sensors_count; i++) { if ( strcmp(rpccalibrate.type,sensorm[i].getSensorDriver()->getType())==0) { uint8_t rc = sensorm[i].sensor->setForcedRecalibrationFactor(rpccalibrate.value); diff --git a/platformio/stima_v3/stimawifi/src/measure_thread.h b/platformio/stima_v3/stimawifi/src/measure_thread.h index 19e411f95..7875a5c5a 100644 --- a/platformio/stima_v3/stimawifi/src/measure_thread.h +++ b/platformio/stima_v3/stimawifi/src/measure_thread.h @@ -13,7 +13,7 @@ struct measure_data_t { // thread communication data summarydata_t* summarydata; MutexStandard* i2cmutex; georef_t* georef; - BinaryQueue* calibratequeue; + BinaryQueue* rpccalibratequeue; sensor_t sensors[SENSORS_MAX]; uint8_t sensors_count; }; diff --git a/platformio/stima_v3/stimawifi/src/publish_thread.cpp b/platformio/stima_v3/stimawifi/src/publish_thread.cpp index 7fbe01e5f..8c60bb27f 100644 --- a/platformio/stima_v3/stimawifi/src/publish_thread.cpp +++ b/platformio/stima_v3/stimawifi/src/publish_thread.cpp @@ -79,7 +79,7 @@ void publishThread::Run() { for(;;){ // if there are no enough space left on the mqtt queue send it to the DB - while (data->mqttqueue->NumSpacesLeft() < MQTT_QUEUE_SPACELEFT_PUBLISH){ + while (data->mqttqueue->NumSpacesLeft() <= QUEUE_SPACELEFT_PUBLISH){ store(); data->status->publish.publish=error; } @@ -123,15 +123,24 @@ void publishThread::Run() { } if (status_connected){ - mqttMessage_t mqttMessage; - // wait for message and peek it from the queue - while (data->mqttqueue->Peek(&mqttMessage, pdMS_TO_TICKS( 1000 ))){ - // publish message - if (!doPublish()) break; + mqttMessage_t message; + data->mqttqueue->Peek(&message, pdMS_TO_TICKS( 1000 )); // wait for a new incoming message + while(data->mqttqueue->Peek(&message, pdMS_TO_TICKS( 0 ))){ + if (!doPublish(message)) break; // publish message + data->mqttqueue->Dequeue(&message, pdMS_TO_TICKS( 0 )); + } + while (data->recoveryqueue->Peek(&message, pdMS_TO_TICKS( 0 ))){ + if (!doPublish(message)) break; // publish message + data->recoveryqueue->Dequeue(&message, pdMS_TO_TICKS( 0 )); + while(data->mqttqueue->Peek(&message, pdMS_TO_TICKS( 0 ))){ + if (!doPublish(message)) break; // publish message + data->mqttqueue->Dequeue(&message, pdMS_TO_TICKS( 0 )); + } } } - data->logger->notice(F("publish mqtt queue space left %d"),data->mqttqueue->NumSpacesLeft()); + data->logger->notice(F("publish mqtt queue space left %d"),data->mqttqueue->NumSpacesLeft()); + data->logger->notice(F("publish recovery queue space left %d"),data->recoveryqueue->NumSpacesLeft()); // check heap and stack //data->logger->notice(F("HEAP: %l"),esp_get_minimum_free_heap_size()); @@ -604,13 +613,9 @@ void publishThread::store() { // try to send message to the broker // send the same message to the queue for DB with flag to describe if publish is completed with success -bool publishThread::doPublish() { +bool publishThread::doPublish(mqttMessage_t mqtt_message) { bool rc=false; - - mqttMessage_t mqtt_message; - data->mqttqueue->Dequeue(&mqtt_message, pdMS_TO_TICKS( 0 )); - bool resend = mqtt_message.sent; if(mqttPublish(mqtt_message,false)){ @@ -710,7 +715,7 @@ int calibrateRpc(JsonObject params, JsonObject result) { strncpy(rpccalibrate.type,type,4); rpccalibrate.value = params["value"]; - if(publishThread::global_data->calibratequeue->Enqueue(&rpccalibrate)){ + if(publishThread::global_data->rpcCalibratequeue->Enqueue(&rpccalibrate)){ publishThread::global_data->logger->notice(F("enqueue rpc calibrate : %s ; %d"), rpccalibrate.type, rpccalibrate.value); result[F("state")] = F("done"); return 0; @@ -767,7 +772,7 @@ int recoveryDataRpc(JsonObject params, JsonObject result) { //strcpy(rpcrecovery.dtstart,"2024-05-09T00:00:00") ; //strcpy(rpcrecovery.dtend, "2024-05-09T01:00:00") ; - if(publishThread::global_data->recoveryqueue->Enqueue(&rpcrecovery)){ + if(publishThread::global_data->rpcRecoveryqueue->Enqueue(&rpcrecovery)){ publishThread::global_data->logger->notice(F("enqueue rpc recovery : %s ; %s"), rpcrecovery.dtstart, rpcrecovery.dtend); result[F("state")] = F("done"); return 0; diff --git a/platformio/stima_v3/stimawifi/src/publish_thread.h b/platformio/stima_v3/stimawifi/src/publish_thread.h index 5266da4bf..52aa18d0e 100644 --- a/platformio/stima_v3/stimawifi/src/publish_thread.h +++ b/platformio/stima_v3/stimawifi/src/publish_thread.h @@ -19,8 +19,9 @@ struct publish_data_t { frtosLogging* logger; Queue* mqttqueue; Queue* dbqueue; - BinaryQueue* recoveryqueue; - BinaryQueue* calibratequeue; + Queue* recoveryqueue; + BinaryQueue* rpcRecoveryqueue; + BinaryQueue* rpcCalibratequeue; stimawifiStatus_t* status; station_t* station; }; @@ -52,7 +53,7 @@ class publishThread : public Thread { void reset_status_summary(); bool publish_constantdata(); void store(); - bool doPublish(); + bool doPublish(mqttMessage_t message); publish_data_t* data; IPStack ipstack; MQTT::Client mqttclient; diff --git a/platformio/stima_v3/stimawifi/src/stimawifi.h b/platformio/stima_v3/stimawifi/src/stimawifi.h index 37f8b12a4..b61fbb4e3 100644 --- a/platformio/stima_v3/stimawifi/src/stimawifi.h +++ b/platformio/stima_v3/stimawifi/src/stimawifi.h @@ -101,23 +101,24 @@ gps_i2c_data_t gps_i2c_data={1,&frtosLog,&stimawifiStatus.gps,&georef,&frtosRTC, gpsI2cThread threadGpsI2c(&gps_i2c_data); #endif -Queue dbQueue(DB_QUEUE_LEN,sizeof(mqttMessage_t)); // ~ 1 minutes queue -Queue mqttQueue(MQTT_QUEUE_LEN,sizeof(mqttMessage_t)); // ~ 1.5 minutes queue -BinaryQueue recoveryQueue(sizeof(rpcRecovery_t)); -BinaryQueue calibrateQueue(sizeof(rpcCalibrate_t)); -BinarySemaphore recoverySemaphore(false); +Queue dbQueue(DB_QUEUE_LEN,sizeof(mqttMessage_t)); +Queue recoveryQueue(RECOVERY_QUEUE_LEN,sizeof(mqttMessage_t)); +Queue mqttQueue(MQTT_QUEUE_LEN,sizeof(mqttMessage_t)); +BinaryQueue rpcRecoveryQueue(sizeof(rpcRecovery_t)); +BinaryQueue rpcCalibrateQueue(sizeof(rpcCalibrate_t)); +BinarySemaphore rpcRecoverySemaphore(false); #if (ENABLE_SDCARD_LOGGING) -db_data_t db_data={1,&frtosLog,&dbQueue,&mqttQueue,&recoverySemaphore,&recoveryQueue,&stimawifiStatus.db,&station,&logFile}; +db_data_t db_data={1,&frtosLog,&dbQueue,&recoveryQueue,&rpcRecoverySemaphore,&rpcRecoveryQueue,&stimawifiStatus.db,&station,&logFile}; #else -db_data_t db_data={1,&frtosLog,&dbQueue,&mqttQueue,&recoverySemaphore,&recoveryQueue,&stimawifiStatus.db,&station,NULL}; +db_data_t db_data={1,&frtosLog,&dbQueue,&recoveryQueue,&rpcRecoverySemaphore,&rpcRecoveryQueue,&stimawifiStatus.db,&station,NULL}; #endif dbThread threadDb(&db_data); -measure_data_t measure_data={1,&frtosLog,&mqttQueue,&dbQueue,&stimawifiStatus.measure,&station,&summarydata,&i2cmutex,&georef,&calibrateQueue}; +measure_data_t measure_data={1,&frtosLog,&mqttQueue,&dbQueue,&stimawifiStatus.measure,&station,&summarydata,&i2cmutex,&georef,&rpcCalibrateQueue}; measureThread threadMeasure(&measure_data); -publish_data_t publish_data={1,&frtosLog,&mqttQueue,&dbQueue,&recoveryQueue,&calibrateQueue,&stimawifiStatus,&station}; +publish_data_t publish_data={1,&frtosLog,&mqttQueue,&dbQueue,&recoveryQueue,&rpcRecoveryQueue,&rpcCalibrateQueue,&stimawifiStatus,&station}; publishThread threadPublish(&publish_data); #if defined(ARDUINO_LOLIN_C3_MINI) diff --git a/platformio/stima_v3/stimawifi/src/stimawifi.ino b/platformio/stima_v3/stimawifi/src/stimawifi.ino index 3a7972415..89926f6b3 100644 --- a/platformio/stima_v3/stimawifi/src/stimawifi.ino +++ b/platformio/stima_v3/stimawifi/src/stimawifi.ino @@ -1039,7 +1039,7 @@ void displayStatus() // send signal to DB thread for recovery unsent data from DB on SD card void dataRecovery() { - recoverySemaphore.Give(); + rpcRecoverySemaphore.Give(); } // send signal to measure thread to start measuremets @@ -1185,6 +1185,7 @@ void setup() { m_card->end(); + //ESP32 supports three RF calibration methods during RF initialization //Full calibration takes 100 ms longer than the partial //calibration method. If boot duration is not of critical //importance to the application, the full calibration method is