OpenHarmony au service de l'agriculture intelligente
— Terminal de contrôle de serre basé sur Hi3861 et HarmonyOS
De la collecte des capteurs au contrôle en temps réel sur mobile, un système IoT complet pour l'agriculture intelligente.
Deux cartes de développement à tâches distinctes, relayage MQTT, terminal HarmonyOS pleinement fonctionnel.
Présentation générale du projet
Rapport de conception du cours du second semestre de l'année 2025-2026, présenté par : Chen Zirui (Ray Chen)
Qu'est-ce que Smart Shed ?
Smart Shed (Serre Intelligente) est un système complet de contrôle IoT pour l'agriculture intelligente, basé sur OpenHarmony et HarmonyOS NEXT de Huawei. En bref : deux cartes de développement s'occupent de percevoir et de contrôler les paramètres environnementaux, communiquent en temps réel avec l'application mobile via le protocole MQTT, et permettent finalement le monitoring automatique et le pilotage intelligent de la température, de l'humidité, de la luminosité et de l'humidité du sol dans la serre.
OpenHarmony + Hi3861 × 2
Collecte capteurs & contrôle actionneurs
EMQX MQTT Broker
Relayage de messages & routage par Topic
HarmonyOS NEXT (API23)
Mate 70 Pro+ / MatePad Pro
01 · Vue d'ensemble & Stack technique
Architecture globale, défis techniques rencontrés, innovations apportées
Architecture système : collaboration logiciel-matériel, intégration verticale
Côté embarqué collecte les données → Serveur relaie les messages → Mobile affiche et contrôle
Côté embarqué
OpenHarmony 1.0 Release
Rayawa/rgb @ HiSilicon-Hi3861
Rayawa/soi @ HiSilicon-Hi3861
Collecte capteurs + affichage OLED
Contrôle PWM/GPIO des actionneurs
Côté serveur
MQTT 5.0 WebSocket
wss://broker.emqx.io:8084
@MQTTX
Relayage de messages public
Routage distribué par Topic
Côté application
HarmonyOS 6.1.0 (API23)
Smart Shed @ Mate 70 Pro+
Smart Shed @ MatePad Pro 12.2
Affichage de données en temps réel
Modes Manuel / Intelligent
Défis techniques
Problèmes réellement rencontrés durant le développement
Côté embarqué
- Nombreux problèmes de compatibilité des versions d'interface de pilotes
- L'accès concurrent multi-périphériques au bus I2C provoque des conflits
- L'espace de pile et la priorité des threads LiteOS-M nécessitent de nombreux réglages itératifs
Côté application
- La documentation originale était basée sur JavaUI API7, bien trop ancienne
- Le code original ne fonctionnait que sur une tablette spécifique ; changement d'appareil = interface en désordre
- Une seule carte d'extension pouvait gérer un seul composant, mais quatre systèmes avaient été conçus : refonte massive requise
Couche communication
- Le transport MQTT n'est pas très stable, et les messages d'erreur sont peu explicites
- Le module WiFi du Hi3861 est vieillissant, capacité de charge faible
- Le mécanisme d'envoi/réception côté application était rudimentaire, quasi sans gestion d'erreurs : tout se faisait au feeling
Innovations
Architecture double carte séparée
Carte de perception environnementale (RGB) et carte d'exécution sol (SOI) isolées physiquement et découplées logiquement : chacune gère son domaine tout en collaborant.
Client MQTT zéro dépendance
Côté HarmonyOS, les paquets MQTT sont entièrement construits manuellement depuis TCP Socket, sans aucune dépendance tierce.
Système visuel avancé HDS
Intégration de la bibliothèque officielle HarmonyOS Design System : navigation immersive, effets gravitationnels, arrière-plan lumineux.
Modes Manuel / Intelligent
Mode Manuel : ajustement libre des niveaux. Mode Intelligent : décision automatique selon les seuils, thread résident sécurisé en arrière-plan.
Adaptation forme Glass
Application supplémentaire sous forme Glass pour montre connectée, avec matériaux immersifs et animations gazeuses.
Garantie de fiabilité
Détection automatique hors ligne (timeout 5s), reconnexion avec recul exponentiel, bus de journalisation GlobalLogBus comme filet de sécurité global.
Stack technique
Embarqué (Hi3861)
Serveur (Communication)
Application (HarmonyOS)
02 · Serveur MQTT
Principe de l'architecture Pub/Sub et conception du flux de données
Architecture Pub/Sub (Publication/Abonnement)
MQTT est un protocole léger de messagerie, conçu spécifiquement pour les scénarios IoT à faible bande passante
Mécanisme de collaboration tripartite
Le côté embarqué Hi3861 agit en tant qu'émetteur, encapsule les données des capteurs en JSON et les envoie vers le Topic désigné.
EMQX agit en tant que Broker MQTT : après réception d'un message, il le transfère aux abonnés correspondants selon les règles de Topic.
L'application HarmonyOS, une fois abonnée aux Topics concernés, reçoit les données des capteurs et peut également envoyer des commandes de contrôle.
Conception du flux de données
Comment les données transitent du matériel jusqu'au mobile, et comment les commandes reviennent vers le matériel pour exécution
Montant : données capteurs → affichage mobile
① Échantillonnage capteurs
Les capteurs de la carte d'extension collectent les données brutes → lecture ADC de luminosité/humidité du sol, lecture I2C de AHT20 température/humidité
② Encapsulation & envoi
Le Hi3861 convertit les données en format JSON et les envoie au Broker EMQX via un paquet MQTT PUBLISH
③ Routage distribué
EMQX reçoit le message et le distribue aux clients abonnés selon les règles de Topic
④ Rafraîchissement de l'interface
HarmonyOS reçoit et analyse le message → mise à jour d'état via @StorageLink → rafraîchissement des chiffres UI / jugement des seuils en mode intelligent
Descendant : action utilisateur → exécution matérielle
① Action utilisateur ou déclenchement automatique
Mode Manuel : glisser le curseur pour régler le niveau. Mode Intelligent : génération automatique de commande si dépassement de seuil
② Encapsulation & envoi
HarmonyOS convertit la commande de contrôle en paquet MQTT, qui est distribué via EMQX
③ Exécution matérielle
Après réception du message, le Hi3861 analyse le sujet et le contenu → contrôle des sorties GPIO/PWM → actionnement ventilateur/pompe/lumière
03 · Côté embarqué Hi3861
OpenHarmony LiteOS-M + multithread CMSIS-RTOS, développement entièrement en C
Deux cartes de développement, chacune sa mission
Carte RGB (Perception environnementale)
Responsable de « voir l'environnement » et « afficher localement »
- Capteur AHT20 température/humidité — Lecture I2C de température et humidité
- Photo-résistance — Lecture ADC de l'intensité lumineuse (0~4095)
- LED RGB trichromatique — GPIO10/11/12 => PWM1/2/3 pour contrôle de luminosité
OLED SSD1306 (128×64) avec rafraîchissement en temps réel des données de température, humidité et luminosité
Carte SOI (Exécution sol)
Responsable de « mesurer le sol » et « agir »
- Capteur d'humidité du sol (installation par remplacement) — Lecture ADC de l'humidité du sol
- Écran OLED — Impression d'état local
- Ventilateur — Contrôle PWM de la vitesse
- Pompe — Contrôle GPIO marche/arrêt
Structure du projet
Grandes fonctions séparées, petits modules divisés : clair et facile à maintenir
common/ Couche commune
Connexion Wi-Fi, communication MQTT, pilote OLED : tout est ici. Le mutex I2C est aussi géré ici pour éviter que plusieurs threads ne s'accaparent le bus.
modules/ Couche métier
Divisée en deux sous-répertoires :
- sensors/ — Fichiers d'en-tête et programmes des capteurs AHT20, intensité lumineuse, humidité du sol
- actuators/ — Programmes de contrôle ventilateur, lumière complémentaire, pompe
boards/ Couche de build
Les fichiers de build .gn des deux cartes sont gérés de manière unifiée. La compilation conditionnelle active dynamiquement les modules selon la carte : ajouter une nouvelle carte = ajouter simplement un fichier gn.
Architecture multithread
CMSIS-RTOS gère les tâches parallèles sous le noyau temps réel LiteOS-M
Point d'entrée du thread principal
- Au démarrage du système, SYS_RUN crée le thread principal
smart_shed_all.c, avec une pile de 8 Ko - Le thread initialise séquentiellement et lance tous les sous-threads : collecte capteurs, contrôle actionneurs, communication MQTT, affichage OLED
- La compilation conditionnelle active dynamiquement les modules correspondants selon la configuration de la carte, avec un point d'ordonnancement unifié
Six sous-threads travaillant en parallèle
Chaque module fonctionnel tourne indépendamment dans le noyau LiteOS, avec son propre espace de pile (4Ko~8Ko) et sa priorité, sans blocage mutuel :
AHT20 / I2C
Échantillonnage ADC
Échantillonnage ADC
Contrôle GPIO/PWM
Rendu SSD1306
Publication/Abonnement Paho
Mutex I2C : résolution des conflits de bus
Le capteur AHT20 et l'écran OLED partagent le même bus I2C0 (GPIO13 & GPIO14). Si deux threads y accèdent simultanément, ça coince. Solution :
Le thread de collecte temp./humid. et le thread de rafraîchissement OLED lisent et écrivent simultanément sur I2C0, provoquant une corruption des données
Utiliser le mutex i2c0_lock/unlock : verrouillage/déverrouillage avant et après chaque lecture/écriture, garantissant qu'un seul périphérique occupe le bus à un instant donné
Correspondance des connexions matérielles
Carte SOI (Exécution sol)
I2C0-0x78 GPIO13&14
oled_ssd1306.c
ADC_CH4
soil_moisture_task.c
P06
water_pump_task.c
P08
fan_task.c
Carte RGB (Perception environnementale)
I2C0-0x78 GPIO13&14
oled_ssd1306.c
I2C0-0x44
temp_and_hum_task.c
ADC_CH4
light_intensity_task.c
GPIO10/11/12=>PWM1/2/3
led_task.c
Réseau et communication
Connexion Wi-Fi → TCP établi → MQTT envoie/reçoit → Les actionneurs bougent
Flux de communication
Connexion Wi-Fi
Connexion au SSID "Rayawa", obtention d'une IP via DHCP puis passage en communication TCP lwIP
Encodage/décodage MQTT
La bibliothèque Paho gère uniquement l'encodage/décodage des paquets ; le cycle de vie complet du Socket TCP doit être géré manuellement
Envoi des données capteurs
Les données des capteurs sont transmises au Broker EMQX au format JSON
Exécution des commandes de contrôle
Réception d'un paquet PUBLISH → analyse du sujet et de la charge utile via MQTTDeserialize_publish() → définition des variables globales via mqtt_apply_command(). Les threads d'actionneurs lisent continuellement ces variables pour contrôler les sorties GPIO/PWM, faisant fonctionner ventilateur, pompe, etc.
04 · Application HarmonyOS
ArkTS · Modèle Stage · Visuels avancés HDS · Client MQTT auto-implémenté
Smart Shed App
Terminal de contrôle pleinement fonctionnel tournant sur Mate 70 Pro+ et MatePad Pro
Aperçu des fonctionnalités
Glisser le curseur pour régler ventilateur (0-3 niveaux), pompe (0-3 niveaux), lumière complémentaire (0-100%). Synchronisation automatique du niveau actuel vers la carte à l'entrée de page, support retour haptique.
Définir les seuils min/max de température, humidité, luminosité et humidité du sol. Polling périodique des données capteurs, déclenchement automatique du contrôle en cas de dépassement. Thread résident en arrière-plan, destruction sécurisée à la sortie de page contre les fuites mémoire.
Callback MQTT réceptionnant les données capteurs, gestion d'état @StorageLink pilotant le rafraîchissement automatique des chiffres ArkUI.
Bus d'événements GlobalLogBus enregistrant l'état de communication, les actions utilisateur et les messages d'erreur, pratique pour diagnostiquer les problèmes.
Structure du projet App (Modèle Stage)
Architecture en couches basée sur ArkTS
AppScope/
Point d'entrée unifié pour les ressources globales de l'application et les scripts de build Hvigor.
view/ & pages/
Couche UI construite en ArkTS, incluant l'interface complète des modes Manuel/Intelligent et du panneau de debug.
service/
Encapsulation du client MQTT (MqttReceiverClient.ts), connexion directe TCP Socket pour communication bidirectionnelle, zéro dépendance tierce.
viewmodel/
Structures de données centrales et modèles d'état, assurant la liaison réactive entre UI et données.
MqttReceiverClient.ts — Client MQTT écrit depuis zéro
Pourquoi l'avoir écrit soi-même ?
Côté HarmonyOS, aucune bibliothèque MQTT tierce n'a été utilisée : les paquets ont été entièrement construits à la main depuis TCP Socket. Cela donne un contrôle total sur l'ensemble du processus de communication, et facilite grandement le diagnostic en cas de problème.
Couche protocole
- Assemblage manuel de Fixed Header + Variable Header + Payload
- Implémentation des paquets principaux CONNECT / PUBLISH / SUBSCRIBE / PINGREQ
- Heartbeat KeepAlive toutes les 60s pour maintien de connexion
- MQTT 5.0 over WSS connexion directe au Broker public EMQX
Garantie de fiabilité
- Reconnexion automatique en cas de coupure + recul exponentiel
- Connexion TCP unique, abonnement multi-Topic et routage distribué
- Gestion d'état @StorageLink et découplage vis-à-vis d'ArkUI
- Bus de journalisation GlobalLogBus traçant l'intégralité des communications
États et méthodes
Gestion centralisée des niveaux de ventilateur, pompe et luminosité LED, partage d'état inter-pages via @StorageLink.
Données capteurs et commandes de contrôle transmises de manière fiable via un format unifié dans la couche MQTT.
GlobalLogBus collecte de manière unifiée l'état de communication, les enregistrements d'opérations et les informations d'anomalies.
Création de la connexion à l'entrée de page, destruction du thread et libération des ressources à la sortie : zéro fuite mémoire.
Design UI : HDS + ArkUI
Non seulement fonctionnel, mais aussi beau
Composants clés HDS
Navigation supérieure immersive à champ lumineux, effet flou glassmorphism
Déformation élastique à l'appui + diffusion du champ lumineux en retour tactile
Entrée échelonnée avec délai, courbe ressort pour une expérience fluide
Style visuel
Arrière-plan lumineux fluide traversant toute l'interface, ambiance maximale en mode sombre
Adaptation tablette en double colonne, équilibre entre densité d'information et harmonie visuelle
Animation : champ gravitationnel
Effet de champ gravitationnel lors des transitions de page, animations d'attraction/répulsion naturelles entre éléments.
Animation : champ lumineux
Arrière-plan lumineux fluide + champ lumineux global sombre double colonne, ombres dynamiques variant avec les interactions.
Animation : transition
Fondu + animation élastique, courbe SpringMotion pour des transitions soyeuses.
Mise en page responsive
Système de grille responsive ArkUI, adaptation automatique aux deux facteurs de forme mobile et tablette :
Colonne unique défilement vertical, cartes empilées
Double colonne côte à côte, exploitation optimale de l'espace large
Smart Shed Glass
Forme montre connectée — Matériaux immersifs + Animations gazeuses
Caractéristiques de la forme Glass
- Matériaux immersifs — L'interface fusionne avec la texture en verre du cadran
- Animations gazeuses — Transitions légères et aériennes
- Transition gravitationnelle — Conservation du même langage d'interaction que l'App principale
- Lumière fluide double bordure — Décoration dynamique sur les côtés du cadran
Composants personnalisés HdsButtons
Système de composants boutons personnalisés basé sur les spécifications HDS, unifiant l'apparence visuelle et le retour tactile de tous les éléments interactifs sous la forme Glass. Supporte plusieurs tailles et styles d'état (par défaut/appuyé/désactivé), agréable à utiliser sur petit écran.
05 · Questions fréquentes & Conclusion
Ce que vous vous posez peut-être, et ce que ce projet m'a apporté
Questions fréquentes
Pourquoi avoir choisi OpenHarmony plutôt qu'Arduino/ESP32 ?
OpenHarmony offre un vrai RTOS (LiteOS-M) avec ordonnancement préemptif, gestion multithread native et un écosystème matériel Huawei mature. Arduino/ESP32, c'est bien pour prototyper, mais dès qu'on veut faire du multitâche sérieux avec mutex, piles configurables et compilation conditionnelle, on atteint vite les limites. Et puis, travailler avec un système d'exploitation complet plutôt qu'un simple framework, c'est une expérience d'apprentissage totalement différente.
Combien de temps a pris le développement ?
Environ 6 semaines au total : 2 semaines pour la partie embarquée (drivers, multithread, MQTT), 3 semaines pour l'App HarmonyOS (refonte complète depuis JavaUI API7 vers ArkTS API23, implémentation MQTT from scratch, design HDS), et 1 semaine pour l'intégration, les tests et la rédaction du rapport. Le plus long a été la refonte côté application — le code legacy était vraiment difficile à migrer.
Le plus gros challenge technique ?
Sans hésiter : le conflit de bus I2C. AHT20 et SSD1306 partagent le même bus I2C0, et quand le thread de collecte et celui d'affichage y accèdent en même temps, c'est le chaos. La solution paraît simple (un mutex), mais trouver la source du bug a pris presque 2 jours de debug avec un oscilloscope logique. Ensuite, écrire un client MQTT entier depuis zéro en ArkTS a aussi été un bon défi — surtout la gestion de la reconnexion et du cycle de vie des threads.
Quels outils de debug avez-vous utilisés ?
Côté embarqué : oscilloscope logique USB pour tracer le bus I2C, serial print sur UART0 pour les logs, et MQTTX pour visualiser les messages en temps réel. Côté HarmonyOS : DevEco Studio avec son debugger intégré, HiLog pour les logs système, et le panneau GlobalLogBus intégré à l'App pour suivre toute l'activité MQTT en direct. L'outil le plus précieux ? Probablement MQTTX — pouvoir voir exactement ce qui passe sur le broker en temps réel a sauvé pas mal de soirées.
Ce projet pourrait-il être utilisé en conditions réelles ?
Pour un prototype de cours, il est déjà assez abouti. Mais pour un déploiement réel, il manque quelques choses : authentification MQTT (actuellement sans mot de passe), persistance des seuils de mode intelligent (stockés en mémoire volatile), et une UI de configuration initiale (SSID/mot de passe WiFi actuellement codés en dur). Le hardware aussi : le Hi3861 n'est pas certifié industriel, et les capteurs bas coût manquent de calibration. Mais l'architecture logicielle est solide — ces améliorations seraient relativement simples à intégrer.
Qu'avez-vous appris grâce à ce projet ?
Beaucoup plus que prévu. Sur le plan technique : programmation système embarquée, RTOS, protocoles IoT, développement d'application mobile moderne. Sur le plan méthodologique : comment architecturer un système distribué de bout en bout, gérer la complexité avec des couches propres, et documenter correctement. Et surtout : la patience face aux bugs matériels qui ne s'expliquent pas, et la satisfaction de voir un système complet fonctionner de bout en bout — du capteur jusqu'à l'écran du téléphone.
Bilan du projet
Un projet de A à Z
De la première ligne de code à la présentation finale, SmartShed a été un voyage complet à travers l'écosystème HarmonyOS/OpenHarmony. J'ai touché à presque chaque couche d'un système IoT : drivers matériels, RTOS, protocoles réseau, développement d'application mobile, design d'interface utilisateur, et même un peu de devOps avec la chaîne de build GN/Ninja.
Si je devais retenir une chose, c'est que la complexité se gère par l'architecture. Au début, j'ai essayé de tout mettre dans un seul fichier — résultat : cauchemar de maintenance. Après refactorisation en couches (common/modules/boards) et adoption du modèle Stage côté App, chaque modification devient ciblée et prévisible.
Merci d'avoir lu jusqu'ici. Si ce projet vous inspire ou si vous avez des questions, n'hésitez pas à me contacter ou à explorer le code source sur GitHub — il est entièrement open-source.