J'expérimente ici l'impression d'images avec des imprimantes de tickets sur papier thermique.
Ces imprimantes de tickets sont très répandues et je crois, assez faciles à trouver en récupération. Epson, qui en a fabriqué et en fabrique encore beaucoup, a développé un langage pour les piloter : l'ESC/POS. Ce langage ou protocole est devenu standard pour le contrôle des appareils de ce type, qu'ils soient de la marque Epson ou d'une autre.
L'usage habituel de ces imprimantes reste l'impression rapide de caractères. L'essentiel du langage ESC/POS traite des questions de texte et layout de texte. Cependant, quelques fonctions sont prévues pour l'impression d'images. Pour des logos par exemple.
Le principe du procédé d'impression repose sur l'emploi d'un "papier thermique" qui noircit lorsque qu'il est porté à une certaine température (le papier n'est pas "brûlé", c'est une réaction chimique). Il n'y a pas de contrôle du niveau de gris. Le pixel sera soit noir soit blanc (1 bit d'information par pixel, donc).
La tête d'impression est constituée d'une barette de petites éléments chauffants très finement alignés. Ces petites résistances chauffent ou pas le papier en coordination avec le défilement du papier pour le faire noircir là où il le faut.
Pour donner une idée, sur l'imprimante que je possède, une TM-82, la barrette porte 512 éléments chauffants, sur 72 mm de longueur, ce qui donne une résolution selon l'axe de la barette de 180 dpi (= 7 pixel par mm).
Ces machines sont pilotées par ordinateur via le port série. Les commandes sont donc des séries de valeurs binaires spécifiques à chaque commande, assorties ou pas d'une "charge utile" telle que le texte ou l'image.
La documentation de ce langage est assez longue, il y a de nombreuses commandes et de nombreuses variantes spécifiques à telle ou telle série d'appareils.
Il peut s'agir également de commandes de configuration ou d'administration, de commande pour actionner le cutter et détacher le ticket, etc.
Dans mon projet j'ai implémenté plusieurs commandes :
Pour les commandes d'impression bitmap, la machine s'attend à recevoir les données de l'image dans un certain ordre (sachant qu'un octet code 8 pixels). La documentation décrit les choses de manière très sommaire. J'ai du beaucoup essayer avant de comprendre comment il fallait packer ces pixels. L'image tout en haut de cette page montre d'ailleurs un exemple de "données pixels mal rangées" !
Il existe des câbles/convertisseur tout faits. Il m'est arrivé d'en utiliser avec succès. mais je souhaitais faire ça moi-même avec un Arduino.
Le RS-232 et l'USB ne fonctionnent pas avec les mêmes tensions (jusqu'à ±25V pour le premier, +5V pour l'autre). Il faut donc intercaler une interface de conversion de niveaux bidirectionnelle entre l'Arduino et l'imprimante dont voici un schéma. Le circuit est assez malin pour ne pas nécessiter d'alimentation autre que le 5v provenant de l'Arduino, et pourtant être capable de générer des signaux 12V.
Les machines que j'ai pu approcher étaient toutes équipées d'un connecteur 25 broches DB-25 mais nous n'avons besoin que de 3 broches : la transmission (TX), la réception (RX), et la masse (GND).
Dans mon système, l'Arduino ne sert finalement presque à rien, il "passe les plats", les commandes série étant écrites et envoyées depuis la page de contrôle. L'arduino ne fait que les recevoir et les renvoyer telles qu'elles.
Il est entendu qu'on ne cherche pas ici la haute définition :-)
Le fait que les pixels ne peuvent être que noir ou blanc interdit d'imprimer directement en niveaux de gris. Si on ne fait rien, l'image sera imprimée selon un seuil, ce qui est généralement peu satisfaisant, surtout avec ce procédé dont la qualité des applats noirs laisse franchement à désirer.
On peut contourner cette limitation avec un algorithme de traitement d'image préalable comme celui de Floyd-Steinberg ou autre algorithme de "diffusion d'erreur". Après traitement, l'image ne sera plus constituée de pixels niveaux de gris mais de pixels noirs et blancs.
Les niveau de gris seront néanmoins bien rendus localement, grâce à la distribution statistique des points zone par zone. Le prix de cela est une certaine perte de définition (mais les résultats sont tellement meilleurs qu'avec le rendu "seuil" que cela n'est pas gênant).
Mon application permet l'impression en matrice. Voici un exemple format d'environ 50x60 cm, imprimé en un quart d'heure (6x8 carrés imprimés).
Pour accéder à la page, cliquer ici.
Je ne vais pas rentrer dans les détails de l'implémentation, simplement dire qu'elle est pourvue de quelques facilités pour l'image et le texte, et qu'il s'agit d'un application servie avec node.js.