Born to be wired

Articles taggés avec ‘code’

 SMS automatisé – Final round

 8 décembre 2013  Domotique  Aucun commentaire

Maintenant, terminé les enfantillages. Envoyer des SMS en ligne de commande à des gens avec un nom rigolo, c’est très amusant, mais ça montre rapidement ses limites. Pour aller plus loin, il faut mettre en place un système capable de gérer de manière autonome les échanges avec la carte SIM, et de proposer une interface de communication à la fois simple, robuste, et utilisable par un grand nombre d’applications.

La base de données est une interface idéale pour cela, et il existe justement un système qui peut l’utiliser comme backend pour communiquer avec le modem GSM. Ce système, c’est gnokii-smsd.

(suite…)

 Winter is coming – S01E01

 14 octobre 2013  Domotique  1 commentaire »

L’hiver vient. Après avoir automatisé le démarrage et l’arrêt des radiateurs de mon appartement grâce à l’installation de fils pilotes et d’une centrale de programmation, je souhaite vivement mettre en place une fonctionnalité similaire sur ma climatisation réversible. Elle constitue pour moi un moyen économique et rapide de chauffer ma pièce principale, il serait donc intéressant de pouvoir la déclencher de manière programmée, ou encore mieux, à distance, par exemple de manière automatique le matin avant que je me lève, ou manuellement à l’heure où je sors du travail, afin que la pièce soit déjà chauffée lorsque j’arrive chez moi.

Seulement, mettre en place un tel projet n’est pas évident. Ma clim de marque Airton n’est pas programmable. Je ne peux pas non plus automatiser son déclenchement en connectant son alimentation sur des relais, cela équivaudrait à couper brutalement le courant lorsque je demande un arrêt, ce qui n’est pas conseillé quand le climatiseur est activé.

Ma seule possibilité d’interaction avec l’appareil reste sa télécommande. Je dois donc trouver un moyen de récupérer les codes infrarouges envoyés par la télécommande et de les faire reproduire par un second dispositif automatisable.

Pour récupérer les codes de la télécommande d’origine, j’ai choisi de ressortir mon Arduino, qui jusqu’ici ne m’avait pas encore beaucoup servi, et de lui connecter un récepteur infrarouge issu d’un petit kit de développement commandé chez DealExtreme. J’ai effectué le câblage de la manière suivante :

ir-receiver-breadboardir-receiver-schematicsJe précise, pour ceux qui ne connaissent pas et qui voudrait réaliser des plans de câblage similaires, que ces schémas ont été réalisés avec le fabuleux Fritzing. Attention, selon le type de récepteur infrarouge utilisé, le brochage peut varier. Vérifiez la notice du composant en cas de doute.

J’ai récupéré et utilisé la bibliothèque de commande infrarouge pour Arduino développée par Ken Shirriff sur la page GitHub associée. Le blog de Ken Shirriff regorge également d’excellentes explications sur l’utilisation de cette bibliothèque.

J’ai enfin compilé et déployé le code suivant sur l’Arduino. C’est du quick and dirty, pour le test :

#include <IRremote.h>
int RECV_PIN = 11; //define input pin on Arduino
IRrecv irrecv(RECV_PIN);
decode_results results;

void setup()
{
	Serial.begin(9600);
	irrecv.enableIRIn(); // Start the receiver
	irrecv.blink13(true); // Blink LED 13 during IR reception
}

// Dumps out the decode_results structure.
// Call this after IRrecv::decode()
void dump(decode_results *results) {
	int count = results->rawlen;
	if (results->decode_type == UNKNOWN) {
		Serial.print("Unknown encoding: ");
	}
	else if (results->decode_type == NEC) {
		Serial.print("Decoded NEC: ");
	}
	else if (results->decode_type == SONY) {
		Serial.print("Decoded SONY: ");
	}
	else if (results->decode_type == RC5) {
		Serial.print("Decoded RC5: ");
	}
	else if (results->decode_type == RC6) {
		Serial.print("Decoded RC6: ");
	}
	else if (results->decode_type == PANASONIC) {
		Serial.print("Decoded PANASONIC - Address: ");
		Serial.print(results->panasonicAddress,HEX);
		Serial.print(" Value: ");
	}
	else if (results->decode_type == JVC) {
		Serial.print("Decoded JVC: ");
	}
	Serial.print(results->value, HEX);
	Serial.print(" (");
	Serial.print(results->bits, DEC);
	Serial.println(" bits)");
	Serial.print("Raw (");
	Serial.print(count, DEC);
	Serial.print("): ");

	for (int i = 0; i < count; i++) {
		if ((i % 2) == 1) {
			Serial.print(results->rawbuf[i]*USECPERTICK, DEC);
		}
		else {
			Serial.print(-(int)results->rawbuf[i]*USECPERTICK, DEC);
		}
		Serial.print(" ");
	}
	Serial.println("");
}

void loop() {
	if (irrecv.decode(&results)) {
		Serial.println(results.value, HEX);
		dump(&results);
		irrecv.resume(); // Receive the next value
	}
}

La carte est maintenant prête à recevoir les codes de quelques télécommandes. Afin d’afficher les codes IR reconnus par le dispositif, il est nécessaire de lancer le moniteur série de l’éditeur Arduino.

Montage sur platine d'essais, on ne peut plus simple.

Montage sur platine d’essais, on ne peut plus simple.

