Photobooth : monnayeur, déparasitage et relais

Photobooth : le monnayeur et le relais

Photobooth : la machine à selfies
Photobooth : la machine à selfies

Une soirée à thème très prochainement ? Un mariage se profile dans quelques mois ? Le photobooth est la machine idéale pour animer vos évènements festifs. L’idée est la suivante…

Vous célébrez un évènement avec vos convives dans un espace de convivialité. A l’écart, dans une pièce isolée, le photobooth est disposé autour d’une décoration à thème. Avec les accessoires de déguisement mis à disposition au sein de cet espace intime, les conditions sont ainsi réunies pour favoriser la créativité des protagonistes et les inciter à se mettre en scène. En s’affranchissant du tarif abordable de 0.10€, l’utilisateur de cette machine à « selfies » à l’ancienne repart avec une photo instantanément imprimée sur papier thermique… mais ce n’est pas tout !

Les photos prises par le photobooth seront exportées vers un autre Raspberry chargé de les projeter sur écran afin de partager les clichés (en couleur et haute résolution) avec l’ensemble des convives !

C’est un projet ambitieux mais très enrichissant : les notions impliquées sont denses et les difficultés à surmonter sont assez complexes. Le challenge technique est de taille : de nombreuses lignes de code Python nous attendent alors démarrez le Raspberry et ouvrez le terminal en grand : il va y avoir du pulse sur les GPIOs !

Avant de se lancer, voici un aperçu des photos imprimées :

Photos imprimées sur papier thermique
Photos imprimées sur papier thermique

Eu égard au coût de revient de l’imprimante et du papier thermique, la qualité d’impression est tout à fait acceptable.

Fonctionnement

Afin de percevoir le fonctionnement du photobooth, le tableau ci-dessous fournit une description des différents écrans affichés sur l’écran HDMI au fil de l’utilisation de la machine.

Enchainement des écrans du Photobooth
Enchainement des écrans du Photobooth

Le matériel

Le Photobooth vu de l'intérieur
Le Photobooth vu de l’intérieur

La photo ci-dessus illustre l’agencement des composants à l’intérieur du photobooth. Le matériel à mettre en œuvre est le suivant :

  • Un monnayeur CH-926 ;
  • Un écran LCD 800×480 HDMI ;
  • Un écran LCD HD44780 20×04 avec interface I2C ;
  • Une PiCaméra ;
  • Un ruban CSI ;
  • Une imprimante thermique liaison série ;
  • Un gros bouton ;
  • Un relais ;
  • Une alimentation 5V 10A ;
  • Un convertisseur USB 5V-12V ;
  • Un convertisseur HDMI-VGA ;
  • Des câbles dupont, une multiprise, visserie,…
  • Des pièces imprimées en 3D :
    • Un support pour fixer le Raspberry à l’intérieur du photobooth ;
    • Un support pour loger le module camera en façade.
  • Du bois MDF, des vis, des boulons et des écrous,…

Commençons par le monnayeur.

Le monnayeur

Le modèle utilisé (CH-928) permet de reconnaître jusqu’à 8 pièces différentes. D’après la documentation, le périphérique se base sur le matériau, le poids et la taille de la pièce pour la reconnaître. Avec un taux d’identification annoncé à 99.5%, le monnayeur est a priori précis, précision qui dépendra de l’échantillon utilisé lors de la programmation… Oui, le monnayeur doit « apprendre » à discerner les pièces pour les reconnaître. Cet apprentissage est réalisé en insérant un échantillon de pièces.

Monnayeur CH-928
Monnayeur CH-928

Programmation du monnayeur

Pour configurer les pièces à reconnaître, le monnayeur doit être programmé par un « entrainement » de reconnaissance avec un échantillon d’au moins 15 samples distincts. Par exemple, pour lui apprendre les pièces de 2 euros, il est recommandé d’utiliser 15 pièces de 2 euros différentes.

La programmation du monnayeur est réalisée à l’aide des boutons « Add » et « Minus » et de l’écran LED à deux digits présent sur le monnayeur. Le tableau ci-dessous détaille les paramètres à configurer lors du processus de programmation.

