Launchpad touch è un progetto per la realizzazione di una console con controllo touch per la creazione di linee musicali tramite riproduzione di file audio campionati in sequenza od in parallelo.
Il progetto utilizza tecnologia Arduino e RaspberryPI, in comunicazione tra loro attraverso connessione Seriale.
L’HARDWARE
La realizzazione HW consiste in una console in plexiglass con alloggiati 36 tasti in alluminio, costituiti da una placca di alluminio collegata attraverso un conduttore al rispettivo ingresso dell’Arduino Mega.
Al di sotto di ogni tasto è stato inserito un diodo Led Multicolore che si illumina di un colore casuale al tocco del tasto stesso.
Per la gestione della matrice di Leds è stata realizzata una scheda elettronica di controllo di potenza, che utilizza i bjt BC558 e l’integrato ULN2803:
Ogni modulo per il controllo di linea:
La Part List della scheda:
ARDUINO e RASPBERRY
Arduino Mega utilizzato ha la duplice funzione di acquisizione del “tocco” dei tasti attraverso la libreria software capacitiveSensor.h e di controllo accensione dei leds attraverso la scheda elettronica realizzata.
La tastiera touch viene realizzata senza HW dedicato, ma solo via software con l’utilizzo della libreria indicata. Questa prevede 17 livelli di sensibilità attraverso i quali si rileva la capacità elettrica di chi sfiora il tasto.
Arduino poi invia sulla porta seriale il numero corrispondente al tasto attivato, che verrà utilizzato da Raspberry per la selezione del file audio da riprodurre.
Contemporaneamente attiva, accendendolo di un colore casuale tra i 7 possibili con un led RGB, attraverso la scheda elettronica di controllo di potenza, il led posto sotto al tasto sfiorato.
Programma Arduino:
#include "capacitiveSensor.h"
// sensori touch
int capSensePin1 = 16;
int capSensePin2 = 17;
int capSensePin3 = 18;
int capSensePin4 = 19;
int capSensePin5 = 22;
int capSensePin6 = 23;
int capSensePin7 = 24;
int capSensePin8 = 25;
int capSensePin9 = 26;
int capSensePin10 = 27;
int capSensePin11 = 28;
int capSensePin12 = 29;
int capSensePin13 = 30;
int capSensePin14 = 31;
int capSensePin15 = 32;
int capSensePin16 = 33;
int capSensePin17 = 34;
int capSensePin18 = 35;
int capSensePin19 = 36;
int capSensePin20 = 37;
int capSensePin21 = 38;
int capSensePin22 = 39;
int capSensePin23 = 40;
int capSensePin24 = 41;
int capSensePin25 = 42;
int capSensePin26 = 43;
int capSensePin27 = 44;
int capSensePin28 = 45;
int capSensePin29 = 46;
int capSensePin30 = 47;
int capSensePin31 = 48;
int capSensePin32 = 49;
int capSensePin33 = 50;
int capSensePin34 = 51;
int capSensePin35 = 52;
int capSensePin36 = 53;
// controlli ULN2803
int I0 = A0;
int I1 = A1;
int I2 = A2;
int I3 = A3;
int I4 = A4;
int I5 = A5;
// controlli Linee RGB leds
int BL0 = A8;
int BL1 = A9;
int BL2 = A10;
int BL3 = A11;
int BL4 = A12;
int BL5 = A13;
int GL0 = 2;
int GL1 = 3;
int GL2 = 4;
int GL3 = 5;
int GL4 = 6;
int GL5 = 7;
int RL0 = 8;
int RL1 = 9;
int RL2 = 10;
int RL3 = 11;
int RL4 = 12;
int RL5 = 13;
// led di test
int led = A7;
int colore;
int sensorLevel = 6; // sensibilità lettura 1-17
void setup() {
// sensori touch
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);
pinMode(capSensePin19, OUTPUT);
pinMode(capSensePin20, OUTPUT);
pinMode(capSensePin21, OUTPUT);
pinMode(capSensePin22, OUTPUT);
pinMode(capSensePin23, OUTPUT);
pinMode(capSensePin24, OUTPUT);
pinMode(capSensePin25, OUTPUT);
pinMode(capSensePin26, OUTPUT);
pinMode(capSensePin27, OUTPUT);
pinMode(capSensePin28, OUTPUT);
pinMode(capSensePin29, OUTPUT);
pinMode(capSensePin30, OUTPUT);
pinMode(capSensePin31, OUTPUT);
pinMode(capSensePin32, OUTPUT);
pinMode(capSensePin33, OUTPUT);
pinMode(capSensePin34, OUTPUT);
pinMode(capSensePin35, OUTPUT);
pinMode(capSensePin36, OUTPUT);
// controlli ULN2803
pinMode(I0, OUTPUT);
pinMode(I1, OUTPUT);
pinMode(I2, OUTPUT);
pinMode(I3, OUTPUT);
pinMode(I4, OUTPUT);
pinMode(I5, OUTPUT);
// controlli Linee RGB leds
pinMode(BL0, OUTPUT);
pinMode(BL1, OUTPUT);
pinMode(BL2, OUTPUT);
pinMode(BL3, OUTPUT);
pinMode(BL4, OUTPUT);
pinMode(BL5, OUTPUT);
pinMode(GL0, OUTPUT);
pinMode(GL1, OUTPUT);
pinMode(GL2, OUTPUT);
pinMode(GL3, OUTPUT);
pinMode(GL4, OUTPUT);
pinMode(GL5, OUTPUT);
pinMode(RL0, OUTPUT);
pinMode(RL1, OUTPUT);
pinMode(RL2, OUTPUT);
pinMode(RL3, OUTPUT);
pinMode(RL4, OUTPUT);
pinMode(RL5, OUTPUT);
pinMode(led, OUTPUT);
digitalWrite(led, LOW);
leds(0, 0);
Serial.begin(9600);
}
void loop() {
if(readCapacitivePin(capSensePin1)>sensorLevel) {
Serial.print("0");
leds(1, 1);
}
else if(readCapacitivePin(capSensePin2)>sensorLevel) {
Serial.print("1");
leds(2, 1);
}
else if(readCapacitivePin(capSensePin3)>sensorLevel) {
Serial.print("2");
leds(3, 1);
}
else if(readCapacitivePin(capSensePin4)>sensorLevel) {
Serial.print("3");
leds(4, 1);
}
else if(readCapacitivePin(capSensePin5)>sensorLevel) {
Serial.print("4");
leds(5, 1);
}
else if(readCapacitivePin(capSensePin6)>sensorLevel) {
Serial.print("5");
leds(6, 1);
}
else if(readCapacitivePin(capSensePin7)>sensorLevel) {
Serial.print("6");
leds(1, 2);
}
else if(readCapacitivePin(capSensePin8)>sensorLevel) {
Serial.print("7");
leds(2, 2);
}
else if(readCapacitivePin(capSensePin9)>sensorLevel) {
Serial.print("8");
leds(3, 2);
}
else if(readCapacitivePin(capSensePin10)>sensorLevel) {
Serial.print("9");
leds(4, 2);
}
else if(readCapacitivePin(capSensePin11)>sensorLevel) {
Serial.print("a");
leds(5, 2);
}
else if(readCapacitivePin(capSensePin12)>sensorLevel) {
Serial.print("b");
leds(6, 2);
}
else if(readCapacitivePin(capSensePin13)>sensorLevel) {
Serial.print("c");
leds(1, 3);
}
else if(readCapacitivePin(capSensePin14)>sensorLevel) {
Serial.print("d");
leds(2, 3);
}
else if(readCapacitivePin(capSensePin15)>sensorLevel) {
Serial.print("e");
leds(3, 3);
}
else if(readCapacitivePin(capSensePin16)>sensorLevel) {
Serial.print("f");
leds(4, 3);
}
else if(readCapacitivePin(capSensePin17)>sensorLevel) {
Serial.print("g");
leds(5, 3);
}
else if(readCapacitivePin(capSensePin18)>sensorLevel) {
Serial.print("h");
leds(6, 3);
}
else if(readCapacitivePin(capSensePin19)>sensorLevel) {
Serial.print("i");
leds(1, 4);
}
else if(readCapacitivePin(capSensePin20)>sensorLevel) {
Serial.print("l");
leds(2, 4);
}
else if(readCapacitivePin(capSensePin21)>sensorLevel) {
Serial.print("m");
leds(3, 4);
}
else if(readCapacitivePin(capSensePin22)>sensorLevel) {
Serial.print("n");
leds(4, 4);
}
else if(readCapacitivePin(capSensePin23)>sensorLevel) {
Serial.print("o");
leds(5, 4);
}
else if(readCapacitivePin(capSensePin24)>sensorLevel) {
Serial.print("p");
leds(6, 4);
}
else if(readCapacitivePin(capSensePin25)>sensorLevel) {
Serial.print("q");
leds(1, 5);
}
else if(readCapacitivePin(capSensePin26)>sensorLevel) {
Serial.print("r");
leds(2, 5);
}
else if(readCapacitivePin(capSensePin27)>sensorLevel) {
Serial.print("s");
leds(3, 5);
}
else if(readCapacitivePin(capSensePin28)>sensorLevel) {
Serial.print("t");
leds(4, 5);
}
else if(readCapacitivePin(capSensePin29)>sensorLevel) {
Serial.print("u");
leds(5, 5);
}
else if(readCapacitivePin(capSensePin30)>sensorLevel) {
Serial.print("v");
leds(6, 5);
}
else if(readCapacitivePin(capSensePin31)>sensorLevel) {
Serial.print("w");
leds(1, 6);
}
else if(readCapacitivePin(capSensePin32)>sensorLevel) {
Serial.print("x");
leds(2, 6);
}
else if(readCapacitivePin(capSensePin33)>sensorLevel) {
Serial.print("y");
leds(3, 6);
}
else if(readCapacitivePin(capSensePin34)>sensorLevel) {
Serial.print("z");
leds(4, 6);
}
else if(readCapacitivePin(capSensePin35)>sensorLevel) {
Serial.print("j");
leds(5, 6);
}
else if(readCapacitivePin(capSensePin36)>sensorLevel) {
Serial.print("k");
leds(6, 6);
}
else {
Serial.print("-");
leds(0, 0);
}
}
void leds(int X, int Y) { // controllo accensione leds
// RESET comando ULN2803
digitalWrite(I0, LOW);
digitalWrite(I1, LOW);
digitalWrite(I2, LOW);
digitalWrite(I3, LOW);
digitalWrite(I4, LOW);
digitalWrite(I5, LOW);
// RESET comando Linee RGB leds
digitalWrite(BL0, LOW);
digitalWrite(BL1, LOW);
digitalWrite(BL2, LOW);
digitalWrite(BL3, LOW);
digitalWrite(BL4, LOW);
digitalWrite(BL5, LOW);
digitalWrite(GL0, LOW);
digitalWrite(GL1, LOW);
digitalWrite(GL2, LOW);
digitalWrite(GL3, LOW);
digitalWrite(GL4, LOW);
digitalWrite(GL5, LOW);
digitalWrite(RL0, LOW);
digitalWrite(RL1, LOW);
digitalWrite(RL2, LOW);
digitalWrite(RL3, LOW);
digitalWrite(RL4, LOW);
digitalWrite(RL5, LOW);
// generazione valore random
colore = random(1, 4);
// controllo colonne
if(X == 6) digitalWrite(I0, HIGH);
if(X == 5) digitalWrite(I1, HIGH);
if(X == 4) digitalWrite(I2, HIGH);
if(X == 3) digitalWrite(I3, HIGH);
if(X == 2) digitalWrite(I4, HIGH);
if(X == 1) digitalWrite(I5, HIGH);
// controllo righe
if(Y == 1) {
if(colore == 1) digitalWrite(BL0, HIGH);
if(colore == 2) digitalWrite(GL0, HIGH);
if(colore == 3) digitalWrite(RL0, HIGH);
}
if(Y == 2) {
if(colore == 1) digitalWrite(BL1, HIGH);
if(colore == 2) digitalWrite(GL1, HIGH);
if(colore == 3) digitalWrite(RL1, HIGH);
}
if(Y == 3) {
if(colore == 1) digitalWrite(BL2, HIGH);
if(colore == 2) digitalWrite(GL2, HIGH);
if(colore == 3) digitalWrite(RL2, HIGH);
}
if(Y == 4) {
if(colore == 1) digitalWrite(BL3, HIGH);
if(colore == 2) digitalWrite(GL3, HIGH);
if(colore == 3) digitalWrite(RL3, HIGH);
}
if(Y == 5) {
if(colore == 1) digitalWrite(BL4, HIGH);
if(colore == 2) digitalWrite(GL4, HIGH);
if(colore == 3) digitalWrite(RL4, HIGH);
}
if(Y == 6) {
if(colore == 1) digitalWrite(BL5, HIGH);
if(colore == 2) digitalWrite(GL5, HIGH);
if(colore == 3) digitalWrite(RL5, HIGH);
}
}
La riproduzione dei files campionati di Effetti, Tappeti musicali, Brani 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 per Raspberry:
#!/usr/bin/env python
import serial
import pygame.mixer
from time import sleep
from sys import exit
pygame.mixer.init(48000, -16, 1, 1024)
P1 = pygame.mixer.Sound("/home/pi/launchpad/suoni/0.wav")
P2 = pygame.mixer.Sound("/home/pi/launchpad/suoni/1.wav")
P3 = pygame.mixer.Sound("/home/pi/launchpad/suoni/2.wav")
P4 = pygame.mixer.Sound("/home/pi/launchpad/suoni/3.wav")
P5 = pygame.mixer.Sound("/home/pi/launchpad/suoni/4.wav")
P6 = pygame.mixer.Sound("/home/pi/launchpad/suoni/5.wav")
P7 = pygame.mixer.Sound("/home/pi/launchpad/suoni/6.wav")
P8 = pygame.mixer.Sound("/home/pi/launchpad/suoni/7.wav")
P9 = pygame.mixer.Sound("/home/pi/launchpad/suoni/8.wav")
P10 = pygame.mixer.Sound("/home/pi/launchpad/suoni/9.wav")
P11 = pygame.mixer.Sound("/home/pi/launchpad/suoni/10.wav")
P12 = pygame.mixer.Sound("/home/pi/launchpad/suoni/11.wav")
P13 = pygame.mixer.Sound("/home/pi/launchpad/suoni/12.wav")
P14 = pygame.mixer.Sound("/home/pi/launchpad/suoni/13.wav")
P15 = pygame.mixer.Sound("/home/pi/launchpad/suoni/14.wav")
P16 = pygame.mixer.Sound("/home/pi/launchpad/suoni/15.wav")
P17 = pygame.mixer.Sound("/home/pi/launchpad/suoni/16.wav")
P18 = pygame.mixer.Sound("/home/pi/launchpad/suoni/17.wav")
P19 = pygame.mixer.Sound("/home/pi/launchpad/suoni/18.wav")
P20 = pygame.mixer.Sound("/home/pi/launchpad/suoni/19.wav")
P21 = pygame.mixer.Sound("/home/pi/launchpad/suoni/20.wav")
P22 = pygame.mixer.Sound("/home/pi/launchpad/suoni/21.wav")
P23 = pygame.mixer.Sound("/home/pi/launchpad/suoni/22.wav")
P24 = pygame.mixer.Sound("/home/pi/launchpad/suoni/23.wav")
P25 = pygame.mixer.Sound("/home/pi/launchpad/suoni/24.wav")
P26 = pygame.mixer.Sound("/home/pi/launchpad/suoni/25.wav")
P27 = pygame.mixer.Sound("/home/pi/launchpad/suoni/26.wav")
P28 = pygame.mixer.Sound("/home/pi/launchpad/suoni/27.wav")
P29 = pygame.mixer.Sound("/home/pi/launchpad/suoni/28.wav")
P30 = pygame.mixer.Sound("/home/pi/launchpad/suoni/29.wav")
P31 = pygame.mixer.Sound("/home/pi/launchpad/suoni/30.wav")
P32 = pygame.mixer.Sound("/home/pi/launchpad/suoni/31.wav")
P33 = pygame.mixer.Sound("/home/pi/launchpad/suoni/32.wav")
P34 = pygame.mixer.Sound("/home/pi/launchpad/suoni/33.wav")
P35 = pygame.mixer.Sound("/home/pi/launchpad/suoni/34.wav")
P36 = pygame.mixer.Sound("/home/pi/launchpad/suoni/35.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 == "0":
soundChannel1.play(P1)
try:
while True:
RxData = arduino.read()
if RxData != "0":
break
except KeyboardInterrupt:
exit()
if RxData == "1":
soundChannel2.play(P2)
try:
while True:
RxData = arduino.read()
if RxData != "1":
break
except KeyboardInterrupt:
exit()
if RxData == "2":
soundChannel3.play(P3)
try:
while True:
RxData = arduino.read()
if RxData != "2":
break
except KeyboardInterrupt:
exit()
if RxData == "3":
soundChannel1.play(P4)
try:
while True:
RxData = arduino.read()
if RxData != "3":
break
except KeyboardInterrupt:
exit()
if RxData == "4":
soundChannel2.play(P5)
try:
while True:
RxData = arduino.read()
if RxData != "4":
break
except KeyboardInterrupt:
exit()
if RxData == "5":
soundChannel3.play(P6)
try:
while True:
RxData = arduino.read()
if RxData != "5":
break
except KeyboardInterrupt:
exit()
if RxData == "6":
soundChannel1.play(P7)
try:
while True:
RxData = arduino.read()
if RxData != "6":
break
except KeyboardInterrupt:
exit()
if RxData == "7":
soundChannel2.play(P8)
try:
while True:
RxData = arduino.read()
if RxData != "7":
break
except KeyboardInterrupt:
exit()
if RxData == "8":
soundChannel3.play(P9)
try:
while True:
RxData = arduino.read()
if RxData != "8":
break
except KeyboardInterrupt:
exit()
if RxData == "9":
soundChannel1.play(P10)
try:
while True:
RxData = arduino.read()
if RxData != "9":
break
except KeyboardInterrupt:
exit()
if RxData == "a":
soundChannel2.play(P11)
try:
while True:
RxData = arduino.read()
if RxData != "a":
break
except KeyboardInterrupt:
exit()
if RxData == "b":
soundChannel3.play(P12)
try:
while True:
RxData = arduino.read()
if RxData != "b":
break
except KeyboardInterrupt:
exit()
if RxData == "c":
soundChannel1.play(P13)
try:
while True:
RxData = arduino.read()
if RxData != "c":
break
except KeyboardInterrupt:
exit()
if RxData == "d":
soundChannel2.play(P14)
try:
while True:
RxData = arduino.read()
if RxData != "d":
break
except KeyboardInterrupt:
exit()
if RxData == "e":
soundChannel3.play(P15)
try:
while True:
RxData = arduino.read()
if RxData != "e":
break
except KeyboardInterrupt:
exit()
if RxData == "f":
soundChannel1.play(P16)
try:
while True:
RxData = arduino.read()
if RxData != "f":
break
except KeyboardInterrupt:
exit()
if RxData == "g":
soundChannel2.play(P17)
try:
while True:
RxData = arduino.read()
if RxData != "g":
break
except KeyboardInterrupt:
exit()
if RxData == "h":
soundChannel3.play(P18)
try:
while True:
RxData = arduino.read()
if RxData != "h":
break
except KeyboardInterrupt:
exit()
if RxData == "i":
soundChannel1.play(P19)
try:
while True:
RxData = arduino.read()
if RxData != "i":
break
except KeyboardInterrupt:
exit()
if RxData == "l":
soundChannel2.play(P20)
try:
while True:
RxData = arduino.read()
if RxData != "l":
break
except KeyboardInterrupt:
exit()
if RxData == "m":
soundChannel3.play(P21)
try:
while True:
RxData = arduino.read()
if RxData != "m":
break
except KeyboardInterrupt:
exit()
if RxData == "n":
soundChannel1.play(P22)
try:
while True:
RxData = arduino.read()
if RxData != "n":
break
except KeyboardInterrupt:
exit()
if RxData == "o":
soundChannel2.play(P23)
try:
while True:
RxData = arduino.read()
if RxData != "o":
break
except KeyboardInterrupt:
exit()
if RxData == "p":
soundChannel3.play(P24)
try:
while True:
RxData = arduino.read()
if RxData != "p":
break
except KeyboardInterrupt:
exit()
if RxData == "q":
soundChannel1.play(P25)
try:
while True:
RxData = arduino.read()
if RxData != "q":
break
except KeyboardInterrupt:
exit()
if RxData == "r":
soundChannel2.play(P26)
try:
while True:
RxData = arduino.read()
if RxData != "r":
break
except KeyboardInterrupt:
exit()
if RxData == "s":
soundChannel3.play(P27)
try:
while True:
RxData = arduino.read()
if RxData != "s":
break
except KeyboardInterrupt:
exit()
if RxData == "t":
soundChannel1.play(P28)
try:
while True:
RxData = arduino.read()
if RxData != "t":
break
except KeyboardInterrupt:
exit()
if RxData == "u":
soundChannel2.play(P29)
try:
while True:
RxData = arduino.read()
if RxData != "u":
break
except KeyboardInterrupt:
exit()
if RxData == "v":
soundChannel3.play(P30)
try:
while True:
RxData = arduino.read()
if RxData != "v":
break
except KeyboardInterrupt:
exit()
if RxData == "w":
soundChannel1.play(P31)
try:
while True:
RxData = arduino.read()
if RxData != "w":
break
except KeyboardInterrupt:
exit()
if RxData == "x":
soundChannel2.play(P32)
try:
while True:
RxData = arduino.read()
if RxData != "x":
break
except KeyboardInterrupt:
exit()
if RxData == "y":
soundChannel3.play(P33)
try:
while True:
RxData = arduino.read()
if RxData != "y":
break
except KeyboardInterrupt:
exit()
if RxData == "z":
soundChannel1.play(P34)
try:
while True:
RxData = arduino.read()
if RxData != "x":
break
except KeyboardInterrupt:
exit()
if RxData == "j":
soundChannel2.play(P35)
try:
while True:
RxData = arduino.read()
if RxData != "j":
break
except KeyboardInterrupt:
exit()
if RxData == "k":
soundChannel3.play(P36)
try:
while True:
RxData = arduino.read()
if RxData != "k":
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()