Category Archives: Non classé

[Raspberry Pi] Un afficheur pour mon thermostat

by Matthieu

Résumé du projet :

  • Récupérer certaines infos sur Internet
  • Récupérer des infos locales
  • Créer une image avec ses infos
  • Afficher l’image

Vous vous souvenez du thermostat pour mon radiateur électrique ? Bien. Ce Raspberry Pi avait donc 2 rôles : faire des acquisitions de températures pour les envoyer à un serveur qui log ces données pour la postérité et, en fonction d’un fichier de consigne, piloter un radiateur pour choisir quelle commande de chauffage il doit utiliser, en fonction de la température ambiante et de l’heure (chauffer pendant la journée en semaine, c’est pas cool avec Dame Nature).
Bref, c’est un Raspberry Pi qui se tourne un peu les pouces. Et c’est là qu’intervient le recyclage d’un écran Adafruit (2.8′, tactile, avec des boutons en dessous, non utilisé dans mon cas … pour le moment) qui dormait dans une boite parce que je n’avais pas pu l’utiliser sur mon robot comme prévu.

Un boitier adapté (Adafruit également) et un peu de code plus tard, voilà tout plein d’info pertinente afficher sur l’écran !

On y voit donc :

  • La date
  • L’heure
  • La température interne
  • L’état de la commande de chauffage
  • La température extérieure, le taux d’humidité relative, la vitesse du vent, et la date d’acquisition de ses trois infos.

Cette dernière ligne est en fait issue d’un site qui recense plein de donnée météo, le National Oceanic and Atmospheric Administration. Il existe sous Debian l’outil weather-util permettant de récupérer ces infos en utilisant le nom de la station météo, son code d’immatriculation, ou bien des coordonnées dans votre petit terminal. Vous trouverez des détails sur son utilisation ici. Cela dit, je me suis rendu compte qu’en tapant http://weather.noaa.gov/pub/data/observations/metar/decoded/XXXX.TXT dans votre navigateur internet on peut récupérer les mêmes infos, il suffit de remplacer XXXX par le code de la station, trouvable via le site weather.nooa.gov. Avec un simple wget on récupère un TXT, il ne reste plus qu’à le traiter.

Concernant le traitement des données, j’ai fait un bout de code en C qui récupère le .TXT, le décode pour récupérer les données (température/humidité/vent/horodatage), récupère les infos de la sonde locale (réutilisation du code du thermostat), et on passe tous ces paramètres dans la commande « convert » venant du package debian « imagemagick » qui va afficher tout plein de texte sur un fond noir (Détails ici).

Pour utiliser l’écran, il faut avoir installé les petits package prévu par Adafruit (le tuto ici) et lancer la commande permettant d’envoyer l’image. Avec un cron toutes les minutes, ça permet d’afficher un résumé météo rapide.

Et voilà le travail ! Il faudrait encore modifié la plaquette d’essai histoire de rendre ça encore plus joli. Voir même afficher sur l’image de fond un graph de la température, changer l’afficher avec les boutons, ou que sais-je encore !


[Raspberry Pi] Thermostat pour radiateur Pass Program

by Matthieu

J’ai laissé un peu de côté mon p’tit robot RPi-kee pour m’atteler à un autre projet, un peu plus terre à terre, et nettement plus utile pour l’humanité. Sous cette introduction un peu pompeuse, se cache sauvegarde de la planète, économie d’énergie et tout le bullshit marketing qui va avec.

Depuis maintenant plus d’un an, j’ai l’honneur d’avoir dans mon salon un Raspberry Pi avec une sonde DS18xxx et un système logiciel pour récupérer cette température et la coller dans une base de données. Si vous me demandez quelle était la température le 4 juin 2014 à 11h dans mon appartement, je suis capable de vous répondre ! C’est beau la technologie. Mais pas très utile.

Avec l’hiver qui vient (TM de la famille Stark), nous avons remis en route un radiateur sur les 5 disponibles chez nous. J’ai beau avec un appartement neuf (refait en 2008), il a été construit avec des jolis convecteurs peuvent être un gouffre financier. Nous avons donc pris l’habitude de le mettre en route le matin au réveil, de le couper en partant, de le relancer le soir en rentrant et finalement de l’éteindre au coucher.

Et si on automatisait tout ça ?

J’ai donc commencé par regarder de plus près mes radiateurs. Il s’agit de modèle F18 de chez Atlantic (mais si, la pub radio avec Charlotte de Turkeim…), qui ne sont pas vraiment haut de gamme, bien au contraire. Néanmoins, ils ont l’avantage d’être « programmable ». Ils disposent de base de 2 thermostats (un « jour » et un « nuit ») ainsi qu’un mode hors gel, et off. On peut donc avec un curseur passé de jour à nuit, à off et à hors gel. Mais alors, programmable, ça veut dire quoi ?
Ça veut dire qu’ils sont connectés à mon réseau électrique par 3 fils : Phase (fil marron, 220V alternatif), Neutre (fil bleu), et le p’tit dernier, le Pilote (fil noir). J’ai donc enquêté un peu, et j’ai regardé comment était câblé tout ça en démontant le cache dans le mur où vont (les putes, TM Tywin Lannister) les fils du radiateur. Comme je le disais plus haut, mon appartement est à peu près neuf, et donc l’électricité est bien faite. Je suis descendu voir mon tableau électrique, et que vois-je : 5 fils noirs qui ne sont connectés à rien, et un fil marron. J’ai pris l’initiative de penser que tout ça est un pré câblage pour un boitier de contrôle.

En regardant la documentation du radiateur, j’ai appris que le fil pilote permet de mettre le radiateur dans des modes de fonctionnement particuliers en fonction du signal envoyé sur le fil pilote. Les différents signaux sont les suivants :

  • Rien : mode jour
  • 220V double alternance : mode nuit
  • 220V alternance positive : mode arrêt délestage
  • 220V alternance négative : mode hors gel
  • 220V double alternance un peu déphasée: mode jour -1°C
  • 220V double alternance un peu plus déphasée: mode jour -2°C

Au final, chaque mode est une transformation du signal 220V plus ou moins compliqué. Quand on regarde la doc toujours, on voit qu’il est possible d’installer (ou de faire installer) un boitier dans le tableau électrique pour réaliser ses opérations. Après, il existe plusieurs options genre thermostat sans fil à placer dans le salon, programmateur plus ou moins complexe, et tout ça, pour faire des sous ! Pour vous donner une idée, le programmateur simple pour UN radiateur coûte entre 50 et 100 euros, et je ne vous parle même pas du thermostat central, et j’évite le sujet du prix de l’intervention de l’installateur agréé.

Le truc quand même bien fait, c’est que le pilotage entre le mode jour et le mode nuit est super simple : soit on déconnecte le fil pilote, soit on y colle 220V.

Voilà, l’objectif est défini, faire un interrupteur commandé par une électronique, le Raspberry Pi en l’occurrence. Et coup de bol, celui qui trône dans mon salon est à 2m du radiateur (caché derrière un meuble, parce que le côté esthétique est important aussi).

Hardware requis :

Le mot clé, c’est « relai ». Un relai en électronique, c’est un interrupteur commandé. On met une tension à la borne du relai, il se ferme. On met 0V, il s’ouvre. De l’autre côté du relai, on branche le 220V et le fil pilote, et zou, terminé.
Evidemment, en pratique, il faut rajouter quelques fioritures pour avoir quelques choses d’utilisable. Et par chance (ou bien alors parce que c’est un besoin pas si exceptionnel) j’ai trouvé sur le site mchobby.be un joli pack « Relai 220V« , avec la doc de montage adéquat.

Ce kit est composé d’un relai pilotable en 5V, d’une diode de roue libre (l’entrée d’un relai est une bobine dans lequel le courant est stocké, la diode de roue libre permet au relai de se vider proprement quand vous le déconnecter), d’un couple transistor/résistance pour piloter le relai (en gros, ça fait la conversion entre une GPIO 3,3V du RPi ou du 5V d’un Arduino pour avoir suffisamment de patate pour attaquer le relai), et pour la rigolade d’une LED pour voir quand le relai est fermé (d’ailleurs elle est monté à l’envers sur le schéma de mchobby, pensez à la retourner si vous l’utilisez). Comme support le site conseil une carte permaproto, ce qui est un très bon conseil. Avoir un support solide quand on joue avec le secteur, c’est plutôt sécurisant.
Coût total : moins de 20€ (hors Raspberry Pi que j’avais déjà).

J’ai rajouté un câble pour relier le triplet 5V/Gnd/GPIO au RPi, un câble pour relier le 220V et le fil pilote (pour le coup, je me suis branché directement au domino reliant le radiateur au réseau câblé dans le mur), et voilà pour le hardware.

Côté Soft :

