Pourquoi fabriquer son propre radio-réveil ?
Vous en avez marre de votre vieux radio réveil qui n’arrive plus à capter la FM et a un bruit de sonnerie infernal ?
Vous aimeriez un radio réveil qui puisse capter la radio FM via internet : de bien meilleur qualité audio et qui puisse avoir une sonnerie de votre choix ?
Vous pourriez utiliser votre téléphone mais il faut penser à couper toutes ces notifications dont vous avez besoin en journée qui le font vibrer la nuit inutilement.
Pourquoi utiliser un raspberry Pi ?
Alors pourquoi ne pas utiliser un Raspberry Pi ? Voilà ce que je me suis dit il y a quelques temps.
On pourrait tenter de le faire avec un arduino ou un ESP32. Mais il faut quand même pouvoir lire du son en streaming ou une liste de fichiers mp3 dans une thread distincte : un Arduino n’est pas assez puissant pour ça. Et l’ESP32 sera limite.
De quoi aurions nous besoin ?
On peut tout imaginer comme options possibles.
Mais partons de la base. Il faut à minima :
- Afficher l’heure (donc la connaitre)
- Disposer d’un petit écran
- Lire un fichier mp3 (ou une liste de fichiers mp3)
- Avoir une sortie son
- Lire une source de streaming audio (Web radio FM)
- Avoir des boutons de réglage
- On pourrait aussi afficher la température ambiante, le taux d’humidité ambiante et tout un tas de choses amusantes.
Le choix de l’écran
On ne va pas utiliser un moniteur de PC ! Donc je suis parti sur un petit écran OLED qui possède déjà plusieurs (3 + 1 multi-positions) la présence des boutons intégrés à l’écran va grandement diminuer les câblages nécessaires.
![]() |
Le waveshare 1.44 inch Oled a une résolution de 128×128 et l’avantage d’intégrer 4 boutons. Mais comme tous les écrans de type “Hat”, il a l’inconvénient d’occuper toutes les broches du GPIO mêmes celles dont il n’a pas besoin. Aussi, pour utiliser d’autres broches du GPIO, il faut prévoir un HAT dérivateur. |
![]() |
Ce type de HAT, posé entre le raspberry et l’écran peut servir pour pouvoir utiliser les pin du GPIO en plus de l’écran. Sinon, seul l’écran pourra être connecté |
La mesure du temps
Contrairement à un radio-réveil classique ou un PC : Le Raspberry ne comporte pas d’horloge interne : il récupère l’heure par internet puis décompte le temps qui passe. Donc soit :
- Vous utilisez ajouter une horloge RTC : comme il faudra la connecter au GPIO , il faudra utiliser le dérivateur de GPIO , en ce cas, il devient disponible pour d’autres sondes comme par exemple : la mesure de la température.
- Soit vous faites confiance à sa connexion à internet et vous pouvez vous passer de l’horloge RTC et possiblement du dérivateur. Remarque : le tout dernier modèle de Raspberry Pi (le 5) possède une horloge RTC, ce peut-être une option.
1ers essais
Au départ, je souhaitais avoir la mesure de la température de la pièce, du taux d’humidité et avoir une horloge RTC. J’ai donc installé un dérivateur de port. Tout fonctionnait très bien mais évidement l’ensemble n’était pas très esthétique et nécessiterait un boitier. N’étant pas familier de l’impression 3D, j’ai décidé finalement de l’horloge, de la sonde de température et donc du dérivateur.
Choix final du matériel :
- Un Raspberry Pi2 ou 3 ou 4 ou 5 ou même un Pi Zéro (n’importe lequel fera l’affaire)
- L’écran Oled de chez Waveshare
- Un boitier : plusieurs solutions sont possibles, j’ai choisis un refroidisseur passif : le Pi2 est pris en sandwich entre 2 plaques de metal équipées d’ailettes de refroidissement et l’écran se pose au-dessus grâce à un petit prolongateur de GPIO.
![]() |
Le boitier du Pi2 (compatible Pi3) est un sandwich de 2 plaques de métal équipées d’ailettes. |
![]() |
Le boitier éloigne l’accès au port GPIO, j’ai utilisé ce petit prolongateur de 2 rangées de 20 PINS femelles – mâles |
La programmation :
Qui dit utilisation d’un Raspberry et destination grand public dit : Python bien sûr
Donc je suis parti de la dernière distribution de Raspi OS (actuellement Bookworm) en version light (sans le bureau car je n’en ai pas besoin mais vous pouvez le laisser et choisir la version “normale”, le Pi consommera juste du CPU pour rien)
Qui dit distribution récente de Linux dit aussi Python 3. Car python 2 est abandonné et il n’est presque plus utilisé.
Comme tous les langages de programmation, pour communiquer avec des différents éléments extérieur au Pi (ou au PC) on a 2 possibilités
- tout faire soit même en réinventant la roue.
- ou utiliser des bibliothèques pour les tâches spécifiques (ex ici : le pilotage de l’écran et des boutons)
L’écran m’a été fournis avec une carte de visite comportant un lien , il utilise le port SPI qu’il faudra activer grâce à l’utilitaire “raspi-config“.
Le lien concerne le wiki de l’écran, y sont expliqués comment il fonctionne, quelles bibliothèques installer pour pouvoir l’utiliser et des exemples de code d’utilisation ainsi que des scripts pour tester l’écran et les boutons.
Pour ceux que cela intéresse voici les 14 pin qu’utilise l’écran (il n’utilise donc pas les 40 Pins)
- Pour le port SPI :
- RST= 27
- DC = 25
- CS = 8
- BL = 24
- Pour le bouton de gauche qui a 5 fonctions : haut, bas, gauche, droite et presser :
- UP = 6, DOWN = 19
- LEFT = 5
- RIGHT = 26
- PRESS = 13
- Pour les 3 boutons de droites :
- KEY1 = 21
- KEY2 = 20
- KEY3 = 16
- Plus
- une masse
- et un +3,3V
On peut même forcer Raspi OS pour qu’il utilise cet écran comme moniteur mais je le déconseille : que faire d’un bureau sur un écran de 128×128 ?
Installation des bibliothèques pour python3
sudo apt-get update sudo apt-get install python3-pip sudo apt-get install python3-numpy sudo pip3 install RPi.GPIO sudo pip3 install spidev
Vous avez reconnu plusieurs commandes : apt (apt-get) permet de télécharger et d’installer des logiciels. Parmi ceux qui sont nécessaires, il y a “Pip” qui est l’outil indispensable pour installer des librairies complémentaires à Python et NumPy qui est une bibliothèque réalisée en C, compilée et qui fourni à Python des capacités de calculs mathématiques améliorés.
Enfin il y a Rpi.GPIO qui permet à python d’exploiter le port GPIO auquel est connecté l’écran et spidev qui permet d’utiliser le protocole SPI que l’écran exploite.
Téléchargement et tests de l’écran
sudo apt-get install p7zip-full -y wget https://files.waveshare.com/upload/f/fa/1.44inch-LCD-HAT-Code.7z 7z x 1.44inch-LCD-HAT-Code.7z sudo chmod 777 -R 1.44inch-LCD-HAT-Code cd 1.44inch-LCD-HAT-Code/RaspberryPi/
Maintenant dans 1.44inch-LCD-HAT-Code/RaspberryPi/, vous devez avoir:
- Un dossier nommé C qui contient des codes sources en C qu’on ne va pas utiliser
- Un dossier nommé python qui contient les codes en Python
Dans le dossier python on a :
- un script pour tester l’affichage de l’écran : sudo python main.py
- un script pour tester les boutons : sudo python key_demo.py
- un script de bibliothèque nommé LCD_1in44.py : il sait initialiser l’écran, l’effacer et lui demander d’afficher une image, c’est tout !
- un script de bibliothèque nommé LCD_config.py utilisé par LCD_1in44.py qui est de plus pas niveau encore : il initialise l’écran et lui envoie des données bits à bits.
Les fonctionnalités désirées :
Je souhaite que mon “Pi radio-réveil puisse” :
- Afficher l’heure qu’il est
- Afficher le jour qu’il est
- Se mettre tout seul à l’heure
- Me permettre de choisir l’heure à laquelle je veux être réveillé et afficher l’heure du réveil
- Activer – désactiver le réveil, me permettant de visualiser si l’alarme est mise ou non
- Choisir si je veux être réveillé par une sonnerie ou par la radio ou par l’écoute de titres que je possède
- Choisir la sonnerie entre différents sons possibles
- Choisir la station de radio qui me réveille
- Choisir le titre ou une liste de titre à écouter durant mon réveil
- Lancer moi-même à tout instant l’écoute d’une radio ou d’u mp3 ou d’une liste de mp3
- Stopper l’écoute que ce soit au réveil ou pas.
- Stopper l’écoute à tout moment sans être obligé d’attendre la fin du morceau
Ca fait pas mal non ? D’autant que je le rappelle : la bibliothèque fournie ne sait faire que 2 choses : effacer l’écran ou lui demander d’afficher une image ! Bref toute information à afficher doit être dans une image. Donc en fait, il faut construire l’image puis l’envoyer à l’écran. Et voilà on va avoir besoin de la bibliothèque python Pillow (Pil) dont c’est justement la spécialité et c’est pour cela qu’elle est utilisée dans les scripts d’exemples fournis !
Etant donné que créer une nouvelle image et l’envoyer à l’écran prend du temps, on ne le fera que lorsque cela est nécessaire ! (Ex : on vient de passer de 12h11 à 12h12 ou un utilisateur a appuyé sur un bouton).
La lecture de sons :
Pendant la lecture du son (sonnerie ou radio, ou fichier mp3), le réveil doit continuer de répondre à l’utilisateur (afficher le changement d’heure (ex si on passe de 13h01 à 13h02) et réagir aux pressions sur les boutons. Donc la lecture de fichiers audio doit se faire dans un autre processus que le traitement de l’écran et des boutons.
En fait, j’ai choisis de faire simple : le programme du réveil lancera un sous-programme en récupérant son identifiant ce qui lui permettra de le “tuer” si l’utilisateur souhaite stopper l’écoute. J’ai donc commencer par développer ce sous-programme.
Toujours en python : pour la lecture de sons je vais utiliser la bibliothèque “playsound”, pour l’installer, c’est simple :
sudo pip3 install playsound
Il faut aussi installer celles qui permet à Linux de lire du streaming:
sudo apt-get install libgstreamer1.0 libgstreamer1.0-dev gstreamer1.0-tools
Mon script recevra 1 seul argument : le fichier audio à lire ou l’url à ouvrir ou une liste de fichiers audio à lire (fichier m3u)
Il s’utilise ainsi :
- Pour lire un fichier mp3 : python3 play.py /home/pi/mon_titre.mp3
- Pour lire une liste de fichiers mp3 : python3 play.py /home/pi/ma_liste.m3u
- Pour écouter Radio Nostalgie : python3 play.py https://scdn.nrjaudio.fm/adwz2/fr/30601/mp3_128.mp3?origine=radio.net
- Télécharger play.mp3 :

A noter : pour que la lecture d’un fichier m3u fonctionne il doit :
- Etre dans le même dossier que les fichiers audio
- Contenir une ligne par fichier audio et ne pas préciser contenir le chemin du dossier
Exemple (ici mon 1er fichier se nomme réellement “01. Child Fire.mp3” : avec le 01. devant et les espaces) :
01. Child Fire.mp3 02. Magical Harmony.mp3 03. Not Heal Yet.mp3 04. Chosen One.mp3 05. Blood Brothers.mp3 06. Ignorance.mp3 07. Delicately.mp3 08. Not a Detail.mp3 09. Grey Circles.mp3 10. Ascension.mp3 11. Near Death Experience.mp3
Vous avez essayer playsound.py ? il fonctionne ? Alors passez à la suite. Sinon, recherchez pourquoi. Il s’agit probablement d’un problème de sélection de la carte son par défaut ou d’un oubli d’installer la bibliothèque playsound.
A noter : entre le moment où play.py est lancé et le moment où vous entendez les 1ers sons, il peut se passer quelques secondes voir une bonne dizaine de secondes.
Stockage des données du programme :
Si vous débranchez le réveil puis que vous le réallumez, il va bien falloir qu’il retrouve si l’alarme était activée, à quelle heure, ce qui doit être joué au réveil (lecture de radio, de fichier son). Donc ces données doivent être stockées sur la SD Card.
Pour ces données, j’ai choisi d’utiliser un fichier “param.ini” et si ce fichier n’est pas présent, ce n’est pas grave : le programme va le recréer avec un réveil inactif prévu à 00:00, avec comme sélection : aucune station de radio et aucun fichier mp3 ni liste de fichiers mp3.
De même, je ne compte pas permettre d’utiliser les boutons pour saisir l’url d’une nouvelle station de radio ou le nom d’un nouveau fichier mp3 ! Donc l’utilisateur va devoir choisir parmi une liste d’options possibles. L’utilisateur choisira par clic cours sur un bouton. Chaque clic sélectionnant le fichier suivant. Une fois arrivé au dernier, le prochain clic indiquera qu’aucun fichier n’est sélectionné et au clic suivant que le 1er fichier de la liste l’est. Tandis que l’appui long déclenchera ou arrêtera la lecture du fichier son (ou de la radio)
Ces informations sont stockées dans 2 fichiers json distincts :
Le fichier radiolist.json
Il contient une liste de station radio accessible par internet, voici un exemple :
[
{"id":"0", "name":"MBS" , "url":"https://mbs.ice.infomaniak.ch/mbs-128.mp3"},
{"id":"1", "name":"Nostalgie" , "url":"https://scdn.nrjaudio.fm/adwz2/fr/30601/mp3_128.mp3?origine=radio.net"},
{"id":"2", "name":"Oui FM" , "url":"https://ouifm.ice.infomaniak.ch/ouifm-high.mp3"},
{"id":"3", "name":"Floyd Rock" , "url":"http://91.121.59.45:8013/stream"}
]
L’ensemble est entouré de crochets car c’est une liste de plusieurs stations de radio
Chaque station commence et se termine par une accolade puis une virgule (sauf pour la dernière)
Pour chaque station on retrouve :
- Un id : numéro séquentiel
- name : le nom tel qu’il sera affiché sur l’écran
- url : l’url qui permet de capter la diffusion de la station
Le fichier audiolist.json
Il contient une liste fichiers audio de musique présent sur votre carte SD !
Exemple :
[
{"id":"0", "name":"Amartia list" , "filename":"/home/pi/lcd/musique/amartia_in_a_quiet_place/amartia_in_a_quiet_place.m3u"},
{"id":"1", "name":"Not a detail" , "filename":"/home/pi/lcd/musique/amartia_in_a_quiet_place/08. Not a Detail.mp3"},
{"id":"2", "name":"NDE" , "filename":"/home/pi/lcd/musique/amartia_in_a_quiet_place/11. Near Death Experience.mp3"},
{"id":"3", "name":"Ascension" , "filename":"/home/pi/lcd/musique/amartia_in_a_quiet_place/10. Ascension.mp3"}
]
La structure générale est la même (ce sont des fichiers json) mais cette fois-ci pas d’url mais un “filename” qui est le chemin complet d’accès au fichier. A noter : vous pouvez mettre des fichiers mp3, ogg, wav, flac, mu3 : tout ce qui est fichier son que votre raspberry sait lire.
Le fichier alarmelist.json
Il contient une liste fichiers audio utilisables comme réveil matin. Ils doivent être présent sur votre carte SD !
Exemple :
[
{"id":"0", "name":"Beep" , "filename":"/home/pi/lcd/alarme/beep.mp3"},
{"id":"1", "name":"Incendie" , "filename":"/home/pi/lcd/alarme/incendie.mp3"},
{"id":"2", "name":"Coq" , "filename":"/home/pi/lcd/alarme/coq.mp3"}
]
La structure générale est la même que pour les titres à écouter (audiolist.json)



