Arduino Forum

International => Français => Topic started by: lesept on Nov 18, 2018, 12:47 am

Title: Esp32 : deep sleep et SPIFFS
Post by: lesept on Nov 18, 2018, 12:47 am
Bonsoir

En étudiant le deep sleep de l'esp32 j'ai vu que les variables sont perdues si on ne prend pas la précaution de les stocker dans la RAM de la RTC, qui est le seul bloc du SoC qui reste alimenté. Mais qu'en est il de la mémoire SPIFFS ? Est ce que les fichiers stockés sont conservés durant ce deep sleep ?

Je crois que la RAM de la RTC fait 4ko ou 8ko. Le compilateur m'indique que les variables globales de mon code occupent près de 50000 octets, donc ça ne rentrera pas dans la RAM RTC, même si je pousse très fort... D'où l'idée de stocker ce dont je me sers dans un fichier dans la SPIFFS. Qu'en pensez vous ?
Title: Re: Esp32 : deep sleep et SPIFFS
Post by: J-M-L on Nov 18, 2018, 06:30 am
Le SPIFFS est conservé même si vous coupez le jus. c'est en mémoire flash, pas SRAM
Ce sera lent au réveil de tout charger.

50Ko de variables globales ? vous y faites conservez quoi ?
Title: Re: Esp32 : deep sleep et SPIFFS
Post by: lesept on Nov 18, 2018, 09:50 am
C'est vrai que le code est un peu long et fait appel à pas mal de bibliothèques. Il va chercher l'heure et la météo sur Internet, parse les données Json et les affiche sur deux écrans OLED. Il y a aussi un accéléromètre et un DHT22.

L'IDE m'indique ceci:
Quote
Le croquis utilise 876190 octets (66%) de l'espace de stockage de programmes. Le maximum est de 1310720 octets.
Les variables globales utilisent 45108 octets (13%) de mémoire dynamique, ce qui laisse 282572 octets pour les variables locales. Le maximum est de 327680 octets.
C'est bien 45 ko de variables globales ? C'est vrai que j'ai une douzaine de const String utilisés par la bibliothèque ArduinoJson, mais le reste de mes variables n'est pas grand chose, à part 5 tableaux de dimension 6...

Cette consommation vient-elle des bibliothèques ?
Title: Re: Esp32 : deep sleep et SPIFFS
Post by: al1fch on Nov 18, 2018, 09:57 am
Bonjour

