Mini Game Center -6-
Par makoto doushite le mardi, 26 mai 2020, 20:55 - Raspberry Pi - Lien permanent
Toujours à la recherche d'une solution simple pour piloter les bornes du MiniGameCenter, c'est maintenant vers la transmission infrarouge directement au Raspberry que je vais me tourner.
Ce n'est pas une technique qui m'est inconnue, puisque je l'utilise sur mon médiacenter et mon WebRadioReveilWifi, mais pensant faire autrement je ne l'avais pas envisagée jusqu'alors.
Ainsi je devrais pourvoir faire la même chose qu'avec ce qu'on à vu la dernière fois sans fil avec le bluetooth, en utilisant 2 fils soit un GPIO.
Et si je veux pouvoir utiliser la fonction « Power ON », il faudra me résoudre à câbler un fil supplémentaire.
Voyons déjà comment ça se passe avec le soft Lirc, car c'est pas toujours évident à faire marcher, déjà la fois dernière j'avais dû bricoler un peu pour que ça fonctionne sur le Raspbian de l'époque, alors que plutôt encore, c'était bien passé…
Support de l'infra-rouge :
- Installer le soft de gestion de l'infrarouge :
sudo apt update sudo apt install lirc
À l'heure où j'installe ce soft, l’installation plante (Ha ça commence !)
- Mais rien n'est perdu, y faut bricoler, et déplacer un fichier…
sudo mv /etc/lirc/lirc_options.conf.dist /etc/lirc/lirc_options.conf
- Puis relancer l'installation :
sudo apt install lirc
- Ensuite on va modifier le fichier de configuration comme suis :
sudo nano /etc/lirc/lirc_options.conf
driver = default device = /dev/lirc0
- Renommer cet autre fichier :
sudo mv /etc/lirc/lircd.conf.dist /etc/lirc/lircd.conf
- Activer le module sur le Raspberry en éditant config.txt afin d'ajouter la ligne suivante pour activer le GPIO6 et redémarrer le Rpi.
Le Capteur IR est impérativement alimenté par le 3,3V du Raspberry, et donc sa broche de signal branchée sur le GPIO6.
J'ai mis le dessin standard d'une RpiZero, mais on passera ici par le connecteur GPIO du Pi-HAT.
sudo nano /boot/config.txt
dtoverlay=gpio-ir,gpio_pin=6
- Pour vérifier que le module fonctionne :
sudo systemctl status lircd.service
- Et enfin pour tester si les commandes infrarouge sont bien reçues :
sudo killall lircd sudo mode2 -d /dev/lirc0
- À chaque appuie sur une touche de la télécommande, devrait s'afficher ce genre de truc :
space 1223 pulse 281 space 1193 pulse 350 space 1199 pulse 264 space 1901
Configuration de la télécommande :
- Comme dans ce billet d'époque on va identifier la télécommande et associer chacun de ses boutons à une touche du clavier.
sudo irrecord -d /dev/lirc0 telecommande''
Sauf que la commande irrecord ne fonctionne pas avec Raspbian Buster (actuellement la version 10.4 avec le kernel 4.19.97+).
Ça va donc être coton pour configurer une télécommande exotique, et il serait plus facile de se référer à la base de télécommande en ligne de Lirc.
Par chance, j'ai retrouvé une petite télécommande sympatique que ne me servait plus et qui est bien listée dans la base !
- Je peux donc me contenter de simplement copier/coller le fichier correspondant :
sudo nano /etc/lirc/lircd.conf.d/PCTV_800i.conf
# this config file was automatically generated # using lirc-0.8.5(default) on Fri Oct 2 14:44:45 2009 # contributed by Aaron Hurt (ahurt[at]anbcs[dot]com) # brand: Pinnacle Systems 800i begin remote name PCTV_800i bits 13 flags RC5|CONST_LENGTH eps 30 aeps 100 one 913 842 zero 913 842 plead 932 gap 112434 toggle_bit_mask 0x800 begin codes key_mute 0x11C0 key_menu 0x11C1 key_power 0x11F9 key_volumeup 0x11C3 key_volumedown 0x11C9 key_channelup 0x11C6 key_channeldown 0x11CC btn_1 0x11CF btn_2 0x11D5 btn_3 0x11D0 btn_4 0x11D8 btn_5 0x11DB btn_6 0x11DE btn_7 0x11D1 btn_8 0x11E1 btn_9 0x11D2 btn_0 0x11E7 key_screen 0x11E4 key_t 0x11EA key_rewind 0x11ED key_playpause 0x11F0 key_fastforward 0x11F3 key_record 0x11F6 key_stop 0x11FC key_question 0x11FF end codes end remote
- Reste alors à redémarrer le service Lirc.
sudo service lircd restart
Logiciel de pilotage de la playlist vidéo :
- La télécommande devrait être instantanément reconnue, reste alors à reprendre le code Python initié lors des bidouilles avec le bluetooth et de l'adapter pour fonctionner avec Lirc, avec l'import de la librairie correspondante, dans le fichier VideoOMXcontrol_GPIO_Multifonctions_Playlist_IR.py .
Et comme il est maintenant possible de piloter plusieurs Rpi, en connectant les GPIO6 de chacun d'eux sur le capteur IR, il faut ajouter un système de sélection permettant de choisir à quelle machine on décide de s'adresser. (indiqué dans le code par la balise ### Début de zone à adapter à chaque Rpi).
- Ainsi pour piloter par exemple le Rpi N°2, on appuie simplement sur la touche 2, et toutes les actions suivantes seront effective uniquement pour lui.
- De même en appuyant sur la touche Menu, on pourra piloter toutes machines simultanément… On verra ça dans une démo vidéo plus bas.
#!/usr/bin/env python2.7 # coding: utf-8 # Compatible Python3 # Programme pour RaspberryPi # Joue une playliste de vidéos avec omxplayer # Pilotage des vidéos et de la playliste avec télécommande IR ################################## # Import des modules nécessaires # ################################## from omxcontrol import * import subprocess import RPi.GPIO as GPIO import time from lirc import RawConnection ############# # Init GPIO # ############# PIN_BRIGHTNESS = 12 # GPIO18, PWM de réglage de la luminosité GPIO.setmode(GPIO.BOARD) ## Use board pin numbering GPIO.setup(PIN_BRIGHTNESS, GPIO.OUT) #################### # Variable Globale # #################### conn = RawConnection() Activation = 0 ##################### # Ressources Vidéos # ##################### def Selection(i): switcher={ 0:'/home/pi/deathsml_15-07-2015_1cc_h264-21.mp4', 1:'/home/pi/dodonpachi_23-02-2014_montage.mp4', 2:'/home/pi/espgal_26-02-2015_1cc_x264_crf23.mp4', 3:'/home/pi/galaxian.mp4', } return switcher.get(i,"Séléction Invalide") ############# # Variables # ############# vid = 0 brightness = 100 pwm = GPIO.PWM(PIN_BRIGHTNESS, 130) # channel et frequence en Hz, meilleur résultat à 120 et 130Hz ########################## # Démarrage (facultatif) # ########################## os.system('sudo pkill omxplayer') # S'assure qu'aucune instance omxplayer ne tourne encore, en cas de plantage # omxplayer /home/pi/deathsml_15-07-2015_1cc_h264-21.mp4 --aspect-mode stretch -o local pwm.start(brightness) # Démarrage de la PWM du rétroéclairage LCD au max (100) ############################### # Fonctions pour Télécommande # ############################### def bouton_VOLUMEMOINS(): # baisse le volume print("Volume -") omx.action(OmxControl.ACTION_DECREASE_VOLUME) def bouton_VOLUMEPLUS(): # augmente le volume print("Volume +") omx.action(OmxControl.ACTION_INCREASE_VOLUME) def bouton_LUMMOINS(): global brightness # Baisser la luminosité de l'écran LCD brightness = brightness - 10 if brightness <= 10: brightness = 10 print("Luminosité baissée au max") print("Baisse la luminosite :", brightness) pwm.ChangeDutyCycle(brightness) def bouton_LUMPLUS(): global brightness # Augmenter la luminosité de l'écran LCD brightness = brightness + 10 if brightness >= 100: brightness = 100 print("Luminosité augmentée au max") print("Augmente la luminosite :", brightness) pwm.ChangeDutyCycle(brightness) def bouton_BACK(): # un petit saut un arriére dans la vidéo print('<<') omx.action(OmxControl.ACTION_SEEK_BACK_SMALL) def bouton_PRECEDENT(): global vid # Stopper la lecture et tombe donc en erreur via Try > Except de la boucle principale print('Vidéo Précédente') omx.action(OmxControl.ACTION_EXIT) vid = vid - 1 # pour lire la vidéo précédente if vid == -1: vid = 3 print('vid : ',vid) omx.action(OmxControl.ACTION_PAUSE) def bouton_FORWARD(): # un petit saut en avant dans la vidéo print('>>') omx.action(OmxControl.ACTION_SEEK_FORWARD_SMALL) def bouton_SUIVANT(): global vid # Stopper la lecture et tombe donc en erreur via Try > Except de la boucle principale print('Vidéo Suivante') omx.action(OmxControl.ACTION_EXIT) vid = vid + 1 # pour lire la vidéo suivante if vid == 4: vid = 0 print('vid : ',vid) omx.action(OmxControl.ACTION_PAUSE) def bouton_PLAY(): # Pause/Play la vidéo print('Pause/Play') omx.action(OmxControl.ACTION_PAUSE) def bouton_STOP(): # Stoppe la vidéo print('Stop') omx.action(OmxControl.ACTION_EXIT) def ProcessIRRemote(): #get IR command #keypress format = (hexcode, repeat_num, command_key, remote_id) try: keypress = conn.readline(.0001) # print(keypress) except: keypress="" if (keypress != "" and keypress != None): data = keypress.split() sequence = data[1] command = data[2] #ignore command repeats if (sequence != "00"): return # print(data) # print(sequence) print(command) return command ##################### # Boucle Principale # ##################### while True: try: omx = OmxControl() # appel librairie OmxControl Commande = ProcessIRRemote() # scrutte les touches de télécommande ### Début de zone à adapter à chaque Rpi (changer le bouton utilisé dans le if et elif) if Commande == 'btn_1' : Activation = 1 # activation de la réception pour ce Rpi elif Commande == 'btn_2' or Commande == 'btn_3' or Commande == 'btn_4' or Commande == 'btn_5' or Commande == 'btn_6' or Commande == 'btn_7' or Commande == 'btn_8' or Commande == 'btn_9' or Commande == 'btn_0': Activation = 0 # désactivation de la réception pour ce Rpi si récetion d'un code bouton qui ne lui est pas destiné elif Commande == 'key_menu': # activation de la réception pour tous les Rpi Activation = 1 #### Fin de zone if Activation == 1: if Commande == 'key_volumedown' : bouton_VOLUMEMOINS() # Vol- elif Commande == 'key_volumeup': bouton_VOLUMEPLUS() # Vol+ elif Commande == 'key_screen': bouton_LUMMOINS() # Lum- elif Commande == 'key_t': bouton_LUMPLUS() # lum+ elif Commande == 'key_rewind': bouton_BACK() # << elif Commande == 'key_fastforward': bouton_FORWARD() # >> elif Commande == 'key_channeldown': bouton_PRECEDENT() # précédent elif Commande == 'key_channelup': bouton_SUIVANT() # suivant elif Commande == 'key_playpause': bouton_PLAY() # Play/Pause elif Commande == 'key_stop': bouton_STOP() # Stop except OmxControlError as ex: # si le controle ne voit plus D-Bus, relance la vidéo print("ERREUR de contrôle D-Bus, relance de la vidéo") print('Selection : ',Selection(vid)) subprocess.Popen(['omxplayer','--aspect-mode', 'stretch', '-o', 'local', Selection(vid)], stdin=subprocess.PIPE) time.sleep(3) # tempo pour laisser le temps au player vidéo de démarrer omx = OmxControl() # appel librairie OmxControl omx.action(OmxControl.ACTION_DECREASE_VOLUME) omx.action(OmxControl.ACTION_DECREASE_VOLUME) omx.action(OmxControl.ACTION_DECREASE_VOLUME) omx.action(OmxControl.ACTION_DECREASE_VOLUME) omx.action(OmxControl.ACTION_DECREASE_VOLUME) omx.action(OmxControl.ACTION_DECREASE_VOLUME) # -18 db # on réinitialise les ports GPIO en sortie de script GPIO.cleanup() ##################################################### # Fonctions disponible dans la librairie OmxControl # ##################################################### #ACTION_DECREASE_SPEED #ACTION_INCREASE_SPEED #ACTION_REWIND #ACTION_FAST_FORWARD #ACTION_SHOW_INFO #ACTION_PREVIOUS_AUDIO #ACTION_NEXT_AUDIO #ACTION_PREVIOUS_CHAPTER #ACTION_NEXT_CHAPTER #ACTION_PREVIOUS_SUBTITLE #ACTION_NEXT_SUBTITLE #ACTION_TOGGLE_SUBTITLE #ACTION_DECREASE_SUBTITLE_DELAY #ACTION_INCREASE_SUBTITLE_DELAY #ACTION_EXIT #ACTION_PAUSE #ACTION_DECREASE_VOLUME #ACTION_INCREASE_VOLUME #ACTION_SEEK_BACK_SMALL #ACTION_SEEK_FORWARD_SMALL #ACTION_SEEK_BACK_LARGE #ACTION_SEEK_FORWARD_LARGE #ACTION_SEEK_RELATIVE #ACTION_SEEK_ABSOLUTE #ACTION_STEP #ACTION_BLANK #ACTION_MOVE_VIDEO #ACTION_HIDE_VIDEO #ACTION_UNHIDE_VIDEO #ACTION_HIDE_SUBTITLES
Gestion du Power On/Off, une solution hybride :
Je suis assez content du résultat, ça fonctionne vraiment bien, et pour parachever le tout il faudrait pouvoir allumer et éteindre proprement toutes les mini-bornes également avec la télécommande.
- Pour ce faire on va profiter des trucs expérimentés lors des études précédentes pour mélanger les solutions :
- Je suis donc obligé de rajouter un fil sur la pin Switch du PiHAT, prévue pour cela… Un fil ce sera toujours mieux que de devoir tout câbler.
- Et pour chaque Rpi donc, raccorder ce fil sur un Arduino Pro-mini 3,3V, qui prendra lui aussi le capteur IR en entrée…
Ce qui m'arrange pas mal c'est de pouvoir alimenter le capteur IR par le VCC (3,3V) de l'Arduino, ce qui évite de tirer cette tension depuis un Rpi ou d'une alim dédiée.
- Et grâce à ce programme, on va pouvoir éteindre le système d'exploitation du Rpi sélectionné, et aussi le rallumer tranquillement. En cas de plantage logiciel, si le Rpi venait à ne plus répondre, on pourra aussi forcer la coupure de l'alimentation.
/* Pilotage IR MiniGameCenter * Gestion du power on/off */ #include <IRremote.h> #include <SoftwareSerial.h> //################ //# DÉCLARATIONS # //################ //——— Prototypes Fonctions ———// void decodage_touche(void); void Selection(void); void PowerONOFF(void); void ForcePowerOFF(void); //——— Pins ———// #define RPi02 2 #define RPi03 3 #define RPi04 4 #define RPi05 5 #define RPi06 6 #define RPi07 7 #define RPi08 8 #define RPi09 9 #define RPi10 10 #define RPi01 11 int RECV_PIN = 12; //——— Variables ———// int Activation = 0; //——— Lib ———// IRrecv irrecv(RECV_PIN); decode_results results; //######### //# SETUP # //######### void setup() { Serial.begin(9600); Serial.println("Enabling IRin"); irrecv.enableIRIn(); // Start the receiver irrecv.blink13(true); Serial.println("Enabled IRin"); pinMode(RPi01, OUTPUT); pinMode(RPi02, OUTPUT); pinMode(RPi03, OUTPUT); pinMode(RPi04, OUTPUT); pinMode(RPi05, OUTPUT); pinMode(RPi06, OUTPUT); pinMode(RPi07, OUTPUT); pinMode(RPi08, OUTPUT); pinMode(RPi09, OUTPUT); pinMode(RPi10, OUTPUT); digitalWrite(RPi01, HIGH); digitalWrite(RPi02, HIGH); digitalWrite(RPi03, HIGH); digitalWrite(RPi04, HIGH); digitalWrite(RPi05, HIGH); digitalWrite(RPi06, HIGH); digitalWrite(RPi07, HIGH); digitalWrite(RPi08, HIGH); digitalWrite(RPi09, HIGH); digitalWrite(RPi10, HIGH); } //############# //# FONCTIONS # //############# void decodage_touche() { if (irrecv.decode(&results)) { Serial.println(results.value, HEX); irrecv.resume(); // Receive the next value } } void Selection() { switch (results.value) { case 0x1CF: // Pinnacle PCTV_800i touche 1 (elle répond à deux codes, 1CF et 9CF) Serial.println("Selection Rpi N°1"); results.value = 0; // empéche la répétition de touche Activation = 1; break; case 0x9CF: // Pinnacle PCTV_800i touche 1 (elle répond à deux codes, 1CF et 9CF) Serial.println("Selection Rpi N°1"); results.value = 0; // empéche la répétition de touche Activation = 1; break; case 0x1D5: // Pinnacle PCTV_800i touche 2 (elle répond à deux codes, 1D5 et 9D5) Serial.println("Selection Rpi N°2"); results.value = 0; // empéche la répétition de touche Activation = 2; break; case 0x9D5: // Pinnacle PCTV_800i touche 2 (elle répond à deux codes, 1D5 et 9D5) Serial.println("Selection Rpi N°2"); results.value = 0; // empéche la répétition de touche Activation = 2; break; case 0x1D0: // Pinnacle PCTV_800i touche 3) Serial.println("Selection Rpi N°3"); results.value = 0; // empéche la répétition de touche Activation = 3; break; case 0x9D0: // Pinnacle PCTV_800i touche 3 Serial.println("Selection Rpi N°3"); results.value = 0; // empéche la répétition de touche Activation = 3; break; case 0x1D8: // Pinnacle PCTV_800i touche 4) Serial.println("Selection Rpi N°4"); results.value = 0; // empéche la répétition de touche Activation = 4; break; case 0x9D8: // Pinnacle PCTV_800i touche 4 Serial.println("Selection Rpi N°4"); results.value = 0; // empéche la répétition de touche Activation = 4; break; case 0x1DB: // Pinnacle PCTV_800i touche 5) Serial.println("Selection Rpi N°5"); results.value = 0; // empéche la répétition de touche Activation = 5; break; case 0x9DB: // Pinnacle PCTV_800i touche 5) Serial.println("Selection Rpi N°5"); results.value = 0; // empéche la répétition de touche Activation = 5; break; case 0x1DE: // Pinnacle PCTV_800i touche 6) Serial.println("Selection Rpi N°6"); results.value = 0; // empéche la répétition de touche Activation = 6; break; case 0x9DE: // Pinnacle PCTV_800i touche 6) Serial.println("Selection Rpi N°6"); results.value = 0; // empéche la répétition de touche Activation = 6; break; case 0x1D1: // Pinnacle PCTV_800i touche 7) Serial.println("Selection Rpi N°7"); results.value = 0; // empéche la répétition de touche Activation = 7; break; case 0x9D1: // Pinnacle PCTV_800i touche 7) Serial.println("Selection Rpi N°7"); results.value = 0; // empéche la répétition de touche Activation = 7; break; case 0x1E1: // Pinnacle PCTV_800i touche 8) Serial.println("Selection Rpi N°8"); results.value = 0; // empéche la répétition de touche Activation = 8; break; case 0x9E1: // Pinnacle PCTV_800i touche 8) Serial.println("Selection Rpi N°8"); results.value = 0; // empéche la répétition de touche Activation = 8; break; case 0x1D2: // Pinnacle PCTV_800i touche 9) Serial.println("Selection Rpi N°9"); results.value = 0; // empéche la répétition de touche Activation = 9; break; case 0x9D2: // Pinnacle PCTV_800i touche 9) Serial.println("Selection Rpi N°9"); results.value = 0; // empéche la répétition de touche Activation = 9; break; case 0x1E7: // Pinnacle PCTV_800i touche 0) Serial.println("Selection Rpi N°10"); results.value = 0; // empéche la répétition de touche Activation = 10; break; case 0x9E7: // Pinnacle PCTV_800i touche 0) Serial.println("Selection Rpi N°10"); results.value = 0; // empéche la répétition de touche Activation = 10; break; case 0x1C1: // Pinnacle PCTV_800i touche menu Serial.println("Selection de tous les Rpi !"); results.value = 0; // empéche la répétition de touche Activation = 11; break; case 0x9C1: // Pinnacle PCTV_800i touche menu Serial.println("Selection de tous les Rpi !"); results.value = 0; // empéche la répétition de touche Activation = 11; break; default: // if nothing else matches, do the default // default is optional break; } } void PowerONOFF(){ if ((Activation == 1) && ((results.value == 0x1F9) || (results.value == 0x9F9))) { Activation = 0; Serial.println("Power ON/OFF Rpi N°1"); results.value = 0; // empéche la répétition de touche digitalWrite(RPi01, LOW); // Power ON Rpi N°1 delay(300); // simule un appuie court digitalWrite(RPi01, HIGH); } else if ((Activation == 2) && ((results.value == 0x1F9) || (results.value == 0x9F9))) { Activation = 0; Serial.println("Power ON/OFF Rpi N°2"); results.value = 0; // empéche la répétition de touche digitalWrite(RPi02, LOW); // Power ON Rpi N°2 delay(300); // simule un appuie court digitalWrite(RPi02, HIGH); } else if ((Activation == 3) && ((results.value == 0x1F9) || (results.value == 0x9F9))) { Activation = 0; Serial.println("Power ON/OFF Rpi N°3"); results.value = 0; // empéche la répétition de touche digitalWrite(RPi03, LOW); // Power ON Rpi N°3 delay(300); // simule un appuie court digitalWrite(RPi03, HIGH); } else if ((Activation == 4) && ((results.value == 0x1F9) || (results.value == 0x9F9))) { Activation = 0; Serial.println("Power ON/OFF Rpi N°4"); results.value = 0; // empéche la répétition de touche digitalWrite(RPi04, LOW); // Power ON Rpi N°4 delay(300); // simule un appuie court digitalWrite(RPi04, HIGH); } else if ((Activation == 5) && ((results.value == 0x1F9) || (results.value == 0x9F9))) { Activation = 0; Serial.println("Power ON/OFF Rpi N°5"); results.value = 0; // empéche la répétition de touche digitalWrite(RPi05, LOW); // Power ON Rpi N°5 delay(300); // simule un appuie court digitalWrite(RPi05, HIGH); } else if ((Activation == 6) && ((results.value == 0x1F9) || (results.value == 0x9F9))) { Activation = 0; Serial.println("Power ON/OFF Rpi N°6"); results.value = 0; // empéche la répétition de touche digitalWrite(RPi06, LOW); // Power ON Rpi N°6 delay(300); // simule un appuie court digitalWrite(RPi06, HIGH); } else if ((Activation == 7) && ((results.value == 0x1F9) || (results.value == 0x9F9))) { Activation = 0; Serial.println("Power ON/OFF Rpi N°7"); results.value = 0; // empéche la répétition de touche digitalWrite(RPi07, LOW); // Power ON Rpi N°7 delay(300); // simule un appuie court digitalWrite(RPi07, HIGH); } else if ((Activation == 8) && ((results.value == 0x1F9) || (results.value == 0x9F9))) { Activation = 0; Serial.println("Power ON/OFF Rpi N°8"); results.value = 0; // empéche la répétition de touche digitalWrite(RPi08, LOW); // Power ON Rpi N°8 delay(300); // simule un appuie court digitalWrite(RPi08, HIGH); } else if ((Activation == 9) && ((results.value == 0x1F9) || (results.value == 0x9F9))) { Activation = 0; Serial.println("Power ON/OFF Rpi N°9"); results.value = 0; // empéche la répétition de touche digitalWrite(RPi09, LOW); // Power ON Rpi N°9 delay(300); // simule un appuie court digitalWrite(RPi09, HIGH); } else if ((Activation == 10) && ((results.value == 0x1F9) || (results.value == 0x9F9))) { Activation = 0; Serial.println("Power ON/OFF Rpi N°10"); results.value = 0; // empéche la répétition de touche digitalWrite(RPi10, LOW); // Power ON Rpi N°10 delay(300); // simule un appuie court digitalWrite(RPi10, HIGH); } else if ((Activation == 11) && ((results.value == 0x1F9) || (results.value == 0x9F9))) { Activation = 0; Serial.println("Power ON/OFF de tous les Rpi !"); results.value = 0; // empéche la répétition de touche digitalWrite(RPi01, LOW); // Power ON Rpi N°1 digitalWrite(RPi02, LOW); // Power ON Rpi N°2 digitalWrite(RPi03, LOW); // Power ON Rpi N°3 digitalWrite(RPi04, LOW); // Power ON Rpi N°4 digitalWrite(RPi05, LOW); // Power ON Rpi N°5 digitalWrite(RPi06, LOW); // Power ON Rpi N°6 digitalWrite(RPi07, LOW); // Power ON Rpi N°7 digitalWrite(RPi08, LOW); // Power ON Rpi N°8 digitalWrite(RPi09, LOW); // Power ON Rpi N°9 digitalWrite(RPi10, LOW); // Power ON Rpi N°10 delay(300); // simule un appuie court digitalWrite(RPi01, HIGH); digitalWrite(RPi02, HIGH); digitalWrite(RPi03, HIGH); digitalWrite(RPi04, HIGH); digitalWrite(RPi05, HIGH); digitalWrite(RPi06, HIGH); digitalWrite(RPi07, HIGH); digitalWrite(RPi08, HIGH); digitalWrite(RPi09, HIGH); digitalWrite(RPi10, HIGH); } } void ForcePowerOFF(){ if ((Activation == 1) && ((results.value == 0x1F6) || (results.value == 0x9F9))) { Activation = 0; Serial.println("Force Power OFF Rpi N°1"); results.value = 0; // empéche la répétition de touche digitalWrite(RPi01, LOW); // Force Power OFF Rpi N°1 delay(4000); // simule un appuie long digitalWrite(RPi01, HIGH); } else if ((Activation == 2) && ((results.value == 0x1F6) || (results.value == 0x9F6))) { Activation = 0; Serial.println("Force Power OFF Rpi N°2"); results.value = 0; // empéche la répétition de touche digitalWrite(RPi02, LOW); // Force Power OFF Rpi N°2 delay(4000); // simule un appuie long digitalWrite(RPi02, HIGH); } else if ((Activation == 3) && ((results.value == 0x1F6) || (results.value == 0x9F6))) { Activation = 0; Serial.println("Force Power OFF Rpi N°3"); results.value = 0; // empéche la répétition de touche digitalWrite(RPi03, LOW); // Force Power OFF Rpi N°3 delay(4000); // simule un appuie long digitalWrite(RPi03, HIGH); } else if ((Activation == 4) && ((results.value == 0x1F6) || (results.value == 0x9F6))) { Activation = 0; Serial.println("Force Power OFF Rpi N°4"); results.value = 0; // empéche la répétition de touche digitalWrite(RPi04, LOW); // Force Power OFF Rpi N°4 delay(4000); // simule un appuie long digitalWrite(RPi04, HIGH); } else if ((Activation == 5) && ((results.value == 0x1F6) || (results.value == 0x9F6))) { Activation = 0; Serial.println("Force Power OFF Rpi N°5"); results.value = 0; // empéche la répétition de touche digitalWrite(RPi05, LOW); // Force Power OFF Rpi N°5 delay(4000); // simule un appuie long digitalWrite(RPi05, HIGH); } else if ((Activation == 6) && ((results.value == 0x1F6) || (results.value == 0x9F6))) { Activation = 0; Serial.println("Force Power OFF Rpi N°6"); results.value = 0; // empéche la répétition de touche digitalWrite(RPi06, LOW); // Force Power OFF Rpi N°6 delay(4000); // simule un appuie long digitalWrite(RPi06, HIGH); } else if ((Activation == 7) && ((results.value == 0x1F6) || (results.value == 0x9F6))) { Activation = 0; Serial.println("Force Power OFF Rpi N°7"); results.value = 0; // empéche la répétition de touche digitalWrite(RPi07, LOW); // Force Power OFF Rpi N°7 delay(4000); // simule un appuie long digitalWrite(RPi07, HIGH); } else if ((Activation == 8) && ((results.value == 0x1F6) || (results.value == 0x9F6))) { Activation = 0; Serial.println("Force Power OFF Rpi N°8"); results.value = 0; // empéche la répétition de touche digitalWrite(RPi08, LOW); // Force Power OFF Rpi N°8 delay(4000); // simule un appuie long digitalWrite(RPi08, HIGH); } else if ((Activation == 9) && ((results.value == 0x1F6) || (results.value == 0x9F6))) { Activation = 0; Serial.println("Force Power OFF Rpi N°9"); results.value = 0; // empéche la répétition de touche digitalWrite(RPi09, LOW); // Force Power OFF Rpi N°9 delay(4000); // simule un appuie long digitalWrite(RPi09, HIGH); } else if ((Activation == 10) && ((results.value == 0x1F6) || (results.value == 0x9F6))) { Activation = 0; Serial.println("Force Power OFF Rpi N°10"); results.value = 0; // empéche la répétition de touche digitalWrite(RPi10, LOW); // Force Power OFF Rpi N°10 delay(4000); // simule un appuie long digitalWrite(RPi10, HIGH); } } //############# //# PROGRAMME # //############# void loop() { decodage_touche(); // pour récupérer le code des touches Selection(); // sélectionne le Rpi à opérer PowerONOFF(); // appelle le script de powerOff, seulement si le Rpi a été sélectionné avant ForcePowerOFF(); // Coupe l'alim du Rpi brutalement, seulement si le Rpi a été sélectionné avant delay(100); }
- Vidéo démo :
Pour finir :
- Je repense au Bluetooth qui de fait se retrouve par défaut alimenté en permanence sur les Rpi, alors on va le désactiver pour économiser une peu de courant :
sudo echo "dtoverlay=disable-bt" | sudo tee -a /boot/config.txt sudo systemctl disable hciuart.service sudo systemctl disable bluetooth.service sudo apt purge bluez -y sudo apt autoremove -y
Après celà on économise 0,011 A.
À Suivre…
Ressources :
- https://www.instructables.com/id/Setup-IR-Remote-Control-Using-LIRC-for-the-Raspber/
- https://www.instructables.com/id/Easy-Setup-IR-Remote-Control-Using-LIRC-for-the-Ra/