J’utilise la même librairie de pilotage de GPIO que pour RPi-kee, qui dispose pour le test d’un petit utilitaire pour switcher les GPIO à partir du shell de Debian, très pratique pour les premiers tests, permettant de vérifier le concept.
Ensuite, j’ai préparé un petit tableau Excel avec quelques infos pertinentes, comme une température de consigne, et également des plages horaires pendant lesquelles le radiateur doit être en mode jour. Une fois le tableau sauvegardé au format CSV, reste à faire une bout de code en C pour lire le fichier, trouvé la température de consigne, et déterminer si le radiateur doit être en mode jour ou en mode nuit. Condition supplémentaire, si la température de la pièce est supérieure à la consigne, alors on passe forcément en mode nuit.
La seule opération qui reste à faire sur le radiateur est donc de configurer correctement les deux roulettes de puissance. Celle du mode nuit le plus bas possible, est celle du mode jour assez haute pour chauffer la pièce normalement.
Le plus « difficile » pour ce programme, c’est surtout le décodage du fichier texte contenant les données de la sonde de température, et le décodage du fichier de consigne. Oui, piloter une GPIO avec WiringPi, c’est juste tout con.

Le soft final est lancé avec une tâche planifiée (crontab) tous les quarts d’heure, et roulez jeunesse. Ensuite on peut faire un peu tout et n’importe quoi pour rendre le truc plus facile d’accès, comme une interface web pour la configuration du fichier de consigne ou la lecture en live de la sonde de température, histoire que d’autres personnes du foyer puisse modifier le chauffage sans avoir à modifier le CSV via SSH.

Au final j’ai donc un radiateur qui s’allume le matin avant que je me lève, et qui se coupe tout seul quand il fait bon. Mission accomplie, et si je veux utiliser mes autres radiateurs, je n’ai plus qu’à relier les fils pilotes dans mon tableau électrique.

Note de bas de page : quand on touche au 220V, on met le circuit hors tension avec le disjoncteur AVANT ! Si vous mourrez en faisant de la merde dans votre tableau électrique, spa dma faute !


[R-Pi] RPi-kee – Partie 3 : Informatique

by Matthieu

Et on continue avec la suite de ceci.

Informatique

La partie logicielle est à mes yeux la plus large des trois. En effet, il y a mille et une manière de faire tout et n’importe quoi, et dans l’ensemble on peut faire et défaire tout comme on le souhaite. Entre les OS, les langages, les librairies, les algorithmes, les compétences et les préférences du développeur… Il y a autant de réponse à une question donnée qu’il y a de question !

Le système d’exploitation

Déjà, quel OS pour le Raspberry ? La question est vite réglé, malgré les diverses versions de GNU/Linux disponible : le choix est Raspbian, la version de Debian spécialement adapté au Pi. C’est la version la plus utilisée, et donc celle sur laquelle on a le plus de support. Ensuite, l’avantage de l’OS, c’est le fait de pouvoir lancer des process, rentre certaines taches automatiques simplement, la partie communication avec l’extérieur est simple (par exemple sauvegarder un fichier de log en local puis le synchroniser sur un répertoire partagé sur le réseau, c’est bête comme chou).

Langage de Programmation

Le Pi est, principalement, dédié à être utilisé avec des scripts en python. On trouve à ce titre des dizaines de trucs fait en python pour tout et n’importe quoi : piloter des GPIO, la caméra, faire des sauvegardes ou bien faire une interface console pour l’utilisateur. Mais parce qu’on a un OS Linux, on a aussi moyen d’utiliser n’importe quel langage. Et quand je parlais des préférences du développeur, c’est là que ça joue. Moi, le python… c’est pas trop ma tasse de thé, alors que le C, ça me branche vachement plus. Et je me débrouille mieux avec. Dans la mesure du possible donc, je tente de faire un maximum de chose en C, et d’utiliser d’autres options (script python tout prêt, Shell scripts, …) uniquement quand je n’ai pas le choix. Garder une certaine homogénéité me parait important pour pouvoir maintenir plus facilement l’ensemble du projet.

Accéder aux fonctions « spéciales » du Raspberry Pi

Sans rien autour de lui, le RPi est un ordinateur sous Linux, ni plus ni moins. Mais il dispose d’interface avec le monde extérieur qui nécessite un peu de boulot pour être exploités. La question se pose donc, dois-je développer moi-même mes propres fonctions pour y accéder ou existe-t-il des bibliothèques toutes faites pour me faciliter la vie ? Et ces bibliothèques valent-elles vraiment le coup ?

– GPIO

=> La fondation Raspberry a eu une bonne et une mauvaise idée. La bonne c’est de rapidement mettre à disposition des utilisateurs une librairie pour facilement utiliser toutes les fonctions des GPIO, que ça soit l’utilisation en mode brut (entrée/sortie numérique), ou bien l’utilisation des bus de communication disponible (I2C et SPI). La mauvaise, c’est que c’est en python. C’est là qu’intervient WiringPi, une librairie pour la gestion de GPIO en C. Pile poil ce que je voulais. Son auteur a le bon goût d’avoir rendu sa lib compatible avec le RPi B+ très rapidement.
J’ai procédé rapidement à quelques tests unitaires, pas de problème pour piloter les moteurs (utilisation des GPIOs), ni pour faire récupérer des données sur l’ADC (utilisation du bus SPI).

– Camera

=> Ici les choses se compliquent un peu. Je n’ai pas trouvé de librairies pour piloter la caméra directement. Ma principale expérience pour le moment est la réalisation d’un système de détection de mouvement, avec la caméra montée sur un moteur. Pour faire une simple capture, il faut taper une commande dans la console sous linux, dans laquelle on indique la résolution de sortie, le format, si on pivote l’image, si on applique un filtre, l’ISO, etc. C’est facile, mais la caméra met alors plus seconde pour faire une capture (indépendamment de la vitesse d’obturation). Pas terrible pour faire du suivi rapide d’objet en déplacement. L’astuce est alors lancé la capture en mode daemon (en lui précisant la taille, le format, etc.) et de lui envoyer par la suite un signal pour faire une capture. A ce moment, le cliché est instantané. Bref, c’est presque parfait, sauf que c’est en ligne de commande, et donc ça sent le Shell script. Première entorse à ma sacro-sainte homogénéité.
Capturer une image c’est bien, en faire quelque chose c’est mieux. Quand on parle traitement d’image sous Linux, il y a une bibliothèque qui vient rapidement à l’esprit, c’est OpenCV (Open Computer Vision). Elle dispose d’une myriade d’outils de traitement tout prêt pour faire tout et n’importe quoi avec vos images. Mais pour être honnête, c’est un mastodonte. Quand j’ai commencé mon détecteur de mouvement, j’ai eu envie de faire le traitement moi-même, histoire d’en apprendre un peu plus sur le traitement d’images. Au départ je voulais simplement comparer des images, mais de fils en aiguilles j’ai aussi implémenté la possibilité d’appliquer des filtres matriciels sur les images, calculer et afficher des histogrammes, ainsi que d’autre fonction simple comme de n’afficher que la luminance, ou bien une seul couleur en particulier. Bref, quand j’ai commencé à m’aventurer par-là, j’ai transformé mon soft de détection de mouvement en un sous-produit d’une librairie que j’ai appelé LLIPS (pour Light Library for Image ProcesS). Ça vaudrait un article à elle toute seule, mais je n’ai pas vraiment fini de la faire jolie avec les commentaires et la documentation qui va bien.
Pourquoi s’emmerder à faire une librairie qui existe déjà ? Simplement parce que je n’ai pas besoin de tout, et aussi parce que pour le coup, je peux adapter l’outil très rapidement. Pendant que je travaille sur le code RPi-kee, il m’arrive régulièrement de fignoler Llips, et de commiter à part les modifications.

– Généralité