La plupart des télécommandes que j’avais sous la main ont été reconnues par le récepteur, à l’exception de ma télécommande Xbox. La LED du récepteur clignote lorsqu’il reçoit un signal IR. C’est d’ailleurs ce qui m’a permis de constater que mon écran PC parasitait le récepteur, j’ai donc pris soin de conserver une distance suffisante entre les deux appareils pour mes tests.

Je me suis par la suite focalisé sur le décodage des codes IR reçus, et affichés dans moniteur série. Sans surprise, la télécommande DealExtreme affiche les codes de télécommande NEC, tels que l’indique sa documentation.

La télécommande de mon climatiseur Airton est également reconnue comme utilisant le protocole NEC. En cherchant des informations sur ce protocole, j’ai trouvé entre autres cette synthèse, très bien réalisée. Elle m’a alors permis de vérifier si les codes IR reçus étaient cohérents par rapport au protocole reconnu.

decoded-ir-codes-with-raw-data

Attention, là, ça devient un poil technique :

La synthèse du protocole NEC m’apprend que celui-ci transmet une information sur 4 octets (soit 32 bits), plus un en-tête et un stop bit. Chaque bit 0 ou 1, ainsi que l’en-tête et le stop bit, sont codés par un niveau actif (émission de lumière IR) suivi d’un niveau inactif (pas d’émission de lumière), la durée de chacun de ces niveaux déterminant le type de bit codé. Pendant un niveau actif, l’émission de lumière n’est pas continue mais pulsée à la fréquence de 38 kHz. Enfin, sur les 4 octets, seuls 2 comportent une information utile, puisque les 2 autres contiennent un XOR de l’octet précédent avec 0xFF. Pour les novices en informatique, le XOR est un OU EXCLUSIF logique bit à bit, et n’a aucun rapport avec un personnage de fiction exerçant la profession de shérif de l’espace. Ici un XOR avec 0xFF revient à inverser chaque bit, donc 0 devient 1 et 1 devient 0.

Ainsi par exemple, au niveau de ma télécommande DealExtreme, le premier code remonté est FFA25D, ce qui correspond en réalité à une réception de 00FFA25D exprimé avec 32 bits. Les 4 octets sont 0x00, 0xFF, 0xA2, 0x5D. Le premier octet représente l’adresse (0), le second 0xFF correspond bien à l’inversion bit à bit de 0x00, le troisième octet 0xA2 représente la commande, et le quatrième 0x5D correspond bien à l’inversion bit à bit de 0xA2. Notez que la commande reçue 0xA2 est exprimée en LSB-first, bit de poids faible transmis en premier, et que si on la convertit en MSB-first, bit de poids fort transmis en premier comme l’être humain moyen a l’habitude de manier les nombres (en général on écrit les dizaines à gauche des unités), on obtient le code logique de commande 0x45, soit 69 en décimal.

La commande reçue correspond donc à un code 69 envoyé à l’adresse 0. Fin de la plongée dans le détail du protocole.

Si je regarde maintenant les codes reçus correspondants aux appuis de touches sur ma télécommande Airton, 2 points m’interpellent :

  • J’ai appuyé sur plusieurs boutons de ma télécommande, et tous sont décodés comme 6A8E0000 par le dispositif. Tous les boutons qui envoient le même code, c’est louche.
  • Au niveau de la structure du code reçu, si 0x6A est l’adresse, alors son inversion bit à bit devrait être 0x95, et non pas le 0x8E obtenu. De même, l’inversion bit à bit de 0x00 devrait être 0xFF, et non pas le 0x00 obtenu. Il y a donc vraiment quelque chose qui cloche.

Forcément, je m’attendais à ce que cela ne soit pas simple. La bonne nouvelle pour moi, c’est que le signal envoyé par la télécommande est bien perçu par le récepteur. La mauvaise, c’est que le récepteur ne semble pas décoder ce signal de la bonne façon. Il faut donc investiguer sur la bibliothèque de commande infrarouge, comprendre comment elle fonctionne, et probablement la modifier pour l’adapter aux spécificités de ma télécommande Airton. Mais ça, c’est pour une prochaine fois.

 SMS automatisé – Round two

 11 octobre 2013  Projet Serveur  Aucun commentaire

Dans mon premier article sur le sujet, j’avais promis que la suite de l’aventure se déroulerait sur une seconde maquette démontrant l’envoi de SMS grâce à l’utilisation d’un modem GSM et des commandes AT. Cette expérience constituera donc le sujet de cet article.

Comme d’habitude en retard en ce qui concerne la rédaction de mes articles (les photos que vous pourrez voir dans celui-ci ont été prises il y a pile un an), je tiens à préciser que ce retard se comble néanmoins peu à peu, avec pour effet de bord une accumulation de retard sur les interactions sociales avec les individus de mon espèce.

À la question « Pourquoi le modem GSM quand on peut déjà scripter l’envoi de SMS avec un Nokia 3310 ? », je répondrais : « Pour sa capacité à s’intégrer dans une chaîne de traitement automatisée ! Le 3310 ne fonctionne qu’avec son chargeur branché en permanence, avec les conséquences sur la batterie, et il doit être rallumé manuellement si jamais il venait à s’éteindre. Le modem GSM est alimenté par USB et sous tension dès que la machine/le serveur sur lequel il est connecté l’est aussi. »

