1. Introduction

Avez-vous déjà vu ces vidéos sur YouTube où des musiciens s'adonnent à reprendre les plus célèbres chansons, mais en jouant avec des bouteilles ? Souvent, ils ne font que les frapper avec des cuillères ou des baguettes, et la chose semble tellement facile au spectateur qu'il sera tenté de reproduire l'expérience lui-même. Cependant voilà, le spectateur se rend vite compte qu'il est un piètre xylophoniste et que jouer avec des bouteilles requiert une certaine dextérité et technique. En plus il est obligé de ne jouer qu'une, voire deux notes à la fois, ce qui n'offre pas beaucoup de possibilités musicales. Ah, si seulement jouer avec des bouteilles était aussi simple qu'appuyer sur la touche d'un piano...

Eh bien il se trouve que c'est justement le but de ce projet ! M'étant retrouvé dans la situation énoncée précédemment, je me suis demandé s'il était possible d'automatiser la frappe sur la bouteille, déjà simplement avec un bouton connecté à un Raspberry Pi, qui actionnerait un moteur frappant la bouteille. L'idée s'est ensuite développée pour devenir alors le projet de connecter un clavier MIDI sur le Raspberry Pi, dont 16 des touches actionneraient chacune un servomoteur venant frapper la bouteille correspondante ; cela ayant pour résultat potentiel un instrument de musique chromatique sur seize notes.

2. Matériel et méthodes

2.1 Matériel

  • 1 x Raspberry Pi 3
  • 1 x Adafruit 16-Channel PWM/Servo HAT for Raspberry Pi
  • 1 x Breadboard
  • 1 x Mini Breadboard Soudable
  • 1 x Optocoupleur 6N138
  • 1 x Socket DIN-5 femelle
  • 1 x Diode 1N4148
  • 1 x Résistance 220 Ohms
  • 1 x Résistance 1000 Ohms
  • 1 x Résistance 10'000 Ohms
  • 1 x Clavier MIDI (ici Alesis Q25)
  • 1 x Câble MIDI
  • 1 x Câble d'alimentation 5V 10A
  • 16 x Micro Servomoteurs
  • 16 x Baguettes de glockenspiel sciées (ou autre type de marteau ou baguette)
  • 16 x Bouteilles en verre (remplies à différents niveaux)

2.2 Méthode

La méthode précise pour réaliser le projet va s'articuler en trois sous-parties traitant des différents composants dont ils faudra s'occuper, puis mettre en commun.

2.2.1 Préparer le HAT et les servomoteurs

En effet, pour utiliser jusqu'à 16 servomoteurs, il y a besoin d'un HAT pour le Raspberry, et pour utiliser ce HAT pour contrôler ces moteurs, il y a besoin d'un peu de préparation. Tout d'abord il faut s'assurer d'avoir une alimentation correspondant au nombres de moteurs que l'on veut faire tourner ; dans le cas de mon projet j'en ai utilisé 16, donc j'ai utilisé une alimentation 5V 10A. Une fois l'alimentation choisie, branchez votre HAT sur le Raspberry. Les servomoteurs viendront à leur tour se brancher, chacun sur une des colonnes à 3 pins en bas du HAT. Veillez à toujours brancher le câble noir ou brun (ground) en bas et à brancher le câble jaune ou blanc (signal) en haut.

Une fois cela fait, il va falloir configurer le Raspberry pour qu'il puisse utiliser I2C, qui est nécessaire pour que le Raspberry détecte et puisse utiliser le HAT. Pour cela, il suffit d'entrer ce code :

sudo apt-get install python-smbus
sudo apt-get install i2c-tools

Cela installera le support SMBus sur le Raspberry (celui-ci inclut I2C).

Pour tester si le RPi reconnaît le HAT, on peut alors simplement entrer la commande :

sudo i2cdetect -y 1

Si tout fonctionne correctement, on devrait obtenir une image comme celle-ci :

code_adafruit_servo.png

A partir de ce moment-là, cela veut dire que le HAT fonctionne, on peut alors préparer le terrain pour l'utilisation des servomoteurs.

Il existe une library simple d'accès pour l'utilisation des servomoteurs. C'est celle-ci que nous allons utiliser. Le moyen le plus simple pour y accéder, pour moi, est d'utiliser un câble Ethernet pour cloner le code depuis le git :

