Système automatisé de notification des dates de sortie de séries TV et anime
Composants et fournitures
| Composant | Quantité | |
|---|---|---|
| PCB personnalisé JLCPCB | 1 | |
| Arduino Nano 33 IoT | 1 | |
| Raspberry Pi 3 Model B | 1 | Raspberry Pi 3 ou Raspberry Pi 4 |
| Raspberry Pi 4 Model B | 1 | Raspberry Pi 3 ou Raspberry Pi 4 |
| Écran Nokia 5110 SparkFun | 1 | |
| Lecteur MP3 série OPEN-SMART | 1 | |
| LED RGB à anode commune diffuse | 1 | |
| Carte mémoire Flash, carte SD | 2 | |
| Résistance 220 ohms | 12 | |
| Interrupteur poussoir 6x6x5 | 4 | |
| Prise d'alimentation DC 2.1mm type barillet montage PCB | 1 |
Outils et machines nécessaires
- Fer à souder (générique)
- Pistolet à colle chaude (générique)
Applications et services en ligne
- IDE Arduino
- KiCad
- NotePad++
À propos de ce projet
Description
Bien qu'il existe une myriade d'applications web et mobiles pour suivre les dates de sortie des émissions préférées, je voulais créer un appareil qui me notifie lorsqu'un nouvel épisode d'une série ou d'un anime de ma liste est disponible, de zéro - matériel et logiciel - avec diverses fonctionnalités.
Tout d'abord, j'ai créé une application web - Suivi des dates de sortie Séries TV / Anime - en PHP pour créer une liste de séries/animes et recueillir des informations sur leurs dates de sortie. À cet égard, j'ai utilisé l'API REST TVMAZE qui permet à l'application d'obtenir les informations d'épisodes par date de sortie précisément, sans étapes de codage complexes. Ensuite, j'ai mis en place un serveur LAMP (avec MariaDB) sur Raspberry Pi pour exécuter l'application. Mais pour ceux qui n'ont pas de Raspberry Pi ni ne veulent en utiliser un comme hôte, j'ai publié une version gratuite de l'application avec une interface conviviale sur mon site web. Vous pouvez aussi trouver le code source ci-dessous.
Après avoir transféré les informations avec l'application web, s'il y a un nouvel épisode en sortie, j'ai décidé d'utiliser un Arduino Nano 33 IoT comme carte de développement pour collecter les données générées par l'application. Vous trouverez plus d'informations ci-dessous sur la façon dont j'ai traité la réponse transférée par l'application en utilisant un délimiteur. Pour gérer les fonctionnalités et modes implémentés sur le Nano 33 IoT, j'ai conçu une interface utilisateur (menu) avec un écran Nokia 5110 et des boutons poussoirs.
Enfin, pour être informé lorsqu'un nouvel épisode d'une série de ma liste sort avec sa chanson d'ouverture, j'ai utilisé un module Lecteur MP3 Série (OPEN-SMART) grâce à sa liste de commandes UART simple à utiliser. De plus, cela m'a permis d'ajouter le mode Lecteur MP3 pour jouer toutes les chansons d'ouverture, ce qui a transformé l'appareil en un accessoire intriguant pour ma chambre :)
Après avoir finalisé mon design sur plaque d'essai et testé le code, j'ai conçu un PCB (Notificateur de dates de sortie Séries TV / Anime) avec une forme unique de téléphone rétro pour créer un appareil au look neuf et facile à utiliser.
Un grand merci à JLCPCB pour le parrainage de ce projet.
Étape 1 : Conception et soudage du PCB Notificateur Séries TV / Anime
J'ai conçu le PCB Notificateur Séries TV / Anime avec KiCad. J'ai joint le fichier Gerber du PCB ci-dessous. Si vous le souhaitez, vous pouvez commander ce PCB chez JLCPCB pour reproduire ce projet et être notifié lors de la sortie de nouveaux épisodes de vos émissions favorites :)
Tout d'abord, avec un fer à souder, j'ai fixé les connecteurs, boutons poussoirs, résistances 220Ω, la prise d'alimentation, la LED RGB anode 5mm.
Liste des composants sur le PCB :
- A1 (Connecteurs pour Arduino Nano 33 IoT)
- J1 (Connecteurs pour Lecteur MP3 Série)
- J2 (Connecteurs pour DS3231 - Non requis)
- J3 (Connecteurs pour Écran Nokia 5110)
- J4 (Prise d'alimentation)
- D1 (LED RGB anode 5mm)
- K1, K2, K3, K4 (Boutons poussoirs)
- R1-R12 (Résistances 220Ω)
Étape 2 : Configuration d'un serveur web LAMP avec MariaDB sur Raspberry Pi
Si vous êtes novice en programmation avec Raspberry Pi, vous pouvez consulter les instructions et tutoriels bien expliqués sur le site officiel de Raspberry Pi.
Tutoriel officiel Raspberry Pi pour serveur LAMP
- Ouvrez une fenêtre de terminal en sélectionnant Accessoires > Terminal dans le menu.
- Installez le paquet apache2 en tapant la commande suivante dans le terminal et en appuyant sur Entrée :
sudo apt-get install apache2 -y
- Pour tester le serveur, ouvrez Chromium via Internet > Navigateur Web Chromium et entrez
https://localhost. - Vous pouvez aussi utiliser l'adresse IP de votre Raspberry Pi :
hostname -I
- Installez le paquet PHP avec la commande suivante :
- N'oubliez pas de mettre à jour le Pi.
sudo apt-get update
sudo apt-get install php -y
- Installez le serveur MySQL (MariaDB) et les paquets PHP-MySQL :
sudo apt-get install mariadb-server php-mysql -y
- Pour créer un nouvel utilisateur, lancez la commande d'installation sécurisée MySQL :
sudo mysql_secure_installation
- On vous demandera Enter current password for root (enter for none): — appuyez sur Entrée.
- Tapez Y et Entrée pour Set root password.
- Tapez bot à l'invite New password:, puis Entrée.
- Tapez Y pour Remove anonymous users.
- Tapez Y pour Disallow root login remotely.
- Tapez Y pour Remove test database and access to it.
- Tapez Y pour Reload privilege tables now.
- À la fin, vous verrez le message : All done! and Thanks for using MariaDB!
- Pour créer une base de données (tvseries) pour sauvegarder les variables générées par l'API REST TVMAZE, lancez cette commande MySQL :
sudo mysql -uroot -p
- Entrez le mot de passe root - bot
- Vous serez accueilli par Welcome to the MariaDB monitor.
- Suivez les lignes ci-dessous après l'invite MariaDB [(none)]> : pour créer la base tvseries dans MariaDB :
create database tvseries;
GRANT ALL PRIVILEGES ON tvseries.* TO 'root'@'localhost' IDENTIFIED BY 'bot';
FLUSH PRIVILEGES;
- Quittez l'invite MariaDB avec Ctrl + D.
- Pour obtenir des données de l'API REST TVMAZE en utilisant simplement la fonction
file_get_contents()en PHP, installez le paquet php-curl :
sudo apt-get install php-curl
- Redémarrez le serveur apache pour utiliser les paquets installés sur localhost :
sudo service apache2 restart
Étape 3 : Récupération d'informations via l'API REST TVMAZE sur vos séries/animes favoris
TVMAZE fournit une API REST gratuite et facile à utiliser, permettant de rechercher des émissions par nom, date, numéro d'épisode, etc. Vous pouvez consulter les points de terminaison et requêtes disponibles :
J'ai utilisé l'option Épisode par date pour récupérer tous les épisodes d'une émission donnée qui ont été diffusés à une date spécifique.
Pour obtenir des informations par dates de sortie, vous devez rechercher vos émissions favorites sur TVMAZE et utiliser l'ID TV indiqué dans leurs liens.
- URL :
/shows/:id/episodesbydate?date=:date - Date : format ISO 8601
- Exemple :
https://api.tvmaze.com/shows/1/episodesbydate?date=2013-07-01
S'il y a un épisode diffusé à la date donnée, l'API retourne un tableau avec les infos complètes de l'épisode.
Sinon, l'API retourne une erreur HTTP 404.
Ci-dessous, ma liste de séries/animes favorites pour suivre les nouveaux épisodes avec mon projet. J'ai ajouté The Late Late Show pour tester le code car c'est une émission quotidienne.
1) One Piece - TV ID: 1505 - Lien TVMAZE
2) My Hero Academia - TV ID: 13615 - Lien TVMAZE
3) Westworld - TV ID: 1371 - Lien TVMAZE
4) The Simpsons - TV ID: 83 - Lien TVMAZE
5) The Late Late Show with James Corden - TV ID: 2831 - Lien TVMAZE
Étape 4 : Développement de l'application Suivi Séries TV / Anime (exécutée sur Raspberry Pi en PHP) et création de la table séries pour insérer les données
J'ai développé l'application en PHP et expliqué le code source ci-dessous pour les intéressés.
Si vous n'aimez pas le développement web PHP, vous pouvez télécharger l'application (TV-Series-Anime-Episode-Tracker.zip) et l'uploader sur Raspberry Pi sans coder en PHP.
Installation :
- Téléchargez l'application (TV-Series-Anime-Episode-Tracker.zip) incluant
index.phpetquery.php. - Extrayez l'archive.
- Déplacez le dossier d'application vers le serveur (
/var/www/html) via terminal car le serveur apache est un emplacement protégé :
sudo mv /home/pi/Downloads/TV-Series-Anime-Episode-Tracker/ /var/www/html/
- Accédez à l'application :
https://localhost/TV-Series-Anime-Episode-Tracker/
Fonctionnalités :
1) À l'ouverture de index.php, l'application crée automatiquement la table series et affiche Database Table Created!
2) Si la table existe déjà, elle affiche Database Table Found!
3) Pour insérer les variables requises pour l'API TVMAZE (nom série, TV ID, statut), utilisez le terminal :
sudo mysql -uroot -p
# mot de passe: bot
USE tvseries;
INSERT INTO `series` (`series_name`, `tv_id`, `status`) VALUES ('One Piece', '1505', 'Pending');
5) Sur query.php, l'application interroge l'API TVMAZE pour détecter les nouveaux épisodes. Si un épisode est sorti, elle affiche une chaîne parsable par l'Arduino Nano 33 IoT (une seule fois pour éviter la récurrence) :
%Nom_Série%Saison%Numéro_Episode%Nom_Episode%
%The Late Late Show%2020%91%Jason Schwartzman, Alicia Key%
6) Sinon, elle affiche No Entry Found!
Explication du code :
1) index.php
- Définit les paramètres de connexion à la base de données : « localhost », « root », « bot », « tvseries ».
- Dans
checkDatabase(), détecte si une table existe. - Dans
createTable(), crée la tableseriessi absente et informe l'utilisateur.
2) query.php
- Dans la classe
query, définit le chemin vers l'API TVMAZE. - Dans
define_user(), récupère les paramètres de connexion et le nom de table. - Dans
check_ep_release_date(), utilisefile_get_contents()pour détecter un nouvel épisode à la date actuelle. Change le statut de Pending à Released pour éviter la récurrence. - Dans
track_db_entries(), exécute la vérification pour chaque série enregistrée.
Étape 4.1 : Exécution de l'application web sans Raspberry Pi
Pour les abonnés de mon site (TheAmplituhedron), j'ai développé une version gratuite de l'application pour ceux qui n'ont pas de Raspberry Pi. Elle offre une interface conviviale pour gérer la base de données. Contactez-moi pour l'utiliser.
Accès à l'application : https://www.theamplituhedron.com/dashboard/TV-Series-Anime-Episode-Tracker/
Étape 5 : Configuration de l'Arduino Nano 33 IoT
Si vous êtes novice avec Arduino Nano 33 IoT : pas de souci, c'est simple avec l'IDE Arduino. Téléchargez les pilotes requis - Arduino SAMD Core - comme expliqué ici.
Pour le WiFi, téléchargez la bibliothèque WiFiNINA.
Pour l'écran Nokia 5110, téléchargez la bibliothèque LCD5110_Basic.
J'ai utilisé le second port série (Serial1) sur l'Arduino Nano 33 IoT pour communiquer avec le Lecteur MP3 Série.
Ports série sur Arduino Nano 33 IoT :
« Le connecteur USB de la carte est directement connecté aux broches hôte USB du SAMD21. Ce routage permet d'utiliser l'Arduino NANO 33 IoT comme périphérique USB client (agissant comme souris ou clavier) ou comme hôte USB pour connecter souris, clavier, téléphone Android. Ce port peut aussi servir de port série virtuel avec l'objet Serial. Les broches RX0 et TX1 sont un second port série disponible comme Serial1. »
L'Arduino Nano 33 IoT est prêt à exécuter le code du projet :)
Étape 6 : Envoi de commandes au Lecteur MP3 Série (OPEN-SMART)
J'ai créé une playlist avec les openings de mes séries/animes favoris :
- One Piece - Opening
- My Hero Academia - Opening
- Westworld - Opening
- The Simpsons - Opening
- The Late Late Show - Opening
Vous pouvez télécharger ma playlist (opening_songs.zip).
L'utilisation d'un Lecteur MP3 Série avec Arduino Nano 33 IoT est simple si vous connaissez les commandes UART. J'ai utilisé un module avec haut-parleur OPEN-SMART. Si vous avez une autre marque, ces commandes ne fonctionneront pas.
Instructions :
« Le module est un lecteur MP3 simple basé sur une puce audio haute qualité. Supporte 8k Hz ~ 48k Hz, formats MP3 et WAV. Embase pour carte micro SD. Le MCU contrôle la lecture via UART : changer de chanson, volume, mode lecture. Débogable via USB-UART. Compatible Arduino/AVR/ARM/PIC. »
« Assurez-vous que votre carte micro SD est formatée FAT16 ou FAT32 avec des chansons. Créez les dossiers « 01 » et « 02 », placez les fichiers nommés 001xxx.mp3 / 002xxx.mp3 / 003xxx.mp3 dedans. »
Enregistrez vos chansons dans un dossier « 01 » avec numéros consécutifs : 001One Piece-Opening.mp3, 002My Hero Academia-Opening.mp3, etc.
Pour envoyer les commandes UART, j'ai créé la fonction send_command_to_MP3_player. Elle transfère chaque octet de la commande vers le Lecteur MP3 via le second port série (RX0/TX1) - Serial1 - selon la longueur (4, 5 ou 6 octets).
Séparez la commande par octets - 0x7e. Toutes commencent par '7E' et finissent par 'EF'. Le second octet est le nombre d'octets entre - '02', '03', '04'. Téléchargez le manuel du Lecteur MP3 Série OPEN-SMART pour toutes les commandes.
// Commandes MP3 Player requises
// Sélectionner périphérique stockage carte TF
static int8_t select_SD_card[] = {0x7e, 0x03, 0X35, 0x01, 0xef}; // 7E 03 35 01 EF
// Jouer chanson dossier: /01/001xxx.mp3
static int8_t play_song_1[] = {0x7e, 0x04, 0x41, 0x00, 0x01, 0xef}; // 7E 04 41 00 01 EF
// Jouer chanson dossier: /01/002xxx.mp3
static int8_t play_song_2[] = {0x7e, 0x04, 0x41, 0x00, 0x02, 0xef}; // 7E 04 41 00 02 EF
// Jouer chanson dossier: /01/003xxx.mp3
static int8_t play_song_3[] = {0x7e, 0x04, 0x41, 0x00, 0x03, 0xef}; // 7E 04 41 00 03 EF
// Jouer chanson dossier: /01/004xxx.mp3
static int8_t play_song_4[] = {0x7e, 0x04, 0x41, 0x00, 0x04, 0xef}; // 7E 04 41 00 04 EF
// Jouer chanson dossier: /01/005xxx.mp3
static int8_t play_song_5[] = {0x7e, 0x04, 0x41, 0x00, 0x05, 0xef}; // 7E 04 41 00 05 EF
// Lecture
static int8_t play[] = {0x7e, 0x02, 0x01, 0xef}; // 7E 02 01 EF
// Pause
static int8_t pause[] = {0x7e, 0x02, 0x02, 0xef}; // 7E 02 02 EF
// Suivant
static int8_t next_song[] = {0x7e, 0x02, 0x03, 0xef}; // 7E 02 03 EF
// Précédent
static int8_t previous_song[] = {0x7e, 0x02, 0x04, 0xef}; // 7E 02 04 EF
Étape 7 : Programmation de l'Arduino Nano 33 IoT
- Inclure les bibliothèques requises.
- Définir vos paramètres WiFi - SSID et mot de passe.
- Entrer l'adresse IP de votre Raspberry Pi.
- Définir le chemin de l'application (
query.php) sur Raspberry Pi. - Initialiser la bibliothèque client Ethernet.
- Définir les paramètres de l'écran Nokia 5110.
- Définir les graphismes pour les modes écran - tv et musique.
- Créer des graphismes (images monochromes) via Monochrome Image Converter.
- Définir les commandes MP3 Player requises.
- Définir les options de menu et modes avec booléens volatils.
- Définir les broches des boutons de contrôle et LED RGB.
- Initialiser la communication série pour le module Lecteur MP3 sur le second port -
Serial1. - Se connecter au réseau WiFi.
- Vérifier la connexion sur le moniteur série et l'écran Nokia 5110.
- Dans
read_buttons(), lire les boutons - Droite, OK, Gauche, Sortie. - Dans
change_menu_options(), incrémenter/décrémenter l'option avec Droite/Gauche. - Dans
interface(), afficher le menu. - Si mode Init Tracker sélectionné, se connecter à l'application web.
- Si octets entrants disponibles, récupérer la réponse.
- Avec
endsWith(), détecter si la réponse contient le symbole pourcentage (délimiteur). - Si inclus, diviser la chaîne par le délimiteur prédéfini (
'%'). - Extraire les sous-chaînes : Nom_Série, Saison, Épisode, Nom_Épisode.
- Afficher les infos et jouer l'opening de la série/anime jusqu'à arrêt.
- Attendre l'appui sur le bouton Sortie.
- Si réponse vide, afficher No Released Episode Detected :(
- Dessiner l'icône TV en attendant la prochaine requête.
- Attendre la prochaine requête.
- Si mode MP3 Player sélectionné, dessiner l'icône musique. Contrôler avec Droite, Gauche, OK.
- Si mode Sleep sélectionné, activer le mode veille dans 10 secondes et afficher le compte à rebours.
Connexions et ajustements
// Connexions
// Arduino Nano 33 IoT:
// Nokia 5110 Screen
// D2 -------------------------- SCK (Clk)
// D3 -------------------------- MOSI (Din)
// D4 -------------------------- DC
// D5 -------------------------- RST
// D6 -------------------------- CS (CE)
// RGB
// D9 -------------------------- R
// D10 -------------------------- G
// D11 -------------------------- B
// LEFT_BUTTON
// A0 --------------------------- S
// OK_BUTTON
// A1 --------------------------- S
// RIGHT_BUTTON
// A2 --------------------------- S
// EXIT_BUTTON
// A3 --------------------------- S
// DS3231 (Optionnel pour Nano, Non requis pour Nano 33 IoT)
// A4 --------------------------- SDA
// A5 --------------------------- SCL
Après avoir téléversé le code, j'ai connecté tous les composants via les connecteurs.
J'ai aussi prévu un emplacement pour un module RTC DS3231 pour ceux qui veulent remplacer le Nano 33 IoT par un Nano classique. Mais vous devrez entrer manuellement les dates de sortie pour chaque série sur le Nano sans pouvoir récupérer les données de l'application web pour créer un compte à rebours avec le RTC.
Note : Vous pouvez connecter un haut-parleur ou un casque au Lecteur MP3 Série. J'ai utilisé le haut-parleur fourni avec le module OPEN-SMART.
Modes et fonctionnalités
1) Connexion WiFi : Affiche Waiting... Attempting to connect to WiFi.
2) Connexion réussie : Affiche Connected to WiFi!!!
3) Interface (menu) : Modes disponibles - A.Init Tracker, B.MP3 Player, C.Sleep. Naviguer avec Droite/Gauche, valider avec OK.
A.Init Tracker
A.1) Connexion au serveur local (Raspberry Pi). Succès : Connected to the server!!! Échec : Connection Error!!!
A.2) Si l'application envoie des données d'épisode sorti :
- Affiche : Nom série, Saison, Numéro épisode, Nom épisode (ex: One Piece, 10x54, Luffy's Determination)
- Joue l'opening de la série/anime
- Allume la LED RGB avec la couleur assignée
Couleurs assignées :
- One Piece → Rouge
- My Hero Academia → Vert
- Westworld → Bleu
- The Simpsons → Jaune
- The Late Late Show → Violet
L'appareil notifie une seule fois par épisode pour éviter les récurrences.
A.3) Après appui sur Sortie, affiche l'icône TV en attendant la prochaine requête.
A.4) Si aucun épisode sorti : No Released Episode Detected :( puis icône TV.
A.5) Retour au menu si Sortie pressé pendant l'icône TV.
B. MP3 Player
Fonctionnalité ludique pour transformer l'appareil en accessoire de chambre.
B.1) Affiche l'icône note de musique. Contrôles : Droite = Suivant, Gauche = Précédent, OK = Pause.
B.2) Retour au menu si Sortie pressé.
C. Sleep
C.1) Active le mode veille dans 10 secondes avec compte à rebours.
C.2) En veille, applique un motif de couleurs sur la LED RGB comme veilleuse.
C.3) Retour au menu si Sortie pressé.
Vidéos et conclusion
Après toutes les étapes, j'ai fixé l'appareil à ma bibliothèque avec un pistolet à colle chaude. Il fonctionne parfaitement :)
Code
Series_Release_Date_Notifier.ino (Arduino)
//////////////////////////////////////////////////// // TV Series / Anime New Episode // // Release Date Notifier // // ------------------------- // // Arduino Nano 33 IoT // // by Kutluhan Aktar // // // //////////////////////////////////////////////////// // Get informed when new episodes of your favorite shows are on release with their opening songs via Nano 33 IoT and Raspberry Pi. // // I developed a corroborating web application in PHP for this project, named TV Series / Anime Release Date Tracker. // You can either use a Raspberry Pi as the server, explained in the project tutorial, or TheAmplituhedron with the real-time database interface if you are a member. // // For more information: // https://www.theamplituhedron.com/projects/TV-Series-Anime-New-Episode-Release-Date-Notifier/ // // You can use the mentioned web application in free version on TheAmplituhedron as the host server if you are a subscriber: // https://www.theamplituhedron.com/dashboard/TV-Series-Anime-Episode-Tracker/ // // Connexions // Arduino Nano 33 IoT: // Nokia 5110 Screen // D2 --------------------------- SCK (Clk) // D3 --------------------------- MOSI (Din) // D4 --------------------------- DC // D5 --------------------------- RST // D6 --------------------------- CS (CE) // RGB // D9 --------------------------- R // D10 --------------------------- G // D11 --------------------------- B // LEFT_BUTTON // A0 --------------------------- S // OK_BUTTON // A1 --------------------------- S // RIGHT_BUTTON // A2 --------------------------- S // EXIT_BUTTON // A3 --------------------------- S // DS3231 (Optional for Nano and Not Required for Nano 33 IoT) // A4 --------------------------- SDA // A5 --------------------------- SCL // Bibliothèques requises: #include #include #include char ssid[] = "[_SSID_]"; // votre SSID réseau (nom) char pass[] = "[_PASSWORD_]"; // votre mot de passe réseau (WPA ou clé WEP) int keyIndex = 0; // index clé réseau (nécessaire seulement pour WEP) int status = WL_IDLE_STATUS; // Note: Décommentez les paramètres de connexion équivalents fournis sous les lignes associées pour utiliser l'application web hébergée sur TheAmplituhedron si vous êtes abonné. // Adresse IP de votre Raspberry Pi. IPAddress server(192, 168, 1, 22); /* // Adresse nom pour TheAmplituhedron. Changez avec votre serveur si vous utilisez un hôte différent. char server[] = "www.theamplituhedron.com"; */ // Chemin de l'application sur Raspberry Pi. String application = "/TV-Series-Anime-Episode-Tracker/query.php"; /* // Définissez votre hedron si vous utilisez TheAmplituhedron comme serveur hôte: String HEDRON = "[_HEDRON_]"; // Chemin de l'application web. Si vous utilisez TheAmplituhedron, entrez votre hedron. Sinon, le chemin sur votre serveur. String application = "/dashboard/TV-Series-Anime-Episode-Tracker/" + HEDRON; */ // Initialiser la bibliothèque client Ethernet WiFiClient client; /* WiFiSSLClient client; */ // Paramètres écran. LCD5110 myGLCD(2,3,4,5,6); extern uint8_t SmallFont[]; extern uint8_t MediumNumbers[]; // Graphismes pour modes écran. extern uint8_t tv[]; extern uint8_t music[]; // Commandes MP3 Player requises. static int8_t select_SD_card[] = {0x7e, 0x03, 0X35, 0x01, 0xef}; static int8_t play_song_1[] = {0x7e, 0x04, 0x41, 0x00, 0x01, 0xef}; static int8_t play_song_2[] = {0x7e, 0x04, 0x41, 0x00, 0x02, 0xef}; static int8_t play_song_3[] = {0x7e, 0x04, 0x41, 0x00, 0x03, 0xef}; static int8_t play_song_4[] = {0x7e, 0x04, 0x41, 0x00, 0x04, 0xef}; static int8_t play_song_5[] = {0x7e, 0x04, 0x41, 0x00, 0x05, 0xef}; static int8_t play[] = {0x7e, 0x02, 0x01, 0xef}; static int8_t pause[] = {0x7e, 0x02, 0x02, 0xef}; static int8_t next_song[] = {0x7e, 0x02, 0x03, 0xef}; static int8_t previous_song[] = {0x7e, 0x02, 0x04, 0xef}; // Options menu et modes avec booléens volatils. volatile boolean TV = false; volatile boolean Music = false; volatile boolean Sleep = false; volatile boolean Activated = false; // Boutons de contrôle. #define B_Exit A3 #define B_Right A2 #define B_OK A1 #define B_Left A0 // Broches LED RGB. #define redPin 9 #define greenPin 10 #define bluePin 11 // Variables de données: int Right, OK, Left, Exit; int selected = 0; void setup() { // Boutons: pinMode(B_Exit, INPUT); pinMode(B_Right, INPUT); pinMode(B_OK, INPUT); pinMode(B_Left, INPUT); // RGB: pinMode(redPin, OUTPUT); pinMode(greenPin, OUTPUT); pinMode(bluePin, OUTPUT); adjustColor(0, 0, 0); // Noir // Initialiser écran. myGLCD.InitLCD(); myGLCD.setFont(SmallFont); Serial.begin(9600); // Communication série pour Lecteur MP3. Serial1.begin(9600); // Sélectionner carte SD. send_command_to_MP3_player(select_SD_card, 5); // Vérifier module WiFi: if (WiFi.status() == WL_NO_MODULE) { Serial.println("Communication with WiFi module failed!"); myGLCD.print("Connection Failed!", 0, 8); while (true); } // Tentative connexion WiFi: while (status != WL_CONNECTED) { Serial.print("Attempting to connect to SSID: "); Serial.println(ssid); myGLCD.print("Waiting...", 0, 8); myGLCD.print("Attempting to", 0, 16); myGLCD.print("connect to", 0, 24); myGLCD.print("WiFi !!!", 0, 32); // Connexion WPA/WPA2. Changez cette ligne pour réseau ouvert ou WEP: status = WiFi.begin(ssid, pass); // Attendre 10 secondes pour connexion: delay(10000); } // Vérifier connexion sur moniteur série et écran Nokia 5110. Serial.println("Connected to wifi"); myGLCD.clrScr(); myGLCD.print("Connected to", 0, 8); myGLCD.print("WiFi!!!", 0, 16); delay(2000); myGLCD.clrScr(); } void loop() { read_buttons(); change_menu_options(); interface(); if(TV == true){ do{ myGLCD.invertText(true); myGLCD.print("A.Init Tracker", 0, 16); myGLCD.invertText(false); delay(100); if(OK == HIGH){ myGLCD.clrScr(); Activated = true; while(Activated == true){ // Connexion à l'application web. Changez '80' par '443' si TheAmplituhedron comme hôte. if (client.connect(server, 80)) { Serial.println("connected to server"); myGLCD.print("Connected to", 0, 8); myGLCD.print("the server!!!", 0, 16); // Requête HTTP: client.println("GET " + application + " HTTP/1.1"); //client.println("Host: www.theamplituhedron.com"); client.println("Host: 192.168.1.22"); client.println("Connection: close"); client.println(); }else{ myGLCD.print("Connection", 0, 8); myGLCD.print("Error!!!", 0, 16); } delay(2000); // Attendre 2 secondes après connexion... // Si octets entrants, récupérer réponse. String response = ""; while (client.available()) { char c = client.read(); response += c; } if(response != "" && response.endsWith("%")){ // Diviser la chaîne par le délimiteur prédéfini. '%' est le délimiteur. int delimiter, delimiter_1, delimiter_2, delimiter_3, delimiter_4; delimiter = response.indexOf("%"); delimiter_1 = response.indexOf("%", delimiter + 1); delimiter_2 = response.indexOf("%", delimiter_1 +1); delimiter_3 = response.indexOf("%", delimiter_2 +1); delimiter_4 = response.indexOf("%", delimiter_3 +1); // Extraire informations comme sous-chaînes. String Series_Name = response.substring(delimiter + 1, delimiter_1); String Season = response.substring(delimiter_1 + 1, delimiter_2); String Episode = response.substring(delimiter_2 + 1, delimiter_3); String Episode_Name = response.substring(delimiter_3 + 1, delimiter_4); // Afficher informations. myGLCD.clrScr(); myGLCD.print(Series_Name, 0, 0); myGLCD.print(Season + " x " + Episode, 0, 16); myGLCD.print(Episode_Name, 0, 32); // Jouer l'opening jusqu'à arrêt: if(Series_Name == "One Piece") { send_command_to_MP3_player(play_song_1, 6); adjustColor(255,0,0); } if(Series_Name == "My Hero Academia") { send_command_to_MP3_player(play_song_2, 6); adjustColor(0,255,0); } if(Series_Name == "Westworld") { send_command_to_MP3_player(play_song_3, 6); adjustColor(0,0,255); } if(Series_Name == "The Simpsons") { send_command_to_MP3_player(play_song_4, 6); adjustColor(255,255,0); } if(Series_Name == "The Late Late Show") { send_command_to_MP3_player(play_song_5, 6); adjustColor(80,0,80); } // Attendre bouton Sortie... volatile boolean song = true; while(song == true){ read_buttons(); if(Exit == HIGH){ song = false; send_command_to_MP3_player(pause, 4); adjustColor(0,0,0); } } myGLCD.clrScr(); }else{ // Aucune épisode. myGLCD.clrScr(); myGLCD.print("No Released", 0, 0); myGLCD.print("Episode", 0, 16); myGLCD.print("Detected :(", 0, 32); delay(5000); myGLCD.clrScr(); } // Dessiner icône TV en comptant jusqu'à nouvelle requête... myGLCD.drawBitmap(8, 0, tv, 60, 48); delay(10 * 1000); // Attendre prochaine requête... myGLCD.clrScr(); // Sortie. read_buttons(); if(Exit == HIGH){ Activated = false; myGLCD.clrScr(); } } }while(TV == false); } if(Music == true){ do{ myGLCD.invertText(true); myGLCD.print("B.MP3 Player", 0, 24); myGLCD.invertText(false); delay(100); if(OK == HIGH){ myGLCD.clrScr(); Activated = true; while(Activated == true){ read_buttons(); // Dessiner icône lecteur musique. myGLCD.drawBitmap(8, 0, music, 60, 48); // Lecteur MP3: if(Right == true) send_command_to_MP3_player(next_song, 4); if(Left == true) send_command_to_MP3_player(previous_song, 4); if(OK == true) send_command_to_MP3_player(pause, 4); // Sortie. if(Exit == HIGH){ Activated = false; myGLCD.clrScr(); send_command_to_MP3_player(pause, 4); } } } }while(Music == false); } if(Sleep == true){ do{ myGLCD.invertText(true); myGLCD.print("C.Sleep", 0, 32); myGLCD.invertText(false); delay(100); if(OK == HIGH){ // Activer mode veille dans 10 secondes. myGLCD.clrScr(); myGLCD.print("Entering", CENTER, 0); myGLCD.print("Sleep Mode", CENTER, 8); myGLCD.print("in", CENTER, 16); myGLCD.print("Seconds", CENTER, 40); // Afficher secondes restantes. myGLCD.setFont(MediumNumbers); for (int s=10; s>=0; s--){ myGLCD.printNumI(s, CENTER, 24, 2, '0'); delay(1000); } myGLCD.enableSleep(); Activated = true; while(Activated == true){ // Motif couleurs: adjustColor(255,0,0); delay(500); adjustColor(0,255,0); delay(500); adjustColor(0,0,255); delay(500); adjustColor(255,255,0); delay(500); adjustColor(80,0,80); delay(500); // Sortie. read_buttons(); if(Exit == HIGH){ Activated = false; myGLCD.clrScr(); myGLCD.disableSleep(); myGLCD.setFont(SmallFont); adjustColor(0,0,0); } } } }while(Sleep == false); } } void read_buttons(){ Right = digitalRead(B_Right); OK = digitalRead(B_OK); Left = digitalRead(B_Left); Exit = digitalRead(B_Exit); } void send_command_to_MP3_player(int8_t command[], int len){ Serial.print("\nMP3 Command => "); for(int i=0;i 3) selected = 1; delay(100); switch(selected){ case 1: TV = true; Music = false; Sleep = false; break; case 2: TV = false; Music = true; Sleep = false; break; case 3: TV = false; Music = false; Sleep = true; break; } } void adjustColor(int red, int green, int blue){ red = 255 - red; green = 255 - green; blue = 255 - blue; analogWrite(redPin, red); analogWrite(greenPin, green); analogWrite(bluePin, blue); }
index.php (PHP)
0) ? true : false; } function createTable($table_name, $conn){ if(!checkDatabase($table_name, $conn)){ $sql = "CREATE TABLE `$table_name`( id int(11) AUTO_INCREMENT PRIMARY KEY NOT NULL, series_name varchar(255) NOT NULL, tv_id varchar(255) NOT NULL, status varchar(255) NOT NULL );"; if(mysqli_query($conn, $sql)){ echo "Database Table Created!"; }else{ echo "Error!"; } }else{ echo "Database Table Found!"; } } createTable("series", $conn_database); ?>
query.php (PHP)
conn = $conn; $this->table_name = $table_name; } private function check_ep_release_date($API_ID, $series_name, $status){ $date = date("Y-m-d"); $URL = self::ROOT.$API_ID.self::PATH.$date; if($get_content = json_decode(file_get_contents((String)$URL))){ if($status != "Released"){ echo "%".$series_name."%".$get_content[0]->season."%".$get_content[0]->number."%".$get_content[0]->name."%"; $sql = "UPDATE `$this->table_name` SET `status`='Released' WHERE series_name='$series_name'"; mysqli_query($this->conn, $sql); } }else{ if($status != "Pending"){ $sql = "UPDATE `$this->table_name` SET `status`='Pending' WHERE series_name='$series_name'"; mysqli_query($this->conn, $sql); } } } public function track_db_entries(){ $sql = "SELECT * FROM `$this->table_name` ORDER BY `id` DESC"; if($result = mysqli_query($this->conn, $sql)){ $check = mysqli_num_rows($result); if($check > 0){ while($row = mysqli_fetch_assoc($result)){ $this->check_ep_release_date($row['tv_id'], $row['series_name'], $row['status']); } }else{ echo "No Entry Found!"; } }else{ echo "No Database Found!"; } } } $conn_database = mysqli_connect("localhost", "root", "bot", "tvseries"); $table = "series"; $q = new query(); $q->define_user($conn_database, $table); $q->track_db_entries(); ?>
Pièces personnalisées et boîtiers
- gerber_ycEfXzZq6h.zip (fichiers Gerber PCB)
- tv-series-anime-episode-tracker_gCfN0nFiA8.zip (application PHP)
- opening_songs_y2LCEw79tg.zip (chansons d'ouverture)
- tv_Iz2isO8nGI.c (graphisme TV)
- music_SA2xR86cZw.c (graphisme musique)
Schémas
Processus de fabrication
- Construire une télécommande universelle Raspberry Pi professionnelle avec LIRC
- Conversion RF vers DC avec Raspberry Pi : Construction et dépannage d'un détecteur d'enveloppe
- Cycle Chaser : Transformer votre vélo en spectacle lumineux nocturne avec Raspberry Pi
- Construire un détecteur de voleur basé sur Raspberry Pi – Guide étape par étape
- Construire un moniteur de température domestique avec Raspberry Pi, MCP9808, InfluxDB et Grafana
- Construire un système domotique piloté par Raspberry Pi pour contrôle à distance
- Raspberry Pi 3 B+ — Fonctionnalités, Spécifications et Guide d'Achat Mis à Jour
- Robot DIY inspiré de Wall‑E : Raspberry Pi dans une boîte de CD recyclée
- RasPiRobot Board V2 : Transformez votre Raspberry Pi en contrôleur robot puissant