[Tuto] Programmation non bloquante pour Arduino & Co

  • Nico! C’est quoi le programme du jour ?
  • Heu… T’es sûr de vouloir le savoir?
  • Bah oui, ça fait trop longtemps, j’en peux plus d’attendre!
  • Ok, alors si on parlait Arduino et temps réel? Je vais te montrer comment on programme des événements récurrents de façon non bloquante!

Une petite contextualisation me semble nécessaire. En ce moment je travaille sur une interface MIDI, pour synchroniser un microcontrôleur (Teensy) avec des instruments de musique. Pour la faire courte, la Teensy va donner un tempo en BPM, et les instruments MIDI vont se caler dessus.

La Teensy est géniale dans ce contexte, parce qu’elle peut se faire passer pour un périphérique MIDI standard et son API dispose de toute une batterie de fonctions pour envoyer des instructions MIDI à qui veut bien les écouter.

Mais pour l’instant, pas besoin de rentrer dans le protocole d’horloge midi, on va se contenter d’afficher du texte dans le moniteur série, et après si vous êtes sages, on fera clignoter des LEDs. Houlala, mais quel programme trépidant!

1. Approche naïve pour gérer un événement récurrent

Si vous êtes en train de lire ceci, il y a de forte chances pour que vous ayez testé votre première Arduino avec l’exemple blink.

Rien de choquant, on est tous passé par là :).

Affichons plutôt des messages, ce sera plus pratique pour la suite:

Si j’ai maintenant envie d’afficher « Paf » toutes les 500ms et « Pif » toutes les 3 secondes… Comment faire?
On pourrait utiliser un compteur, mettre un delay(500), à chaque tour afficher Paf, et tous les 6 tours afficher Pif.

Ça peut vite devenir très compliqué l’histoire. Et d’autant plus que pendant l’appel à delay(), il ne se passe rien, le programme est bloqué pendant 500ms.
C’est la méga-cagade si on doit faire d’autres traitements en parallèle (lecture d’entrées, affichage…).

2. Approche non bloquante

Pour remédier à cela, on doit avoir une approche non bloquante, basée sur l’heure actuelle (ou plus précisément sur le nombre de millisecondes (ou microsecondes) écoulées depuis le démarrage du programme).
On va utiliser les fonction millis() ou micros(), selon la précision désirée (respectivement à la milliseconde ou à la microseconde près).

L’exemple proposé dans l’IDE Arduino est BlinkWithoutDelay, et on peut l’adapter ainsi pour notre exemple:

Dans ce cas, à chaque tour de loop(), on va regarder si la durée nécessaire est passée, et si ce n’est pas le cas on laisse filer (et du coup on peut faire autre chose plutôt que d’attendre bêtement).

3. Approche plus encapsulée

On est déjà bien mieux que dans le tout premier exemple, mais il y a des variables globales qui se baladent, des grosses conditions dans les if(), ce n’est pas encore très élégant.

Pour mon projet, j’ai encapsulé ce fonctionnement dans une classe C++ histoire de faciliter l’utilisation:

Pour reprendre notre exemple précédent, on aurait donc:

C’est plus léger. Plus de variables globales pour stocker des états dont on se fout royalement dans le programme principal.
Vous noterez que l’heure (ici en microsecondes) est lue une seule fois, puis passée en paramètre aux méthodes de test. Ça permet d’éviter des décalages de temps causés par l’exécution du code qui peut être « longue » (~100µs pour un analogRead() par exemple). En faisant comme ça, on travaille sur la même référence de temps pour toutes les opérations.

4. Application : Faire clignoter une LED de façon contrôlée et non bloquante

Je dis LED, mais le concept s’applique évidemment au contrôle de moteurs pas à pas, à l’envoi de signaux d’horloge MIDI, et que sais-je encore.

Voici l’interface de la classe :

Si je veux faire clignoter une LED à 3Hz, pendant 5 impulsions, il me suffit d’écrire:

Si je veux faire 3 clignotements à 5 Hz chaque seconde, il me suffit d’écrire le programme suivant:

Les deux projets sont dispo sur GitHub et dans les bibliothèques Arduino avec des exemples!

https://github.com/toxnico/DMTimer

https://github.com/toxnico/DMOscillator

Être ou ne pas être… Python

Voilà bien longtemps que je me dis qu’il faudrait me mettre à Python.
Selon les adeptes de ce langage, une fois qu’on y a touché, c’est comme le crack. Ou disons comme le fondant au chocolat.

Mais il n’y a pas moyen, je n’arrive pas à m’y coller… Et à chaque fois que j’essaie de me lancer pour un nouveau projet, je tombe toujours sur le même problème: Python 2 ou python 3?

Beaucoup de librairies ne sont disponibles qu’en Python 2, alors que Python 3 existe officiellement depuis… 2008. Oui, 9 ans. Et à chaque fois, les librairies qui me seraient utiles pour le projet du moment n’ont pas été portées sur Python 3, alors finalement je pars sur du bon vieux C#.

Allez, je réessaye, on verra bien… Cette fois, j’ai trouvé Pillow, le portage de PIL en Python 3, qui devrait faire l’affaire. En avant Guingamp!

[PS] Je viens d’apprendre que le serpent qui se mord la queue est un symbole qui s’appelle Ouroboros
L’image provient du site http://www.animogen.com. Il a l’air malin maintenant…

Interfaces de programmation pour ESP8266

La première question qu’on se pose quand on reçoit un ESP8266, c’est…

« Ah merde, mais comment je vais programmer ce machin? »

