Capteurs de fenêtre sans fil maison: STM32L051 + RFM69 + Android

Bonjour, cher Khabrovites! Il y a quelques années, j'ai acheté une publicité zWave colorée et installé des capteurs de fenêtre basés sur ce protocole. Un zWave-Stick USB a été connecté au serveur domestique, qui a joué le rôle d'un contrôleur, un petit module Java a été écrit qui a reçu des données de ce contrôleur, et une petite application pour Android a été écrite qui affiche magnifiquement l'état de tous les capteurs. Les piles sont insérées, les capteurs sont enregistrés sur le contrôleur, tout a fonctionné. Mais après quelques mois, il y a eu une terrible déception. Tout d'abord, ces capteurs zWave fonctionnent sur le principe "envoyer un message et s'endormir sans attendre de confirmation". Dans mon cas, cela a conduit au fait que le signal des capteurs les plus éloignés du contrôleur n'a tout simplement pas atteint le contrôleur. Même l'installation d'un répéteur zWave supplémentaire n'a pas aidé. Deuxièmement, ils ont déchargé la batterie si rapidement qu'après environ six mois, tous les capteurs ont cessé de fonctionner. La raison en est qu'ils se réveillaient toutes les heures pour informer le contrôleur de leur état. Désactiver ou modifier cette option ne fonctionnait pas, car le logiciel standard ne le permettait catégoriquement pas. Après deux ans de tourments avec cette technologie brute, peu fiable et hostile, j'ai décidé que j'en avais assez. Mais au lieu de tout ranger et de le jeter, j'ai eu l'idée de laisser les étuis, mais de changer l'électronique dedans. Le choix s'est porté sur un émetteur-récepteur RFM69 assez simple (433 MHz), sur la base duquel il était possible de réaliser à la fois une carte pour le capteur et un contrôleur connecté via USB au serveur. Le nouveau système est déjà opérationnel depuis 5 mois, la fiabilité est proche de 100% (mais il y a quand même eu quelques pannes), les batteries ne semblent pas encore vides. Autrement dit, il est déjà visible que toutes les lacunes de l'ancien système basé sur zWave ont été éliminées, et je veux partager les détails techniques de cet article, voir la photo.



Peu importe, s'il vous plaît, sous le chat.

Il me semble que zWave dans mon cas s'est avéré inopérant pour deux raisons: la maison a deux étages avec des planchers en béton armé et une grande surface (c'est-à-dire une suppression importante de certains capteurs du contrôleur). Eh bien, des failles dans le logiciel propriétaire, qui ne permettaient pas de désactiver le réveil périodique des capteurs, ce qui entraînait une décharge rapide de la batterie. Quand il est devenu clair que je n'étais pas sur le chemin avec zWave, j'ai commencé à chercher d'autres options qui pourraient être insérées dans les mêmes boîtiers de capteur.

Mon premier prototype de capteurs était basé sur l'ESP8266. Le contrôleur - sur la base de mon paiement dont j'ai déjà écrit sur Habré . Le système a même fonctionné comme prototype, mais j'ai dû l'abandonner pour deux raisons. La première raison est la même - dans la maison, il y avait des coins avec un très faible niveau de signal WiFi, ce qui a conduit à un temps d'activation très long de l'ESP8266 au réveil et, par conséquent, à une forte décharge de la batterie. Bien que j'avoue que je ne sais tout simplement pas comment cuisiner ce très ESP8266 (des articles comme celui-ci confirment cette thèse). Mais la deuxième raison était plus sérieuse. Depuis que j'ai décidé de laisser non seulement le boîtier, mais aussi le compartiment de la batterie, je me suis limité à une batterie CR123A, qui est de 3,0 volts. Autrement dit, le prix et la complexité du capteur ont augmenté en raison de l'augmentation du convertisseur CC / CC. Bien qu'il y ait un merveilleux article sur ce sujet sur Habré. Mais, de toute façon, ces deux raisons l'emportent et j'ai rejeté ESP8266.

Le deuxième prototype a été câblé. J'ai fait un prototype du capteur et du contrôleur USB, j'ai ajouté un module serveur pour qu'il comprenne ce contrôleur en plus du zWave-Stick. Il y avait une idée de tirer progressivement les fils et le capteur après capteur pour changer la carte zWave en filaire. Mais à la fin, il n'a pas choisi de murs et ce prototype a également été jeté.

