Esp32 : deep sleep et SPIFFS

Une façon simple de traiter le problème est de vous concentrer uniquement sur vos données et traiter le réveil du deep sleep comme un reboot (voir carrément rebooter)

c'est un peu le même principe de la reprise après panne / démarrage à froid -> vous avez stocké dans une mémoire permanente les valeurs clés et vous initialisez vos variables avec cela

Quand j'ai ce besoin généralement je mets toutes mes variables d'états dans une grosse structure globale (cf un exemple dans mon petit projet de gestion te T°) en utilisant une "séquence magique" pour vérifier que la mémoire a bien été initialisée. L'avantage de la structure c'est que vous pouvez écrire ça comme un BLOB (binary large object) et tout dumper ou lire d'un seul coup en EEPROM ou sur un fichier

Merci J-M-L, je vais étudier ça

l'avantage de "forcer" le reboot c'est que vous repassez par le setup() et donc réinitialisez toutes vos classes comme il faut (faut prêter attention à toutes celles qui ont un begin() ou un init() sinon)

j'ai des montages ou je ne m'ennuie pas à gérer le sleep car il y a aussi l'alimentation de tout le reste donc j'éteins carrément le système en utilisant un Pololu Power Switches. ce switch c'est ce que l'utilisateur va appuyer pour démarrer manuellement le système mais en le connectant à une RTC ou un autre petit système vous pouvez aussi déclencher le réveil quand vous voulez en envoyant un front au power switch

