Come tra gli elementi di un gruppo musicale così Arduino e Raspberry interagiscono nella creazione delle note con questo progetto di realizzazione di strumenti musicali digitali di FunLab
HARDWARE
L’Ukulele Touch è stato realizzato sfruttando il manico e la tastiera di un Ukulele classico, smontando la tastiera, applicando fori nei quali inserire i cilindri di alluminio realizzati in CNC ai quali è applicato un conduttore che si collega con il corrispondente ingresso su Arduino Mega.
ARDUINO e RASPBERRY
L’Arduino Mega viene utilizzato per acquisire il “tocco” delle dita sulle placche di alluminio della tastiera, attraverso la libreria software capacitiveSensor.h inclusa nel programma.
Ad ogni ciclo loop() invia sulla porta seriale collegata a Raspberry il numero del tasto selezionato.
Programma Arduino Mega:
#include "capacitiveSensor.h"
int capSensePin0 = A7; //Plettro
int capSensePin1 = A0; //E1
int capSensePin2 = A1; //A1
int capSensePin3 = A2; //D2
int capSensePin4 = A3; //F1
int capSensePin5 = A4; //A#1
int capSensePin6 = A5; //D#2
int capSensePin7 = 2; //F#1
int capSensePin8 = 3; //B1
int capSensePin9 = 4; //E2
int capSensePin10 = 5; //G1
int capSensePin11 = 6; //C2
int capSensePin12 = 7; //F2
int capSensePin13 = 8; //G#1
int capSensePin14 = 9; //C#2
int capSensePin15 = 10; //F#2
int capSensePin16 = 11; //A1
int capSensePin17 = 12; //D2
int capSensePin18 = 13; //G2
int sensorLevel = 6; // sensibilità lettura 1-17
void setup() {
pinMode(capSensePin0, OUTPUT);
pinMode(capSensePin1, OUTPUT);
pinMode(capSensePin2, OUTPUT);
pinMode(capSensePin3, OUTPUT);
pinMode(capSensePin4, OUTPUT);
pinMode(capSensePin5, OUTPUT);
pinMode(capSensePin6, OUTPUT);
pinMode(capSensePin7, OUTPUT);
pinMode(capSensePin8, OUTPUT);
pinMode(capSensePin9, OUTPUT);
pinMode(capSensePin10, OUTPUT);
pinMode(capSensePin11, OUTPUT);
pinMode(capSensePin12, OUTPUT);
pinMode(capSensePin13, OUTPUT);
pinMode(capSensePin14, OUTPUT);
pinMode(capSensePin15, OUTPUT);
pinMode(capSensePin16, OUTPUT);
pinMode(capSensePin17, OUTPUT);
pinMode(capSensePin18, OUTPUT);
Serial.begin(9600);
}
void loop() {
if(readCapacitivePin(capSensePin1)>sensorLevel && readCapacitivePin(capSensePin0)>sensorLevel) {
Serial.print("1");
}
if(readCapacitivePin(capSensePin2)>sensorLevel && readCapacitivePin(capSensePin0)>sensorLevel) {
Serial.print("2");
}
if(readCapacitivePin(capSensePin3)>sensorLevel && readCapacitivePin(capSensePin0)>sensorLevel) {
Serial.print("3");
}
if(readCapacitivePin(capSensePin4)>sensorLevel && readCapacitivePin(capSensePin0)>sensorLevel) {
Serial.print("4");
}
if(readCapacitivePin(capSensePin5)>sensorLevel && readCapacitivePin(capSensePin0)>sensorLevel) {
Serial.print("5");
}
if(readCapacitivePin(capSensePin6)>sensorLevel && readCapacitivePin(capSensePin0)>sensorLevel) {
Serial.print("6");
}
if(readCapacitivePin(capSensePin7)>sensorLevel && readCapacitivePin(capSensePin0)>sensorLevel) {
Serial.print("7");
}
if(readCapacitivePin(capSensePin8)>sensorLevel && readCapacitivePin(capSensePin0)>sensorLevel) {
Serial.print("8");
}
if(readCapacitivePin(capSensePin9)>sensorLevel && readCapacitivePin(capSensePin0)>sensorLevel) {
Serial.print("9");
}
if(readCapacitivePin(capSensePin10)>sensorLevel && readCapacitivePin(capSensePin0)>sensorLevel) {
Serial.print("a");
}
if(readCapacitivePin(capSensePin11)>sensorLevel && readCapacitivePin(capSensePin0)>sensorLevel) {
Serial.print("b");
}
if(readCapacitivePin(capSensePin12)>sensorLevel && readCapacitivePin(capSensePin0)>sensorLevel) {
Serial.print("c");
}
if(readCapacitivePin(capSensePin13)>sensorLevel && readCapacitivePin(capSensePin0)>sensorLevel) {
Serial.print("d");
}
if(readCapacitivePin(capSensePin14)>sensorLevel && readCapacitivePin(capSensePin0)>sensorLevel) {
Serial.print("e");
}
if(readCapacitivePin(capSensePin15)>sensorLevel && readCapacitivePin(capSensePin0)>sensorLevel) {
Serial.print("f");
}
if(readCapacitivePin(capSensePin16)>sensorLevel && readCapacitivePin(capSensePin0)>sensorLevel) {
Serial.print("g");
}
if(readCapacitivePin(capSensePin17)>sensorLevel && readCapacitivePin(capSensePin0)>sensorLevel) {
Serial.print("h");
}
if(readCapacitivePin(capSensePin18)>sensorLevel && readCapacitivePin(capSensePin0)>sensorLevel) {
Serial.print("i");
}
if(readCapacitivePin(capSensePin0)<sensorLevel || (
readCapacitivePin(capSensePin1)<sensorLevel
&& readCapacitivePin(capSensePin2)<sensorLevel
&& readCapacitivePin(capSensePin3)<sensorLevel
&& readCapacitivePin(capSensePin4)<sensorLevel
&& readCapacitivePin(capSensePin5)<sensorLevel
&& readCapacitivePin(capSensePin6)<sensorLevel
&& readCapacitivePin(capSensePin7)<sensorLevel
&& readCapacitivePin(capSensePin8)<sensorLevel
&& readCapacitivePin(capSensePin9)<sensorLevel
&& readCapacitivePin(capSensePin10)<sensorLevel
&& readCapacitivePin(capSensePin11)<sensorLevel
&& readCapacitivePin(capSensePin12)<sensorLevel
&& readCapacitivePin(capSensePin13)<sensorLevel
&& readCapacitivePin(capSensePin14)<sensorLevel
&& readCapacitivePin(capSensePin15)<sensorLevel
&& readCapacitivePin(capSensePin16)<sensorLevel
&& readCapacitivePin(capSensePin17)<sensorLevel
&& readCapacitivePin(capSensePin18)<sensorLevel )) {
Serial.print("0");
}
}
La riproduzione dei suoni di chitarra campionati in formato WAV, è affidata al Raspberry PI, sul quale è installato PYGAME MIXER, una applicazione per la gestione del suono su 3 canali.
Un file Python, mandato in esecuzione al boot del Raspberry, legge continuamente i dati provenienti da Arduino attraverso la porta seriale e manda in esecuzione il file audio richiesto.
Programma Python:
#!/usr/bin/env python
import serial
import pygame.mixer
from time import sleep
from sys import exit
pygame.mixer.init(48000, -16, 1, 1024)
E1 = pygame.mixer.Sound("/home/pi/ukulele_touch/note/e1.wav")
F1 = pygame.mixer.Sound("/home/pi/ukulele_touch/note/f1.wav")
Fd1 = pygame.mixer.Sound("/home/pi/ukulele_touch/note/f1+.wav")
G1 = pygame.mixer.Sound("/home/pi/ukulele_touch/note/g1.wav")
Gd1 = pygame.mixer.Sound("/home/pi/ukulele_touch/note/g1+.wav")
A1 = pygame.mixer.Sound("/home/pi/ukulele_touch/note/a1.wav")
Ad1 = pygame.mixer.Sound("/home/pi/ukulele_touch/note/a1+.wav")
B1 = pygame.mixer.Sound("/home/pi/ukulele_touch/note/b1.wav")
C2 = pygame.mixer.Sound("/home/pi/ukulele_touch/note/c2.wav")
Cd2 = pygame.mixer.Sound("/home/pi/ukulele_touch/note/c2+.wav")
D2 = pygame.mixer.Sound("/home/pi/ukulele_touch/note/d2.wav")
Dd2 = pygame.mixer.Sound("/home/pi/ukulele_touch/note/d2+.wav")
E2 = pygame.mixer.Sound("/home/pi/ukulele_touch/note/e2.wav")
F2 = pygame.mixer.Sound("/home/pi/ukulele_touch/note/f2.wav")
Fd2 = pygame.mixer.Sound("/home/pi/ukulele_touch/note/f2+.wav")
G2 = pygame.mixer.Sound("/home/pi/ukulele_touch/note/g2.wav")
soundChannel1 = pygame.mixer.Channel(1)
soundChannel2 = pygame.mixer.Channel(2)
soundChannel3 = pygame.mixer.Channel(3)
arduino = serial.Serial(
port='/dev/ttyACM0',
baudrate = 9600,
parity = serial.PARITY_NONE,
stopbits = serial.STOPBITS_ONE,
bytesize = serial.EIGHTBITS,
timeout = 1
)
try:
while True:
RxData = arduino.read()
if RxData == "1":
soundChannel1.play(E1)
try:
while True:
RxData = arduino.read()
if RxData != "1":
break
except KeyboardInterrupt:
exit()
if RxData == "2":
soundChannel2.play(A1)
try:
while True:
RxData = arduino.read()
if RxData != "2":
break
except KeyboardInterrupt:
exit()
if RxData == "3":
soundChannel3.play(D2)
try:
while True:
RxData = arduino.read()
if RxData != "3":
break
except KeyboardInterrupt:
exit()
if RxData == "4":
soundChannel1.play(F1)
try:
while True:
RxData = arduino.read()
if RxData != "4":
break
except KeyboardInterrupt:
exit()
if RxData == "5":
soundChannel2.play(Ad1)
try:
while True:
RxData = arduino.read()
if RxData != "5":
break
except KeyboardInterrupt:
exit()
if RxData == "6":
soundChannel3.play(Dd2)
try:
while True:
RxData = arduino.read()
if RxData != "6":
break
except KeyboardInterrupt:
exit()
if RxData == "7":
soundChannel1.play(Fd1)
try:
while True:
RxData = arduino.read()
if RxData != "7":
break
except KeyboardInterrupt:
exit()
if RxData == "8":
soundChannel2.play(B1)
try:
while True:
RxData = arduino.read()
if RxData != "8":
break
except KeyboardInterrupt:
exit()
if RxData == "9":
soundChannel3.play(E2)
try:
while True:
RxData = arduino.read()
if RxData != "9":
break
except KeyboardInterrupt:
exit()
if RxData == "a":
soundChannel1.play(G1)
try:
while True:
RxData = arduino.read()
if RxData != "a":
break
except KeyboardInterrupt:
exit()
if RxData == "b":
soundChannel2.play(C2)
try:
while True:
RxData = arduino.read()
if RxData != "b":
break
except KeyboardInterrupt:
exit()
if RxData == "c":
soundChannel3.play(F2)
try:
while True:
RxData = arduino.read()
if RxData != "c":
break
except KeyboardInterrupt:
exit()
if RxData == "d":
soundChannel1.play(Gd1)
try:
while True:
RxData = arduino.read()
if RxData != "d":
break
except KeyboardInterrupt:
exit()
if RxData == "e":
soundChannel2.play(Cd2)
try:
while True:
RxData = arduino.read()
if RxData != "e":
break
except KeyboardInterrupt:
exit()
if RxData == "f":
soundChannel3.play(Fd2)
try:
while True:
RxData = arduino.read()
if RxData != "f":
break
except KeyboardInterrupt:
exit()
if RxData == "g":
soundChannel1.play(A1)
try:
while True:
RxData = arduino.read()
if RxData != "g":
break
except KeyboardInterrupt:
exit()
if RxData == "h":
soundChannel2.play(D2)
try:
while True:
RxData = arduino.read()
if RxData != "h":
break
except KeyboardInterrupt:
exit()
if RxData == "i":
soundChannel3.play(G2)
try:
while True:
RxData = arduino.read()
if RxData != "i":
break
except KeyboardInterrupt:
exit()
if RxData == "0":
soundChannel1.stop()
soundChannel2.stop()
soundChannel3.stop()
# per uscita con interrupt da tastiera dal programma (control+C)
except KeyboardInterrupt:
exit()