=> Quand j’ai réalisé les premiers softs sur avec la caméra et le moteur, le cœur principal de mon programme était en Shell script (abordé un peu ici : ). Ce qui est bien avec les scripts c’est de pouvoir lancer des trucs en tache de fond. C’est très pratique car je peux lancer un mouvement moteur et faire autre chose pendant que ça tourne. De même, avec les traitements d’images, que ça soit des redimensionnements (que je faisais avec mogrify, vachement bien), des comparaisons, etc. Par contre j’ai un peu galéré pour la communication entre les différentes tâches. Ne serait-ce que pour lancer un chronomètre, je suis passé par un compteur écrit dans un fichier texte, qu’un programme écrit et qu’un autre relit. Bref, pas terrible.
Pour RPi-kee, j’ai rapidement compris que cette solution ne serait pas terrible, voir carrément à chier. De plus, si je m’amusais à coder un process pour faire des acquisitions, un autre pour les traiter, un autre pour faire du TCP et les transmettre, le coup des fichiers textes pour communiquer serait vraiment pourri. Il me restait donc deux solutions :
– La mémoire partagé entre les process, comme je l’avais fait il y a biiiieeeeeen longtemps à l’IUT
– Plusieurs tâches au sein d’un même process.
La deuxième solution m’attirait beaucoup plus, surtout que j’ai l’habitude d’utiliser un OS temps réel au boulot, et que je suis donc assez familier du sujet. J’ai donc déniché dans un coin la bibliothèque pthread !
Elle est disponible sous Linux nativement, et dispose également d’un port sous Windows, avec quelques restrictions mais qui n’impacte pas les fonctions de base. Ce port me permet donc de bosser également sous Windows. Pthread permet de définir fonction sous forme de thread tourne donc joyeusement en parallèle (dans la mesure du parallélisme tel qu’il existe dans un processeur de PC). Ce n’est pas une émulation ou une astuce du genre, quand on lance plusieurs threads on voit bien dans un gestionnaire de tâches le nombre de threads qu’on a lancé. Cela convient donc très bien à mes fonctions de pilotage moteur qui sont en fait une séquence ordonnée sur 4 GPIOs avec un délai entre chaque pas. Appeler la fonction « avancer » bloque donc ainsi l’exécution du programme. Avec un thread dédié par moteur, je peux donc lancer mes boucles en parallèle et faire autre chose en même temps. La possibilité de faire des threads change d’ailleurs grandement la façon d’implémenter une fonction. Si on prend l’exemple des acquisitions sur l’ADC; avec un seul thread, vous devez d’abord faire votre acquisition, qui vous prendra un temps T1, puis mettre en forme les données reçues, avec par exemple l’utiliser de look-up-table pour transformer la tension des capteurs IR en cm, traitement long d’une durée T2. Votre fonction prendra donc un temps T1+T2. Si vous travaillez maintenant avec des threads, vous synchronisez le début de la tâche « Calcul » avec la fin de votre première tâche « Acquisition ». Ainsi, lorsque la première acquisition sera finie, vous commencerez immédiatement la deuxième acquisition pendant que vous traiterez la première. Si T1 est plus grand que T2, votre fonction d’acquisition ne prendra plus qu’un temps T1. Si c’est T2 qui est plus grand, c’est le contraire (à quelques cas particuliers près qui se gèrent sans trop de difficulté).
S’il y en a deux qui suive au fond, ils n’auront pas manqué de noter que j’ai dit que je travaillais également sur l’OS de Microsoft. Et oui, c’est bien le cas.
Si j’ai réalisé plusieurs tests unitaires directement en développant sur le Raspberry Pi, à grand coup de putty et de WinSCP, quand j’ai commencé à créer le projet, j’ai préféré travailler avec un IDE. De plus, comme je développe ça sur mes heures perdues (dans le train, dans le salon sur mon portable, sur mon PC fixe, parfois même au boulot entre midi et deux), j’ai mis en place une compilation conditionnée à l’OS utilisé. Je fais donc la partie driver/bas niveau sur le Pi en SSH, et tout le haut niveau sur PC Windows. Evidemment je ne récupère pas toutes les valeurs analogiques et je ne peux pas utiliser WiringPi, mais cela me permet de faire les threads, le traitement d’image, la communication TCP et le contrôle commande de façon indépendante. Pour avoir les schémas électriques, les images de test et la doc technique, Google Drive est mon ami, et pour le code j’utilise un dépôt SVN … sous Github. Je leur dois au passage une reconnaissance éternelle d’avoir mis en place l’accès SVN à leurs dépôts ! En effet, je n’aime pas Git.

A l’heure actuelle, je n’ai pas encore terminé. La partie logicielle va être assez tordu à faire, avec toutes les tâches que j’ai prévu de faire, mais ça devrait m’occuper un bon moment. Il me reste également quelques soucis mécaniques à résoudre, et puis valider que les moteurs 12V peuvent faire leur boulot correctement. Au final, je suis quand même assez près de mon but, et j’espère pouvoir finir par avoir quelques choses de vraiment chouette. Dans les tâches annexes qu’il me reste à côté, j’aimerai également pouvoir utiliser un écran qui se plug directement sur le Raspberry Pi, histoire par exemple d’afficher en temps réel des infos sur le robot. Le problème étant surtout que l’écran utilise la même liaison SPI que l’ADC et qu’il y a de bonne chance qu’ils s’entre perturbent. Dans les à côté également, j’aimerai finir proprement Llips, histoire par exemple de le rendre multithread. Cela me permettrait surement de gagner encore un peu de temps de process, le cœur ARM11 du RPi n’étant un modèle de rapidité. Si j’avais VRAIMENT que ça à faire, il serait même probablement possible d’utiliser le GPU pour faire le boulot. Mais, du temps, c’est pas forcement ce dont je dispose le plus !

Et histoire d’illustrer un peu l’article parce que les images c’est cool, voilà le genre de traitement. On part d’une image avec une ligne (c’est un tapis ikea du meilleur goût), on cherche les zones de contraste, et on définit un certain nombre de point et de segment appartenant à cette zone de contrate.

On se servira ensuite des angles et positions pour définir la trajectoire du robot. Simple, non ?


[RaspberryPi] Log de température, communication IP et Camera Board

by Matthieu

Hop la, le retour du blog ! Dans les épisodes précédents, j’avais expliqué comment mettre en place un serveur de téléchargement. Depuis j’ai un peu changer/améliorer l’installation, d’abord d’un point de vue hardware :

  • Changement du système de fichier du disque « NAS » (ça a l’air de rien, mais ça a ses petites conséquences) sur le Raspberry Pi (que l’on appellera RpiWeb, qui contient les fonctions évoquer dans l’article précédent, à savoir serveur Web, NAS, Seedbox)
  • Installation d’un deuxième Raspberry Pi (que l’on appellera RpiAcq) contenant notamment deux sondes de températures DS18B20 et une Camera Board)
  • Suite à mon récent déménagement j’ai également changé de box Internet, et l’air de rien ça a des conséquences également.
  • Également sur RpiAcq, j’ai installé tout récemment un moteur pas-à-pas (stepper motor outre-manche)

Travaux sur la box

Bon, l’air de rien, ça fait pas mal de choses nouvelles à gérer. Déjà, la box internet. Avant, je routais sagement le port 80 du Rpi sur le port 80 de la Freebox. Mais ça, c’était avant. Maintenant j’ai une BBox (pas Sensation, mais alors pas du tout) que c’est un peu de la merde, pour 2 choses un peu essentiel. Déjà, quand je route le 80 du Pi vers le 80 de la box, ça m’affiche … le port 80 de la box. Ok, je me retrouve donc avec l’interface de config de la box accessible par le monde entier, super safe, et pas vachement pratique pour auto-héberger son p’tit site. Mais bon, j’ai changé le port externe et j’arrive à accéder à mon site sur un autre port, mais ça fait con, et en plus y a que le port 80 qui passe au boulot. Autre incommodité, impossible de se connecter « de l’intérieur » sur le site via l’adresse externe. Problème que je n’avais pas avec la Freebox. Contournement, un favori « RpiWeb interne » et un « RpiWeb externe ». Typiquement le genre de tracasserie qui en soit n’est pas grave mais qui put l’amateurisme. Mais bon, c’est le prix d’un Youtube réactif….

Travaux sur RpiWeb

Bref, concernant le RpiWeb, j’ai également changé le disque du NAS, par un modèle plus gros de récup et formater en ext au lieu de NTFS. L’installation a grandement gagné en stabilité, et si j’avais parfois le disque NTFS qui se déconnectait/démontait tout seul, plus aucun soucis maintenant… à part qu’il a faut maintenant que je gère précisément les droits d’accès, ce qui est parfois un peu pénible, gérer mon utilisateur moi-même, mon guest pour le partage réseau, et le serveur Web qui écrit des choses à droite à gauche.

J’avais également des déconnexions réseaux/wifi, et j’ai donc dégagé le dongle USB par un boitier CPL, le Netgear XAVT5602, qui a le bon gout d’être vendu par 3, et de disposer de 2 port Ethernet sur chaque boitier. Ceci me permet de simplifier la config Internet du Rpi, et de faire un p’tit hub Ethernet local.
J’ai rajouté pas mal de script shell pour automatiser pas mal de tâche propre à ce serveur, genre :

  • Faire un backup régulier du répertoire home et web
  • Scanner tout le sous réseau local pour afficher ensuite les machines présentes, et loguer les heures de présence
  • En fonction du script précédent, détecter certaines machines particulières (mon téléphone est-il connecté ? Le RpiAcq ?)
  • Vérifier l’adresse externe de la box et uploader sur un site une redirection vers cette adresse (pour ne pas avoir à me souvenir de l’IP externe de la box quand je me connecte à partir d’une machine qui n’est pas à moi). J’avais expliqué dans mon article précédent pourquoi je faisais ça et pourquoi je ne voulais pas passer par noip ou dyndns

Dernier point, depuis le passage en ext, mon script perl permettant de faire du téléchargement direct fonctionne de façon erratique. Je l’ai donc remplacé par une page en PHP de mon cru. Soit, je perds certaines fonctionnalités genre le téléchargement de plusieurs fichiers en parallèle, mais pour ce que je m’en sers ça colle très bien à mon usage.

Capteur de température sur RpiAcq

Bon, on va être honnête, c’est clairement ce qui m’a le plus amusé. Ayant déménagé d’une maison avec une chaudière à gaz avec thermostat à un appartement chauffé au grille-pain électrique, je me suis dit que faire le thermostat moi-même pourrait être chouette. Direction learn.adafruit.com, le site de la bidouille par excellence, bien documenté, avec des liens vers les différents composants dans leur boutique pour que ton côté geek compulsif puisse s’exprimer dans une réalisation électronique facile mais au combien gratifiante. Le site n’est pas le moins cher, mais il est bien foutu, et on trouve tout, tout de suite. J’ai donc acheté une plaquette d’essai, des câbles, un déport de connexion pour le port d’extension du Rpi, et une sonde DS18B20.

