Une des particularités des modules de communication série Yoctopuce comme le Yocto-I2C, le Yocto-RS232 et le Yocto-RS485-V2 est qu'ils peuvent exécuter de manière autonome des petits jobs de communication, par exemple pour interroger des capteurs. Nous avons récemment ajouté la possibilité de synchroniser ces échanges automatiques sur des contraintes temporelles précises.
Jusqu'à présent, les échanges automatisés gérés par les jobs pouvaient être déclenchés
- par l'arrivée d'un message externe (job réactif, commande expect)
- par l'expiration d'un délai (job périodique, commande wait)
Nous avons récemment rencontré deux circonstances pour lesquelles il était souhaitable de déclencher une communication non pas en fonction d'un délai ou d'une périodicité relative, mais sur une base temporelle absolue, par rapport à l'heure réelle.
Lecture de compteurs cumulatifs
Le premier cas de figure concerne la lecture d'un capteur qui mesure une accumulation dans le temps, comme un compteur d'énergie ou un compteur de précipitations. Si l'on veut pouvoir transformer la valeur accumulée en une quantité par heure ou par jour, il faut pouvoir s'assurer que l'interrogation du capteur ait lieu à des heures déterminées.
Nous avons donc rajouté deux fonctions qui permettent d'inclure des contraintes de temporalité absolue dans les expressions reconnues par le langage de job: utctime() et utcdate(). La fonction utctime() retourne le nombre de secondes écoulées depuis minuit UTC, tandis que la fonction utcdate() retourne le nombre de jours écoulés depuis le 1er janvier 1970. Utilisées dans une commande assert, ces fonctions permettent de s'assurer qu'une tâche ne s'exécute que lorsqu'une condition temporelle précise est remplie. Par exemple, la tâche suivante - qui envoie l'heure sous forme textuelle sur le port série - ne s'exécutera qu'à chaque heure ronde:
assert utctime() mod 3600 == 0 compute h = utctime() div 3600 writeVar "Il est ($h:INT)h" writeLine ""
On peut donc utiliser cette technique pour lire périodiquement le compteur à accumulation avant de le remettre à zéro, ou sinon pour lire la nouvelle valeur, calculer la différence avec la valeur précédente et stocker la nouvelle valeur. Dans ce dernier cas, il faut toutefois prévoir un mécanisme qui remet néanmoins périodiquement le compteur à zéro pour éviter les problèmes de débordement.
Synchronisation avec l'envoi de mesures
Le deuxième cas de figure nécessitant une synchronisation avec une horloge en temps réel est la transmission de données à intervalles fixes. Si vous avez par exemple configuré un YoctoHub-Ethernet ou votre VirtualHub pour transmettre des données à un serveur Web via un callback HTTP chaque quart d'heure, vous pourriez vouloir lire des mesures récentes juste avant que le callback HTTP se fasse. La méthode de synchronisation utilisée précédemment conviendra donc aussi à ce cas de figure, avec une expression du type:
assert utctime() mod 900 == 890
Une problématique similaire peut se poser lorsqu'on lit des valeurs plusieurs fois par seconde pour les transmettre par le mécanisme des callback périodiques - par exemple via MQTT. Dans ce cas, il peut être souhaitable que la lecture de mesures soit synchronisée avec l'envoi des notifications périodiques, afin de s'assurer que chaque valeur lue soit transmise. Pour cela, il existe une nouvelle commande sync, similaire à la commande wait, mais qui permet d'attendre jusqu'au passage du prochain multiple de la période spécifiée en millisecondes avant de passer à la commande suivante. Par exemple, si le genericSensor1 est configuré pour envoyer 10 valeurs par seconde, le script suivant assurera que chaque valeur lue ait bien l'occasion d'être transmise par une notification périodique.
sync 100 writeLine "?" expect "($1:FLOAT)" sync 100 writeLine "?" expect "($1:FLOAT)" sync 100
Disponibilité
Ces nouvelles fonctions sont disponibles dès aujourd'hui pour tous les modules de communication série. Il vous suffit de mettre à jour le firmware de votre module pour en profiter.