Rapport de cours · Semestre printemps 2025-2026

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.

Côté embarqué

OpenHarmony + Hi3861 × 2
Collecte capteurs & contrôle actionneurs

Côté serveur

EMQX MQTT Broker
Relayage de messages & routage par Topic

Côté application

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)

Hi3861 HiSilicon OpenHarmony 1.0 LiteOS-M CMSIS-RTOS C GPIO PWM I2C ADC AHT20 SSD1306 Paho MQTT lwIP Wi-Fi STA

Serveur (Communication)

MQTT 5.0 WebSocket Secure EMQX Broker TCP Socket JSON Pub/Sub Routage Topic

Application (HarmonyOS)

HarmonyOS 6.1.0 API23 ArkTS ArkUI Modèle Stage @StorageLink @ObjectLink HDS UIDesignKit Forme Glass

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

Publisher Émetteur

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é.

Broker Relais

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.

Subscriber Abonné

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 »

Capteurs
  • Capteur AHT20 température/humidité — Lecture I2C de température et humidité
  • Photo-résistance — Lecture ADC de l'intensité lumineuse (0~4095)
Actionneurs
  • LED RGB trichromatique — GPIO10/11/12 => PWM1/2/3 pour contrôle de luminosité
Affichage local

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 »

Capteurs
  • Capteur d'humidité du sol (installation par remplacement) — Lecture ADC de l'humidité du sol
Actionneurs
  • É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 :

Collecte température/humidité air

AHT20 / I2C

Détection luminosité

Échantillonnage ADC

Lecture humidité du sol

Échantillonnage ADC

Ventilateur/LED/Pompe

Contrôle GPIO/PWM

Rafraîchissement affichage OLED

Rendu SSD1306

Communication réseau MQTT

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 :

Scénario de conflit

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

Solution

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)

OLED Impression d'état I2C0-0x78 GPIO13&14 oled_ssd1306.c
Humidité du sol Sonde externe ADC_CH4 soil_moisture_task.c
Pompe Pompe externe P06 water_pump_task.c
Ventilateur Ventilateur externe P08 fan_task.c

Carte RGB (Perception environnementale)

OLED Impression d'état I2C0-0x78 GPIO13&14 oled_ssd1306.c
Capteur temp./humid. Détection paramètres air I2C0-0x44 temp_and_hum_task.c
Photo-résistance Détection intensité lumineuse ADC_CH4 light_intensity_task.c
LED RGB trichrome Contrôle éclairage serre 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

Mode Manuel

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.

Mode Intelligent

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.

Monitoring temps réel

Callback MQTT réceptionnant les données capteurs, gestion d'état @StorageLink pilotant le rafraîchissement automatique des chiffres ArkUI.

Panneau de debug

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

États de contrôle

Gestion centralisée des niveaux de ventilateur, pompe et luminosité LED, partage d'état inter-pages via @StorageLink.

Transmission de paramètres

Données capteurs et commandes de contrôle transmises de manière fiable via un format unifié dans la couche MQTT.

Synchronisation des logs

GlobalLogBus collecte de manière unifiée l'état de communication, les enregistrements d'opérations et les informations d'anomalies.

Cycle de vie

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

HdsNav Barre de navigation

Navigation supérieure immersive à champ lumineux, effet flou glassmorphism

PressShadow Effet gravitationnel

Déformation élastique à l'appui + diffusion du champ lumineux en retour tactile

SpringMotion Animation ressort

Entrée échelonnée avec délai, courbe ressort pour une expérience fluide

Style visuel

Champ lumineux sombre

Arrière-plan lumineux fluide traversant toute l'interface, ambiance maximale en mode sombre

Mise en page double colonne

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 :

Version mobile

Colonne unique défilement vertical, cartes empilées

Version tablette

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.