esp32 domotique espressif

/Test de l'esp32-h2 zigbee avec home assistant

May 21, 2024

Dans le cadre de la réalisation de mon interrupteur connecté, nous revenons cette fois-ci avec un ESP32-H2-MINI-1-N4, équipé d'un processeur 96MHz et prenant en charge le Bluetooth, Zigbee et Thread.

Pour rappel, mes essais avec un Raspberry Pi Pico ont révélé une autonomie insuffisante. Bien que l'ESP32-WROOM réponde à mes attentes en termes de mode veille, il présente une latence avec la connexion Wi-Fi trop élevée.

La principale difficulté de ce nouveau test résidait dans la programmation. Aucun runtime JS n'était disponible à ma connaissance, et ESPHome n'était pas pris en charge. Nous nous sommes donc retrouvés avec le bon vieux langage C, que je n'avais pas utilisé depuis plus de dix ans.

Environnement de développement

Deux options s'offrent à nous : utiliser l'Arduino IDE ou l'ESP IDF.

  • L'Arduino IDE est plus facile à prendre en main, mais offre moins de ressources pour la partie Zigbee, qui reste en phase bêta dans cet environnement.
  • L'ESP IDF est la solution officielle d'Espressif pour les ESP. Il existe plusieurs façons de l'installer : via VS Code, Eclipse ou manuellement.

Après avoir exploré toutes les solutions (à l'exception d'Eclipse), j'ai opté pour l'ESP IDF avec une installation manuelle.

Installation (Linux Pop OS)

La documentation officiel est très bien faite.

# installation des dépendences
sudo apt-get install git wget flex bison gperf python3 python3-pip python3-venv cmake ninja-build ccache libffi-dev libssl-dev dfu-util libusb-1.0-0

# installation de ESP IDF
mkdir -p ~/esp
cd ~/esp
git clone -b v5.2.1 --recursive https://github.com/espressif/esp-idf.git

# setup
cd ~/esp/esp-idf
./install.sh esp32h2

Développement

  • Test zigbee et connexion avec Home assistant
  • Test Deep sleep
  • Test GPIO pour un interrupteur avec configuration zigbee

Zigbee

Ce protocole domotique est basé sur une architecture en cluster. Lors de la programmation, il sera donc nécessaire de déclarer des clusters pour y référencer l'usage qui en sera fait. Cela permet d'établir une norme à communiquer aux différentes box domotiques. Par exemple, pour des fonctions telles que la température, l'humidité, les interrupteurs, etc.

Pour mieux comprendre ces concepte je vous invite à regarder cette exélente vidéo qui ma permi de démarrer ce projet.

La partie zigbee est expliqué dans la vidéo, je ne reviendrais pas dessus. Dans mon cas j'utilise un cluster binaire.

    esp_zb_binary_input_cluster_cfg_t binary_input_cfg = {
        .out_of_service = 0,
        .status_flags = 0,
    };
    uint8_t present_value = 0;
    esp_zb_attribute_list_t *esp_zb_binary_input_cluster = esp_zb_binary_input_cluster_create(&binary_input_cfg);
    esp_zb_binary_input_cluster_add_attr(esp_zb_binary_input_cluster, ESP_ZB_ZCL_ATTR_BINARY_INPUT_PRESENT_VALUE_ID, &present_value);

Deep Sleep

Pour réaliser mon projet, je prévois de ne pas réveiller l'ESP32 à intervalles réguliers, mais uniquement lorsqu'un appui sur mon interrupteur est détecté.

Pour cela, j'utilise la fonction esp_deep_sleep_start() pour mettre la carte en sommeil, et je la réveille par GPIO en utilisant esp_sleep_enable_ext1_wakeup().

J'ai rencontré quelques difficultés à comprendre cette dernière fonction. Contrairement à esp_sleep_enable_ext0_wakeup(), qui n'est pas implémentée sur l'ESP-H2 et prend en paramètre le numéro du pin, ext1 peut utiliser plusieurs pins, donc il est nécessaire de passer par un masque.

Le calcul est le suivant : 2 puissance numéro du premier pin + 2 puissance numéro du second pin, le tout converti en hexadécimal. Par exemple, pour le pin 8 : 2 puissance 8 = 256, en hexadécimal : 0x0100.

Après avoir découvert ce calcul, j'ai également trouvé la fonction BIT() qui réalise le masquage pour nous.

Exemple :

esp_sleep_enable_ext1_wakeup(BIT(GPIO_NUM_12), ESP_EXT1_WAKEUP_ANY_HIGH);

esp_deep_sleep_start();

GPIO

Ici, rien de bien particulier pour un microcontrôleur. Nous utilisons simplement la fonction gpio_set_direction() pour définir le mode d'entrée (Input).

Build

Dans le répertoire de son projet

# init les variable d'environnement
. $HOME/esp/esp-idf/export.sh

# Flasher l'esp
idf.py -p /dev/ttyACM0 flash

Si nécessaire, vous pouvez écraser complètement la mémoire flash. Dans mon cas, j'ai dû le faire la première fois.

idf.py -p /dev/ttyACM0 erase-flash

/dev/ttyACM0 correspond à mon port USB. Pour plus d'informations à ce sujet, vous pouvez consulter cette ressource.

Pour visualiser vos Log il est très pratique d'utilisé la commande :

idf.py -p /dev/ttyACM0 monitor

Important, pour sortir du mode monitor : Ctrl+]

Le code complet : https://github.com/batosai/esp-h2-zigbee

Résultat

Malgré une latence plus faible que celle du Wi-Fi, elle reste importante pour un interrupteur. Par conséquent, je mets en pause le projet le temps de trouver des personnes avec qui je pourrai échanger.

Ressources

https://beta.gammatroniques.fr/projects/esp32h2-zigbee

https://github.com/xmow49/ESP32H2-Zigbee-Demo

https://github.com/espressif/esp-idf/blob/master/examples

https://microcontrollerslab.com/esp32-external-interrupts-wake-up-deep-sleep/

https://randomnerdtutorials.com/esp32-touch-wake-up-deep-sleep/

https://docs.espressif.com/projects/esp-idf/en/v5.2.1/esp32h2/api-reference/system/power_management.html

https://docs.espressif.com/projects/esp-idf/en/latest/esp32c3/api-guides/usb-serial-jtag-console.html#uploading-the-application

https://www.upesy.fr/blogs/tutorials/install-esp32-on-arduino-ide-complete-guide

Partage

©2024 Jeremy Chaufourier.