Maintenant que tout est dit, passons au détail. J’ai choisi un modem Fastrack Wavecom en USB, ou un de ses clones, acheté à un vendeur chinois pour une somme très raisonnable sur un célèbre de site de vente aux enchères au logo multicolore et aux commissions sur les ventes outrageantes. L’appareil m’a été livré seulement deux semaines après l’achat, cette livraison dans un laps de temps si court prouve qu’il n’est pas arrivé à pied par la Chine.

Un paquet mystère en provenance de Chine.

Un paquet mystère en provenance de Chine.

Détail intéressant n°1, comme à leur habitude, les Chinois ne se prennent pas trop la tête avec la douane. La déclaration sur le paquet mentionne une valeur de marchandise de 1$, le contenu est décrit comme étant des LED, et la case « gift » est coché. Tout est fait pour que le colis passe les frontière comme une lettre à la poste, c’est le cas de le dire.

Le formulaire accolé sur le paquet suit à la lettre les préceptes du livre "Comment gruger les services de douane en loucedé", éditions Gallimard.

Le formulaire accolé sur le paquet suit à la lettre les préceptes du livre « Comment gruger les services de douane en loucedé », éditions Gallimard.

Au déballage, on retrouve le modem, son antenne amovible, un cordon USB et un mini-CD.

Pas de grosse surprise au déballage.

Pas de grosse surprise au déballage.

Détail intéressant n°2, le mini-CD inclus dans le package, auquel j’ai tenté d’accéder, comme ça pour rigoler. Évidemment, le support est blindé à craquer de fichiers tous plus chelous les uns que les autres, entre autres des bons vieux exécutables chargés à ras bord de plus de chevaux de Troie qu’il ne faudrait pour mettre à sac un pays entier. Timeo Danaos et dona ferentes, et cela s’applique aussi aux Chinois.

Double-cliquez sur n'importe quel exécutable pour transformer votre PC en robot-spammeur, plate-forme d'échange de numéros de cartes bancaires volés, et proxy pour darknet pédophile.

Double-cliquez sur n’importe quel exécutable pour transformer votre PC en robot-spammeur, plate-forme d’échange de numéros de cartes bancaires volés, et proxy pour darknet pédophile.

Par sécurité, je décide que le mini-CD ne sera plus jamais lu sur un système Windows. La lecture du support sur un système Linux, afin de fouiller si des instructions intéressantes sont présentes, ne me permet de ne faire qu’une seule découverte digne de ce nom : le support Unicode est bien opérationnel sur ma plate forme.

Et on remercie la fonction copier/coller du terminal pour naviguer dans les répertoires en chinois.

Et on remercie la fonction copier/coller du terminal pour naviguer dans les répertoires en chinois.

Le déballage effectué, il est maintenant temps de passer aux choses sérieuses, à savoir, pour commencer, le chargement d’une carte SIM dans le modem et le test de quelques commandes AT. J’ai effectué ces tests de commandes AT sous Windows.

La carte SIM B&You prête à reprendre du service.

La carte SIM B&You prête à reprendre du service.

Le but de cet article n’est pas de détailler l’utilisation des commandes AT. Quelques minutes de browsing en passant par votre moteur de recherche préféré vous conduiront directement à des tutoriels très bien faits sur le sujet, dont celui-ci que je trouve extrêmement complet.

Une fois la base des commandes AT comprises, l’envoi d’un SMS de test devient rapidement une formalité, comme l’illustre la capture d’écran ci dessous.

Envoi d'un message simple par commandes AT.

Envoi d’un message simple par commandes AT.

Un détail intéressant à propos des commandes AT, surtout à l’ère des communications internationales, est la possibilité malgré un ensemble de commandes utilisant un jeu de caractères réduit,  d’envoyer également des caractères Unicode, pour peu que le modem supporte la fonction (et que le mobile puisse les afficher). Cela se fait au travers d’une petite gymnastique de conversion décrite sur ce site. J’ai bien évidemment testé :

Envoi d'un message Unicode par commandes AT.

Envoi d’un message Unicode par commandes AT.

Et le résultat ne se fait pas attendre, les 2 SMS sont bien reçus par le mobile destinataire, ici un Nokia C7.

Réception immédiate et conforme aux messages envoyés.

Réception immédiate et conforme aux messages envoyés.

J’en sais assez, l’expérience peut prendre fin. Il est temps de confier la tâche de l’envoi à une application de plus haut niveau qui se chargera d’envoyer les commandes AT au modem pour moi. Et cette application, c’est encore une fois gnokii, sur système Linux cette fois-ci.

En premier vient la préparation du système. Si ce n’est pas déjà fait, cela consiste à ajouter les options suivantes dans le noyau Linux :

Device Drivers --->
-----USB Support --->
----------USB Serial Converter support --->
--------------- USB FTDI Single Port Serial Driver
--------------- USB Prolific 2303 Single Port Serial Driver

Si pl2303 est bien chargé automatiquement au démarrage, ce n’est pas le cas de ftdi_sio. La déclaration de ftdi_sio  dans /etc/modules permet de résoudre ce problème. J’ai aussi créé un lien symbolique /dev/wavecom vers le périphérique USB adéquat (/dev/ttyUSB0 chez moi) grâce à udev.

Enfin, le fichier de configuration de gnokii (/etc/xdg/gnokii/config sur Debian) est mis à jour de la manière suivante :

