Table des matières
Failomaton
Le projet est de réaliser un photomaton qui vous rate le portrait consciencieusement. Un bijou de technologie pour un résultat décevant.
Conception du distributeur de photos
$fn = 200; // Épaisseur CP 10mm cote(); translate([350, 145]) rotate(180) cote(); translate([290, 165]) rotate(90) support(); translate([305, 155]) rotate(90) mirror([0, 1, 0]) glissiere(); translate([330, 470]) rotate(180) glissiere(); translate([15, 600]) rotate(-90) trapeze(); translate([123, 558]) mirror([0, 1, 0]) trapeze(); // Épaisseur CP 15mm translate([-120, 50]) renfort1(); translate([-10, 50]) mirror([1, 0, 0]) renfort1(); translate([-260, 0]) rotate(-30) ecarteur(); translate([-30, 30]) rotate(150) ecarteur(); module cote() { difference() { union() { square([290, 150]); translate([90, -10]) square([30, 10]); } square([55, 6]); // Encoche rabat translate([290, 0]) rotate(-30) translate([-400, 0]) square([400, 200]); translate([0, 80]) rotate(-30) translate([-100, 0]) square([100, 100]); translate([265, 0]) rotate(-30) square([100, 100]); // Petite pointe translate([0, 80]) rotate(-30) translate([-100, 0]) square([100, 100]); // Encoches glissieres translate([290,0]) rotate(-30) translate([-131.6, -10]) square([50, 11]); translate([290,0]) rotate(-30) translate([-231.6, -10]) square([50, 11]); } } module support() { difference() { square([236, 290]); translate([49.9, 34.9]) square([10.2, 30.2]); translate([175.9, 34.9]) square([10.2, 30.2]); translate([16.9, 84.9]) square([16.2,15.2]); translate([202.9, 84.9]) square([16.2,15.2]); } } module glissiere() { difference() { square([331.6, 60]); square([60.1, 10]); translate([109.9, 0]) square([50.2, 10]); translate([209.9, 0]) square([150, 35]); } } module trapeze() { difference() { square([135 * cos(30) + 40, 135 * sin(30)]); rotate(30) square([200, 200]); translate([0, 2]) difference() { translate([0, 58]) resize([320, 116]) circle(d=100); translate([0, 58]) resize([315.3, 111.5]) circle(d=100); translate([0, 58]) square([200, 100]); } } difference() { rotate(30) translate([-20, 0]) square([200, 30]); translate([0, 135 * sin(30)]) square([200, 100]); } translate([135 * cos(30) + 39.9,0]) square([0.1, 135 * sin(30)]); // Fil pour créer une poche pour la CNC } module ecarteur() { difference() { rotate(30) translate([-20, 0]) square([200, 30]); translate([0, 135 * sin(30)]) square([200, 100]); } } module renfort1() { difference() { square([49.9, 50]); translate([-15, 0]) rotate(45) square([100, 100]); } translate([17, -10]) square([16, 10]); }
Installation de ImageMagick
Installation du paquet
sudo apt-get install imagemagick
Vérifier la bonne installation de ImageMagick
identify -version
Pour tester le bon fonctionnement en convertissant un fichier .jpg en .png
convert photo.jpg photo.png
Voici la méthode pour recadrer la photo afin qu'elle corresponde aux dimensions du papier hagaki :
convert -crop 3836x2592+386+0 photo.jpg photo1.jpg
La méthode pour modifier l'orientation de l'image :
convert -rotate -90 photo.jpg photo1.jpg
Installation de mplayer
sudo apt-get install mplayer
Vérifier la bonne installation avec
mplayer --version
Afin d'optimiser le lecteur il faut éditer le fichier de configuration :
sudo nano ~/.mplayer/config
A la fin du fichier ajouter cette ligne qui indique que nous n'avons pas besoin de télécommande
lirc=no
Pour lancer un fichier audio
mplayer /home/pi/Audio/audio01.wav
Le son sort par le mini-jack de la Raspberry Pi
Réalisation de la voix de synthèse
La réalisation des différentes instructions par des voix de synthèse a été faite à travers ce site
Voici les réglages :
Matériel
Monnayeur
Carte son
Installation de wiringPi
Attention la librairie WiringPi ne fonctionne que sous Raspbian 32bits et pour un modèle 4B au maximum.
cd /tmp wget https://project-downloads.drogon.net/wiringpi-latest.deb sudo dpkg -i wiringpi-latest.deb
Vérifier l'installation avec
gpio -v
La version doit être la 2.52
Installation de l'imprimante
Mise en route de l'imprimante
Suivre les instructions du mode d'emploi pour installer l'imprimante.
La seule configuration nécessaire est de désactiver l'extinction automatique
Avec les flèches aller sur le menu configuration (L'image des outils), puis appuyer sur OK
Aller sur Réglage de l'imprimante puis OK
Aller avec la flèche du bas sur Extinction auto, OK
Sélectionner Désac. puis Ok
Puis appuyer sur Home
Installation de CUPS
Sur une image de Raspberry fraichement installée et mise à jour. Installer CUPS :
sudo apt-get install cups
Puis
sudo usermod -a -G lpadmin pi
Ici, l'utilisateur est celui par défaut pi, vous pouvez le changer si vous avez initialisé un autre nom d'utilisateur.
sudo /etc/init.d/cups restart
Pour redémarrer le service afin que les changements aient bien été pris en compte.
Si vous êtes avec une Raspberry Pi sans écran et connectée en ssh, vous pouvez accéder à la page de configuration des imprimantes si vous suivez ces instructions :
Éditer le fichier de configuration de CUPS :
sudo nano /etc/cups/cupsd.conf
Modifier la section suivante :
# Only listen for connections from the local machine. Listen localhost:631 Listen /var/run/cups/cups.sock
Afin qu'elle ressemble à celle-ci :
# Only listen for connections from the local machine. Port 631 Listen /var/run/cups/cups.sock
Puis modifier cette section :
# Restrict access to the server... <Location /> Order allow,deny </Location> # Restrict access to the admin pages... <Location /admin> Order allow,deny </Location> # Restrict access to configuration files... <Location /admin/conf> AuthType Default Require user @SYSTEM Order allow,deny </Location>
Pour qu'elle ressemble à ceci :
# Restrict access to the server... <Location /> Order allow,deny Allow all </Location> # Restrict access to the admin pages... <Location /admin> Order allow,deny Allow all </Location> # Restrict access to configuration files... <Location /admin/conf> AuthType Default Require user @SYSTEM Order allow,deny Allow all </Location>
Redémarrer ensuite CUPS :
sudo /etc/init.d/cups restart
Ajouter une nouvelle imprimante
Configuration de CUPS
Dès à présent, vous pouvez ouvrir un navigateur et accéder à la page de configuration à cette adresse :
https://failomaton.local:631/admin
Si vous changez la configuration, il faudra vous identifier avec les éléments de CUPS
L'imprimante n'apparaît pas dans les imprimantes locales mais juste dans les imprimantes réseaux. Cliquer sur le bouton puis [Continuer]
Sur la page Ajouter une imprimante cliquer juste sur continuer
Sur la page suivante sélectionner dans le menu Canon SELPHY CP1300, driverless, cups-filters 1.28.17 (en), puis cliquer sur [Ajouter une imprimante]
Sur la page Définir les options de l’imprimante Vérifier que les paramètres par défaut sont bien cela :
Cliquer sur [Définir les options par défaut]
Impression d'une page test
Cliquer sur [Imprimantes]
Cliquer sur [Canon_SELPHY_CP1300]
Maintenance > Imprimer une page test
Impression d'une photo
Dans un fenêtre du terminal : Lister les imprimantes disponibles
lpstat -p -d
Définir l'imprimante comme imprimante par défaut
lpoptions -d Canon_SELPHY_CP1300
Pour imprimer une photo
lp -d Canon_SELPHY_CP1300 photo1.jpg
Code
Fichier de configuration de la caméra
Placer un fichier config.txt dans le répertoire où est placé le fichier en C
sudo nano config.txt
Copier et coller ces éléments dans le fichier :
timeout=2 verbose=0
Ctrl O pour enregistrer puis valide puis Ctrl X pour quitter.
Code C pour la Raspberry Pi
// gcc -Wall -o test test.c -lwiringPi #include <dirent.h> #include <stdio.h> #include <unistd.h> #include <wiringPi.h> #include <string.h> #include <signal.h> #include <time.h> #include <stdlib.h> #define declenchementArduino 16 int nbPhotos = 0; time_t compteurTemps; void reverse(char s[]) { int i, j; char c; for (i = 0, j = strlen(s)-1; i<j; i++, j--) { c = s[i]; s[i] = s[j]; s[j] = c; } } void itoa(int n, char s[]) { int i, sign; if ((sign = n) < 0) /* record sign */ n = -n; /* make n positive */ i = 0; do { /* generate digits in reverse order */ s[i++] = n % 10 + '0'; /* get next digit */ } while ((n /= 10) > 0); /* delete it */ if (sign < 0) s[i++] = '-'; s[i] = '\0'; reverse(s); } void photo() { time_t temps = time(NULL); if (difftime(temps, compteurTemps) > 5) // Permet d'éliminer les rebonds de l'interrupteur { printf("Top\n"); compteurTemps = temps; char buffer [6]; itoa(nbPhotos, buffer); char src[40] = "/home/pi/Photos/photo_" ; strcat(src, buffer); strcat(src, ".jpg"); printf("%s\n",src); nbPhotos++; digitalWrite(declenchementArduino, HIGH); static pid_t pid = 0; if ((pid = fork()) == 0) { // libcamera-jpeg -o photo_0.jpg -c config.txt execl("/usr/bin/libcamera-jpeg", "", "-o", src, "-c", "config.txt", NULL); } sleep(1); digitalWrite(declenchementArduino, LOW); FILE * fichier ; do { fichier = fopen(src, "r"); } while (fichier == NULL); fclose(fichier); static pid_t pid1 = 0; if ((pid1 = fork()) == 0) { // convert -crop 3836x2592+386+0 -rotate -90 Photos/photo_0.jpg Photos/photo1.jpg execl("/usr/bin/convert", "", "-crop", "3836x2592+386+0", "-rotate", "90", src, src, NULL); } sleep(2); static pid_t pid2 = 0; if ((pid2 = fork()) == 0) { // convert -crop 3836x2592+386+0 -rotate -90 Photos/photo_0.jpg Photos/photo1.jpg execl("/usr/bin/lp", "", "-d", "Canon_SELPHY_CP1300", src, NULL); } } } int main() { wiringPiSetup(); pinMode (15, INPUT); // Pin de l'interrupteur pullUpDnControl(15, PUD_UP); wiringPiISR (15, INT_EDGE_FALLING, &photo); pinMode (declenchementArduino, OUTPUT); // Pin de déclenchement de l'arduino compteurTemps = time(NULL); //system("mplayer -really-quiet /home/pi/Audio/audio01.wav"); /*static pid_t pid = 0; if((pid = fork()) == 0) { execl("/usr/bin/mplayer", "/usr/bin/mplayer", "-really-quiet", "/home/pi/Audio/audio01.wav", NULL); }*/ // Comptage des fichiers struct dirent *dir; DIR *d = opendir("/home/pi/Photos/"); if (d) { while ((dir = readdir(d)) != NULL) { if (dir->d_name[0] != '.') { nbPhotos++; } } //printf("%i\n", nbPhotos); closedir(d); } while(1) { } return 0; }
Code Arduino
#include <Servo.h> #define declencheur 2 #define posFermeVerrou 0 #define posOuvertVerrou 80 #define posBrasLeve 137 #define posBrasBaisse 65 Servo verrou; Servo bras; void setup() { pinMode(declencheur, INPUT); pinMode(8, INPUT_PULLUP); pinMode(13, OUTPUT); bras.attach(6); verrou.attach(5); sequence(); } void loop() { if (digitalRead(declencheur) == HIGH) { sequence(); } if (digitalRead(8) == 0){ digitalWrite(13, HIGH); } } void sequence() { delay(600); verrou.write(posOuvertVerrou); delay(1500); bras.write(posBrasLeve); delay(1000); verrou.write(posFermeVerrou); delay(500); bras.write(posBrasBaisse); delay(500); }