Faire l'inventaire des donnnées minimales dont il faut absolument disposer au redémarrage
(les données à afficher ? d'autres ?)

SI le cumul tient dans les 8k et s'il n'est pas indispensable de conserver les données en cas de coupure de l'alimentation utiliser la Ram RTC

Sinon utiliser la mémoire Flash SPI par SPIFFS comme indiqué par J-M-L
(L'EEPROM émulée peut également servir mais il faut tenir compte de la taille des pages et sans doute faire un partitionnement adapté)

J-M-L, le réveil partir d'un deepsleep(ESP8266 ou ESP32) est un redémarrage avec exécution du setup() !

En deep sleep tout est 'éteint' dans les ESP sauf la partie dite RTC (timer et ram)
C'est un redémarrage total avec le bénéfice de la conservation du contenu de la RAM RTC.
Il me semble d'ailleurs qu'on retrouve même les états initiaux des GPIO. Les valeurs en RAM normale sont aléatoires.
L'ESP doit recharger le code de la Flash vers la Ram. (en gros 100ms)
Bien entendu millis() repart à zéro , je sauvegarde en Ram RTC sa valeur juste avant l'appel du deepsleep , ça me permet de suivre la durée des phases d'eveil que je cherche à réduire.

Bien entendu en deep sleep il reste une petite consommation , mais avec les 5µA de l'ESP32 j'ai renoncé à faire des coupures d'alimentation. (5µA obtenus sans interface série/USB et sous alimentation directe 3,2V donc sans régulateur)

Bon, merci de votre aide. Pour l'instant ça marche...

Il me reste à tester le réveil par interruption de l'accéléromètre et par les touchs de l'ESP32.
Et à peaufiner le code. Mais je ne vois toujours pas d'où viennent ces 45ko de variables globales. Lorsque je passe mes variables à moi dans la RAM RTC, le nombre diminue un peu : en gros j'utilise réellement moins d'un ko.
Le reste c'est en effet les buffers des écrans et ... quoi ? Les buffers des json ?

Ton apllication repose sur un socle de fonctionnalités dont RTOS qui est en service d'office en arrière plan pour l'ESP32.(même si tu ne t'y réfères pas explicitement)

La sur-couche d'abstraction Arduino par dessus l'IDF Espressif masque tout cela.

Regardes l'exemple 'Bare Minimum' : setup() et main() vide -> 13272 octets de RAM
Ajoutes la pile de protocole réseau , le WIFI et un client -> 41 504 octets
Le complément vient avec des librairies....... et enfin..... 'peanuts' tes variables.

Voir par exemple cette analyse d'un simple Hello World

J-M-L, le réveil partir d'un deepsleep(ESP8266 ou ESP32) est un redémarrage avec exécution du setup() !

Ce que je voulais dire (à vérifier) c’est qu’au reboot les variables globales sont bien mises à zéro et la config des pins connue etc alors que je ne suis pas sûr que le démarrage post deep sleep soit similaire - mais je me trompe peut être, je n’ai pas exploré en détail cette partie ‘je préfère tout éteindre)

J'ai moi même été surpris de la profondeur du sommeil, je ne m'attendais pas à celà !!
Plus qu'un réveil c'est une re-naissance !
Le deep-sleep eteint lui même tout à la seule exception de la partie nommée RTC.
Tout redémarre au reveil comme pour une mise sous tension ...... c'est ailleurs effectivement une mise sous tension de la quasi totalité du SOC

Oui

==>

(source ESP32 Deep Sleep Tutorial)

Mais ça n’éteint pas les systèmes connexes - d’où le petit switch pilotable

Mais ça n'éteint pas les systèmes connexes - d'où le petit switch pilotable

Effectivement , l'ESP32 dort profondément quand les autres restent eveillés !!

Pour faire une gestion globale j'aime bien le TPL5110 (timer + commande du PMOS externe)


Un 'breakout' d'Adafruit rassemble le tout
(Je ne connaissais pas les modules Power Switch de Pololu)

J-M-L:
Mais ça n’éteint pas les systèmes connexes - d’où le petit switch pilotable

Je suppose que c'est ce qui permet de le réveiller via une interruption envoyée par un capteur, dans mon cas l'accéléromètre ?

lesept:
Je suppose que c'est ce qui permet de le réveiller via une interruption envoyée par un capteur, dans mon cas l'accéléromètre ?

Oui j'alimente tout le système par le switch - donc quand j'éteins le switch (on peut le faire par programme) - ça coupe tout et quand il se rallume, ben ça rallume tout comme si vous aviez appuyé sur le bouton.

Salut,

Heu, je suis un peu surpris par le contenu de ce sujet ... Je n'ai pas encore utilisé l'ESP32 mais je connais bien l'ESP8266, j'imagine que c'est plus ou moins la même chose :slight_smile:

En résumé, oui, quand tu te reveille d'un DeepSleep, c'est pareil qu'un boot, donc TOUTES TA MEMOIRE a disparu hormis le contenu de la RTC.
Je pense qu'il y a une grosse confusion à ce niveau : il faut considérer cette mémoire comme un stockage externe à l'instar d'un fichier stocké sur la SPIFF.

Voici comment je procède :

J'ai créé une librairie qui me facilite la gestion de la RTC : KeepInRTC.
Les informations que je souhaites conserver sont stockées dans des variables "normale". Une instance de KeepInRtc::KeepMe gère le fait qu'on souhaite le sauvegarder.
J'ai les fonctions suivantes :

  • le constructeur de ma classe KeepMe par laquelle, je reserve chacune des variables : je passe un pointeur sur celle-ci et sa taille . Si ma RTC contient des données valables (que j'identifie par une "valeur magique" comme l'expliquait J-M-L), je restore la valeur de ma variables ... ce qui me permet de la conserver d'un redemarrage a un autre

  • save() que j'appele à chaque fois que je souhaites sauvegarder le nouveau contenu de ma variable

Il y a des exemples dans le répertoire du même nom.

Pour un exemple plus complet avec tout pleins de variables sauvegardés de manière parfaitement anarchiques (== n'importe quand), y'a mon projet pour mon poulailler. Il fonctionne très bien mais je n'irai pas au bout, car j'ai eu des problèmes avec le poulailler lui-même donc je suis parti sur autre chose. Mais j'utilise ma librairie pour d'autres projets :slight_smile:

Bref, ce code est pour ESP8266, je n'ai pas (encore :slight_smile: ) utilisé l'ESP32, mais y'a peut-être de quoi s'en inspirer.

A+

Bonsoir detroyedlolo

Je pense qu'il y a une grosse confusion à ce niveau

peux tu préciser en quoi consisterait cette 'grosse confusion' ?

Oui les ESP8266 et ESP32 sont voisins quand au deep sleep, mias pas identiques, plus simple.

Nous sommes d'accord pour dire que tout le contenu de la SRAM interne à l'ESP32 (520k) a disparu ...puisqu'elle a cessé d'être alimentée.. à l'exception des 2 RAM RTC (8k chacunes) qui, elles, ont continué à être alimentées.
Bien entendu la ROM interne à l'ESP32 (448k) est conservée de même que le contenu de la mémoire SPI FLASH externe (souvent 4 MB) ...( plus toujours externe d'ailleurs puis qu'Expressif vient de sortir deux variantes d'ESP32 avec une FLASH interne de 2 ou 4 MB... plus besoin dans ce cas du petit boitier Winbond 4MB ou 8MB , toujours associé jusqu'à présent aux l'ESP32*)*

(J'utilise les termes 'interne et externe' au sens physique : ce qui est ou n'est pas dans le boitier de la puce)

Oui la RAM RTC(8k) disponible sur un ESP32 s'utilise d'une manière très simple : Il suffit déclarer spécifiquement les variables que l'on veut y placer (autres plages d'adresses) Bien déclarées on peut à tout moment y accéder en lecture ou écriture, sans mécanisme particulier contrairement à une EEPROM, une , une FLASH, sans appel d'une fonction particulière contrairment à l'ESP8266.

RTC_DATA_ATTR int bootCount = 0;
.....
++bootCount;
Serial.println("Boot number: " + String(bootCount));

ben par rapport au

45 ko de variables globales

Est-il vraiment obligatoire d'y stocker TOUTES les variables globales ?
Normalement, seul les variables de contextes ont ce besoin :slight_smile:

destroyedlolo:
ben par rapport auEst-il vraiment obligatoire d'y stocker TOUTES les variables globales ?
Normalement, seul les variables de contextes ont ce besoin :slight_smile:

c’est quoi une “variable de contexte” selon vous?...

Bonsoir
Merci de toutes vos réponses. J'ai en effet sauvegardé mes 'variables de contexte', c'est à dire celles que je dois pouvoir utiliser après un réveil, dans la RAM RTC comme l'indique Al1 dans la réponse 22.

Ça, ça marche.
J'ai ensuite testé la mise en sommeil et le réveil par timer et par les touches tactiles de l'ESP32.

Ça, ça marche aussi.
Maintenant, je me bats avec le réveil par une interruption externe : un bouton d'abord. Ça marche. C'est dommage que ce soit incompatible du réveil par les touches tactiles, j'aurais bien aimé avoir les deux...

Reste à implémenter le réveil par la détection d'un mouvement avec un accéléromètre MPU6050... Et là, ça marche pas, je rame... Rien de probant sur le net. Si vous avez des pistes, je suis preneur.

Bonsoir lesept

Pas encore résolu la question du seuil de mouvement et de la durée de mouvement pour obtenir une interruption en sortie du MPU6050 :wink: ?

Je ne connais pas bien la puce, sa datasheet et la ou les librairies mais une idée vient :
l'interruption par 'détection du mouvement' est elle possible DMP désactivée ?

En effet, question pertinente. Je me suis posé la même, mais pas eu le temps de tester...

EDIT : ton lien est faux... Peux-tu vérifier ?

lien corrigé, c'était encore la malédiction du http://http://http//.....""""""