[global]
port = /dev/wavecom
model = AT
initlength = default
connection = serial
use_locking = yes
serial_baudrate = 9600

Les préparatifs sont terminés, place à l’action. On commence par tester que le lien avec le modem est fonctionnel, grâce à une commande qui retourne les principales informations liées au modem.

Modem reconnu par gnokii, numéro IMEI générique.

Modem reconnu par gnokii, numéro IMEI générique.

Détail intéressant n°3, le modem est livré avec un numéro IMEI non programmé, c’est à l’utilisateur de le faire au moyen d’une commande AT (vraisemblablement irréversible une fois effectué). Le numéro par défaut est 012345678901234. Je n’ai pas testé l’écriture d’un numéro IMEI à l’heure où j’écris ces lignes, l’envoi de SMS fonctionne très bien sans cela. Je ne pourrais que conseiller d’être prudent avec cette fonction, il serait en effet dommage d’entrer un IMEI au hasard bloqué par les opérateurs (par exemple suite à un vol de mobile). Si je devais le faire, j’utiliserais un IMEI issu d’un vieux téléphone mobile qui traine dans mes cartons, par exemple le Nokia 3310 qui m’a servi lors des tests précédents.

Avant de tenter un envoi, on prendra soin de débloquer la carte SIM en saisissant le code PIN. L’exemple suivant montre comment effectuer l’opération :

dhalsim:/# gnokii --identify
gnokiid Version 0.6.30
IMEI         : 012345678901234
Fabricant: WAVECOM MODEM
Aucune section flags dans le fichier de configuration.
Modele       : MULTIBAND  900E  1800
Nom du produit : MULTIBAND  900E  1800
Revision     : 532a09gg.2C2 182812
dhalsim:/# gnokii --getsecuritycodestatus
gnokiid Version 0.6.30
Etat du code de securite: en attente du code PIN.
dhalsim:/# gnokii --entersecuritycode PIN
gnokiid Version 0.6.30
Entrez votre code:
Code ok.
dhalsim:/# gnokii --getsecuritycodestatus
gnokiid Version 0.6.30
Etat du code de securite: rien a entrer.

On peut ensuite tester l’envoi de SMS en bonne et due forme. Pour commencer, un envoi d’un message long avec divers caractères accentués (NB : l’encodage de caractères des paramètres régionaux de ma session est l’UTF-8). Gnokii m’informe que le message a bien été envoyé en 2 parties.

Envoi d'un message avec caractères accentués par gnokii.

Envoi d’un message avec caractères accentués par gnokii.

Dans la foulée, j’en profite pour tester l’envoi de caractères un peu plus exotiques, directement depuis le shell. Celui-ci est bien envoyé également.

Envoi d'un message avec caractères chinois par gnokii.

Envoi d’un message avec caractères chinois par gnokii.

Attention toutefois, chaque idéogramme compte pour plus d’un caractère, on peut donc vite dépasser la limite du sous-message à 160 caractères en envoyant n’importe quoi. Pour ma part, bien que cela soit prévu par la norme GSM j’ai réussi à bloquer gnokii en tentant d’envoyer « 短信猫驱动与配套软件及安装说明书 ». Je n’ai pas cherché qui de gnokii ou du modem était en faute, ce genre de message n’étant pas représentatif des communications que je compte automatiser. J’aime simplement connaître les limites des systèmes que j’utilise. J’espère juste qu’un modem chinois est capable d’envoyer des message en chinois, sinon, le monde est mal barré.

Les messages correctement traités par gnokii ont bien été reçus sur le Nokia C7, avec un bémol sur le message en chinois : le mobile repère bien 4 caractères correspondant à mes 4 idéogrammes, mais ne les affiche pas. Je présume qu’il n’embarque pas la police de caractère adéquate. Décidément, Nokia, ce n’est plus ce que c’était.

Les messages envoyés par le shell sont reçus sur le mobile, et plus ou moins bien affichés en fonction du jeu de caractères constituant chacun d'entre eux.

Les messages envoyés par le shell sont reçus sur le mobile, et plus ou moins bien affichés en fonction du jeu de caractères constituant chacun d’entre eux.

La photo ci-dessus fait également apparaitre un message « Test réception SMS », que j’ai moi-même écrit à partir du mobile et envoyé au numéro de téléphone correspondant à la carte SIM à l’intérieur du modem. Le but de l’opération étant cette fois-ci de tester la réception et la récupération de messages à partir du shell. Une fois encore, c’est gnokii qui s’occupe de cette tâche. La commande permet d’afficher tous les messages enregistrés dans la boîte de réception de la carte SIM. Le message envoyé à partir de mon mobile est bien visible (tout en bas).

Dépilage des messages stockés dans la carte SIM.

Dépilage des messages stockés dans la carte SIM.

Au fait, ne vous en faîtes pas pour les impayés dont il est question dans la capture d’écran ci-dessus, le message bien qu’alarmant a été envoyé par erreur par B&You à un grand nombre de ses clients parfaitement en règle avec leurs échéances de paiement. Les malencontreuses erreurs de fonctionnement que l’on rencontre au début quand on est un nouvel opérateur sur le marché, j’imagine…

Voila pour l’instant, les résultats de ces test sont très satisfaisants. Bien sûr, il reste encore à mettre en place une architecture proposant les interfaces d’envoi et de réception à n’importe quel script ou process présent sur le système, en passant par une base de données par exemple.