Pour info, cette sonde n’est pas un « bête » capteur de température, mais une sonde « intelligente » qui intègre un contrôleur OneWire, un protocole utilisé en domotique pour récupérer facilement les informations des capteurs/actionneurs d’une installation. Ce protocole n’est pas géré en tant que tel sur le Rpi, mais le noyau Linux permet de faire du bit banging imitant le codage/décodage du OneWire. Bon, en gros, une fois le câblage fini, c’est super fastoche à utiliser. Vous chargez 2 modules dans le noyau de l’OS (ça fait style je m’y connais, de dire ça, mais si vous préférez, c’est 2 commandes à recopier dans un terminal), vous faites un cat d’un certain fichier et zou c’est plié, la température du capteur s’affiche en millidegré.

Soyons honnête de suite, d’un point de vue hardware je me suis arrêté là. J’ai acheté 2 capteurs pisse que j’habite un 2 pièces, mais pour le moment ils sont montés l’un à côté de l’autre. Je voulais aussi pouvoir piloter mes radiateurs, mais ils sont alimentés directement par un câble qui sort du mur, donc comme je n’ai pas envie de tenter de détériorer l’installation, je me suis arrêté là… niveau hardware. Parce que pour le soft, c’est autre chose !
Oui, je me suis dit que j’avais un site web sur un Rpi, un relevé de température sur l’autre, il ne me manquait pas grand-chose pour lier les deux. D’un point de vue générale je me suis fixé la contrainte suivante : ne rien stocker sur RpiAcq. J’ai donc développé un bout de soft pour :

  • Faire une requête de température
  • Aller chercher les températures (les deux sondes ainsi que la température du CPU du RpiAcq
  • Stocker la température

Je suis parti sur un modèle UDP avec socket non bloquante afin d’éviter qu’une mesure de température qui part en couille ne bloque le système. Au départ je stockais le résultat dans un fichier texte toutes les heures, mais après quelques centaines de relevés, je me suis orienté vers une base de données sqlite3 pour pouvoir traiter plus facilement l’affichage des données sur le site web. Au final ça marche bien, et c’est cool, même si un peu inutile (enfin si, j’ai pu me rendre compte qu’en coupant complètement le chauffage par grand froid en mon absence, mon appart descendait sous les 12°C).
A faire : J’ai les deux sondes dans mon salon, faudrait que j’en place une dans la chambre histoire que ça serve un peu plus. En théorie en tirant un seul câble c’est jouable, le OneWire étant fait pour. Et aussi tenter de piloter les radiateurs, je ne sais pas trop comment.

CameraPi sur RpiAcq

Quel achat compulsif cette caméra ! C’est fourni comme le Raspberry, un pauvre PCB, et puis c’est tout. J’ai donc acheté en plus de la camera un petit support en plastique permettant en outre de placer la caméra sur un pied photo. L’avantage de la CameraPi, c’est qu’étant la webcam officielle de la fondation Raspberry Pi, son utilisation est super facile et documentée clairement. Le plus « dur » c’est de la brancher, et c’est pas bien compliqué. Moi mon challenge, c’est comme pour les sondes de températures, c’est de récupérer l’image sur RpiWeb !
Qu’à cela ne tienne, je me suis attelé au développement d’un outil pour transférer l’image de RpiAcq vers RpiWeb. Alors vous me direz… mais pourquoi faire un outil quand il existe déjà des trucs pour faire le taf (Samba, FTP, NFS, voir même ssh ou http). Et bien parce que je voulais un truc TRES simple d’utilisation. Et pour la beauté du dev, aussi. Hop, c’est reparti pour un client/server, mais en TCP cette fois. Principe identique à la température, avec en plus de la gestion de fichier :

  • Faire une requête de transfert de fichier
  • Faire une requête de capture d’image
  • Répondre en envoyant la taille de l’image
  • Transférer l’image p’tit bout par p’tit bout (rappel : un trame TCP c’est 1,5ko max…)
  • Reconstruire le fichier côté RpiWeb

Votre vif esprit aura remarqué que je fais d’abord une requête de transfert de fichier, puis d’image. Le client/serveur que j’ai développé permet en plus de prendre une photo de transférer n’importe quel fichier, histoire que je puisse le réutiliser pour récupérer d’autres trucs. Ça peut être utile…
Une fois l’image récupérée, elle est archivé sur le NAS. Via les crontab, la capture se fait tous les quarts d’heures. Et là vous me direz, mais… il finira par passer à poil devant la caméra ! Et bien non, car si mon téléphone est présent sur le réseau, l’archivage est automatiquement désactivé. J’ai donc une liste d’adresse MAC qui, si elles sont détectées sur le réseau, désactive la prise automatique de photos. Niveau utilité, j’ai donc pu constater que les ouvriers qui devaient venir pendant mon absence n’ont pas trop fait de la merde, et je peux prendre des photos du chat qui glande sur le canapé.

Moteur pas-à-pas sur RpiAcq

Dernier raffinement, rendre la camera orientable. Retour sur Adafruit.com pour trouver de quoi faire. J’ai trouvé des exemples de moteur CC, de servo moteur, et donc de pas-à-pas. J’ai choisi ce dernier pour une raison simple, son utilisation reste dans l’enveloppe énergétique du Rpi. En gros, l’alimentation 5v suffit. Comme d’habitude, le tutoriel sur Adafruit est simple comme tout. J’ai acheté le moteur et une plaquette de test plus grand pour pouvoir bosser proprement et garder mes sondes de températures. Au passage j’ai pris un boitier de protection.

Mon seul regret ici, c’est que je n’ai pas réussi à piloter le moteur avec un soft en C. Ah oui, j’oubliais de le dire, dans les contraintes que je me fixe, j’essaie de ne pas m’éparpiller niveau langage de développement. J’évite donc soigneusement le python parce que je n’aime pas ça, et pour le moment, je fais du C, du shell script, du html/PHP et un poil de SQL. Mais ici j’étais si près de finir que j’ai eu la flemme de chercher pourquoi mon soft en C ne fonctionnait pas. Les fonctions de base pour piloter le moteur sont donc en python.

Pour pouvoir piloter le moteur via RpiWeb, j’ai mis à jour le client TCP du transfert d’image pour qu’il soit possible de demander soit un fichier à transférer, soit la prise de photo, soit un mouvement à gauche/droite.
Dernier raffinement, un petit montage avec des Meccano pour fixer la caméra sur l’arbre. Pour que ça soit tip top moumoute faudra rajouter un axe de rotation verticale avec un deuxième moteur, un pointeur laser, une coque blanche ovoïdale et un haut-parleur qui balancerait des « Where are you ? », « Are you still there ? » et autre « I don’t hate you » de façon aléatoire.

Et pour le fun, une petite vidéo :
Image de prévisualisation YouTube

Si un sujet vous intéresse, n’hésitez pas à poser des questions, je suis ouvert !


Raspberry Pi

by Matthieu


Aujourd’hui, on va parler un peu de ce petit « ordinateur ». En effet, malgré sa taille et son encombrement plus que réduit, il faut bien reconnaitre qu’on y branche la même chose que sur une UC classique (clavier/souris/écran/alim/ »disque dur »), et que ça permet de taper du texte, aller sur l’Internet, envoyer un mail, bref, des trucs qu’on sait déjà tous faire avec un PC classique, une console de jeu ou un smartphone.

Alors qu’est ce que ça fait d’intéressant ? Et bien en général, on y voit 3 applications majeurs :

  • Officiellement, les concepteurs du RPi le voit comme un support pédagogique low cost pour l’apprentissage du développement. La version de l’OS proposé de base, Debian,  embarque de quoi développer dans pas mal de langage différent (python, C, perl, …), avec des approches graphiques (scratch).
  • Pour les autres, une machine embarquant Linux et bouffant 2/3W qui fait un jolie petit serveur domestique (NAS, LAMP)
  • Et pour les radins, ça peut même faire un média center. En effet, si le processeur principal est clairement un peu out-of-date, il embarque un GPU qui à l’air de prendre en charge du 1080p

Et pour moi ? Et bien je me cherche encore. Ça sera de mauvaise foi de dire que j’ai pas eu le temps, car j’ai commandé la carte chez Farnell le 3 mars, et je l’ai reçu il y a 2 semaines. Ça fait un peu de délai oui. En tout j’en ai eu pour 39 euros, frais de port compris. J’ai bidouillé un peu, fait un NAS vite fait, pourri une fois l’OS, tellement que je l’ai déjà réinstallé, et au final je crois que je vais plutôt faire du dev avec, et ce qui me plairait c’est de faire clignoter des Leds. Ouais, faire clignoter c’est tellement chouette. Bon, en gros, interfacer un peu d’électronique avec pour pouvoir construire Optimus Prime.

Alors si toi aussi tu te sens l’âme d’un bidouilleur de l’extrême et que tu veux tenter de faire des choses avec ton Pi Framboise voilà deux trois liens.

Le site de base, pour avoir des news trop bien genre « Tu peux acheter le boitier en Lego ! » : www.raspeberrypi.org

Le wiki « officiel », dans l’ensemble une bonne mine d’information : elinux.org/R-Pi_Hub

Le jour où vous recevez enfin votre Raspberry Pi, que vous avez installez elinux.org/RPi_Beginners. Vous y trouverez les 2 ou 3 trucs de base à savoir pour avoir une jolie Debian avec un compte à votre nom, configurer votre clavier, la langue du système, enfin bref, tout ce qui ce fait lors d’une installation sur un PC classique.

A partir du wiki j’ai extrais des liens vers des lib que je testerais WiringPi et les drivers de Mike McCauley. Ce sont des librairies en C permettant de jouer avec la partie GPIO. Les broches accessibles permettent également de faire d’autre type de communication, plus ou moins supportées également par ces drivers. Au pire ils ont l’air suffisamment bien documenter pour qu’avec la documentation du CPU du Raspberry Pi on puisse les compléter facilement.

Ah, j’oubliais, si l’achat d’un boitier n’a pas beaucoup d’intérêt, j’ai trouvé autre chose qui fait très joli :  le Starter Kit de SKPang. C’est un support pour le RPi avec une plaquette d’évaluation, ainsi que des leds, des résistances et interrupteurs. Ce qui ont fait un peu d’électricité/électronique au lycée auront une petite remonté de souvenirs émus. Pour commencer à faire du prototypage d’I/O vers le monde extérieur, ça m’a l’air pas mal du tout.


OS Temps Réel

by Matthieu

Je quitte un peu les bas fond de l’électronique pour évoquer un sujet nettement plus orienté développement logiciel.

OS Temps Réel Multitâche : Définition

Pour être précis, la définition que j’utilise. Un système temps est un système dont le temps de réaction associé à la moindre action est connu. Un OS Temps Réel (RTOS) est donc un ensemble de routines et de primitives respectant ces conditions. Par exemple le passage d’une tâche à une autre prend toujours le même temps.

Si on étend le concept, la mesure d’une grandeur physique par un capteur est dite « temps réel » quand on sait combien de temps cela prend. Si on attend une valeur au bout de 10s, et que la réponse arrive au bout de 12s, ça ne sert à rien, peu importe le reste (précision, etc.). Cela s’oppose donc à la notion de « temps réel » habituelle du grand public qui tourne plutôt autour de l’immédiateté.

Et le multitâche ?

C’est la possibilité qu’a votre OS de faire plusieurs choses en même temps. Comme vous êtes féru de technologie, vous savez très bien qu’un processeur n’exécute qu’une seul instruction à la fois par cœur (m’emmerdez pas avec votre hyperthreading, c’est pas vraiment le genre de truc qu’on gère dans un microcontrôleur), et on en arrive au fait que votre multitâche est en fait votre µC qui exécute un bout de tâche par-ci et un autre par-là.

Question bonus : un OS ? Genre on peut installer des applis et tout ?

Humm en général non. A part pour les Linux embarqué (et qui ne sont pas forcement temps réel, ucLinux par exemple, mais pas QNX qui lui l’est) qui se comportent comme des Linux, beaucoup d’OS embarqué sont compilés en même temps que le reste de l’application. Cela est évidemment possible car le cœur d’un OS n’est pas « très » compliqué. Une fois les drivers (oui, c’est au développeur de les coder et de les intégrer dans l’OS) et la Dame de Pique enlevés, il ne reste plus que l’ordonnanceur et les objets de l’OS.

Ordonnanceur ?

L’ordonnanceur  (ou scheduler pour les intimes), c’est ce qui fait que votre OS est multitâche. Je disais tout à l’heure que votre µC qui exécute un bout de tâche par-ci et un autre par-là, bon, en vrai votre µC ne fait que ce que le l’ordonnanceur lui demande. Pour bien comprendre comment ça marche, intéressons nous d’abord aux tâches, qu’on va bien nettoyer.

Une tâche est une routine qui s’exécute en boucle et qui peut avoir 3 états fondamentaux :

  • En cours (Running)
  • En attente (Waiting)
  • Prête (Ready)

On peut y rajouter d’autres attributs en fonction de l’OS comme par exemple un numéro de priorité, nécessaire pour beaucoup de système, mais pas obligatoire. L’idée de base, c’est que lorsque votre CPU exécute la tâche, elle est « Running », quand elle va attendre un évènement elle va se mettre en « Waiting » sur cet évènement, quand l’évènement arrivera elle passera en « Ready ». Ensuite quand votre  ordonnanceur se posera la question fondamental « Quelle tâche vais-je donc exécuter maintenant ? » il verra votre tâche qui est « Ready », un peu comme quand vous vous hâtiez de lever la main pour répondre à la maitresse.

Mais si j’ai trois tâches (soyons fou, A, B et C), et que 2 ou plus sont Ready en même temps, mon  ordonnanceur fait quoi ? Et bien ça dépend de l’OS. Premier cas, votre OS gère ce que l’on appelle le Round Robin, et dans ce cas il se débrouillera pour attribuer le même temps CPU à chaque tâche. Deuxième cas, votre OS ne gère pas le Round Robin et dans ce cas c’est le concept de priorité de la tâche qui entre en jeu.

Vous êtes probablement familier avec le concept de niveau de priorité parce que vous avez remarqué que, dans le gestionnaire de tâche de Windows, vous pouviez changer la priorité d’une tâche. J’ai jamais réellement su si ça pouvait avoir un effet bénéfique ou bien si cette option a été créé juste pour rendre instable le PC des téméraires les plus curieux. Mais je m’égares. Certain OS simplifie la gestion des priorités en interdisant que 2 tâches aient le même niveau de priorité. Lorsque c’est le cas, à la question « 3 tâches sont Ready, laquelle passe en Running ? » la réponse est « celle du plus haut niveau de priorité ». Au passage j’élude vite fait les niveaux de priorité identiques : dans ce cas l’OS fait du Round Robin et attribut le même temps CPU aux tâches de même priorités.

Vous l’avez compris, on ne peut avoir qu’une seule tâche en Running. Quand les trois sont Ready, on exécute (la pauvre!) celle de plus haut niveau de priorité. Et quand les trois sont Waiting on … ben on fait quoi ? Et bien on se touche la bite ! On utilise une tâche système qui s’appelle la tâche « Idle ». Un microcontrôleur de base ne peut pas « s’arrêter de tourner », il faut donc lui filer du grain à moudre même si c’est pour lui dire de tourner en rond (astuce belge, le mettre dans une pièce ronde et lui dire de chercher une frite qui se trouve dans un coin). La tâche Idle c’est du vent, une boucle infinie vide. Travaux pratique : faites Ctrl+Shift+Echap et trier par « CPU » dans la liste des process. Et le grand gagnant est… Processus Inactif du Système ! La tâche Idle de Windows, celle qu’exécute l’OS quand il n’y a rien à faire.

Au final, pourquoi un OS dans l’embarqué ?

Ça, c’est la vrai question. Première réponse : surement pas pour accélérer votre code. En effet, passer d’une tâche à l’autre à un coup en terme de RAM et en terme de temps CPU. Si votre appli est ultra optimisée complètement rédigée en assembleur avec un taux d’occupation CPU de 100%, ne rêvez pas, un OS ne vous créera que des ralentissements.

En revanche il est possible que votre appli fasse plein de petites choses différentes, ai besoin d’une communication vers l’extérieur, fasse un contrôle de process dont le temps de réaction est de l’ordre de la milliseconde, tout en contrôlant des variables provenant de capteurs divers, affiche des données statistiques sur un petit écran LCD, etc. Là, un OS peut être utile. En organisant les différentes fonctions de votre applications en différentes tâches, vous posez dissocier les process internes. En choisissant judicieusement vos niveaux de priorité par la suite, vous aurez votre OS qui gérera tranquillement ce que vous lui avez demander sans avoir à vous tapez une grosse machine d’état pour savoir comment organiser votre communication par rapport à votre acquisition de température. Virtuellement les deux se font en même temps.

Et il n’y a pas que l’organisation en tâche qui rend un OS pratique. Il y aussi tout les objets systèmes que votre OS pourra vous proposer. Je n’ai pas abordé le sujet des timer OS, des sémaphores et des boites à lettre, mais ces objets de synchronisation permettent à vos tâches de communiquer entre elles, tout en mettant en place des systèmes sécurisés prêts à emploi.

En attendant un article complémentaire sur quelques mécanismes internes, les objets systèmes et un lave-linge, si le sujet intéresse il y a toujours plein de doc sur les Internettes.


Communiquons

by Matthieu

Retour de notre grande série, Parlons « embarqué » afin de monter dans les hautes sphères de la communication. J’ai parlé la dernière fois de communication entre mon µC (microcontrôleur) et divers composants avec un principe de base, le bus parallèle.

image manquante

Mais vous l’avez constaté vous-même, ça devient vite un peu le bordel, c’est donc pour ça qu’une tétrachié de chercheur et d’ingénieur ont mis au point des bus de communication pour se faciliter un peu le câblage.
Exemple pratique récent avec vos disques durs, regardez moi dans les yeux du blog et dîtes sincèrement que vous ne regrettez absolument pas cette superbe interface qu’était l’IDE (ou Parrallel-Advanced Technology Attachment) au profit d’un Serial ATA beaucoup plus saillant.

image manquante

Hummmmmiam, la bonne vieille nappe IDE qui niquait le flux d’air du PC, qui entrainait des galères de « T’es en slave ou en master sur la nappe? », ça en fait des bons souvenirs !

Bref, rapidement on se rend compte que physiquement parlant, ça serait bien de pouvoir brancher autre chose que des machins qui font quarante fils de large pour quelque chose de plus discret.

Mais avant d’aller voir plus loin, parlons du moyen le plus simple pour « communiquer » avec un µC : le DI/O. Comme Digital Input / Output. Et oui, quoi de plus gratifiant que de faire rentrer un signal (avec un interrupteur ou un bouton poussoir) et de voir un résultat sur une sortie avec une petite LED dessus ? Et oui, ça vend toujours autant du rêve ici. Mais sans déconner, quand vous venez de finir de monter votre PC, vous faites quoi a part appuyer sur un putain de bouton en regardant la diode de la façade, attendant l’allumage de cette dernière tel un enfant qui attend fébrile le père noël ? Comme quoi, avec une diode on fait passer pas mal de message. Si vous voulez, vous pouvez même câbler 8 diodes et faire LE TP d’informatique industrielle le plus célèbre, le « chenillard », ainsi que sa version haut de gamme dite « K2000 ». Avec une Led, vous pouvez faire du morse, bon vieux protocole de communication série qui marche aussi bien avec des fils électriques qu’avec des signaux lumineux (foutez vous de ma gueule avec ma Led, mais les bateaux ont utilisé ce principe pour chatter).

Parallèle ? Série ?

Mais si rappelez-vous, je vous expliquais que le µC plaçait des niveaux électriques sur le bus de données. Dans mon exemple on utilisait un bus 8 bits, on avait donc en parallèle 8 informations sur 8 fils. Et si maintenant on disait que plutôt que d’envoyer 8 infos en même temps sur 8 fils on envoyait un série de 8 informations l’une après l’autre sur un seul fil ? Si la communication parallèle est faite avec une vitesse de 1 rafraichissement par seconde, il suffit d’aller 8 fois plus vite sur un seul fil pour obtenir le même débit.

Un bus parallèle à 1Hz (majuscule au H, je vous rappelle qu’Hertz est un éminent monsieur) offre les même performances qu’un bus série de 8Hz. Donc pour envoyer une information en série sur un seul fil, il suffira de mettre un niveau logique haut puis bas à une fréquence qui sera connu par le récepteur. Vous imaginez bien d’allumer et d’éteindre une Led à une fréquence constante pour envoyer un message est vite chiant, et c’est pour ça que des gens ont sacrifié leur vie pour créer des interfaces de communication standardisées.

Et la première interface qui me servira de support sera… la liaison RS-232 ! J’en vois deux au fond (toujours les mêmes) qui se disent que « tiens ça me rappelle un truc ». Et oui, dans les temps reculer de l’informatique cette sympathique interface méritait d’avoir son propre port sur votre PC, sous la forme d’une prise DB9 qui s’appelait glorieusement sur votre PC : COM1.

image manquante

« AAAAAaaahhhh ouuuuuuuuui ! J’me rappelle, j’y branchais (enfin, papa le faisait…) mon modem US-Robotics 33,6kbauds pour aller occuper la ligne téléphonique avec les CD d’AOL gratuit trop bien ».

Exactement, cette glorieuse interface a fait son temps car elle permettait de brancher un peu un n’importe quoi pourvu qu’un dispose d’un logiciel qui gère une communication avec un périphérique externe (modem, imprimante, scanner, lance missile USB… ah non pas celui là, mais on aurait pu). Aujourd’hui elle a disparu du cul des PC grand public, et seul les professionnels en ont parfois besoin (moi en particulier) car c’est une interface très simple à utiliser pour discuter avec de l’électronique embarquée. Au passage j’en profite pour dire que si le connecteur n’est plus présent, les fils qui l’utilisent sont parfois disponibles sur les cartes-mères. Ainsi vous pouvez à peu de frais acheter le connecteur et faire un coup de tuning/soudure pour un effet rétrochic des plus charmants.

Question : Pourquoi le connecteur ayant disparu, l’interface électrique est elle toujours présente ? Et bien ce n’est que mon avis, mais c’est parce que le module du processeur qui va derrière est tellement bidon, peu cher et historique que tout les designers du puce le garde « au cas où ».

Ce module s’appelle la plupart du temps un UART (Universal Asynchronous Receiver Transmitter). L’UART est un module de µC qui se charge de transformer des signaux électriques en valeur compréhensible par le cœur du processeur, et de faire également l’inverse, transformer des informations venant du cœur en signaux électriques. Parce que manuellement changer les niveaux électriques est fatiguant, l’UART se charge d’envoyer à vitesse constante les octets qu’on lui met en entrée, déchargeant ainsi le CPU de cette tâche ingrate. L’UART est un périphérique qui utilise 3 fils :

  • Un pour la réception (Rx)
  • Un pour l’émission (Tx)
  • Une masse électrique.

D’un point de vue électrique lors d’une communication on observe ce genre de chose :

image manquante

Lorsqu’on connait la vitesse et quelques autres paramètres, on peut facilement regrouper les changements d’états par paquets de 8 et ainsi recréer des octets, qui vont au final former un message qu’on décodera ensuite dans le programme. Sur l’exemple ci dessus, le programme reçoit une trame et en renvoi une identique. Si on fait le regroupement précité, on observe ça :

image manquante

Si avez le temps, observez les niveaux logiques et vous pourrez trouver les valeurs binaires de chaque paquet, qui donne les valeurs hexadécimales de la première ligne. Pour indication la deuxième ligne montre les valeurs ASCII correspondantes (sauf les valeurs entre guillemets car elles ne correspondent à aucun caractère « classique »). Si cette trame est envoyée sur un PC avec un Hyperterminal, vous verrez donc quelques caractères s’afficher à l’écran.

On a donc utilisé 2 fils pour faire transiter 8 octets de 8 bits chacun, soit 64 bits. Plus pratique que 64 fils !

Limitation et contre mesure

La limite principale d’une communication série est la perte de données suite à une vitesse trop élevée. En effet si on regarde les chronogrammes ci dessus, il est facile de comprendre que si un bit est oublié, tout le message est décalé et l’information est mal comprise. Et plus on augmente la vitesse, plus le risque d’incompréhension est grand. De plus, dans le cas de la RS232, le côté « repère temporelle » est indépendant de chaque côté. C’est à dire que l’émetteur et le récepteur sont « sensé » utiliser la même vitesse de communication. Mais si ce n’était pas le cas… impossible de se comprendre.

Autre soucis, la préservation de l’intégrité des données. C’est simple, il n’y en a pas. Si une perturbation vient transformer un 1 en 0, impossible pour le récepteur de le savoir. Cependant on peut palier à ça en intégrant des checksum dans les trames, au prix d’une phase d’analyse supplémentaire à l’émission et à la réception. Et oui, rien n’est parfait en ce bas monde.

Conclusion

Une communication dans un système embarqué est soumise à un certain nombre de contraintes dont l’encombrement. On voit bien avec ces quelques paragraphes l’intérêt d’une communication série qui permet de limité les éléments à câbler. Si la RS232 répond à des besoins simples, elle sera insuffisante pour des communications rapides ou bien soumises à des contraintes de pollution électromagnétique.

Et bien ce que je peux conclure c’est que cet article et déjà assez long comme ça, alors que j’avais envie de parler d’autre type de bus de comm. Rendez un peu plus tard pour parler SPI, CAN et pourquoi pas USB et Ethernet.


Pekeepilot

by Matthieu

Oui, c’est honteux de reprendre ces vieux articles, mais quand j’ai reparcouru mon répertoire de vidéos Youtube, j’ai exprimé un petit sourire de nostalgie, teinté d’une bref montée d’orgueil made in « Yes, I did that ».

Ça parle d’une équipe de jeunes ingés un peu branloss (à l’époque on se trouvait sérieux, mais avec le recul…) qui se sont amusés à développer une appli pour piloter un robot en forme d’aspirateur en Wifi avec une Nintendo DS.

Mon vieil article d’il y a deux ans.

La lol-vidéo :

Image de prévisualisation YouTube

Finalement, avec le recul, on était super précurseur ! L’air de rien on a eu l’idée de piloter un robot avec un machin tactile et des accéléromètres fin 2006 et on l’a fait en janvier 2008. L’Iphone est sorti mi 2007 et le drone Parrot en 2010. La plupart des applis qu’on trouve sur les Market Apple et Android sont grosso merdo le même genre d’appli que ce qui se faisait avec la bibliothèque PALib qu’on avait utilisé pour notre soft.

On n’aurait peut être pas du s’inquiéter du côté légal de notre projet (les linkers sur DS faisaient grand bruit en 2007) et créer une boite pour faire des trucs à la con avec des robots et des périphériques Wifi ! On aurait gagné des millions de fan sur facebook (ça c’est un but intéressant dis-donc), plein d’argent, des bols de coke !

Enfin bon, on a rien fait du projet une fois terminé. Maintenant que je suis dans un bureau de R&D j’ai tout ce qu’il me faut pour refaire un genre de robot pareil, mais le temps… le temps manque ! Et puis je ne suis pas payer pour faire des robots Wifi. C’est dommage des fois, ça pourrait être trop lololol de repartir sur un truc du genre.


Mapping et logique

by Matthieu

Si vous avez manquez les épisodes précédents :

Pour résumer, on avait parlé des opérations de bases d’un processeur et du câblage d’un boitier mémoire ridiculement petit. Un boitier de RAM, c’est bien, plusieurs boitiers, c’est mieux!

J’ai décidé aujourd’hui, en pleine semaine de solde, d’acheter un peu de mémoire flash pour mon montage, dans le but de sauvegarder les résultats de mes calculs même une fois que mes composants seront privés d’électricité (Si je vous dis que la RAM est volatile ça va ? ça ne vous choque pas ? très bien). Et comme c’était les soldes, j’ai eu le droit avec mon boitier de Flash F4k16 (4k de flash 16bit, soit 8 kilooctets de données) à un boitier de RAM M1k (rappel, 1k de ram 8bit, soit 1 kilooctet de données) offert ! Formidable !

Câblage

Nous avions vu la dernière fois que pour câbler notre boitier, nous avions du brancher 4 « catégories » de fil : le bus d’adresse, le bus de donnée, le Read/Write et le Chip Select. Pour les bus, c’est très con, on tire les fils qui vont bien. Pour la RAM, le câblage est identique à celui réalisé précédemment (10 fils, A0 à A9). Pour la flash, la plage d’adresse du boitier de flash étant plus grande (4 est supérieur à 1), il va falloir tirer plus de fils entre le processeur et le boitier. Deux de plus pour être précis. Attention, démonstration ! 4k veut dire 4096 adresses différentes, allant de 0 à 4095. 4095 en binaire vaut 111111111111. Pas la peine de compter les 1, il y en a 12. D’où mes deux fils de plus. Les esprits fins de certains lecteurs auront remarqués que je vais tenter d’interfacer un boitier avec 16bit de data sur un microprocesseur 8 bits. Ben… les promotions Carrefour étaient sur les boitiers 16 bits, que voulez vous que j’y fasse ! Déjà, c’est quoi la différence entre un boitier 16 bits et un boitier 8 bits ?

Interlude « Mathématiques, Hexadécimal et autre décalage logique ».

Je vous ai décrit la fois précédente mon boitier de ram comme un tableau Excel de 1024 lignes dont le contenu pouvait varier entre 0 et 255. Et bien le boitier 16 bit est un tableau dont les valeurs peuvent varier entre 0 et (2^16) – 1, soit 65535. On peut également le voir comme un tableau avec 2 colonnes (au hasard, on va appeler la colonne de droite LSB pour Less Significant Byte, et celle de gauche par MSB pour Most Significant Byte. Attention, en fonction du contexte, le B peut vouloir dire Bit également), dont la valeur peut varier entre 0 et 255.

En multipliant le contenu de la case MSB par 256 et en ajoutant le LSB, on retrouve une valeur 16 bits. Pourquoi cette multiplication par 256 ? Prenons quelques exemples concrets. Et branchez votre cerveau dégourdi, on va faire des multiplications. Par deux, c’est super balèze. En binaire, 0 vaut 0 et 1 vaut 1 (si vous avez un doute, vérifiez avec la calculette de Windows, trop bien pour les conversions). 2 = 10 4 = 100 8 = 1000 Votre esprit aiguisé aura remarqué avec brio que pour passer de 2 à 4 et de 4 à 8, on dirait qu’on a juste rajouté un 0 ! Et oui, vous pouvez vérifier avec par exemple avec 3 (11) et 6 (110). La multiplication par 2 en binaire, c’est un décalage logique de 1 bit vers la gauche. Et par conséquent, une division par 2 est un décalage logique vers la droite : si on décale 14 (1110) d’un bit vers la droite, ça donne 111, soit 7. Par conséquent du conséquent, un décalage de 2 bit vers la gauche implique une multiplication par 4; 3 bit donne une multiplication par 8, etc. Alors what iz ze point avec mon boitier 16 bit ? Et bien votre MSB représente la partie 8 bit haute de votre nombre 16 bit. Elle est donc décaler de 8 bit, et donc est multiplier par 2^8 = 256. Ainsi, si votre MSB vaut 255, que votre LSB vaut 255, votre nombre 16 bit vaut 255 x 256 + 256 = 65535.

Retour à mon montage

Sur le schéma, on voit que j’ai câblé les fils D0 à D7, soit ma colonne « LSB ». Je vais donc pouvoir y accéder sans problème comme sur le boitier de RAM. Pour le MSB (fils D8-D15), je ne vais rien en faire, puisque de toute façon, j’ai un microprocesseur 8 bit (enfin en vrai je vais les câbler à la masse pour éviter les perturbations de signaux mais ce n’est pas le sujet). Vous avez donc compris que je vais gâcher la moitié de la mémoire flash car je ne pourrais en l’état pas y accéder, ni en lecture ni en écriture. Mais puisque je vous dis que c’était les soldes ! Il me reste donc 2 signaux à caser : R/W et CS. R/W peut se câble comme un bus, directement sur chaque composant. Par contre pour CS, c’est un peu plus siouxe.

La source de CS (ce titre de paragraphe n’est là que pour faire monter mes stats Google)

Si vous vous rappelez de l’article précédent (c’est le cas j’en suis sur), vous savez que le CS permet au processeur de désigner à qui il s’adresse, pour qui sont destinés les valeurs qui transitent sur les bus de donnée/adresse. Et manque de bol, je viens de regarder dans la documentation technique (datasheet) du processeur, je n’ai qu’un seul sortie CS ! OMG LOL WTF §§!! Je ne peux pas utiliser le même signal CS sur mes trois boitiers puisque dans ce cas, j’écrirais dans les trois boitiers en même temps, mais surtout la lecture va se faire également en même temps et la si un boitier veut coller 5Volts sur le bus (pour écrire un 1, je rappelle) et que l’autre veut mettre 0 Volts (pour écrire un 0) ça va faire un sacré bordel. Comment vais-je donc faire ? Et bien je vais faire du décodage d’adresse. Qu’est ce que donc ?

Définir le mapping mémoire

Dans un premier, on prend un papier et un crayon, et on organise son merdier. J’ai 2 boitiers avec 1024 adresses, et un boitier avec 4096 adresses. Mon micro, lui, avec son bus d’adresse 16 bit, peut adresse 2^16 soit 65536 adresses différentes. En gros, va falloir organiser les trois plages des boitiers dans l’espace adressable total du µC. Mon premier choix, c’est de dire : j’aligne tout. D’ailleurs c’est tellement une bonne idée que je vais la garder. On n’a qu’à dire que les 1024 premières adresses sont pour le premier boitier de RAM, les 1024 suivantes pour le deuxième boitier, et les 4096 suivantes sont pour la flash. En résumé :

J’ai maintenant une idée de ce que je veux obtenir, je peux ENFIN passer à la gestion de mon Chip Select.

Le décodage d’adresse

Ce qui va faire la différence entre les datas qui vont dans RAM1, RAM2 et Flash, c’est la plage d’adresse que j’ai attribué à chaque composant. Je vais donc me servir de mon bus d’adresse et d’un peu de porte logique pour faire la différence entre les boitiers, j’activerai alors le CS de chacun des boitiers de façon indépendante.

Rappel de logique combinatoire (oui, on en voit des choses aujourd’hui!)

Principe de base : combiner des signaux électriques pour réaliser des opérations logiques. Les briques de bases qui vont nous servir aujourd’hui (il y en a d’autre) sont la porte ET (symbole logique « . », symbole informatique « & »), la porte OU (symbole logique « + », symbole informatique « | ») et la porte NON (symbole logique « / », symbole informatique « ! »). Vous rentrez un ou plusieurs signaux sur les entrées, et vous obtenez un résultat de l’autre côté. On appelle « table de vérité » le principe de comportement de la porte.

Alors pourquoi je parle de ça ? Et bien simplement car grâce à plusieurs portes logiques bien placées, on va pouvoir réaliser une « équation logique » qui va permettre de diriger notre signal CS (oui, je rappelle qu’au départ on parlait de lui, avant que vous ayez eu cette idée stupide d’écrire tl;dr). Si on regarde le mapping mémoire, en particulier les bits de poids fort (les plus à gauche), on voit que les combinaisons qu’ils composent sont propres à chaque composant. Si les bits A10, A11, A12, A13, A14 et A15 sont à zéro, on est sur d’être sur la plage mémoire de RAM1. Puis avec A10 à 1 et A11-A15 à 0, on est sur d’être sur RAM2. Pour le boitier flash, c’est un peu plus tordu car il occupe un nombre plus important de combinaison de A10-A15, mais il existe tout un art concernant la simplification d’équation logique. Nous allons les écrire vite fait, présenter le câblage de notre « décodeur ». Nous cherchons à couper notre CS en trois signaux pour chacun des boitiers : CS1 pour RAM1, CS2 pour RAM2 et CS3 pour la flash.

CS1 = CS.(/A10./A11./A12./A13./A14./A15) : pour activer CS1, il faut avoir CS à 1, et tout les autres à 0

CS2 = CS.( A10./A11./A12./A13./A14./A15) : pour activer CS1, il faut avoir CS à 1, et tous les autres à 0 sauf A10

CS3 = CS.( (/A10. A11./A12./A13./A14./A15) + (A10.A11./A12./A13./A14./A15) + (/A10./A11.A12./A13./A14./A15) + (A10./A11.A12./A13./A14./A15) ) je vous laisse comprendre, comparez ça au mapping un peu plus haut.

Voici donc notre circuit logique qui va nous produire nos trois Chip Select différents. Il sera donc impossible d’adresser en même temps deux composants.

Cependant, il faut être franc, il existe en général des boitiers programmables ou ce genre de boulot, vous simplifiant clairement la tâche. D’ailleurs j’en ai trouvé un par terre, je vais tout de suite le mettre sur mon schéma final !

Voilà, on a encore amélioré notre système embarqué. Vous collez ça avec un alim au fond d’une machine à laver, et vous avez un système capable de :

  • Charger des data qui viennent de la mémoire flash
  • Faire des calculs
  • Ecrire les résultats dans une mémoire externe deux fois plus grande que la dernière fois
  • Faire plein de sauvegarde en flash

Il ne lui manque plus qu’un brin de communication, mais je me le garde pour plus tard. Vous devez déjà bien avoir la gerbe après avoir lu tout ça !


Microprocesseur

by Matthieu

Si vous avez manqué le début, il y a presque un an.

Fonctionnement de base d’un système à microprocesseur.

Le microprocesseur

Voilà, il est beau hein, votre nouveau processeur de la marque « Generic 081628 ». Il est cadencé à 28 gHz, possède un bus de donné de 8 bit, un bus d’adresse de 16 bit et quelques autres machin que je me réserve pour plus tard. Vous vous dîtes « Reste plus qu’à le plugger sur ma carte mère et … » et non, désolé, on fait de l’embarqué, il n’y a pas de carte mère qui accepte les Generic 081028. Va falloir tout faire à la main, comme des hommes. Un processeur tout seul, ça ne fait pas grand chose. Pour simplifier, ça ne dispose que de registres, d’une unité de calcul arithmétique et logique. Le Generic 081628 possède 4 registres de données 8 bits et 5 registres d’adresse 16 bits. Dans un registre 8 bits on peut mettre une valeur entre 0 et (2^8 – 1) soit 255. Dans un registre d’adresse 16 bits, on peut stocker entre 0 et (2^16 – 1) soit 65535. Voilà, on est bien avancé avec ça. Mais c’est déjà pas mal parce qu’on va pouvoir lui faire faire des choses trop bien (la suite est une adaptation d’assembleur adapté par moi même) :

  • Mettre 38 dans RD0 (registre de donnée numéro 0)
  • Mettre 2 dans RD1 (registre de données numéro 1)
  • Additionner RD0 et RD1 et mettre le résultat dans RD0.

Formidable ! A la fin de la manip, vous avez donc 40 dans RD0 et 2 dans RD1. Nous avons donc vu une des opérations de base du micro. Éventuellement on aura pu faire une soustraction, une multiplication, voir même une division dans vos rêves les plus fou.

Comme vous pouvez le constater, le 081628 ne pourra stocké au maximum qu’une valeur de 8 bit sur ses quatre registres. Soit une mémoire de … 4 octets. Pas terrible hein ? Nous allons donc rajouter un petit machin :

La mémoire externe

Et oui, la fameuse RAM de votre PC ! Notre micro est bien pauvre en espace  mémoire, nous allons donc lui rajouter un boitier mémoire de 1 kilooctet. Oui, c’était les soldes, il était en promo je me suis fais plaiz’. Mais comment le brancher à mon micro? Un boitier mémoire de type Generic M1K possède  10 pin (pattes) d’adresse, 8 pin de données et 2 autres pin dont je vais parler un peu plus tard.

Alors comment ça marche ? Sur le principe c’est plutôt simple : ce boitier peut contenir 1024 valeur 8 bits (1024 octet, depuis le temps vous l’aviez compris). Imaginez simplement un tableau Excel de 1024 case, avec des valeurs comprises entre 0 et 255. On place la valeur logique sur les fils du bus d’adresse l’indice du tableau dans lequel on veut écrire, par exemple 10, et sur le bus de donnée on colle la valeur qu’on veut écrire dans la mémoire, par exemple 82. Les novices perspicaces se demandent déjà : « Mais diantre, comme écrit on 82 sur des fils ? ».

Le binaire, le décimal et l’hexadécimal

Bien vu l’aveugle, et bonne question. L’informatique, c’est de l’électronique à la base. Sur un fil, le plus simple c’est soit d’appliquer une tension (en Volt), soit de rien faire du tout. On a donc 2 états électriques possible (et le concept du binaire apparait…). Le micro de cet article peut appliquer une tension de 0V, ou bien de 5V. Le 0 valant un 0 logique, et le 5V le 1 logique. En transformant 82 en une suite de 0 et de 1 (Conversion en binaire) qui vaut 01010010, on peut appliquer zéro ou 5V sur le bus de donnée du micro. Le bus de donnée est composé de 8 fils, nommés D0 à D7; électriquement nous avons donc :

  • D0 à 0 : 0V
  • D1 à 1 : 5V
  • D2 à 0 : 0V
  • D3 à 0 : 0V
  • D4 à 1 : 5V
  • D5 à 0 : 0V
  • D6 à 1 : 5V
  • D7 à 0 : 0V

Câblage

Nous allons relier les 8 fils du bus de donnée du micro au 8 fils de donnée du boitier mémoire. Le boitier mémoire est capable de faire la différence entre 0 et 5V, il va donc être capable de déchiffrer notre 82. Mais pour en faire quoi ? Suivant le modèle du bus de donné, le micro va placer la valeur 10 sur le bus d’adresse.

Sur le même principe, les 16 fils du bus d’adresse sont nommés A0 à A15 et sont connectés sur le boitier mémoire. Alors comment qu’on fait pour coller 16 fils sur un boitier où il n’y en a que 10 ? Bonne question… ou pas. On va faire simple : brancher les 2 A0 ensemble, les 2 A1, etc jusqu’à A9. Le micro va mettre 5V sur le fil A1 et A3 (10 en binaire donne 1010).

Voilà donc les bonnes informations présentes sur les bus, le boitier mémoire fait donc son taf, et récupère la data 82 pour la coller à l’adresse 10. Vous qui avez l’air égayer et joyeux comme des poulets sous exta, je sens poindre en vous un remarque pertinente : sur le schéma du boitier ya deux fils dont j’ai pas parlé! Oui, j’y viens. Un boitier mémoire, ça sert à stocker, mais si on peut relire c’est encore mieux. Pour ce faire, le boitier mémoire possède une entrée « R/W ». Toujours sous exta, vous devinez facilement que le R, c’est read, et que le /W c’est write. Voilà. C’est tout con. Vous avez un fil dédié sur le micro qui va dire si on écrit vers un périphérique (notre exemple où le micro place la data sur le bus de donnée) ou bien si on lit (c’est alors le boitier mémoire qui placera la data sur le bus, le micro ira lire les niveaux de tension).

Le dernier fil n’est pas CS comme counter strike, mais CS comme Chip Select. Le CS, c’est un peu le doigt du microcontrôleur chef d’orchestre qui désigne le périphérique qui doit parler. Tant que l’entrée CS d’un composant est non active, il n’écoute pas, ne parle pas, il ferme sa gueule ce boitier mémoire de merde. Voilà, notre système ressemble donc à ça :

Voilà, c’est un système qui sait :

  • Prendre des données dans une mémoire externe
  • Faire des calculs
  • Ecrire les résultats dans une mémoire externe.

Nous avons vu que notre boitier mémoire contient 1024 octets et est connecté sur les fils A0 à A9. La zone mémoire adressable va donc de l’adresse 0x0000 à l’adresse 0x03FF (1023 en décimal). Et si maintenant on voulait rajouter 1k de mémoire supplémentaire ? Et bien on le brancherait de la même façon (D0-D7; A0-A9; R/W) sauf pour le CS qui lui devra être différent. En effet on utilisera une deuxième sortie Chip Select du micro pour permettre de parler soit au premier boitier, soit au deuxième, et ainsi ne pas se mélanger les pinceaux.

Je vais m’arrêter la pour le moment, car je sais que le sujet peut mener rapidement à une indigestion. Au programme de la prochaine fois : décodage d’adresse, mapping mémoire et liaison série.


Theme by Ali Han | Copyright 2017 Embarquement ! | Powered by WordPress