Il y a besoin de 4 fils : +, -, Rx et Tx, donc la première chose, c’est de se procurer un convertisseur USB-série. Le point crucial, c’est la tension de sortie de ce convertisseur. Elle doit être de 3.3v à la fois sur le Vcc ET sur le Tx. Le risque avec du 5V, c’est tout bêtement de griller l’ESP.

L'interface USB-série
L’interface USB-série. On peut voir en bas le sélecteur 5V-3.3V, et en haut le bouton reset.

L’ESP8266 01 a des broches au pas de 2.54mm, mais n’est pas utilisable dans une breadboard à cause de la position des broches. Donc soit on y va avec des fils et des connecteurs Dupont, soit un se fait un petit circuit imprimé pour connecter tout ça à l’adaptateur USB-série. Au début, j’utilisais la première méthode, mais j’ai finalement opté pour un petit circuit imprimé…

Vert jaune rouge... Rastaman!
Vert jaune rouge… Rastaman!

A gauche, il y a un emplacement pour un cavalier. Il sert à faire démarrer l’ESP8266 en mode programmation.

Oui, je n'avais que des connecteurs femelles à 8 contacts...
Oui, je n’avais que des connecteurs femelles à 8 contacts… C’est joli le scotch…
Et l'ensemble connecté sur le PC, prêt à être programmé!
Et l’ensemble connecté sur le PC, prêt à être programmé!

Le truc avec l’ESP8266, c’est qu’il se décline en je ne sais combien de versions différentes. J’ai aussi un 12e sous la main, et pour lui, l’emplacement des broches est un peu plus particulier, dans le sens où elles sont espacées de 2mm, et non de 2.54mm. Du coup j’ai dû commander des headers au pas de 2mm afin de faire un programmateur et adaptateur.

Il est juste glissé entre les headers pour faire le contact. Pas de soudures, c'est cool!
Il est juste glissé entre les headers pour faire le contact. Pas de soudures, c’est cool!

Après coup, je me dis que j’aurais pu placer les headers pour faire en sorte que l’ESP8266 soit carrément enfiché sur les headers. Mais là, ça va pile poil.

Il faut un cavalier en permanence entre la GPIO15 et la masse pour qu’il démarre (ça il faut le savoir…), et un autre en bas pour mettre la GPIO0 à la masse (ça c’est pour le mode programmation).

Côté connection au PC, c’est le même principe.

Un peu plus gros mais ça va bien :)
Un peu plus gros mais ça va bien 🙂

 

Mozaic framework : un environnement de développement pour PHP

C’est un sujet sensible… Si je souhaite développer un site, public ou privé, en PHP, comment m’y prendre ?

Alors pour des choses standards, des blogs par exemple, il existe moultes plateformes : WordPress, Drupal, Dotclear, Joomla (soyons fous).

Pour ma part, pour mon autre blog flexqueries.org, j’ai commencé avec Dotclear. C’était avant la version 2, et les fonctionnalités et extensions étaient assez limitées.

Puis est arrivé Joomla. Pratique, modulaire, mais… Lourd, vraiment lourd. Des temps de réponse vraiment pas top, et une architecture certes polyvalente, mais vraiment hardcore.

Il tourne actuellement sous Drupal, qui est un environnement assez riche, que j’ai trouvé un peu difficile à aborder au départ. Mais la documentation et les contributions sont nombreuses, et j’ai fini par assimiler les principes.

J’ai même osé écrire mon propre plugin, un truc qui affiche le contenu d’un répertoire du serveur dans une page…

Enfin, j’utilise WordPress pour le blog Dirty Marmotte, qui semble finalement être le plus accessible pour les utilisateurs normaux (non informaticiens).

Comme je disais, tous ces environnements sont personnalisables, mais chacun a ses propres conventions, ses techniques de développement, et en ce qui me concerne, ça m’emmerde de devoir tout réapprendre pour chaque environnement, et de passer des heures avant d’arriver à faire un truc très simple, car obligé de passer par l’API. C’est frustrant.

 

J’ai donc préféré mettre à profit mon expérience de développeur Web pour créer mon propre environnement de développement, sans fioritures. Je l’ai déjà utilisé pour le projet Mozaic, et je l’ai soigneusement enrichi et généralisé.

Pour la structure, je dirais qu’il est MVC-friendly. J’entends par là MVC, mais si on veut faire quelque chose de simple, on n’est pas obligé de se taper le cheminement complet. C’est bête, mais ça peut faire gagner beaucoup de temps.

Pour l’accès à la base de données, j’utilise adodb, dont la qualité n’est plus à prouver.

Pour les templates, j’ai eu une expérience avec Smarty, mais il est assez lourd et surtout, surtout : il ne supporte pas l’héritage. Et ça, ça craint. J’ai donc opté pour Dwoo, et franchement je ne suis pas déçu. L’héritage est vraiment super, et il conserve une compatibilité avec Smarty, donc on n’est pas perdu 🙂

Pour les curieux, c’est ici : http://dirtymarmotte.net/wiki

Exploiter la barre des tâches de Windows 7

Vous l’avez sûrement remarqué, depuis Windows 7, les boutons d’application de la barre des tâches ont quelque peu évolué. Mais comment exploiter ces nouvelles capacités, comme par exemple l’affichage d’une progressbar dans la barre des tâches?

Il faut utiliser l’API de Windows… Mais comme chacun sait, l’appel de fonctions non managées depuis .NET est plus que chiant.

En faisant une petite recherche, j’ai trouvé une bibliothèque fournie par Microsoft, utilisable directement sous .NET : WindowsAPICodePack.

Du coup, pour définir une progressbar à 20% dans l’icône de l’application, il suffit d’un: TaskbarManager.Instance.SetProgressValue(20, 100);

Classe, non ? Il n’y a plus qu’à intégrer ça dans la boucle de votre traitement et c’est tout bon.