Le shutter pour vidéo projecteur, ou volet roulant en français, est un moteur contrôlé à distance permettant de masquer le faisceau de lumière d’un vidéoprojecteur. Pour les gros vidéoprojecteurs nécessitant un temps de chauffe, cet outil permet de maîtriser quand l’utilisateur souhaite projeter le contenu diffusé. Des kits semblables sont disponibles sur le marché mais à des prix très onéreux. Elyxoft a donc décelé une opportunité lorsque l’un de ses futurs clients a fait une demande pour ce type de produit en proposant une alternative beaucoup moins coûteuse. Celui-ci est contrôlé depuis une application smartphone via la technologie Bluetooth et peut être ouvert ou fermé.
Réalisation
Le projet est décomposé en deux parties: embarquée et débarquée.
La partie embarquée comporte du développement en C sur un microcontrôleur ESP32 permettant de gérer la logique intégrée à la carte. Celle-ci comporte aussi la réalisation de modèles 3D ainsi que le choix des matériaux et composants du kit Shutter pour ainsi le rendre compact et facilement manipulable.
La partie débarquée consiste en la réalisation d’une application cross-platform permettant de piloter le shutter depuis un smartphone ou un ordinateur.
Une première version du kit fut développée par l’étudiant en SEOC à l’INPG, Fabien Vermeulen. Le prototype comprenais tout les aspects fonctionnels du Shutter avec un microcontrôleur en boîtier et une application mobile de contrôle Bluetooth. Cette première version ne correspondais pas tout à fait aux attentes de l’entreprise car l’application de contrôle n’était pas cross-plateform. Les outils utilisés pour produire une application cross-plateform posaient des problèmes de compatibilités qui n’ont pu être résolus dans les temps ce qui a obligé Fabien à se concentrer sur le développement d’une application uniquement Android à l’aide d’autres outils.
Suite à ce problème de compatibilité pour du cross-platform, après la fin de son stage Fabien proposa une solution qui sera reprise et testée par l’étudiant en informatique à l’IUT2, Lori Lou. Une deuxième version du kit a pu alors être développée comprenant une toute nouvelle application de contrôle cette fois ci cross-platform.
Conclusion
Bien que le kit du Shutter soit encore au stade de prototype, celui-ci est fonctionnel et est en test sur le terrain pour des spectacles/prestations. Cependant l’entreprise doit encore travailler sur le boîtier et le packaging ainsi que sur certains ajustements au niveau de l’application. Cette tâche pourra certainement être confiée à un futur étudiant !
Lorsque l’on développe un objet communicant arrive le moment ou l’on souhaite s’assurer de son fonctionnement dans le temps, cet article va vous présenter comment configurer en quelques heures un Raspberry Pi pour répondre à ce besoin.
Pour cela nous allons commencer par faire un capteur température/pression/humidité Wi-Fi sur base STM32, puis nous utiliserons le Raspberry Pi en point d’accès Wi-Fi avec les outils nécessaire pour surveiller l’évolution des valeurs sous forme de courbes.
Capteur Wi-Fi – STM32F401
Ce capteur est basé sur la carte RUSHUP Cloud-JAM qui est le condensé des carte NUCLEO-F401RE, X-NUCLEO-IDW01M1, X-NUCLEO-IKS01A2 et X-NUCLEO-NFC01A1. Nous allons modifier le code exemple pour n’utiliser que la partie W-Fi et capteurs de température/pression/humidité le tout connecté à un broker MQTT local.
Le capteur publiera toute les minutes sur un broker MQTT ses valeurs de température, humidité et pression.
Importer sous STM32CubeIDE, Compiler et charger sur la cible
A ce point si l’on se connecte à l’aide d’un terminal série sur le port série virtuel de la carte en 460800bauds on voit apparaître les informations de debug et le fait que la carte ne se connecte pas au Wi-Fi de notre Raspberry Pi, celui-ci n’étant pas configurer …
Monitoring – Raspberry Pi
Plusieurs éléments sont à installer sur le Raspberry Pi, pour cela nous allons suivre quelques guides :
Ajouter le module influxdb depuis le gestionnaire de palette
Arrivé à ce point, notre Tag doit être en mesure de ce connecter en Wi-Fi au Raspberry et publier toute les minutes ces information sur le topic « stm32 », il est facile de vérifier cela en regardant les log de la console série, puis en souscrivant au topic stm32 depuis MQTT.fx.
Il faut maintenant créer une base dans infuxdb dans laquelle nous allons enregistrer nos valeurs. Depuis un terminal sur le Raspberry Pi :
pi@raspberrypi:~ $ influx
Connected to http://localhost:8086 version 1.8.0
InfluxDB shell version: 1.8.0
> CREATE DATABASE stm32
> SHOW DATABASES
name: databases
name
----
_internal
stm32
Notre base de donnée est prête à recevoir des enregistrement, on utilise Node-RED pour récupérer les informations qui arrive sur le topic MQTT, les mettre en forme et les envoyé dans la base de donnée.
Description des différents module :
mqtt in
Fonction de transformation
influxdb batch
N’oublier pas de « déployer » le flow pour le rendre actif. Les modules de debug permette de vérifier la bonne transformation des messages.
La dernière étape connecté grafana à influxdb et afficher les informations.
La première chose va être de configurer une source de donnée :
Maintenant on va ajouter un dashboard et un premier panel pour la température :
Les deux champs à renseigner sont :
« Nucleo » dans la ligne FROM, il doit apparaitre dans une liste déroulante, si ce n’est pas le cas, c’est que la connexion à influxdb n’a pas eu lieu.
« temperature » dans la ligne SELECT, même remarque que précédemment.
On ajoute dans le même dashboard deux autre pannel pour la pression et l’humidité et l’on doit obtenir :
Conclusion
Avec très peu d’effort on obtient un outils capable de présenter les résultats de nos capteurs de façon agréable et facilement exploitable.
L’objectif de cette série d’article est de pouvoir utiliser une commande zigbee green power dans un réseau thread.
Pour cela nous allons réaliser les étapes suivantes :
Mise en place d’un environnement de développement openthread pour pouvoir générer des firmwares.
Mise en place d’un sniffer permettant de visualiser les communications.
Créations d’un réseau thread composé de deux nœuds, un leader et un router.
Ajout d’une implémentation minimaliste du protocole applicatif de la zigbee alliance pour réseau IP (ZCLIP, DotDot, CHIP … en fonction du temps et des communications) afin de réaliser une commande et un actionneur on/off avec nos deux produits.
Implémentation d’un combo zigbee green power minimaliste dans le firmware de l’actionneur on/off.
Idées complémentaire : réalisation d’un proxy minimaliste dans le firmware de la commande on/off, ajout d’un border router, extension de l’app de commissioning thread pour l’ajout de commande green power au réseau, recherche d’un algorithme de maintenance pour l’optimisation des proxy green power à activé en fonctions des niveau rssi reçu par les commandes.
Comme beaucoup (trop) de développeur, mon pc de travail fonctionne sous Windows 10 or openThread fait appel à des outils Linux pour compiler. Dans la suite je vais vous décrire mon installation qui me permet de modifier le code dans un IDE digne de ce nom, de compiler ce même code comme si j’étais sous Linux et enfin de le programmer dans la cible avec les outils natif à mon os fournit par les fabricants de composants.
Environnement de compilation
Le plus simple est d’utiliser docker, d’autant qu’une image existe déjà !
Installation de docker sous Windows 10
Pas de difficulté particulière si ce n’est qu’il faut une version professionnel de Windows 10. Le lien vers la page de téléchargement de Docker Desktop : https://www.docker.com/get-started
A la fin de l’installation on ouvre une Invite de commandes Windows (pas le powershell) et l’on peut vérifier que docker est en route en lui demandant ça version :
Nous allons ensuite chercher l’image docker qui nous intéresse :
docker pull openthread/environment:latest
Pour faciliter la modification ultérieur des fichier sources depuis un IDE sous Windows nous allons activer le partage de disque sous docker. Pour cela on va dans la partie « Setting/Ressources/File sharing » de docker desktop et l’on sélectionne le disque que l’on souhaite partager :
J’ai créé un répertoire spécifique de partage sur mon disque « c » de Windows à l’emplacement « C:_DEV\docker_share » et pour simplifier la suite il sera monté à l’emplacement « /mnt » de l’image Linux. Il est temps de lancer un container :
docker run -it -v c:/_DEV/docker_share:/mnt --rm openthread/environment bash
Dans ce shell Linux nous allons effectuer un enchainement de commandes :
Installation de la toolchain et autres dépendances :
./script/bootstrap
Setup de l’environnement :
./bootstrap
Nous voilà prêt à effectuer la compilation de notre premier firmware, pour ce préparer à l’étape suivante qui est la mise en place d’un sniffer, nous allons construire le firmware nécessaire pour la carte de développement de chez Nordic « nRF52840-DK » :
make -f examples/Makefile-nrf52840 USB=1
le binaire généré ce trouve dans le répertoire « /mnt/openthread/output/nrf52840/bin » mais a encore besoin d’une transformation pour le mettre au format hex :
Dans un terminal Windows mettre installer les dépendances utiles et pyspinel :
pip3 install pyserial ipaddresspyspinel
Ce placer dans un répertoire de travail et cloner le repo openthread/pyspinel :
git clone https://github.com/openthread/pyspinel
Lancer la session de sniffing …
On commence par connecter la carte nRF52840 précédemment flashée avec le firmware ot-rcp.hex par l’usb de debug au PC. A l’aide du gestionnaire de périphérique on note le numéro du port série virtuel associé, COM3 dans mon cas.
Le mini réseau thread sera créé sur le canal 15, on décide de placer le sniffer en écoute sur celui-ci par la commande suivante :
L’objectif est d’avoir un réseau composé d’un leader et d’un routeur, de pouvoir effectué un ping du routeur sur le leader et une communication de type coap. Pour cela nous allons générer un firmware de type Full Thread Device pilotable grâce à la CLIdepuis un terminal série. Le matériel utilisé sera deux cartes Silicon Labs EFR32MG12.
Générer le firmware
Pour pouvoir générer un firmware Silicon Labs il est nécessaire de charger et installer simplicity studio pour pouvoir récupérer la stack flex contenue dans le sdk 2.7.
Une fois simplicity studio installé et la stack Flex SDK v2.7 téléchargée, il faut la copier du répertoire ou elle se trouve (C:\SiliconLabs\SimplicityStudio\v4\developer\sdks\gecko_sdk_suite) dans le repertoire third party de la stack openthread (C:_DEV\docker_share\openthread\third_party\silabs\gecko_sdk_suite).
Depuis notre terminal docker :
make -f examples/Makefile-efr32mg12 COMMISSIONER=1 COAP=1 JOINER=1 DHCP6_CLIENT=1 DHCP6_SERVER=1 BOARD=BRD4161A
Depuis Windows on éxecute l’outils Silicon Labs pour charger les firmware dans la cible : commander (C:\SiliconLabs\SimplicityStudio\v4\developer\adapter_packs\commander) et l’on charge nos deux cartes avec notre firmware fraichement compilé.
Construire le réseau et configurer le sniffer
A l’aide du gestionnaire de périphérique on note les ports séries associés à nos cartes. Dans mon cas les port COM11 et COM12. On ouvre un terminal série par port avec la configuration suivante : 115200 8-N-1
Configuration de la première carte (COM11) pour devenir le leader du réseau.
Initialisation d’un dataset et affichage des valeurs :
dataset init new
Le canal radio choisi est le 20, or nous avons configurer notre sniffer pour écouter sur le canal 15, on change la valeur du canal dans notre dataset pour se positionner sur le canal 15.
dataset channel 15
Maintenant que le dataset nous conviens, on le rend actif, puis on démarre l’interface réseau et la stack thread. au bout d’un quelque secondes lorsque l’on demande son état elle nous informe qu’elle est le leader.
Configuration du sniffer
Plusieurs protocoles sont à configurer en utilisant les valeurs fournies par le dataset du leader.
6LoWPAN
CoAP
IEEE 802.15.4
Thread
Configuration de la deuxième carte (COM12) en tant que routeur
Contrairement à la première carte, on ne va renseigner que la « master key » dans le dataset avant d’activer l’interface et de démarrer la stack.
L’objectif n’est pas d’implémenter l’ensemble du protocole dotdot mais le strict minimum pour passer à l’étape suivante : le pilotage depuis une commande green power. Pour se faire seul la commande toggle du cluster on/off sera implémentée sur le premier endpoint de l’actionneur. Seront donc ignoré :
La découverte des produits et des ressources depuis le /.well-known et de fait la gestion de l’UID produit.
Tous les mécanismes de sécurité.
La gestion du multicast, seul un post unicast sera géré par le serveur.
Les bindings et autres tokens
On peut donc résumé que le client enverra un post coap depuis la cli, le serveur quand à implémentera ce post sur la ressource « /zcl/e/1/s6/c/2 » qui correspond a la commande toggle du cluster on/off sur l’enpoint 1 du produit. Commande qui n’a pas besoin de payload.
Le code !
Jusqu’à présent nous avons compilé le projet exemple qui donne accès à une ligne de commande. Pour réaliser notre objectif on définira le leader comme l’actionneur, on ne touchera pas au code du routeur. Pour simplifier l’on va modifier le projet example cli pour :
créé automatiquement le réseau en tant que leader
activé coap et lui ajouter la ressource zcl/e/1/s6/c/2
ajouter un handler sur cette ressource
imprimer sur la sortie RTT les informations permettant de s’assurer que toute les étapes ce sont bien passée
a chaque fois que le handler de la ressource coap est appelée changé d’état une variable représentant la charge et l’afficher.
Pour le dernier article de cette étude, nous allons voir comment recevoir une trame green power issue d’une commande Philips Tap (https://zigbeealliance.org/zigbee_products/philips-hue-tap/) puis la transformer pour la renvoyer sous forme d’un message DotDot.
Méthodologie:
L’actionneur sera le leader et conserve le code développé précédemment.
Le nœud enfant contiendra le proxy Green Power et sera également modifier pour rejoindre automatiquement le réseau créé par le leader.
Pour simplifier l’adresse ipv6 du leader sera codée en dur dans l’enfant pour l’envoie du message CoAP.
La sécurité Green Power est ignorée pour cette étude. La trame issue de la commande Philips Tap contien l’ordre en clair.
La trame Green Power
Sans chercher à décoder entièrement la trame Green Power pour notre étude, nous utiliserons les filtres suivants:
Au moins 24 octets de long.
Le frame control 802.15.4 doit valoir 0x0801.
Le frame control du header network doit être de type data et la version du protocole doit être 3 (green power).
Le frame counter de la trame reçue doit être supérieur au frame counter de la trame précédente.
L’ordre green power doit être 0x22 (Toggle)
Le code du nœud enfant
Rejoindre le réseau et activer le handler de réception 802.15.4 à placer dans la fonction main avant la boucle infinie.
Filtrer les messages 802.15.4 pour n’être réactif qu’à la trame Green Power qui nous intéresse.
void PromicuousHandleLinkPcapReceive(const otRadioFrame *aFrame, bool aIsTx, void *aContext)
{
OT_UNUSED_VARIABLE(aContext);
// receive frame only
if( !aIsTx )
{
otPlatLog(OT_LOG_LEVEL_NONE, OT_LOG_REGION_PLATFORM, "Rx %d bytes on channel %d, at time %d",
aFrame->mLength,aFrame->mChannel,aFrame->mInfo.mRxInfo.mTimestamp);
// get only frame starting 0x01 0x08 : frame type data without security and short addressing mode fot destination, minimal length shall be 24
if( (aFrame->mLength>=24) && (aFrame->mPsdu[0]==0x01) && (aFrame->mPsdu[1]==0x08) )
{
// green power use data frame with protocol 3, use it only
if( (aFrame->mPsdu[7]&0x0F)==0x0C )
{
static uint32_t ls_previous_frm_counter = 0;
otError lError;
otMessage * message = NULL;
otMessageInfo messageInfo;
otIp6Address coapDestinationIp;
uint32_t l_src_id = aFrame->mPsdu[9] + (aFrame->mPsdu[10]<<8) + (aFrame->mPsdu[11]<<16) + (aFrame->mPsdu[12]<<24);
uint32_t l_frm_counter = aFrame->mPsdu[13] + (aFrame->mPsdu[14]<<8) + (aFrame->mPsdu[15]<<16) + (aFrame->mPsdu[16]<<24);
uint8_t l_cmd_id = aFrame->mPsdu[17];
otPlatLog(OT_LOG_LEVEL_NONE, OT_LOG_REGION_PLATFORM, "GPF from %08X, frame counter %d, command %02X", l_src_id, l_frm_counter, l_cmd_id);
// send CoAP message to leader only if frame counter is higher than previous message and only toggle (0x22) GP order
if( (0x22 == l_cmd_id) && (l_frm_counter > ls_previous_frm_counter) )
{
ls_previous_frm_counter = l_frm_counter;
message = otCoapNewMessage(instance, NULL);
otCoapMessageInit(message, OT_COAP_TYPE_NON_CONFIRMABLE, OT_COAP_CODE_POST);
otCoapMessageGenerateToken(message, 2);
otCoapMessageAppendUriPathOptions(message, "zcl/e/1/s6/c/2");
otIp6AddressFromString("fd85:74ee:7560:9626:dd0e:3508:db6:44c9", &coapDestinationIp);
memset(&messageInfo, 0, sizeof(messageInfo));
messageInfo.mPeerAddr = coapDestinationIp;
messageInfo.mPeerPort = OT_DEFAULT_COAP_PORT;
otPlatLog(OT_LOG_LEVEL_NONE, OT_LOG_REGION_PLATFORM, "Send CoAP message : ");
lError = otCoapSendRequestWithParameters(instance, message, &messageInfo, NULL, NULL,NULL);
if( OT_ERROR_NONE == lError )
{
otPlatLog(OT_LOG_LEVEL_NONE, OT_LOG_REGION_PLATFORM, "SUCCESS\n");
}
else { otPlatLog(OT_LOG_LEVEL_NONE, OT_LOG_REGION_PLATFORM, "FAILED %s\n", otThreadErrorToString(lError)); }
}
}
}
}
}
Le résultat
Conclusion
Tout d’abord POURQUOI ? Pourquoi vouloir utilisé des devices Green Power dans un réseau thread ? Pour plusieurs raison :
Thread possède un type de device Low Energy MAIS il est encore trop consommateur par rapport à un device Green Power
Une commande Green Power peut devenir indépendante du type de réseau mesh 802.15.4 en place (Zigbee ou Thread).
Et la sécurité ? En effet Thread est un réseau sécurisé dans toutes les étape de sa vie. Pour cela il oblige l’utilisation d’un border routeur et d’un outils commissioneur, généralement un smartphone. Green Power contient bien des niveaux de sécurités dont un qui permet d’obtenir le même résultat que la sécurité mise en place dans Thread. Grâce à l’outil on peut venir entrer la clé de sécurité du device Green Power que l’on souhaite utiliser directement dans les proxy/actionneur concerné.
Pour résumer seul les devices Green Power Mono directionnel avec une sécurité de type install code et un frame counter incrémentiel présente un intérêt d’utilisation dans un réseau Thread. En effet ils permettent de combler le manque de spécification d’un device vraiment low power sans dégrader le niveau de sécurité du système.