Skip to content

Développement sur le coeur faible consommation ULP d'un esp32

reichart edited this page Jun 2, 2022 · 7 revisions

Le développement sur le coeur faible consommation (Ultra Low Power) ULP d'un esp32

ulp

principe du réveil pour atteindre une faible consommation

https://randomnerdtutorials.com/esp32-deep-sleep-arduino-ide-wake-up-sources/

installation de l’environnement

https://github.com/duff2013/ulptool

utiliser le convertisseur ADC avec ULP

https://github.com/SensorsIot/ESP32-ULP-Arduino-IDE/blob/master/ulp_adc/adc.s

utilisation pour un réveil par un message

SMS reçu par GSM

Principe

l’ULP est réveillé périodiquement par un timer ( toutes les 100 ms dans mon cas), fait son job et si besoin émet un signal vers le processeur principal puis se rendort.

Si le processeur principal est actif il doit gérer une interruption venant de l’ULP avec quelques infos passée dans la mémoire partagée.

Si le processeur principal est en deepsleep, il est réveillé et il doit identifier l’origine du réveil et traiter avec les quelques infos passée dans la mémoire partagée.

Dans mon cas l’ULP fait deux choses

  •      Surveiller le passage à l’état bas d’une pin (signalement par le modem GSM de l’arrivée d’un SMS)
    
  •      Signaler l’état bas d’une pin pendant N cycles (N défini par proc principal)(par ex 450 * 100 ms = 45 s)
    

Pour les raisons suivantes :

  •      Souhait de mettre l’ESP32 en deepsleep quand il n’a rien à faire, pas pour des pb de consommation mais pour éviter des plantages par « vieillissement du code »
    
  •      Signalement de l’arrivée des SMS par niveau bas imposé par le modem et config matérielle ( TTGO  …)
    
  •      Souhait de réagir sur le changement d’état d’une autre pin (au moins) pour surveiller l’environnement
    
  •      Les fonctionnalités dispo pour la sortie du deepsleep sont : une pin parmi N à l’état haut ou,  N pins toutes à l’état bas : pas souple dans ce dernier cas imposé par le modem GSM 
    

…/…

pin1_check:

/* remplacer pin1_last par pin1_status */

move r0, pin1_status

ld r0, r0, 0

move r2, pin1_last

st r0, r2, 0

/*read input registor */

READ_RTC_REG(RTC_GPIO_IN_REG, RTC_GPIO_IN_NEXT_S, 16)

move r2, PIN_1_RTC_NUM

rsh r0, r0, r2

and r0, r0, 1 /* le bit significatifs est le poids le plus faible */

move r2, pin1_status

st r0, r2, 0   /* stocké dans status */

move r2, pin1_last

ld r2, r2, 0  /* pin_last dans r2 */

add r0, r0, r2

and r0, r0, 1

jump pin2_check, eq

/* traiter cas diff donc front */

move r0, 1

move r2, flag_isr

st r0, r2, 0    

…/…

Merci à Patrick de Viroflay pour son code et ses explications