C’est là qu’intervient gnokii-smsd. Mais cela sera relaté dans un article futur.

 SMS automatisé – Round one, fight !

 16 janvier 2013  Domotique  12 commentaires

S’il existe une fonctionnalité que je souhaite mettre en place depuis bien longtemps autour de mon serveur sans me ruiner, c’est la possibilité de pouvoir envoyer de manière automatisée des SMS de notifications aux numéros de mon choix. Et accessoirement, de pouvoir en recevoir aussi.

Cela ouvre en effet un large éventail de possibilités supplémentaires : couplage avec le système domotique, diversification des moyens de notification, diversification des moyens de déclenchement d’actions, ou pourquoi pas moyens complémentaires de validation d’une session, comme le font la plupart des banques à l’heure actuelle lorsqu’un particulier demande une transaction d’une certaine importance.

Il y a quelques mois, ceci n’aurait été réalisable pour un montant raisonnable à faible volumétrie, lorsqu’on table comme moi sur une vingtaine de SMS par an à tout casser, qu’en passant par des API développées par des prestataires tiers, du type smsbox.net. Mais pour ma part, j’aime l’idée de garder le contrôle de mon architecture amateur sur le plus grand périmètre possible, et ce type de service facture une valeur ajoutée par rapport au coût du SMS simple que je souhaite pouvoir économiser. Avec l’arrivée l’an dernier de l’opérateur béni des dieux Free Mobile sur le marché, les opérateurs de téléphonie mobile ont tous subitement attrapé « comme par hasard » la fièvre humaniste/altruiste et ont décidé à la quasi-unanimité de revoir à la baisse leurs tarifs exorbitants. D’autres encore se sont diversifiés, à l’instar de B&You, proposant une carte pré-payée sans durée limite de validité, pour peu que le client s’affranchisse d’au moins un acte tarifé (communication, SMS, data…) par an.

C’est cette nouvelle offre qui m’a fait sauter le pas, à 5 centimes par an le coût d’envoi du SMS de ping permettant de maintenir la ligne, il serait dommage de se priver.

Avant d’investir dans du matériel plus évolué, j’ai tout d’abord cherché à réutiliser ce qui trainait dans mes vieilles affaires. Pour cette maquette, j’ai donc utilisé :

  • Un serveur Linux, dans mon cas un clone de ma Debian sur VM, qui fera office de machine d’émission de SMS.
  • Un téléphone quelconque avec une carte SIM valide, dans mon cas mon Nokia C7-00 (ne vous moquez pas S.V.P, je n’ai pas les moyens de claquer ma fortune dans un Galaxy S3), qui sera l’appareil destiné à la réception.
  • Un vieux Nokia 3310 de récup’, le téléphone star que les moins de vingt ans ne peuvent pas connaitre, qui faisait de vous à l’époque le personnage le plus hype des utilisateurs de mobile, car on pouvait jouer à Snake et composer ses propres sonneries (moi j’avais composé Ecuador de Sash! et pour ça j’inspirais le respect à mes semblables).
  • Une carte SIM B&You, 4.99€, réglée avec Eurocard Mastercard.
  • Un câble de communication 3310 USB, 5€ sur eBay, réglé avec Eurocard Mastercard.
  • Le plaisir de monter sa propre plate-forme d’envoi de SMS, ça n’a pas de prix.

Pour commencer, on insère la carte SIM B&You dans le mobile et on connecte le câble de communication sur celui-ci. Notez que comme il s’agit d’un modèle du début des années 2000, époque où les téléphones mobiles étaient relativement peu conçus pour permettre à leurs utilisateurs de les connecter avec du matériel informatique, il faut démonter la partie arrière de la coque pour pouvoir brancher le câble de comm’.

Nokia 3310 avec carte SIM B&You et data cable

Nokia 3310 avec carte SIM B&You et data cable

On branche ensuite l’autre extrémité du câble sur le port USB du serveur, la VM pour moi dans le cadre de cette maquette. On allume le mobile et on le déverrouille en entrant le code PIN. On en profite pour changer le logo par défaut, parce que ça permet de se la péter quand on poste la photo sur un blog de geek.

Le soft utilisé pour le logo : LogoManager sous Windows. Oui, ça ne sert à rien, et alors ?

Le soft utilisé pour le logo : LogoManager sous Windows. Oui, ça ne sert à rien, et alors ?

Le câble est basé sur un chip PL2303, qui est automatiquement reconnu par le système pour peu qu’on ait embarqué le support pl2303 dans le kernel ou en tant que module.

dhalsim:/$ lsusb
Bus 003 Device 002: ID 067b:2303 Prolific Technology, Inc. PL2303 Serial Port
Bus 003 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 002 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 004 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 005 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub

Ensuite la magie opère grâce à gnokii, un soft en ligne de commande spécialisé dans la communication FBUS utilisée par les vieux Nokia, mais qui peut aussi communiquer en commandes AT comme le font la plupart des téléphones actuels. Le wiki de gnokki indique que le 3310 utilise le driver Nk6100, ce que j’indique dans le fichier de configuration en même temps que le device sur lequel le câble data USB est connecté. J’ai modifié uniquement 3 lignes du fichier de configuration par défaut :

[global]
model = 6110
port = /dev/ttyS0
connection = serial