IDPIECESECHANTILLON
(nb pieces)
PULSES
(nb_pulses)
PRECISIONCONVERSION
PULSES-CREDIT €
01 à 8 types de piècesPréco.* : 15 à 30 samplesDe 1 à 50.1 à 30
Préco.** : entre 5 et 10
Opération dans le code Python
10.10 €1517credit = nb_pulses/10
20.20 €1527credit = nb_pulses/10
30.50 €1557credit = nb_pulses/10
41.00 €15107credit = nb_pulses/10
52.00 €15207credit = nb_pulses/10
* La quantité de pièces de chaque type influe sur la précision du monnayeur
** La précision 1 est la plus précise

L’échantillon indique le nombre de pièces distinctes utilisées pour programmer le monnayeur. Le nombre de fronts montants envoyés sur la ligne COIN du monnayeur est comptabilisé et stocké dans la variable nb_pulses. Le monnayeur ainsi programmé, la conversion nb_pulses/credit est réalisée avec une simple division par 10 (credit = nb_pulses/10).

La quantité de l’échantillon est importante. Lors des premiers essais, je ne disposais que de 4 pièces de 2 euros distinctes. Avec un échantillon aussi réduit, l’apprentissage n’est pas optimal et il peut parfois arriver qu’une même pièce de 2 euros ne soit pas reconnue et donc rejetée à l’avant du monnayeur.

Algorithme de traitement des séquences de pulses sur la ligne COIN

Tout d’abord, précisons que le switch NO/NC permet de définir l’état par défaut de la ligne COIN (fil blanc) :

  • NO (Normally Opened) : ligne COIN est maintenu à l’état HIGH (5V) et passe nb_pulses fois à LOW (0V) si une pièce est reconnue, puis retour à HIGH ;
  • NC (Normally Closed) : ligne COIN est maintenue à l’état LOW (0V) et passe nb_pulses fois à HIGH (5V) si une pièce est reconnue, puis retour à LOW.

Le bouton SPEED à 3 positions permet quant à lui d’influer sur le « output signal » d’après la documentation succincte fournie. Je n’ai pas su trouvé s’il s’agissait de faire varier la longueur des pulses envoyés sur la ligne COIN ou le laps entre chaque pulse (ou même les deux). Quoi qu’il en soit, les 3 vitesses disponibles sont les suivantes :

  1. SLOW : longueur de pulse = 100ms ;
  2. MEDIUM : longueur de pulse = 50ms ;
  3. FAST : longueur de pulse = 30ms.

Le schéma ci-dessous illustre la variation de tension sur la ligne COIN du monnayeur.

Pulses sur la ligne COIN du monnayeur
Pulses sur la ligne COIN du monnayeur

Lors des premiers essais dans le développement de la librairie COINSELECTOR.py, j’avais envisagé de reconnaitre chaque pièce insérée à l’aide de l’algorithme suivant :

A chaque pulse détecté :

  • Incrémentation de la variable nb_pulses ;
  • Stockage de du timestamp du dernier pulse dans last_pulse ;

Dans une boucle infinie test des deux conditions suivantes :

  • nb_pulse > 0 ?
  • laps de temps écoulé depuis le précédent pulse supérieur à 100ms (configuration du swich output signal du monnayeur sur la vitesse SLOW) ?
    • Les deux conditions vérifiées alors identification de la pièce :
      • coin = nb_pulse /10 ;
      • nb_pulses = 0

Techniquement, cet algorithme fonctionne. Mais d’un point de vue fonctionnel, des résultats inattendus se produiront si l’utilisateur insère trop rapidement deux pièces consécutives. En effet, comme le montre le schéma ci-dessus, si la pièce de 0.20 € est insérée immédiatement après la pièce de 0.10 €, alors le temps tx sera suffisamment court pour que le traitement d’identification de la pièce ne soit pas déclenché après l’insertion de la première pièce mais seulement une fois la seconde insérée. Dans ce cas, l’algorithme conduira à nb_pulses = 3 et le code nous indiquera qu’une pièce de 0.30 € a été insérée ! Après plusieurs tests, je ne suis pas parvenu à identifier le seuil (le laps de temps écoulé entre 2 pulses) adéquat pour discerner à coup sur les séquences de pulses.