git clone -b legacy https://github.com/adafruit/Adafruit-Raspberry-Pi-Python-Code.git
cd Adafruit-Raspberry-Pi-Python-Code
cd Adafruit_PWM_Servo_Driver

Une fois cela fait, on en revient encore à une phase de test. Le fichier Adafruit_PWM_Servo_Driver contient un fichier Servo_Example.py qui est en fait une demo qui permet de vérifier si un servomoteur fonctionne ou pas.

Il suffit alors de lancer le fichier :

sudo python Servo_Example.py

Si votre moteur tourne d'un côté vers l'autre (dans le cas d'un micro servomoteur), cela devrait être bon !

2.2.2 Faire en sorte de pouvoir utiliser du MIDI IN sur le Raspberry Pi

En effet, cela peut sembler évident, mais pour utiliser un clavier MIDI sur le Raspberry, il faut que celui-ci soit capable de lire le MIDI, et ça, il ne le fait pas d'office. Plusieurs méthodes possibles existent pour faire cela et c'est malheureusement à ce moment du projet que j'eus quelques problèmes. En effet, un hack trouvable sur le net semble faire fonctionner le MIDI sur RPi, cependant il ne s'applique pas au Raspberry Pi 3 et Zero. En effet, l'article en question (http://www.samplerbox.org/article/m...) décrit une méthode où il faut utiliser ttyAMA0, qui est utilisé par le GPIO. Cependant ttyAMA0 est, sur les modèles plus récents, utilisé par le Bluetooth, et il est remplacé sur le GPIO par ttyS0. Il semblerait alors logique de vouloir remplacer ttyS0 par ttyAMA0, pour que le code soit alors à nouveau applicable à la situation. C'est ce que j'ai tenté de faire, malheureusement sans succès. Je vais ici décrire la marche à suivre que j'ai utilisée, même si elle n'a pas fonctionné pour moi.

La première étape essentielle et nécessaire dans tous les cas de figure, c'est le circuit électrique. Pour cela il va tout d'abord falloir le réaliser sur votre breadboard comme indiqué ci-dessous (j'ai utilisé pour cela l'optocoupleur, la diode, les trois résistances, la socket et quelques câbles) :

gpio_midiin_circuit.jpg

Circuit_electrique_vue_1.jpg

circuit_electique_vue_2.jpg

Une fois le circuit réalisé, il est possible de souder le tout avec la mini breadboard pour obtenir un travail plus propre, ce que je n'ai malheureusement pas eu le temps de faire.

Il faut maintenant effectuer quelques changements dans le code du Raspberry pour que celui-ci parvienne à lire de l'information provenant d'un appareil MIDI. C'est là qu'intervient la divergence entre les anciennes versions du RPi et les plus récentes. L'article précédemment cité ne fonctionnant pas pour moi, il a fallu trouver une autre solution. Heureusement, un commentaire de l'article contenait un lien menant à une marche à suivre expliquant une alternative similaire pour le RPi 3 et Zero (https://openenergymonitor.org/emon/...) que je vais décrire ici.

Pour que le RPi 3 puisse lire du MIDI, il faut tout d'abord faire un raspi-config et aller désactiver serial, puis reboot le RPI.

Assurez-vous ensuite que votre RPI soit à jour en tapant ceci :

sudo apt-get update
sudo apt-get upgrade
sudo apt-get dist-upgrade
sudo rpi-update

Maintenant nous devrions pouvoir rendre à ttyAMA0 son usage originel en faisant :

sudo nano /boot/config.txt

Ajoutez à la fin ceci :

dtoverlay=pi3-miniuart-bt

Sauvegardez et quittez.

Maintenant il va falloir empêcher le Bluetooth de se connecter. Pour cela il faut entrer ces commandes :

sudo systemctl disable hciuart
sudo nano /lib/systemd/system/hciuart.service

C'est alors là qu'est arrivé mon problème ; l'article décrit qu'il faut remplacer le premier ttyAMA0 par ttyS0. Malheureusement, quand j'ai accédé à ce fichier, je n'y ai trouvé aucune mention d'aucun de ces deux termes. Après quelques recherches, j'ai trouvé une page sur Internet contenant potentiellement la solution à mon problème (https://www.raspberrypi.org/forums/...). Là, il était question de serial0 et serial1, respectivement ttyAMA0 et ttyS0, qui apparaissent alors en effet dans hciuart.service.

Toujours en suivant la marche à suivre, je me suis alors essayé à remplacer serial0 par serial1. Cependant, même en faisant l'inverse, il m'est resté impossible d'obtenir un quelconque signal MIDI sur mon RPi.

J'ai tout de même terminé la marche à suivre, pour voir si mon problème se situait vraiment là.

Maintenant il va falloir effacer console=serial0,115200 de /boot/cmdline.txt :

sudo nano /boot/cmdline.txt

et effacez simplement console=serial0,115200

Puis, rajoutez ceci à la fin de /boot/config.txt

init_uart_clock=39062500
init_uart_baud=38400
dtparam=uart0_clkrate=48000000

Ce sont techniquement les seules étapes nécessaires pour préparer un RPi 3 ou Zero à la réception du MIDI.

Maintenant, pour voir si cela fonctionne, il faut lancer ce code Python (j'ai également remplacé ttyAMA0 par serial0 et serial1, mais cela n'a rien changé) :

#!/usr/bin/python

import serial

ser = serial.Serial('/dev/ttyAMA0', baudrate=38400)

message = 0, 0, 0
while True:
    
i=0
     while i < 3:
     
     data = ord(ser.read(1)) # read a byte
     if data >> 7 != 0:
           i = 0      # status byte!   this is the beginning of a midi message!
     messagei = data
     i += 1
     if i == 2 and message0 >> 4 == 12:  # program change: don't wait for a
     message2 = 0                      # third byte: it has only 2 bytes
           i = 3
       
messagetype = message0 >> 4
messagechannel = (message0 & 15) + 1
note = message1 if len(message) > 1 else None
velocity = message2 if len(message) > 2 else None

if messagetype == 9:    # Note on
     print 'Note on'
elif messagetype == 8:  # Note off
     print 'Note off'
elif messagetype == 12: # Program change
     print 'Program change'

Si le RPi reçoit les messages "Note on" et "Note off", alors c'est que l'objectif est accompli.

2.2.3 Tout connecter

Maintenant, si les servomoteurs et le MIDI marchent chacun de leur côté, il aurait été temps de les combiner. Chez moi, les servomoteurs marchaient, malheureusement pas moyen de faire fonctionner le MIDI. Ici, je décris ce que j'aurais voulu pouvoir produire et comment je l'aurais fait.

Techniquement, pour combiner ces deux facteurs, il n'y aurait rien eu de particulièrement compliqué. En effet, il suffit d'écrire le code que l'on veut que notre moteur effectue, et venir le placer juste après print 'Note on' dans le code pour le MIDI. Note off et Program change n'étant pas importants dans le cas de ce projet, on peut simplement les ignorer.

Le MIDI ne marchant pas, mon professeur m'a suggéré de faire un mock-up du MIDI, c'est-à-dire faire croire au RPi qu'il lit de l'information MIDI, pour pouvoir utiliser cette information. Cela m'aurait permis d'envoyer une certaine fréquence au RPi (p. ex A4 : 440 Hz) et créer un "if" pour qu'alors le moteur s'actionne (quelque chose comme : if freq=440 then "actionner moteur").

Cependant, c'est là qu'est venu s'immiscer un autre problème dans mon projet. En effet depuis le dimanche avant le jeudi de la reddition du projet, je ne pouvais plus connecter mon RPi en Ethernet, et je ne pouvais par conséquent plus y accéder. Je n'ai pu l'utiliser qu'encore une fois lors d'un cours le mercredi, que j'ai employé à vérifier les différentes façons de faire marcher le MIDI IN sur le RPi. N'ayant pas pu accéder au RPi ni depuis l'école, ni depuis chez moi, il m'a été impossible d'écrire cette partie du code.

2.2.4 Bricolage

Je suis arrivé à cette partie comme je l'ai pu. J'avais prévu de construire un instrument chromatique relativement bien fait, cependant mon manque d'organisation vis-à-vis de l'échéance m'a été fatal et je n'ai pu que créer un montage précaire et basique. Encore une fois je vais énoncer mes intentions et décrire ce que j'ai véritablement pu faire.

Maintenant, plus besoin de code, mais bel et bien besoin de mettre en place tous les éléments nécessaires à notre futur instrument de musique, en l'occurence les baguettes, les moteurs et les bouteilles.

Tout d'abord, j'ai décidé d'utiliser des baguettes de glockenspiel comme marteaux pour leur son et leur taille. Ayant eu quelques problèmes avec la commande des 15 servomoteurs qui me manquaient, je n'ai pu faire le montage qu'avec une baguette, une bouteille et un servomoteur. Voulant scier la baguette à l'origine à cause de son poids, je n'ai pas eu le temps de le faire et ai du la garder telle quelle, j'ai cependant maintenu le moteur en place à l'aide d'un étau. J'ai ensuite fixé la baguette comme j'ai pu au servomoteur pour qu'elle tienne en place.

marteau.jpg

N'ayant plus accès à mon RPi, je n'ai cependant pas pu vérifier si le montage fonctionnait correctement, cependant voici à quoi il aurait ressemblé si tout fonctionnait :

Montage_complet.jpg

Si je m'étais mieux organisé, j'aurais arrangé les bouteilles comme un piano (notes naturelles devant, notes altérées derrière), cela laissant aussi une certaine place pour le recul de la baguette après sa frappe sur la bouteille. J'aurais attribué un moteur à chaque bouteille en fixant chaque élément sur un socle lui correspondant, pour encore une fois éviter les confusions et le recul.

Après cela, mon projet aurait été terminé et réalisé.

3. Résultats

Malheureusement les résultats escomptés n'ont pas été obtenus. Je ne suis arrivé qu'à un stade peu avancé de ce que j'avais prévu et n'ai de ce fait pas pu obtenir de résultat satisfaisant. Avec ce que j'ai pu faire, j'ai réussi à faire marcher le servomoteur et à comprendre comment le reste de mon projet aurait du se dérouler, cependant pour cause de certains problèmes techniques, mais aussi de manque d'expérience et d'organisation, je n'ai pas réussi à créer le véritable produit que j'aurais voulu créer.

4. Discussion

L'idée originelle me paraissait très simple, mais je dois avouer avoir eu de la peine à réaliser mon projet. Beaucoup de paramètres que je n'attendais pas sont rentrés en compte et ce qui me paraissait simple devenait de plus en plus compliqué à mesure que j'avançais. Le matériel que j'avais prévu a fini par ne pas suffire et j'ai dû commander beaucoup de choses, parfois trop tard ; j'avais besoin d'un socle pour mes bouteilles, de quelque chose pour maintenir mon moteur en place, d'alimentation et d'accessoires pour mon RPi. De plus, les méthodes trouvées sur Internet étaient toutes très précises et je me suis trop reposé dessus, pensant qu'elles étaient faciles. Il se trouve cependant que j'ai eu besoin de combiner plusieurs de ces méthodes et effectuer un vrai travail de compréhension du résultat à obtenir, plutôt qu'un simple travail de copie. N'ayant pas l'habitude de ce genre de projet, j'ai eu beaucoup de mal à véritablement comprendre ce qui était attendu de moi, et je pense ne l'avoir compris que trop tard. De plus, les divers problèmes techniques m'étant arrivé n'ont fait que me ralentir puisque je devais trouver une solution à ceux-ci.

5. Conclusion

Je regrette de ne pas avoir pris ce projet plus au sérieux plus tôt, car j'aurais pu le perfectionner et obtenir un résultat satisfaisant dans les temps. Malgré tout, je pense avoir acquis une capacité d'analyse et d'organisation qui me permettra de ne pas reproduire les mêmes erreurs dans un projet futur. J'espère trouver le temps de tout de même terminer ce projet dans mon temps libre, puisque je dois avouer être relativement frustré de ne pas avoir pu le finir à temps, et j'aimerais beaucoup le voir aboutir. Je pense avoir compris ce qui est maintenant attendu de moi dans un projet de ce genre et je ferai mon possible pour ne pas commettre les mêmes erreurs à nouveau dans le projet P qui arrivera incessamment sous peu.

6. Sources