On demande à gnokii d’envoyer un SMS de test, grâce à une commande simplissime. Par sécurité, j’ai indiqué le n° destination au format international. J’imagine que l’utilisation des n° au format national est possible aussi.

dhalsim-session-gnokii

On admire enfin la réception du SMS sur le mobile destinataire. On peut alors savourer la victoire avec un bon Dry Martini comme le ferait James Bond après une mission accomplie avec classe.

You win! Perfect!

You win! Perfect!

Voila, c’est tout simple ! J’ai fait une mini-vidéo du processus complet d’envoi-réception, dans laquelle j’envoie simplement la date et l’heure système par SMS, au lieu du message de test ci-dessus. C’est un peu flou, filmé et monté à l’arrache, et il a fallu compresser à outrance pour conserver un fichier de taille raisonnable, mais il faut savoir que je subis des pressions fortes d’une partie de mon entourage professionnel et en même temps unique lectorat pour que je mette en ligne l’article accompagné de la vidéo sans attendre les calendes grecques. Ces gens s’acharnent sur la touche F5 de leur clavier toutes les 10 secondes, me mettant par effet de bord sous la menace d’une attaque DDOS, je ne peux me permettre de ruiner leur productivité plus longtemps 🙂

Prochaine étape de ce projet : seconde maquette avec l’utilisation d’un « vrai » modem GSM et des commandes AT. À moins qu’une connerie ne vienne s’intercaler dans le programme…

 Youba : release du back-end pour robot Youpi

 8 août 2011  Bricolage  54 commentaires
Le workbench pour tester le back-end Youba

Youba Logo

Une bonne nouvelle pour ceux qui attendaient désespérément un outil pour contrôler leur robot Youpi : je me suis botté le cul ces derniers jours, j’ai pu terminer la réalisation de mon back-end, le tester avec le robot, et même apprécier le résultat en générant un scénario de mouvements pour le robot en quelques secondes !

Le nom de cette merveille : Youba (pour YOUpi BAck-end), un petit programme de 500 lignes écrit en Python. Pour rappel, ce programme a été réalisé dans le contexte suivant :

  • Indépendance du front-end : le programme se contente d’attente ses ordres sur un port TCP. Les instructions en questions peuvent être envoyées par n’importe quel front-end (un terminal, un script, une page web, un programme analysant les commandes d’un joystick, tout ce que vous voulez).
  • Bufferisation : les ordres peuvent être envoyés en temps réel ou à l’avance.
  • Portabilité : au moins dans la mesure du possible. 99% du code est indépendant de la plate forme. Les 1% restants concernent l’envoi de données sur le port parallèle, que je n’ai pas su réaliser de manière totalement portable à l’heure actuelle. Les systèmes Linux et Windows sont supportés.
Le workbench pour tester le back-end Youba

Mon plan de travail : un PC, le robot, le câble de connexion adéquat, et un objet à saisir.

Le plan de travail qui m’a permis de valider mes tests se présente comme ceci : un PC avec une distrib Linux (Linux Mint dans ce cas), le robot, le câble de connexion parallèle fabriqué lors des étapes précédentes, et le tube en plastique d’un médicament générique quelconque préalablement lesté avec des contrepoids de touches de piano (j’ai pris ce que j’avais sous la main). Sur le PC, deux terminaux sont ouverts : à gauche le programme Youba qui écoute sur son socket et à droite le terminal d’envoi des instructions par netcat.

Les résultats des tests ont été au delà de mes espérances :

  • Fonctionnellement, le back-end rempli correctement son rôle, enquille les ordres et envoie leur traduction au robot.
  • Le mouvement sur plusieurs axes en simultané est possible. Cela peut paraitre anodin mais ce n’était pas forcément évident à concevoir.
  • Les mouvements sur chaque axe sont réalisés à une vitesse plutôt raisonnable. J’avais peur que le robot soit trop lent à réagir après avoir constaté des problèmes de mise en sommeil trop longue lors des essais avec mon programme Robotest. J’ai quand même réussi à minorer ce problème en revoyant complètement la gestion des intervalles d’envoi d’octets sur le port parallèle.
  • La précision sur les axes est au rendez-vous, et la pince dispose de suffisamment de pression pour tenir des objets cylindriques.

Et enfin, l’utilisation du back-end, grâce à la commande « I!! » qui affiche l’état des compteurs de demi-pas, permet de « cartographier » les déplacements sur chaque axe de manière très précise et d’utiliser ces informations pour scripter des scénarios très rapidement, dès qu’on connait un minimum la syntaxe attendue. J’ai réalisé le mien en moins de 5 minutes, c’est celui que j’utilise dans mon terminal de droite. Voici le script utilisé pour ordonner au robot de chopper mon tube cylindrique et de le déposer quelques centimètres plus loin :

#!/bin/bash
function sendyoupi {
	echo "$1" | nc localhost 12080
}

# Positionner le bras au-dessus du tube
sendyoupi 'C!W!0,R,H,750,1|1,L,H,999,1|2,R,H,4332,1|3,L,H,7334,1|5,R,H,2000,1'
# Serrer la pince
sendyoupi 'A!W!5,L,D,80,1'
# Lever le bras
sendyoupi 'A!W!1,R,D,30,1'
# Tourner la base de 60°
sendyoupi 'A!W!0,L,D,60,1'
# Baisser le bras
sendyoupi 'A!W!1,L,D,30,1'
# Desserrer la pince
sendyoupi 'A!W!5,R,D,80,1'
# Revenir en position de départ
sendyoupi 'A!W!A,I,S,1,1'

Et le résultat du script en images :

Attention, quelques conseils pour ceux qui souhaitent utiliser Youba :

Avant tout, il y a un fichier README.txt à la racine du projet. Si je me suis cassé la tête à l’écrire, c’est qu’il contient des tas d’informations intéressantes à respecter pour que tout puisse fonctionner. Donc, lisez-le. Vérifiez en particulier que le port parallèle est activé dans le BIOS, de préférence en mode EPP, que son driver est bien chargé par le système d’exploitation, et que vous avez correctement configuré son n° d’I/O dans le fichier de configuration. Si le robot ne répond pas aux ordres donnés, lancez Robotest (disponible en page de téléchargements) pour vous assurer que la partie matérielle fonctionne à minima. D’autre part, je n’ai pas eu l’occasion de tester l’intégralité du programme avec Windows (les 50% des 1% qui ne sont pas portables), j’ai bon espoir que cela fonctionne mais on ne sait jamais. Enfin, je rappelle que je ne réponds en général pas aux questions par mail car je préfère qu’elles soient abordées en commentaires afin que tous les intéressés puissent avoir accès aux réponses.

Voila, il est maintenant temps de dévoiler où il est possible de télécharger Youba : c’est sur la page de téléchargements !

Une dernière chose : je serai content de savoir si vous utilisez ce back-end, ce que vous en pensez, quel front-end vous utilisez, et surtout si vous avez de bonnes idées quand à l’utilisation du robot Youpi.

 Backend Youpi :: documentation

 18 juillet 2010  Bricolage  12 commentaires
Diagramme de commandes

Ceux qui ont déjà fait un peu de code savent à quel point il peut être tentant de se lancer tête baissée dans un développement sans avoir pris le temps de réfléchir un minium au préalable. Et à quel point cela peut s’avérer une fausse bonne idée lorsque le développement est démarré depuis longtemps et qu’il faut reconsidérer la moitié de l’implémentation à cause d’une erreur de conception.

Pour une fois, j’ai décidé de suivre la voie de la sagesse, si l’on peut dire, en choisissant de poser avec soin les bases de la communication avec le futur backend du robot Youpi, et de ne pas commencer à coder à la hâte.

Je dévoile donc dans la suite de cet article le draft de communication frontend-backend imaginé ce week-end pendant quelques moments perdus. Il permet déjà d’avoir un bon aperçu de la manière d’implémenter ces exigences dans le code.

Pour ceux qui auraient tendance à trouver ce formatage quelque peu indigeste (et je les comprends), une version RTF avec quelques couleurs est disponible ici : Youpi backend instruction manual (RTF).

Title: Youpi backend instruction manual
Author: AlphaK - www.alphak.net
Revision: 2011-08-01
Status: Draft
.
>
> GLOSSARY
>
.
An instruction is an order for a motor to start or stop a rotation.
.
An instructionSet is a set of instructions executed simultaneously.
.
An instructionChain is a set of instructionSets executed sequentially.
.
An instructionChainModifier is a request to the backend for the modification of the current instructionChain.
.
A specialAction is a request to the backend not related to the rotation of a motor.
.
A command is a set of printable characters sent to the backend to order an instructionChainModifier or a specialAction.
.
>
> SYNOPSIS
>
.
command
(instructionChainModifier|specialAction)\n
A command contains exactly one instructionChainModifier or one specialAction, and ends with a carriage return character (byte 0x0A, symbolized with \n in this document for readability).
.
specialAction
(I|C|R)!!
A specialAction contains exactly one of the I, C, R characters and ends with a double exclamation mark.
I: Information request - Asks the backend to report for each motor the number of half-steps executed since the beginning of the program or the last half-step counter reset.
C: Counter restet - Asks the backend to reset half-step counter.
R: Re-init - Asks the backend to send the re-init instruction to the robot.
.
instructionChainModifier
[action!waitMode!]instructionSet
An instructionChainModifier contains an action, a waitMode parameter, and an instructionSet, separated by exclamation marks. action and waitMode are optional; instructionChainModifier defaults to C!W!instructionSet when not provided by the frontend.
.
action
C|A|M
An action contains exactly one of the C, A, M characters.
C: Cancel - The current and all the following instructionSet in the instructionChain are cancelled, and the instructionChain starts executing the provided instructionSet.
A: Append - The provided instructionSet is appended at the end of the instructionChain.
M: Merge - The current instructionSet in the instructionChain is merged with the provided instructionSet. Remaining instructionSets in the instructionChain are not altered. If the provided instructionSet contains instructions related to a motor for which there is no instruction in the current instructionSet, provided instructions are added to the current instructionSet. If the provided instructionSet contains instructions related to a motor for which there is already an instruction in the current instructionSet, current instructions are cancelled and replaced by provided instructions.
.
waitMode
W|N|D
A waitMode contains exactly one of the W, N, D characters.
W: Wait - Sets the instructionSet in wait mode. In that mode, the backend waits the end of all instructions of the instructionSet to consider the last is over and to execute next instructionSet. If the ordered action is M, the waitMode of the current instructionSet is replaced by the waitMode of the provided instructionSet.
N: Nowait - Sets the instructionSet in nowait mode. In that mode, the backend considers the instructionSet as over as soon as the first instruction has ended. If the ordered action is M, the waitMode of the current instructionSet is replaced by the waitMode of the provided instructionSet.
D: Default - If the ordered action is C or A, waitMode D defaults to W. If the ordered action is M, waitMode D does not modify the waitMode of the current instructionSet.
.
instructionSet
instruction[|instruction...]
An instructionSet contains one or more instructions. Each instruction is separated by a pipe character. If an instructionSet contains several instructions related to the same motor, the instructionSet is considered invalid.
.
instruction
motor,rotation,unit,value,period
An instruction contains exactly 5 parameters given in an invariable order and separated by a comma.
.
motor
0|1|2|3|4|5|A
A motor contains exactly one of the 0, 1, 2, 3 4, 5, A characters. The provided character is related to a motor of the robot.
0: Base motor
1: Shoulder motor
2: Elbow motor
3: Wrist motor
4: Hand motor
5: Plier motor
A: All motors
.
rotation
L|R|N|I
A rotation contains exactly one of the L, R, N, I characters. The provided character is related to a rotation order.
L: Left rotation
R: Right rotation
N: No operation. Asks the motor to stop.
I: Back to Initial state, order motors to rotate back to their initial position according to motor counters. USE WITH CAUTION!
.
unit
H|D|S|U
A unit contains exactly one of the H, D, T, U characters. The provided character is related to a unit order. If rotation is I, unit must be U.
H: Half-step - Provided value represents half-steps, or steps for plier motor.
D: Degrees - Provided value represents degrees. Not relevant for plier motor.
S: Seconds - Provided value represents seconds.
U: Unlimited - Ordered rotation has no limit. USE WITH CAUTION!
.
value
Float value, greater or equal than zero. Decimal separator is a dot '.'.
The value is provided according to the provided unit. If unit is U, value must be 0. As there is no physical or logical limits on the robot to ensure the motor does not exceed the maximum rotation angle, the frontend must ensure that provided values and unit will not damage the robot.
.
period
Float value, greater or equal than one. Decimal separator is a dot '.'.
The period affects the rotation speed for each motor. Default period is 1 and represents the maximum motor speed. The provided period is proportional to the interval of low-level orders sent to the same motor. For instance a provided period of 2 will make the motor rotate twice as slow as the maximum speed.
.
>
> EXAMPLES
>
.
Cancel all orders and asks the base motor to rotate left over 40° at maximum speed:
C!W!0,L,D,40,1\n
.
Appends the order for the shoulder motor to rotate right during 5.2 seconds with 1/3 of maximum speed:
A!W!1,R,S,5.2,3\n
.
Immediately cancel all orders, asks all motors to stop for an unlimited duration:
C!W!A,N,U,0,1\n
.
Cancel all orders and asks elbow and wrist motors to rotate simultaneously 150 half-steps each:
C!W!2,R,H,150,1|3,L,H,150,1\n
.
Adds the order for the base motor to rotate 600 half-steps at half speed meanwhile other motors are already rotating:
M!D!0,L,H,600,2\n
.
Puts back base motor into initial position at 1/4 speed:
C!W!0,I,U,0,4\n
.

Quelques explications supplémentaires en plus du pavé ci-dessus :

Le backend s’attend à recevoir une commande par ligne. Une commande permet de mettre en mouvement ou arrêter un seul ou plusieurs moteurs. Grâce aux différents en-têtes des instructionChainModifiers, le robot sera pilotable en mode temps réel (interactions directes avec l’utilisateur via le frontend), ou scripté (une floppée de commandes fournie au démarrage ou graduellement, et le robot exécute le tout). J’ai également prévu un léger reporting afin que l’utilisateur puisse connaitre la position de chaque moteur depuis une origine et ainsi établir plus facilement ses commandes si un pilotage scripté est désiré.

Le diagramme suivant permet d’avoir un meilleur aperçu des possibilités théoriques du backend. Chaque ligne correspond à un moteur. En abscisses, le temps. Chaque subdivision correspond à une seconde. Une barre horizontale bleue située sur une ligne indique la rotation du moteur correspondant. En bleu figurent également les commandes, ainsi que le moment où elles sont envoyées au backend. Les instructionSets qui composent l’instructionChain sont encadrés en rouge.

Diagramme de commandes

Diagramme de commandes

Voila l’état d’avancement actuel. Il s’agit de ce que je considère actuellement comme un ensemble « idéal » de fonctionnalités. Ces exigences sont encore à l’état de draft et pourront évoluer dans le futur en fonction des différents commentaires et remarques. Pour ce qui est de l’implémentation, j’imagine que ça se fera par étapes en fonctions des priorités.

 Youpi, testons les moteurs !

 30 décembre 2009  Bricolage  21 commentaires

J’avais longuement expliqué dans cet article les étapes de fabrication d’un câble parallèle pour relier le robot Youpi à un PC standard.

Aujourd’hui je vais comme promis diffuser les quelques lignes de code permettant de tester l’ensemble des moteurs. Le programme est grandement inspiré de celui que l’on peut trouver sur le site du BTS-IRIS de Niort.

C’est un programme développé à la va-vite en C. Il pourra servir de base pour tous ceux qui comme moi souhaitent vérifier que tous les moteurs sont en bon état de fonctionnement. (suite…)