Après réflexion, je réalise que faire la différence entre deux pièces de 0.10 € et une pièce de 0.20 € n’a pas de réel intérêt pour le projet. L’essentiel est d’incrémenter le crédit accumulé selon chaque pièce insérée et l’algorithme s’en trouve d’autant simplifié : il suffit d’ajouter la valeur 0.10 à la variable credit à chaque pulse détecté sur la ligne COIN ! Voici donc l’algorithme retenu :

  • A chaque pulse détecté :
    • Incrémentation de la variable credit de 0.10.

Alimentation du monnayeur et tension du signal COIN

Alimentation : fournir l’énergie nécessaire

Le monnayeur fonctionne en 12V. Il sera alimenté à l’aide d’un transformateur 5V (USB) – 12V (DC Jack). Il est possible de connecter l’extrémité USB sur le Raspberry mais un éclair apparaîtra sur l’écran (même avec un condensateur 1000μF) à l’insertion d’une pièce dans le monnayeur. Cela signifie une instabilité de la puissance électrique attendue par le Raspberry lorsque le monnayeur est actionné. Il est donc préférable d’utiliser une alimentation plus puissante type un chargeur de téléphone de 2A. Mes premiers essais ont montré que 1 A ne suffisait pas : en cas de sous-alimentation, même une pièce normalement reconnue par le monnayeur sera rejetée en façade en émettant 3 bips.

SIGNAL COIN : ABAISSER LES 5V A 3.3V POUR LES GPIO DU RASPBERRY

En plaçant le switch NO/NC sur NO, on découvre à l’aide d’un multimètre que la ligne COIN envoie du 5V. Le Raspberry attend du 3.3v sur les GPIO en INPUT : il est donc nécessaire de créer un pont diviseur de tension pour abaisser les 5V à 3.3V. La formule permettant de définir la valeur des résistances est Vout = (Vin x R2) / (R1 + R2) avec Vout = 3.3v et Vin = 5v, on arrive à déterminer que les valeurs 5 kΩ et 10kΩ respectivement pour R1 et R2 conviennent parfaitement. Pour abaisser le signal du monnayeur à 3.3V sur la GPIO 21, le câblage à réaliser est illustré par le schéma ci-dessous.

Pont diviseur de tension pour abaisser les 5V de la ligne COIN du monnayeur à 3.3V pour la GPIO en INPUT du Raspberry
Pont diviseur de tension pour abaisser les 5V de la ligne COIN du monnayeur à 3.3V pour la GPIO en INPUT du Raspberry

Pour réaliser le pont diviseur de tension ainsi que toutes les connexions des GPIOs, nous allons utiliser un module de prototypage qui s’enfiche sur les GPIO du Raspberry : le prototype HAT.

HAT est un acronyme pour Hardware Attached on the Top

Le prototype HAT

La quantité de connexions à réaliser justifie l’ajout d’un module de prototypage.

De gauche à droite : le prototype HAT avec le fils soudés et deux momentary switch, le Raspberry Pi 3 et un support pour Raspberry imprimée en 3D
De gauche à droite : le prototype HAT avec le fils soudés et deux momentary switch, le Raspberry Pi 3 et un support pour Raspberry imprimée en 3D

