GrandOrgue Arduino Mega + Raspberry Pi
Conversazione completa e script per pedaliera MIDI β Novembre 2025
1. Conversazione Completa
2. serial2midi.py
Posizione: /home/pi/serial2midi.py
#!/usr/bin/env python3
import serial
import mido
import mido.backends.rtmidi
import time
SERIAL_PORT = '/dev/ttyMIDI'
BAUD_RATE = 115200
MIDI_CH = 3
mido.set_backend('mido.backends.rtmidi')
outport = mido.open_output('Arduino MIDI', virtual=True)
print("Porta virtuale aperta")
ser = serial.Serial(SERIAL_PORT, BAUD_RATE, timeout=1)
time.sleep(2)
print(f"Bridge MIDI avviato su {SERIAL_PORT}")
stato_reg = [False, False, False, False]
try:
while True:
line = ser.readline().decode('utf-8', errors='ignore').strip()
if not line:
continue
parts = line.split()
if len(parts) < 2:
continue
if parts[0] == 'N' and len(parts) == 3:
nota = int(parts[1])
stato = int(parts[2])
msg = mido.Message('note_on' if stato == 1 else 'note_off',
channel=MIDI_CH, note=nota, velocity=85)
print(f">>> MIDI: {msg}")
outport.send(msg)
elif parts[0] == 'R' and len(parts) == 3:
i = int(parts[1])
cc = 20 + i
stato_reg[i] = not stato_reg[i]
val = 127 if stato_reg[i] else 0
outport.send(mido.Message('control_change', channel=MIDI_CH, control=cc, value=val))
elif parts[0] == 'V' and len(parts) == 2:
volume = int(parts[1])
outport.send(mido.Message('control_change', channel=MIDI_CH, control=7, value=volume))
except KeyboardInterrupt:
ser.close()
outport.close()
π Funzione: Bridge seriale β MIDI. Legge dal seriale (Arduino Mega) e invia messaggi MIDI a GrandOrgue.
3. riconnetti.sh
Posizione: /home/pi/riconnetti.sh
#!/bin/bash
pkill python3
sleep 2
python3 ~/serial2midi.py &
sleep 3
ARDUINO=$(aconnect -l | grep -B1 "Arduino MIDI" | grep "client" | grep -o "client [0-9]*" | grep -o "[0-9]*")
GRANDORGUE=$(aconnect -l | grep -B1 "GrandOrgue Input" | grep "client" | head -1 | grep -o "client [0-9]*" | grep -o "[0-9]*")
echo "Arduino: $ARDUINO, GrandOrgue: $GRANDORGUE"
aconnect ${ARDUINO}:0 ${GRANDORGUE}:0
echo "Riconnesso!"
π Funzione: Riconnette automaticamente Arduino MIDI a GrandOrgue dopo eventuali disconnessioni.
4. avvia_organo1.sh
Posizione: /home/pi/avvia_organo1.sh
#!/bin/bash
sleep 10
rm -f /tmp/.X0-lock
sleep 2
while [ ! -e /dev/ttyMIDI ]; do
sleep 2
done
echo "Mega trovato!"
echo "Aspetto UGREEN..."
while ! aplay -l | grep -q "USB Audio"; do
sleep 2
done
sleep 5
echo "UGREEN pronto!"
pulseaudio --start
sleep 3
python3 /home/pi/serial2midi.py &
sleep 5
while ! aconnect -l | grep -q "Arduino MIDI"; do
sleep 2
done
echo "Arduino MIDI connesso!"
DISPLAY=:0 /usr/bin/GrandOrgue /usr/share/GrandOrgue/packages/demo-4232D4C616E4B99145537F02B34D342D4E3E3808.orgue 2>/dev/null &
sleep 40
aconnect -l > /dev/null
echo "Organo pronto!"
π Funzione: Script di avvio completo che attende la presenza di dispositivi, avvia il bridge MIDI e GrandOrgue.
5. shutdown_button.py
Posizione: /home/pi/shutdown_button.py
#!/usr/bin/env python3
import RPi.GPIO as GPIO
import os
import time
SHUTDOWN_PIN = 27
GPIO.setmode(GPIO.BCM)
GPIO.setup(SHUTDOWN_PIN, GPIO.IN, pull_up_down=GPIO.PUD_UP)
print("Ascoltando pulsante shutdown su GPIO 27...")
try:
while True:
if GPIO.input(SHUTDOWN_PIN) == GPIO.LOW:
print("Pulsante premuto β Shutdown in corso...")
time.sleep(2)
os.system('sudo shutdown -h now')
time.sleep(0.1)
except KeyboardInterrupt:
GPIO.cleanup()
π Funzione: Monitora il pulsante su GPIO 27 e avvia lo shutdown graceful del sistema.
6. .bash_profile
Posizione: ~/.bash_profile (aggiungere queste righe)
python3 ~/shutdown_button.py &
if [ -z "$DISPLAY" ] && [ "$(tty)" = "/dev/tty1" ]; then
startx &
sleep 10
/home/pi/avvia_organo1.sh &
fi
alias riconnetti='/home/pi/riconnetti.sh'
π Funzione: Avvia automaticamente lo shutdown button all’avvio e, se su terminale, avvia l’organo.
π Rendi eseguibili tutti gli script
chmod +x ~/serial2midi.py ~/riconnetti.sh ~/avvia_organo1.sh ~/shutdown_button.py
βοΈ Sistema completo e definitivo per la pedaliera GrandOrgue! π΅