Puis il a décidé de regarder vers les modules radio à 433 et 868 MHz et a commandé plusieurs modules pour les expériences: RFM69HCW , A110LR09A et MRF89XAM8A . En termes de taille de module, de prix, et également en raison de la disponibilité des deux bibliothèques et de bons exemples, j'ai opté pour RFM69HCW, qui constituait la base du système.

Le système ne comprend que quatre composants:

  • capteurs sans fil (433 MHz, pile CR123A 3.0V),
  • contrôleur réseau (433 MHz, alimenté via USB à partir du serveur)
  • le serveur (dont j'ai déjà parlé sur Habré dans cet article ) et le module programme serveur
  • client mobile (application Android)

Ci-dessous, je décrirai chaque module en détail, et à la fin je donnerai des statistiques sur le fonctionnement du système au cours des derniers mois de fonctionnement.

Capteurs


Les capteurs utilisent le module radio RFM69HCW . Il a une large plage de tension de fonctionnement (1,8 V-2,4 V 17 dBm, 2,4 V-3,6 V 20 dBm) et est contrôlé via SPI. Autrement dit, vous avez besoin d'un microcontrôleur. Il y a quelque temps, j'ai fait connaissance avec la série STM32L et commandé le STM32L051 pour des expériences. Il m'a soudoyé comme un petit courant en mode veille (0,27 μA), et la tension de fonctionnement, presque identique à la tension du module radio (1,65V-3,6V). Plus petit prix.

Il s'est avéré le schéma suivant:

image

La tension d'alimentation du microcontrôleur et du module radio est telle qu'ils peuvent être directement alimentés à partir de l'élément CR123A. Le STM32L051 a une référence de tension interne connectée au canal ADC 17, ainsi que la valeur d'étalonnage de cette source, qui vous permet de mesurer la valeur actuelle de la tension d'alimentation VDD. Le module radio est connecté à l'alimentation via l'appareil de terrain Q1, ce qui vous permet de contrôler son alimentation à partir du microcontrôleur.

Le mode veille est implémenté en transférant le microcontrôleur en "veille". Dans ce mode, le STM32L051 a un cœur désactivé, presque tous les périphériques et un régulateur de tension interne, ce qui garantit une consommation au niveau de 0,29 μA (avec l'horloge en temps réel désactivée). Mais dans ce mode, il y a une caractéristique - le microcontrôleur ne se réveille que le long du front montant du signal sur la broche WKUP (A0). Puisqu'un interrupteur magnétique est utilisé, qui est activé / désactivé (fermé ou ouvert), vous avez besoin d'un petit bloc qui génère une impulsion de courte durée à la fois lors de la fermeture et lors de l'ouverture d'un contact magnétique. Cette impulsion est envoyée à l'entrée A0 du microcontrôleur et la réveille. Un tel convertisseur est implémenté sur la puce OU exclusive IC3 de la série 74AUP économe en énergie (74AUP1G86), qui fonctionne dans la plage de tension de 0,8 V à 3,6 V et consomme 0,2 μA. Ainsi, la consommation totale en mode veille devrait être d'environ 0,5 μA, ce qui est confirmé par des mesures sur un capteur entièrement assemblé.

Lorsque le microcontrôleur se réveille, il mesure d'abord la tension d'alimentation et, si elle est inférieure à 1,8 volts, ce n'est pas le destin - l'émetteur ne peut pas être démarré et le microcontrôleur se rendort.

Si la tension de la batterie est supérieure à 1,8 volts, le microcontrôleur s'allume et initialise le module radio, transfère l'état au contrôleur de réseau et attend la confirmation. Le paquet de données comprend un numéro de paquet (événement) 32 bits unique, la tension de la batterie, la température, l'état du contact magnétique, l'octet de contrôle (CRC7). En cas de confirmation réussie, le microcontrôleur s'endort. Sinon, envoie à nouveau le statut, mais au maximum 10 fois. J'ai défini cette limite pour que le capteur n'essaie pas d'attendre indéfiniment une réponse dans une situation où le contrôleur réseau est simplement éteint. Le dernier numéro d'événement unique transmis est stocké dans l'EEPROM interne du microcontrôleur.

Pendant le transfert de données, le microcontrôleur clignote une LED (où sans elle). La LED est allumée à l'aide de PWM, où le rapport cyclique dépend de la valeur de tension actuelle, ce qui vous permet d'avoir presque la même luminosité dans presque toute la plage de tension de fonctionnement.

Les cartes sont conçues en EagleCAD, la conception des cartes est disponible ici . Les cartes sont à double face: le microcontrôleur et son faisceau sont situés sur le côté supérieur face au cadre de la fenêtre, et le module radio et la LED sont sur le côté inférieur face à la pièce. J'ai commandé en Chine, je me suis soudé dans un four de cuisine conventionnel (couche supérieure) et un sèche-cheveux (couche inférieure).

image

Le module radio a besoin d'une antenne. Ce n'est qu'un morceau de fil de 164 mm de long.

Après l'installation, chaque capteur doit être programmé, pour lequel un connecteur SWD est fourni. J'ai laissé les contacts restants au tableau pour d'éventuelles expériences à l'avenir.
Le firmware est écrit en C ++, une partie du code est exécuté dans des classes de base assez universelles qui encapsulent les appels à la bibliothèque ST HAL. Le code source est ici . Pour le développement, System Workbench pour STM32 a été utilisé. La taille du fichier de firmware binaire final est de 22 Ko.

Et voici le capteur dans le boîtier:

image

Selon la position du capteur, pour certains capteurs, j'ai laissé l'antenne à l'extérieur (sur le fond du cadre blanc, cependant, elle n'est pas visible), et pour certains capteurs, j'ai plié le fil dans le cadre et l'ai complètement fourré à l'intérieur du boîtier.

Par souci d'intérêt, j'ai calculé le coût des composants pour un capteur (aux prix du catalogue Mouser, prix et prix total en euros)
ObjetLa descriptionValeurNuméro MOUSERQtéCoût
IC3OU exclusif1G86771-74AUP1G86GW-G10,254
IC1MicrocontrôleurSTM32L051511-STM32L051K6T612.14
SV1ConnecteurSwd68602-406HLF10,157
LED1LED 3 mm3 mm630-HLMP-K15510,351
Q1P-mosfetBSH205771-BSH205G2R10,276
S1Contact magnétiqueORD211-0810876-ORD211-081010,625
IC2Module radio RFM69HCWRFM69HCW474-COM-1391015.36
C1, C2, C3, C6Condensateur SMD0,1 uF80-C0805C104J5RAC40,1
C5Condensateur SMD0.4nFC0805C471K8HACTU10,021
C4Condensateur SMD (tantale)47uF581-TAJR225K016RNJ10,334
R1Résistance SMD10K660-RK73H2ATTDD1002F10,01
R10Résistance SMD330660-RK73H2ATTDD3300F10,01
R3, R4, R6, R7, R8, R11Résistance SMD47K660-RK73H2ATTDD4702F60,06
R5Résistance SMD56660-RK73H2ATTD56R0F10,013
R9Résistance SMD56M603-RC0805JR-0756ML10,037
9.748

Soit dit en passant, il s'est avéré exactement trois fois moins cher que le capteur zWave d'origine. Bien que ce ne soit que le coût des pièces hors boîtier. Mais, à mon avis, dans le commerce, les capteurs zWave sont indécemment chers.

Contrôleur réseau


Pour le contrôleur, le même module radio et le même microcontrôleur ont été utilisés que pour les capteurs. Cela a permis de réutiliser la plupart du code du firmware. Pour le contrôleur, j'ai choisi ce facteur de forme de la carte afin d'utiliser le boîtier prêt à l'emploi de Raspberry Pi. Par rapport au capteur, un connecteur d'antenne externe et une boucle USB basée sur l'isolateur FT232RL et SI-8621 ont été ajoutés. Bien sûr, à la place, on pourrait prendre du STM32 avec USB à bord. Mais ensuite, d'une part, il faudrait séparer le code du firmware et, d'autre part, faire l'implémentation logicielle de l'USB lui-même. L'option avec un FT232RL externe, bien que plus chère, est plus fiable et plus rapide à mettre en œuvre. Le résultat est le schéma suivant :

image

Et sous forme assemblée, il s'est avéré comme ceci:

image

image

Le microcontrôleur ne s'endort pas ici, le module radio fonctionne pour la réception, mais après avoir réussi à recevoir un paquet de l'un des capteurs, le module passe en mode de transmission et envoie un accusé de réception. De plus, tout paquet reçu avec succès est transmis via USB au serveur. Le format du package est une chaîne de valeurs séparées par le symbole «;»:
GW; 3; 12; -57; 0; 146; 30; 18
où:

  • la première position est l'étiquette du paquet (toujours «GW»)
  • deuxième position - type de données (état du capteur ou code d'erreur)
  • troisième position - numéro du capteur
  • quatrième position - la qualité du signal sur le côté du contrôleur de réseau (le RFM69HCW préserve la qualité du signal pendant la réception et vous permet de l'interroger lorsque la réception est terminée)
  • cinquième position - état de la fenêtre (0 ouvert, 1 fermé)
  • sixième position - un numéro unique du paquet (événement) du capteur. Ce numéro vous permet de contrôler côté serveur si tous les événements ont été reçus par le serveur ou si un ou plusieurs événements ont été perdus.
  • septième position - tension actuelle de la batterie (30 correspond à 3,0 V)
  • la dernière, la huitième position est la température du capteur interne du microcontrôleur. Je n'ai pas encore compris comment l'utiliser

Le code source du firmware est au même endroit que pour le capteur . Ils ont un fichier principal commun et une bibliothèque commune de classes de base. L'option de micrologiciel (capteur ou contrôleur) est sélectionnée à l'aide de la directive define du fichier main.cpp.

Le coût du contrôleur de réseau est plus élevé en raison du circuit USB, de l'antenne et des connecteurs supplémentaires. Mais cet additif peut être négligé, car il n'y a qu'un seul contrôleur. Mais même avec ce supplément, il s'est également avéré être trois fois moins cher que le zWave-Stick, qui était auparavant à sa place.

Module serveur


Le contrôleur réseau est connecté à un serveur exécutant CentOS 7. Le serveur exécute un programme écrit en Java. Et dans sa structure, et dans la mise en œuvre, et dans les tâches, le programme est assez simple:

  • En utilisant une bibliothèque RxTx très ancienne et apparemment plus prise en charge , le port USB spécifié dans la configuration est surveillé (dans mon cas / dev / ttyUSB0). À l'heure actuelle, il s'agit de la partie la moins optimisée de l'ensemble du système, car la bibliothèque charge fortement le processeur du serveur.
  • Si des données sont reçues du port USB, elles sont enregistrées dans un fichier journal et stockées dans la classe d'état du capteur. Lorsque vous redémarrez le serveur, l'état est perdu. Pour le restaurer, vous devez faire le tour de la maison et ouvrir et fermer manuellement toutes les fenêtres. C'est probablement le plus gros inconvénient de mon système, mais j'ai tout à fait consciemment refusé d'interroger périodiquement les capteurs pour économiser leurs batteries.
  • L'application est également un petit serveur TCP / IP et écoute sur le port TCP / IP spécifié dans la configuration. Sur ce port, il peut accepter les connexions d'un client mobile.
  • Si le client mobile se connecte au serveur, il envoie l'état actuel de tous les capteurs. À l'aide de messages de fréquence cardiaque périodiques, le serveur surveille également l'activité de la connexion.
  • Le serveur et le client mobile échangent des messages au format XML. Ces messages sont implémentés sous la forme d'une petite bibliothèque Java , partagée à la fois côté serveur et côté application mobile Android.
  • Bien que cela n'ait pas beaucoup de sens, dans l'intérêt, j'ai ajouté la fonction d'autoriser un client mobile via IMEI, ainsi que le cryptage AES des messages entre le serveur et le client à l'aide d'une clé cousue dans le code source (package Java javax.crypto). Mais c'est purement pour l'expérience, car le port TCP / IP de ce module serveur n'est accessible que depuis le réseau interne et n'est pas visible de l'extérieur. Bien que, si je veux ouvrir ce port au grand monde, maintenant ce ne sera pas si effrayant de le faire.

Peu importe, le code source du module serveur est ici .

Client mobile (application Android)


Vous n'écrirez pas grand-chose ici, bien que cette application soit le résultat final de l'ensemble du projet. Il s'agit d'une application Java standard et très simple avec trois onglets: l'état des fenêtres du premier étage, l'état du deuxième étage et une petite télémétrie du serveur (voir le code source ici ):

image

Les graphiques sont basés sur un ensemble de fichiers SVG, qui sont empilés les uns sur les autres en fonction de l'état des capteurs. Un appui long est pris en charge dans la zone de chaque fenêtre, selon lequel un indice est affiché avec l'heure à quelle heure cette fenêtre a été ouverte:

image

En principe, rien ne vous empêche d'ajouter une icône de batterie à cette info-bulle, mais vos mains ne l'ont pas encore atteinte.

Expérience d'exploitation


"Chaque éternuement" est enregistré dans un fichier journal côté serveur. L'analyse de ces fichiers au cours des 5 derniers mois nous permet de comprendre un peu plus en détail ce que ressent ce système.

L'analyse est très simple - il suffit de grep dans le dossier des fichiers journaux sur le serveur.

Combien d'erreurs y a-t-il eu lors de la transmission des données sur le canal radio? Sur 5 mois, 8 erreurs ont été enregistrées lorsque le message a été reçu dans la mauvaise taille et 25 erreurs dans le mauvais CRC. Dans les deux cas, vous ne pouvez pas dire directement quel capteur a rencontré des problèmes, car le paquet de données dans ce cas est complètement endommagé. Étant donné que le contrôleur de réseau ne confirme pas la réception des données dans tous ces cas, le capteur doit envoyer les données d'une nouvelle manière, ce qui dans la plupart des cas corrige ces erreurs.

Et voici un tableau récapitulatif du fonctionnement des capteurs pendant 5 mois.
ÉtageCapteurLa quantité
Des événements
Des perdus
Des événements
La tension
Les piles
Médiane
Puissance
Signal
11010503.1-66
1115203.3-70
11212203.3-61
1138903.3-74
114257303.3-68
11526103.3-60
11654323.3-70
11715623.3-74
11817723.2-68
11938433.3-56
2336823.3-62
248603.3-71
2552123.3-59
2611503.3-62
2731623.3-63
2841913.3-60
298903.3-68

Le capteur n ° 10 se fige une fois. Cela a apparemment conduit à une diminution significative de la tension de la batterie. La raison du gel n'est pas encore claire. Il se bloque à nouveau, vous devez le comprendre.

Le capteur n ° 14 est installé sur la porte avant, c'est pourquoi il a un si grand nombre de réponses. Mais un si grand nombre de déplacements n'a pas encore affecté la tension de la batterie.

Un événement perdu est lorsque le capteur a tenté d'envoyer un état, mais le serveur ne l'a pas confirmé. Tous les événements perdus sont dus au fait que j'ai éteint le serveur pendant environ une demi-journée pour le nettoyage.

La colonne Médiane de la force du signal médian affiche la valeur RSSI médiane (en dBm), où chaque valeur individuelle est obtenue après la réception de chaque paquet. Le capteur avec le meilleur signal (n ° 19, -56 dBm) est situé à 2 mètres du contrôleur de réseau, mais l'antenne de ce capteur est recroquevillée à l'intérieur du boîtier. Le contrôleur de réseau lui-même est situé au rez-de-chaussée. Cependant, le signal des capteurs du deuxième étage est très bon. Cela est dû au fait que sur tous les capteurs du deuxième étage, l'antenne est retirée du boîtier du capteur.

Au lieu d'une postface


D'une part, je suis heureux que, comme passe-temps, par moi-même, il se soit passé de zéro pour concevoir, assembler et faire fonctionner un système de ce niveau. Et encore plus heureux qu'il fonctionne mieux que le système "propriétaire" basé sur la technologie de battage médiatique zWave. Il est également possible de développer et d'améliorer ce système. Je ne suis rongé que par de petits doutes. À savoir, qu'une personne sans éducation électrique spécialisée collecte sur son genou quelque chose qui fonctionne de manière plus fiable que les produits de marque connus dans les cercles étroits des marques IOT. Probablement, les progrès ont tourné quelque part dans la mauvaise direction.

Source: https://habr.com/ru/post/fr482858/


All Articles