Pour nos applications on dipose de 8k en Ram RTC (c'est la RTC Slow  Memory)

Une seconde RAM RTC de 8k (= RTC Fast Memory)  , elle ausi préservée en 'sommeil profond', est résevée au coeur 'protocole' par opposition au coeur 'application'.
(http://forum.arduino.cc/index.php?action=dlattach;topic=580077.0;attach=282299)

-> Délimiter les informations essentielles qu'il faut conserver,  pas  besoin de sauver tout le contexte qui a permis de les produire. Pourquoi sauvegarder le buffer json avant parsing , par exemple ?

8K de Ram préservée ça parait déjà conséquent pour l'application décrite !
Title: Re: Esp32 : deep sleep et SPIFFS
Post by: lesept on Nov 18, 2018, 10:05 am
-> Délimiter les informations essentielles qu'il faut conserver,  pas  besoin de sauver tout le contexte qui a permis de les produire. Pourquoi sauvegarder le buffer json avant parsing , par exemple ?

8K de Ram préservée ça parait déjà conséquent pour l'application décrite !
Je suis d'accord avec toi, c'est pourquoi je posais cette question. Je pense que le buffer json est local à la fonction qui le parse. Je peux gagner de la mémoire en mettant mes const String là où je les utilise.

Le reste j'en ai besoin car typiquement les données sont produites dans une fonction et affichées dans d'autres.
Title: Re: Esp32 : deep sleep et SPIFFS
Post by: J-M-L on Nov 18, 2018, 10:07 am
Si vous pouvez régénérer les données (nouvelle lecture capteur) ce n'est pas nécessaire de les conserver non plus
Title: Re: Esp32 : deep sleep et SPIFFS
Post by: lesept on Nov 18, 2018, 10:31 am
J'ai fait la chasse au gaspi, mais le résultat n'est pas fameux :

Quote
Le croquis utilise 876242 octets (66%) de l'espace de stockage de programmes. Le maximum est de 1310720 octets.
Les variables globales utilisent 44848 octets (13%) de mémoire dynamique, ce qui laisse 282832 octets pour les variables locales. Le maximum est de 327680 octets.
Voila mes déclarations de bibliothèques :
Code: [Select]
#include <Arduino.h>
#include <Wire.h>
#include "I2Cdev.h"
#include "MPU6050.h"
#include <U8g2lib.h>
#include <dummy.h>  //for esp32
#include <WiFi.h>
#include <HTTPClient.h>
#include "time.h"
#include "DHTesp.h"
#include "ArduinoJson.h"

// Bus 1 : les 2 écrans
#define SDA1 19
#define SCL1 23

// Bus 2 : l'accéléro
#define SDA2 5
#define SCL2 4

#define LED_PIN 22
#define DHT_PIN 26

U8G2_SH1106_128X64_NONAME_F_SW_I2C display1(U8G2_R0, SCL1, SDA1);
U8G2_SH1106_128X64_NONAME_F_SW_I2C display2(U8G2_R0, SCL1, SDA1);

// U8G2_SSD1306_128X64_NONAME_F_SW_I2C display1(U8G2_R0, SCL1, SDA1);
// U8G2_SSD1306_128X64_NONAME_F_SW_I2C display2(U8G2_R0, SCL2, SDA2);
MPU6050 accelgyro;
DHTesp dht;

#include "Variables.h"
#include "Internet.h"
#include "Affichage.h"
#include "Accelero.h"


et mes variables :
Code: [Select]
// Accelerometer
byte Orientation;
bool AcceleroSuccess = false;
enum Direction {Xplus, Xmoins, Yplus, Ymoins, Zplus, Zmoins, Unknown};

// Time
int second;
int minute;
int hour;
int day;
int month;
int year;
int weekday;

// Second interval fine adjustment
#define ADJUST_SECONDS 0 // 0 pour ne pas rechercher l'optimum sinon 1
unsigned long nmicro = 1000;
int oldsec;

// Meteo
// Current weather
const char* current_weather_description;
float current_temp;
float current_pressure;
const char* current_PressureTendency_Code;
const char* current_weather_icon;
float current_precip_mm;
int current_humidity;
float current_uv;
// Hourly forecast
#define nbHourForecast 6
byte hourlyHours[nbHourForecast] = {0,1,2,5,8,11};
const char* hourly_weather_description[nbHourForecast];
float hourly_temp[nbHourForecast];
int hourly_weather_icon[nbHourForecast];
int hourly_PreciProba[nbHourForecast];
// Daily forecast
#define nbDayForecast 3
const char* daily_weather_description[nbDayForecast];
const char* daily_weather_icon[nbDayForecast];
const char* daily_date[nbDayForecast];
float daily_mintemp[nbDayForecast];
float daily_maxtemp[nbDayForecast];
float daily_Precip[nbDayForecast];
const char* daily_sunrise[nbDayForecast];
const char* daily_sunset[nbDayForecast];

// Program
bool blinkState = false;
unsigned long chronoD1;
unsigned long chronoAcc;
bool Aff2 = false;


Au passage, quand je compile un code vide (setup et loop vides, pas de variables ni de bibliothèques), j'obtiens quand même :
Quote
Le croquis utilise 173740 octets (13%) de l'espace de stockage de programmes. Le maximum est de 1310720 octets.
Les variables globales utilisent 13272 octets (4%) de mémoire dynamique, ce qui laisse 314408 octets pour les variables locales. Le maximum est de 327680 octets.
De 13000 à 45000, ça me fait 32000 octets : je ne vois pas où ils sont dans mes variables !
Title: Re: Esp32 : deep sleep et SPIFFS
Post by: al1fch on Nov 18, 2018, 10:36 am
l'exemple 'Bare Minimum' donne 13 272 ko  en  'variables globales' (en gros les besoins du 'firmware embarqué
l'exemple 'WiFi Client' donne 41 504 ko

plus peut être les buffers des afficheurs selon les librairies (écriture directe dans l'afficheur ou via un buffer en ram ?)
Title: Re: Esp32 : deep sleep et SPIFFS
Post by: lesept on Nov 18, 2018, 10:42 am
Où vois-tu ça ?

A terme, je compte remplacer les OLED (0.96") par des e-paper. Mais ils seront plus grands...
Title: Re: Esp32 : deep sleep et SPIFFS
Post by: J-M-L on Nov 18, 2018, 11:00 am
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° (http://forum.arduino.cc/index.php?topic=559714.msg3816573#msg3816573)) 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

Title: Re: Esp32 : deep sleep et SPIFFS
Post by: lesept on Nov 18, 2018, 11:10 am
Merci J-M-L, je vais étudier ça
Title: Re: Esp32 : deep sleep et SPIFFS
Post by: J-M-L on Nov 18, 2018, 11:11 am
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 (https://www.pololu.com/category/121/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
Title: Re: Esp32 : deep sleep et SPIFFS
Post by: al1fch on Nov 18, 2018, 11:16 am
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)
Title: Re: Esp32 : deep sleep et SPIFFS
Post by: lesept on Nov 18, 2018, 01:41 pm
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 ?
Title: Re: Esp32 : deep sleep et SPIFFS
Post by: al1fch on Nov 18, 2018, 01:59 pm
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 (https://exploreembedded.com/wiki/Hello_World_with_ESP32_Explained)


Title: Re: Esp32 : deep sleep et SPIFFS
Post by: J-M-L on Nov 18, 2018, 02:01 pm
Quote
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)
Title: Re: Esp32 : deep sleep et SPIFFS
Post by: al1fch on Nov 18, 2018, 02:06 pm
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
Title: Re: Esp32 : deep sleep et SPIFFS
Post by: J-M-L on Nov 18, 2018, 02:08 pm
Oui

(https://hackster.imgix.net/uploads/attachments/474426/F1T3905JG74UWCP.jpg)==>(https://hackster.imgix.net/uploads/attachments/474425/FHZLVVUJG74UWE7.jpg)

(source ESP32 Deep Sleep Tutorial (https://www.hackster.io/nickthegreek82/esp32-deep-sleep-tutorial-4398a7))

Mais ça n'éteint pas les systèmes connexes - d'où le petit switch pilotable
Title: Re: Esp32 : deep sleep et SPIFFS
Post by: al1fch on Nov 18, 2018, 02:17 pm
Quote
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)
(http://forum.arduino.cc/index.php?action=dlattach;topic=580077.0;attach=282324)
Un 'breakout' d'Adafruit rassemble le tout
(Je ne connaissais pas les modules Power Switch  de Pololu)
Title: Re: Esp32 : deep sleep et SPIFFS
Post by: lesept on Nov 18, 2018, 06:33 pm
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 ?
Title: Re: Esp32 : deep sleep et SPIFFS
Post by: J-M-L on Nov 18, 2018, 06:36 pm
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.
Title: Re: Esp32 : deep sleep et SPIFFS
Post by: destroyedlolo on Nov 19, 2018, 12:12 am
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 :)

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 (https://github.com/destroyedlolo/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 :


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 (https://github.com/destroyedlolo/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 :)

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

A+
Title: Re: Esp32 : deep sleep et SPIFFS
Post by: al1fch on Nov 19, 2018, 12:35 am
Bonsoir detroyedlolo
Quote
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.
Code: [Select]

RTC_DATA_ATTR int bootCount = 0;
.....
++bootCount;
Serial.println("Boot number: " + String(bootCount));
Title: Re: Esp32 : deep sleep et SPIFFS
Post by: destroyedlolo on Nov 19, 2018, 08:26 pm
ben par rapport au
Quote
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 :)
Title: Re: Esp32 : deep sleep et SPIFFS
Post by: J-M-L on Nov 19, 2018, 09:49 pm
ben par rapport auEst-il vraiment obligatoire d'y stocker TOUTES les variables globales ?
Normalement, seul les variables de contextes ont ce besoin :)
c'est quoi une "variable de contexte" selon vous?...
Title: Re: Esp32 : deep sleep et SPIFFS
Post by: lesept on Nov 20, 2018, 05:59 pm
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.
Title: Re: Esp32 : deep sleep et SPIFFS
Post by: al1fch on Nov 20, 2018, 06:04 pm
Bonsoir lesept

Pas encore résolu la question du seuil de mouvement et de la durée de mouvement  (https://www.esp32.com/viewtopic.php?f=12&t=8086)pour obtenir une interruption en sortie du MPU6050 ;) ?

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 ?
Title: Re: Esp32 : deep sleep et SPIFFS
Post by: lesept on Nov 20, 2018, 07:25 pm
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 ?
Title: Re: Esp32 : deep sleep et SPIFFS
Post by: al1fch on Nov 20, 2018, 07:42 pm
lien corrigé, c'était encore la malédiction du http://http://http//.....""""""
Title: Re: Esp32 : deep sleep et SPIFFS
Post by: lesept on Nov 20, 2018, 08:52 pm
Au fait, dois-je ou puis-je mettre la pin qui reçoit l'interruption en pullup ou pulldown ?
Title: Re: Esp32 : deep sleep et SPIFFS
Post by: al1fch on Nov 20, 2018, 10:20 pm
la doc du mpu dit que la sortie INT peut être configurée  en 'totem pole' ou 'open drain'
Un pull up ne peut pas faire de mal !
On voit sur le web des schémas avec un pull up externe.
Title: Re: Esp32 : deep sleep et SPIFFS
Post by: lesept on Nov 22, 2018, 11:34 pm
Bonsoir
J'ai pas mal cherché, et j'ai finalement un code qui marche...

Code: [Select]
// Bus 2 : l'accéléro
#define SDA2 5
#define SCL2 4

#include <Wire.h>
#include "I2Cdev.h"
#include <MPU6050.h>

RTC_DATA_ATTR int bootCount = 0;
MPU6050 accelgyro;
/*
  Method to print the reason by which ESP32 has been awaken from sleep
*/
void print_wakeup_reason() {
  esp_sleep_wakeup_cause_t wakeup_reason;
  wakeup_reason = esp_sleep_get_wakeup_cause();
  switch (wakeup_reason)
  {
    case 1  : Serial.println("Wakeup caused by external signal using RTC_IO"); break;
    case 2  : Serial.println("Wakeup caused by external signal using RTC_CNTL"); break;
    case 3  : Serial.println("Wakeup caused by timer"); break;
    case 4  : Serial.println("Wakeup caused by touchpad"); break;
    case 5  : Serial.println("Wakeup caused by ULP program"); break;
    default : Serial.println("Wakeup was not caused by deep sleep"); break;
  }
}

bool InitAccelero () {
  Wire.begin(SDA2, SCL2);
  accelgyro.initialize();
  bool Success  = accelgyro.testConnection(); // verify connection
  if (Success) {
    Serial.println("MPU6050 connection successful");
  }
  else Serial.println("MPU6050 connection failed");
  return Success;
}

void setup() {
  Serial.begin(115200);
  bool AcceleroSuccess = InitAccelero ();

  // instructions from : https://lukelectro.wordpress.com/2016/08/11/how-to-enable-motion-detection-interrupt-on-mpu6050/
  accelgyro.resetGyroscopePath();
  accelgyro.resetAccelerometerPath();
  accelgyro.setInterruptDrive(0);
  accelgyro.setInterruptMode(1); // 0=active-high, 1=active-low
  accelgyro.setDHPFMode(MPU6050_DHPF_5);
  accelgyro.setMotionDetectionThreshold(2); // Threshold in 2mg (ajouté by me)
  accelgyro.setMotionDetectionDuration(100); //Duration in ms
  accelgyro.setAccelerometerPowerOnDelay(1); // Set accelerometer power-on delay
  accelgyro.setFreefallDetectionCounterDecrement(1); // Set Free Fall detection counter decrement
  accelgyro.setMotionDetectionCounterDecrement(1); // Set Motion detection counter decrement
  accelgyro.setIntMotionEnabled(true);

  delay(200); //Take some time to open up the Serial Monitor
  //Increment boot number and print it every reboot
  ++bootCount;
  Serial.println("Boot number: " + String(bootCount));
  delay(20);

  print_wakeup_reason(); //Print the wakeup reason for ESP32
  // Configure RTCIO as wakeup source
  esp_sleep_enable_ext0_wakeup(GPIO_NUM_13, 0); //1 = High, 0 = Low

  //Go to sleep now
  Serial.println("Going to sleep now");
  delay(200);
  esp_deep_sleep_start();
}

void loop() { }
Les connexions :
VCC, GND, SDA sur pin 5, SCL sur pin 4 et INT sur 13.
Title: Re: Esp32 : deep sleep et SPIFFS
Post by: al1fch on Nov 22, 2018, 11:54 pm
Bravo !
Merci pour le retour
Title: Re: Esp32 : deep sleep et SPIFFS
Post by: lesept on Nov 23, 2018, 07:57 pm
Merci mais ce n'est pas encore terminé.
J'ai donc les moyens de mettre mon système en sommeil profond et de le réveiller soit par le timer (toutes les minutes pour affichage de l'heure) soit avec un mouvement par l'accéléromètre.
Mais dans ce dernier cas j'ai alors besoin de savoir combien de temps s'est écoulé depuis la mise en sommeil pour régler le timer avant de remettre en sommeil.
Comment puis je connaître ce temps écoulé ?
Title: Re: Esp32 : deep sleep et SPIFFS
Post by: al1fch on Nov 23, 2018, 08:14 pm
tu veux savoir combien de temps à dormi un 'ESP32 , réveillé par  une interruption.c'est ça ?.
..... pas de pb en ajoutant un circuit RTC !!

Sinon il faudrait, au reveil,  pouvoir lire la valeur du compteur interne 'RTC' , celui qui est capable de réveiller l'ESP
Je ne sais pas si ce compteur est accessible en lecture depui le code exécuté au réveil. Il faut chercher.

(millis () étant remis à zéro au reveil on ne peut s'en servir pour ce que tu veux faire)
Title: Re: Esp32 : deep sleep et SPIFFS
Post by: lesept on Nov 23, 2018, 08:16 pm
Je préférerais éviter la RTC, mon idée était bien de le le contenu de ce registre
Title: Re: Esp32 : deep sleep et SPIFFS
Post by: J-M-L on Nov 23, 2018, 08:18 pm
En demandant l'heure qu'il est à la RTC avant de s'endormir et en le notant dans la mémoire de la RTC puis en comparant avec l'heure qu'il est au réveil ? (ça semble fixé maintenant (https://www.esp32.com/viewtopic.php?t=2128))
Title: Re: Esp32 : deep sleep et SPIFFS
Post by: al1fch on Nov 23, 2018, 08:30 pm
Bonne nouvelle JML !! Merci pour le lien.
ça commence à mériter le terme de RTC ... si en plus on fait tourner ça avec un quartz de 32 kHZ
Reste à tester ça sous IDE Arduino
Title: Re: Esp32 : deep sleep et SPIFFS
Post by: lesept on Nov 23, 2018, 10:06 pm
J'ai trouvé un exemple  (https://github.com/pcbreflux/espressif/blob/master/esp32/app/ESP32_deep_sleep_timer/main/deep_sleep_main.c):

Code: [Select]
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#include "sys/time.h"

#include "sdkconfig.h"

#include "esp_deep_sleep.h"

#define GPIO_DEEP_SLEEP_DURATION     10  // sleep 10 seconds and then wake up
RTC_DATA_ATTR static time_t last;        // remember last boot in RTC Memory

void app_main() {
struct timeval now;

printf("start ESP32\n");

gettimeofday(&now, NULL);

printf("deep sleep (%lds since last reset, %lds since last boot)\n",now.tv_sec,now.tv_sec-last);

last = now.tv_sec;
esp_deep_sleep(1000000LL * GPIO_DEEP_SLEEP_DURATION);

}

Le code se réveille toutes les 10 secondes et affiche le temps de sommeil, mais en secondes. Il reste juste à trouver le moyen d'obtenir des microsecondes...
Probable qu'on puisse utiliser
Code: [Select]
last = now.tv_usec;
ou convertir les temps en microsecondes comme
Code: [Select]
now.tv_sec * 1000000 + now.tv_usec
Je teste ça dès que j'ai un moment...
Title: Re: Esp32 : deep sleep et SPIFFS
Post by: lesept on Nov 24, 2018, 12:35 pm
Voila le résultat :
Code: [Select]
#define uS_TO_S_FACTOR 1000000  /* Conversion factor for micro seconds to seconds */
#define TIME_TO_SLEEP  5       /* Time ESP32 will go to sleep (in seconds) */

#include "sys/time.h"

RTC_DATA_ATTR int bootCount = 0;
RTC_DATA_ATTR static time_t last;        // remember last boot in RTC Memory
RTC_DATA_ATTR static time_t lastus;        // remember last boot in RTC Memory


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

  struct timeval now;
  gettimeofday(&now, NULL);
  long temps = now.tv_sec * 1000000 + now.tv_usec - (last * 1000000 + lastus);
  Serial.println(temps);

  //Configure Timer as wakeup source
  esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP * uS_TO_S_FACTOR);

  delay(1); //delayMicroseconds(400);
  last = now.tv_sec;
  lastus = now.tv_usec;
  esp_deep_sleep_start();
}

void loop() { }


Pour un temps de sommeil demandé de 5 secondes, j'obtiens des réveils avec un temps mesuré autour de 5 secondes et 129 ms

Quote
rst:0x1 (POWERON_RESET),boot:0x17 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0018,len:4
load:0x3fff001c,len:808
load:0x40078000,len:6084
load:0x40080000,len:6696
entry 0x400802e4
20144
ets Jun  8 2016 00:22:57

rst:0x5 (DEEPSLEEP_RESET),boot:0x17 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0018,len:4
load:0x3fff001c,len:808
load:0x40078000,len:6084
load:0x40080000,len:6696
entry 0x400802e4
5129085
ets Jun  8 2016 00:22:57

rst:0x5 (DEEPSLEEP_RESET),boot:0x17 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0018,len:4
load:0x3fff001c,len:808
load:0x40078000,len:6084
load:0x40080000,len:6696
entry 0x400802e4
5129022
Ces 129 ms supplémentaires semblent dépendre des instructions qui se trouvent entre les instructions liées au temps : gettimeofday et affectation des variables last et lastus

Par exemple si je mets
Code: [Select]
  esp_sleep_enable_timer_wakeup(5000000);il y a une multiplication en moins et je passe à 128,9 ms. Par contre si j'ajoute les instructions de configuration de mon accéléromètre, je passe à 528 ms...

Et déplacer le Serial.begin après le gettimeofday ne change rien !

Enfin, le delay(1) sert à attendre que le port série envoie la donnée (temps), si on optimise avec delayMicroseconds(400) on passe à 128,5 ms.

Ce temps additionnel est indépendant de la durée du temps de sommeil : si je mets 10 ou 30 secondes, les résultats sont similaires.
Title: Re: Esp32 : deep sleep et SPIFFS
Post by: J-M-L on Nov 24, 2018, 12:49 pm
pas si mal !!

par acquis de conscience je mettrais
Code: [Select]
#define uS_TO_S_FACTOR 1000000ul  /* Conversion factor for micro seconds to seconds */
#define TIME_TO_SLEEP  5u       /* Time ESP32 will go to sleep (in seconds) */


histoire de forcer les types dans les calculs lors de la phase de précompilation
Title: Re: Esp32 : deep sleep et SPIFFS
Post by: lesept on Nov 24, 2018, 01:21 pm
Mouais
J'ai prévu un réveil chaque minute. Si à chaque fois j'accumule 500 ms je vais vite prendre du retard... 12 minutes par jour, c'est dur.
Il va falloir caractériser finement pour recaler et éviter trop de dérive. Heureusement que je pensais remettre l'heure à jour pendant la nuit...
Title: Re: Esp32 : deep sleep et SPIFFS
Post by: al1fch on Nov 24, 2018, 01:35 pm
Une certaine (je ne sais pas l'estimer) incertitude sur les durées d'activité est  inévitable avec l'ESP32 sous IDE Arduino+IDF Espressif en raison de RTOS. Ton code , le sept, est compilée en tâche(s) parmi d'autres.

Pourl'ESP8266 Espressif a fait é SDK : le 'nonos' , sans RTOS et l'autre avec RTOS.
l'IDE ARduino repose sur le premier
Pour l'ESP32 c'est RTOS pour tout le monde.

Pour le temps de sommeil il faut faire avec l'imprécision de l'oscillateur TC de la RTC