Le prototype HAT (carte rouge à gauche sur la photo ci-dessus) est une simple plaque PCB facilitant la soudure de composants. Une fois les fils soudés, j’ai sécurisant l’ensemble avec de la colle à chaud. L’élément noir (à droite sur la photo ci-dessus) est la partie inférieure d’un boitier pour Raspberry que j’ai imprimé en 3D (modèle .stl téléchargeable à l’adresse https://www.thingiverse.com/thing:922740) pour faciliter l’intégration de l’ensemble dans la partie supérieure du photobooth, comme l’illustre la photo suivante :

Raspberry surmonté du prototype HAT, le tout fixé dans la partie supérieure du photobooth à l'aide du support imprimé en 3D
Raspberry surmonté du prototype HAT, le tout fixé dans la partie supérieure du photobooth à l’aide du support imprimé en 3D

PCB est un acronyme pour Printed Circuit Board

On distingue par ailleurs sur le HAT deux boutons (jaune et bleu). Ces deux interrupteurs momentanés ont été ajoutés pour faciliter des opérations de maintenance sur le Raspberry, sans qu’un clavier ne soit nécessaire :

  • Bouton JAUNE : sortie du script Python photobooth.py pour pouvoir reprendre la main sur le terminal ;
  • Bouton BLEU : arrêt du Raspberry.

Pour ces deux opérations, le code Python prévoit que l’action demandée soit confirmée par un appui sur le gros bouton rouge dans un délai de 5s. Sans confirmation, le script revient à son fil d’exécution nominal une fois le délai écoulé. Voyons dès à présent le gros bouton rouge…

Le bouton rouge

Gros bouton rouge
Gros bouton rouge

Les cas d’utilisation

Le gros bouton rouge type buzzer est un « momentary switch » c’est-à-dire que le changement d’état est actif uniquement le temps de l’appui sur le bouton. Il est doté d’une LED qui permet d’allumer le bouton. Pour suggérer à l’utilisateur d’appuyer sur le bouton rouge, le clignotement de sa LED sera activé. L’utilisateur sera invité à actionner le buzzer dans les 3 situations suivantes :

IDCONTEXTEBLINK LEDDELAITRAITEMENT EN CAS D’APPUITRAITEMENT SANS APPUI ET DELAI ECOULE
1Crédit inséré ≥ 0.10 € (prix fixé)OUI15 sCrédit retranché de 0.10 €
Mise à jour du l’affichage LCD 20x04
Démarrage d’une session photo…
Crédit retranché de 0.10 €
Mise à jour du l’affichage LCD 20x04
Démarrage automatique d’une session photo…
2Affichage à l’écran de la photo prise avec un bandeau invitant à appuyer sur le bouton rouge NON5sImpression de la photo sur l’imprimante thermiqueRetour fil d’exécution nominal du script
3Bouton jaune actionnéOUI5 sSortie du script et retour au terminalRetour fil d’exécution nominal du script
4Bouton bleu actionnéOUI5 sArrêt du RaspberryRetour fil d’exécution nominal du script

Côté Python, c’est la fonction récursive waitForRedButtonPush() qui est appelée pour gérer l’attente d’un éventuel appui sur le bouton rouge.

Comme vous pourrez le comprendre à la lecture des instructions de la fonction waitForRedButtonPush(delai), le traitement est prévu pour éliminer les faux-positifs. En effet, dans la première version de la fonction, j’observais un phénomène inattendu : le crédit de la machine était parfois incrémenté à l’allumage/extinction de la lumière de la pièce dans laquelle se trouvait le photobooth ! Cela signifie que la ligne COIN du monnayeur était pulsée sans qu’aucune pièce ne soit insérée ! Ce bug est évidemment inacceptable ! Comment faire fortune avec une telle machine !?

En reprenant un montage et un code simpliste destiné à afficher « PULSE DETECTE » à chaque front montant envoyé sur une GPIO, je suis parvenu à comprendre qu’il s’agissait de très courtes interférences électriques induites par le changement d’état de l’interrupteur de la pièce. Ainsi, il faut réaliser un déparasitage logicielle pour être en mesurer de définir si le pulse est généré par :

  • une interférence : dans ce cas, il sera très court (inférieur à 100 ms) ;
  • un réel signal issu du monnayeur suite à l’insertion d’une pièce.

La fonction waitForRedButtonPush(delai) est donc nécessairement récursive pour pouvoir, à chaque faux-positif écarté, se rappeler elle-même en décrémentant le délai. Le délai doit être décrémenté car en cas de perturbations fréquentes, la fonction récursive pourrait se rappeler constamment avec un délai de 20 s sans que le timeout ne soit jamais atteint, ce qui conduirait, au cas où l’utilisateur n’appuierait pas sur le bouton rouge à une boucle infinie.

Alimentation de la LED

Une LED devient passante à partir d’un certain seuil de tension. Au-delà de ce seuil, la LED laisse passer tout le courant qui lui parvient : il est donc nécessaire de la protéger par une résistance pour ne pas être endommagée. Une résistance de protection est déjà présente sur la LED, on pourra donc l’alimenter directement. Cette LED fonctionne en 12v : les GPIO n’envoient que du 3.3v, on ne pourra donc pas les utiliser directement pour faire clignoter la LED. Il faudra donc utiliser la source 12v obtenue depuis le rehausseur de tension 5v->12v. Et pour le clignotement, nous allons devoir utiliser un interrupteur dont l’ouverture/fermeture peut être commandée à l’aide d’un signal envoyé depuis la GPIO 18. C’est justement le rôle d’un relais…

Le relais

Le relais est un interrupteur dont on commande l’état à l’aide d’un signal.

Connexion du relais pour commander la LED 12V du bouton rouge
Connexion du relais pour commander la LED 12V du bouton rouge

Par défaut, quand la broche Signal est à l’état LOW, la fiche Common de l’interrupteur est en contact avec la fiche NO. Lorsque la broche SIGNAL passe à l’état HIGH, la fiche Common est mise en contact avec la fiche NC.

si le câblage Vcc et GND inversé, alors seule le LED du module relais s’allume lors du changement d’état du signal de commande sur la GPIO 18 mais le relais ne switch pas

PROBLEME D’ALIMENTATION DU RASPBERRY

Au départ, j’envisageais d’alimenter la Raspberry avec l’alimentation 5V 10A à l’aide de câbles Dupont soudés sur le Prototype HAT. Ainsi alimenté, je constatais ponctuellement l’affichage d’un éclair jaune en haut à droite de l’écran signalant un problème d’énergie (notamment lorsque l’alimentation est instable) sur le Raspberry. Cet éclair apparaissait notamment au démarrage ou à l’exécution de la commande iwlist dont l’exécution exige de l’énergie pour scanner les hotspots wifis disponibles. En comparant la tension entre la sortie de l’alimentation, la sortie des fils dupont et la sortie aux broches +5V et GND du Prototype HAT, en constate une diminution de la tension au fur et à mesure que l’on s’éloigne de l’alimentation.

L’explication est la suivante : que ce soit les câbles Dupont ou le prototype HAT, les conducteurs sont fins et de fait, imposent une forte résistance entrainant une baisse de tension (Pour rappel, le lien entre la tension, la résistance et l’intensité est régit par la formule U = R x I). L’idée peut être vulgarisée à l’aide de la métaphore suivante : « peu de cuivre donc peu « d’espace » pour faire circuler les électrons qui se gênent mutuellement pour circuler ».

Remarques :

  • Chaque câble branché en série ajoute sa résistance au total, c’est-à-dire que ce n’est pas le plus petit qui fait goulot, c’est bien une addition ;
  • Plus le câble est fin, plus il est résistant. Plus le câble est long, plus il est résistant ;
  • Pour pouvoir déceler ces chutes de tensions, les tensions doivent être mesurées à l’aide d’un voltmètre lorsqu’un courant circule effectivement (Raspberry en fonctionnement), c’est-à-dire qu’un composant appelle des électrons (comme le dit la formule U = R x I). Dans le cas contraire, les électrons ne circulent pas et ne se « gênent » pas, et les atténuations de tensions ne pourront donc pas être mises en évidence.

Face à ce problème, je me résous à utiliser un chargeur mini USB classique 5v 2.5A. L’écran est quant à lui alimenté à l’aide d’un câble dupont sur l’alimentation 5V 10A sans problème.

La suite est décrite un second article…

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *