Cette semaine, on a décidé de construire un petit gadget qui va sans aucun doute changer le cours de votre existence. Il s'agit d'un petit cube capable de vous imprimer une blague "Chuck Norris" différente à chaque fois que vous appuyez sur un bouton. Vous pourrez même l'emmener partout avec vous: il fonctionne sans fil.
Un cube magique qui imprime des blagues Chuck Norris, ça vous dit ?
Le principe
L'idée est d'utiliser une minuscule imprimante thermique. Ce modèle se pilote via une interface série TTL et peut fonctionner en 5V. Un Yocto-Serial est donc un outil idéal pour piloter cette imprimante.
Cette minuscule imprimante peut être pilotée à l'aide d'un Yocto-Serial
Le cœur du système est un YoctoHub-Wireless-SR piloté depuis un script PHP grâce à l'API callback. On a choisi le modèle SR pour des raisons esthétiques: pas d'antenne qui dépasse. L'alimentation est assurée par 4 cellules NiMH. Afin de faire durer l'accu le plus longtemps possible, le cube reste en sommeil la majeur partie du temps. Il peut être réveillé sur pression d'un bouton relié à un Yocto-Knob. Finalement, un Yocto-Color indique l'état du cube.
La gestion d'énergie
La seule partie un peu subtile est la gestion d'énergie: on voulait que le cube puisse fonctionner sur piles. On a donc utilisé le système de mise en sommeil du hub. En effet, le YoctoHub-Wireless-SR est capable de s'éteindre tout seul et de se rallumer à intervalle régulier ou encore à la fermeture d'un contact. C'est ce contact qu'on va utiliser pour réveiller le hub quand l'utilisateur presse sur le bouton.
Le YoctoHub-Wireless peut être sorti de son sommeil en fermant un contact.
Interface utilisateur minimale
On voulait une interface utilisateur intuitive et minimaliste: pas question d'avoir un bouton pour allumer le cube et un second pour faire sortir la blague. Cependant, du point de vue l'API Yoctopuce, il n'est pas possible connaître en permanence l'état du contact qui sert à éveiller le hub. On ne peut donc pas l'utiliser pour savoir si l’utilisateur a ré-appuyé sur le bouton du cube une fois le hub éveillé. C'est pourquoi on a aussi besoin d'un Yocto-Knob pour surveiller l'état du bouton. Et c'est là que réside la vraie subtilité de ce bricolage: on aurait logiquement besoin d'un bouton poussoir bi-polaire (DPST) pour actionner en même temps le contact de réveil du hub et une entrée du Yocto-Knob. Seulement voilà, il semble qu'il soit très difficile de se procurer ce genre de bouton: on n'a pas réussi à un trouver un dans le délai imparti pour finir ce projet. C'est pourquoi, on a plutôt utilisé un bouton poussoir unipolaire mais qui fait aussi commutateur (SPDT). Le Yocto-Knob n'étant pas un module isolé, il partage la même masse que le YoctoHub-Wireless-SR. Il nous suffit donc mettre alternativement à la masse le contact du réveil du hub, et l'entrée du Yocto-Knob.
Comment réveiller le hub et agir sur le Yocto-Knob avec un seul bouton poussoir
Donc, appuyer sur le bouton va allumer le hub qui va immédiatement faire un callback PHP ce qui va prendre quelques secondes. Pour que l'utilisateur se rende compte que le cube s'est bien allumé, on utilise un Yocto-Color configuré pour s'allumer en bleu à la mise sous tension, le callback changera la couleur en vert pour indiquer que tout se passe bien. Comme le bouton du cube est aussi relié à un Yocto-Knob, une fois le cube allumé chaque pression supplémentaire va provoquer un nouveau callback.
L'électronique du cube, évidement on va utiliser des câbles 1.27mm plutôt que des cables USB
Réalisation
Le hardware
On a construit le cube en verre acrylique, il est constitué d'un châssis transparent avec des inserts filetés pour visser les différent modules. Le tout est recouvert de plaques en plexi noir pour l'aspect esthétique. La construction ne présente pas de difficulté particulière, pour autant que le châssis soit pensé de manière à ce que toutes les vis de montage soient accessibles.
Une structure en plexi, quelques modules et le tour est joué.
Le software
Le soft de contrôle est un simple petit script PHP qui tourne sur un serveur web. La principale difficulté est de gérer le temps de chauffe de l'imprimante. Elle a besoin de chauffer quelques secondes après son initialisation. C'est un problème parce que l'API callback ne permet pas de faire une pause. Pour résoudre ce problème, on utilise module->set/get_userVar() pour stocker dans le Yocto-Serial une variable d'état qui décrit l'heure de mise en chauffe. Cette variable est stockée dans la RAM du module, elle persiste ainsi d'un callback à l'autre, mais s'efface dès que le système est mis hors tension. Dès la mise en chauffe, on diminue le délai entre deux callback à 1 seconde pour plus de réactivité et pendant le temps de chauffe, le script fait clignoter le Yocto-Color en vert histoire de faire patienter l'utilisateur.
Par défaut, l'imprimante est configurée pour imprimer le plus vite possible ce qui consomme plus de courant que ce que le système ne peut en fournir. Configurer l'imprimante pour qu'elle imprime plus lentement règle le problème.
$button = YFindAnButton("PrintBtn");
$m = $serial->get_module();
$uptime = intVal($m->get_upTime() / 1000);
$stateVar = $m->get_userVar();
if ($stateVar<=0) // not warm yet
{ $stateVar = $uptime ;
$serial->writeHex('1B40'); // printer init
$serial->writeHex('1B3704FFA0'); // config for low consumption
$led1->resetBlinkSeq(); // makes the leds blink
$led2->resetBlinkSeq();
$led1->addRgbMoveToBlinkSeq(0x000000, 0);
$led1->addRgbMoveToBlinkSeq(0x000000, 250);
$led1->addRgbMoveToBlinkSeq(0x00FF00, 0);
$led1->addRgbMoveToBlinkSeq(0x00FF00, 250);
$led2->addRgbMoveToBlinkSeq(0x000000, 0);
$led2->addRgbMoveToBlinkSeq(0x000000, 250);
$led2->addRgbMoveToBlinkSeq(0x00FF00, 0);
$led2->addRgbMoveToBlinkSeq(0x00FF00, 250);
$led1->startBlinkSeq();
$led2->startBlinkSeq();
$m->set_userVar($stateVar); // save state
$network->set_callbackMinDelay(1); // more reactivity
die("waiting for printer to warm up");
}
$warmupduration = $uptime - $stateVar;
if ($warmupduration<6) // still not warm enough
{ die("still waiting for printer to warm up");
}
Note: Il est probablement possible d'optimiser le temps de chauffe en définissant un job dans le Yocto-Serial qui pourrait ainsi initialiser l'imprimante dès la mise sous tension. Ainsi le préchauffage et la connexion au réseau WiFi seraient effectués en parallèle.
Dès que l'imprimante est prête, Le script télécharge une blague depuis le site Internet Chuck Norris Database, et l'imprime avec la date du jour. La gestion de l'impression en elle-même est triviale: il suffit d'envoyer le texte à imprimer sur le port série. Des escape codes permettent de gérer la mise en page.
{ $button->resetCounter();
// download a Chuck Norris joke.
$joke="**CANNOT CONNECT TO api.icndb.com**";
$json = file_get_contents('http://api.icndb.com/jokes/random/');
if (!($json===false))
{ $data = json_decode($json);
$joke = html_entity_decode($data->value->joke);
}
$serial->writeLine(''); // let's print
$serial->writeHex('1B2139'); // bold, dbl width, double line
$serial->writeHex('1B6149'); // centered
date_default_timezone_set('Europe/Paris');
$serial->writeLine(date('j M')); // date
$serial->writeHex('1B2100'); // regular text
$serial->writeLine(date('l')); // day
$serial->writeHex('1B6148'); // regular alignment
$serial->writeLine('');
$serial->writeLine($joke); // Chuck Norris power !
$serial->writeLine('');
$serial->writeLine('');
$serial->writeLine('');
} else print("No print needed");
$led1->set_rgbColor(0x0000FF, 0); // leds back to blue
$led2->set_rgbColor(0x0000FF, 0);
$network->set_callbackMinDelay(10); // a more reasonable callback delay
$wakeUpMonitor= yFirstWakeUpMonitor(); // back to sleep
if ($wakeUpMonitor->isOnline()) $wakeUpMonitor->sleep(9);
Vous remarquerez par ailleurs qu'on utilise le compteur de changement d'état du Yocto-Knob pour savoir si le bouton poussoir a été actionné, parce que, contrairement au get_isPressed(), la valeur de ce compteur persiste d'un callback à l'autre tant qu'elle n'a pas été explicitement remise à zéro.
Et voilà le résultat, rien de tel qu'une petite blague Chuck Norris de temps à autre pour maintenir le moral.
Un distributeur de blagues Chuck Norris, plutôt cool, non?
Conclusion
A l'aide d'une minuscule imprimante à reçus et de quelques modules Yoctopuce, on a construit une mini imprimante sans fil. Contrairement à un modèle traditionnel, elle n'a pas besoin d'un ordinateur local pour fonctionner: elle est pilotée à distance par un site web. Évidement, vous devez vous dire que c'est beaucoup de travail pour quelques blagues qui ne font rire que les nerds. En fait, cette imprimante n'est que la première partie d'un projet plus ambitieux et peut-être moins futile. Mais pour en savoir plus, il faudra revenir la semaine prochaine.