Il mondo vegetale è un mondo inanimato oppure ha un’anima?
Non solo le piante hanno vita, costituendo la maggioranza delle forme viventi sul pianeta, ma presentano, tra le altre caratteristiche, gli stessi segnali elettrici che controllano il corpo umano.
BIO-Sound machine è uno strumento che trasforma le variazioni di queste caratteristiche elettriche dei Bio-organismi, come la conduttività elettrica, in generazione di suoni.
Il programma informatico acquisisce i dati dei sensori attraverso un circuito elettronico progettato, e restituisce i comandi delle note musicali ad un sintetizzatore controllato secondo il protocollo MIDI (Musical Instruments Digital Interface), avvalendosi della tecnologia Arduino.
Il progetto nasce all’interno del nostro Istituto finalizzato alla Didattica ed all’Educazione Ambientale, oltre che per la sensibilizzazione delle persone verso la vita del mondo vegetale.
BIO Organismi: le Piante
Recenti studi scientifici hanno confermato il fatto che le piante, pur non potendosi muovere (sono Sessili), hanno una personalità e percepiscono l’ambiente attraverso una quindicina di sensi, oltre ai 5 che abbiamo anche noi, e sono in grado di sentire la Gravità, i Campi Elettromagnetici, l’Umidità e svariati altri Gradienti Chimici.
Esse non hanno organi unici come accade agli animali, ma diffusi in tutto il loro corpo e sono collegati tra loro da una struttura a rete non diversa da Internet.
Possono comunicare tra loro e con altri esseri viventi, come gli insetti, e sono in grado di produrre ultrasuoni quando sono stressate.
Inoltre è studiato che i segnali elettrici che controllano il corpo umano sono presenti anche nelle piante, sebbene queste non abbiano neuroni.
Come gli altri esseri viventi si scambiano informazioni e interagiscono, adottano strategie per la sopravvivenza, hanno una vita sociale, sfruttano al meglio le risorse energetiche.
Hanno cioè una propria intelligenza e sono capaci di scegliere, imparare e ricordare.
Hanno anche una Intelligenza di Sciame, che permette loro di comportarsi e reagire non come singole unità ma come comunità intera, un po’ come certe specie di uccelli e insetti.
[Greg Gage – Stefano Mancuso].
Le Piante ed il mondo vegetale costituisce il 97% delle forme di vita sul pianeta Terra, contro il 3% costituito dal Regno Animale (2/3 del quale sono insetti).
L’Uomo ne costituisce solo lo 0,01%.
E’ stato però capace di portare all’estinzione dell’83% dei mammiferi esistenti e del 50% delle specie Vegetali.
Da un punto di vista della Biomassa presente sulla Terra le Piante costituiscono l’83% del peso delle forme viventi, i Batteri il 13% ed il Regno Animale solo il 5%.
Tutti gli uomini del pianeta hanno un peso minore dei Virus o dei Vermi!
Tutto questo ci dovrebbe indurre a rivalutare la considerazione che abbiamo di noi genere umano..
La vita segreta delle piante è probabilmente molto più ricca e complicata di quanto pensiamo e oggi siamo solo all’inizio dell’esplorazione scientifica di questo affascinante campo di studio.
BIO Sound Machine
Con la curiosità di chi vuole esplorare l’argomento, abbiamo cercato attraverso il progetto BIO Sound Machine, di capire come fosse possibile dar loro voce utilizzando sensori che traducono alcuni dei loro propri processi biologici in musica.
Processi biologici come quello della fotosintesi o del movimento dei liquidi all’interno della pianta durante il processo di cavitazione, in cui le bolle d’aria vengono aspirate attraverso il corpo della pianta, specialmente quando l’acqua è scarsa.
Come tutti gli organismi viventi, le piante subiscono variazioni di resistenza elettrica dovute a questi fattori, tra cui importantissimi stati fisiologici ed emozionali.
Le piante sono delle grandi antenne, dei ricettori sensibilissimi, esse captano dall’ambiente moltissime variazioni energetiche fisiche (ad esempio campi elettromagnetici statici e variabili..).
Il suono che sentiamo come musica attraverso BIO Sound non è la voce naturale delle piante, ma esso viene generato attraverso un circuito elettronico, il programma informatico che controlla ed elabora i dati captati dai sensori attraverso di esso, ed un sintetizzatore di suoni controllato secondo il protocollo MIDI.
Così come un musicista suona uno strumento con le proprie mani per creare musica, le piante usano BIO Sound per esprimersi facendo musica.



BIO Sound per l’Educazione Ambientale e la Didattica
Il progetto BIO Sound nasce dall’esigenza di sensibilizzare alla conoscenza ed al rispetto del mondo vegetale, e della vita in generale, da parte delle persone, in modo speciale i bambini.
La sua capacità di emozionare è in grado di condurci in una realtà che molto spesso ignoriamo, perchè celata ai nostri occhi.
Scoprire la vitalità delle piante, che grazie a BIO Sound può arrivare ai nostri sensi, è una forma di educazione ambientale che rafforza il rispetto.
La possibilità di interazione a livello emozionale, e non solo in quello della sfera cognitiva, lo rende un mezzo per aprire canali di comunicazione con persone che presentano difficoltà cognitive e comportamentali.
Le sue implicazioni didattiche sono nell’ambito della Musica e delle Scienze, ed accompagna il bambino alla scoperta di sé e dell’altro.
Altro che in questo caso contempla anche il mondo delle piante.




Il Circuito Elettronico
Il circuito elettronico realizzato per il progetto è passato attraverso varie fasi di sviluppo con la creazione di successivi prototipi ai quali si sono aggiunte via via varie funzionalità.




La sezione di ingresso, realizzata con integrato Timer555, ha la funzione di convertire la conduttività elettrica tra foglia e foglia o tra terreno e foglia, rilevata attraverso sensori elettrici adesivi di uso medicale, in un segnale elettronico digitale di frequenza proporzionale ad essa.
Tale frequenza determina la lunghezza dell’impulso (semiperiodo alto) che viene letta in ingresso da Arduino utilizzando la funzione pulseIn(), che restituisce questo valore in mS.

Sulla base della variazione di questi valori rilevati attraverso i sensori collegati all’ingresso del circuito è stato impostato tutto il programma per la generazione del suono MIDI.
Nello schema circuitale sono stati inseriti in ingresso ad Arduino anche tre potenziometri ed un selettore a 12 posizioni, per poter manipolare da programma le modalità di generazione del suono.
La versione 4 di BIO Sound prevede, oltre al circuito elettronico ed Arduino, che costituiscono il modulo di generazione delle note, anche l’utilizzo di un microcomputer Raspberry sul quale è installato il sintetizzatore FluidSinth, rendendo quindi lo strumento indipendente dall’utilizzo di un computer e dalla presenza della rete wifi.
Il Programma Arduino
L’algoritmo legge il valore della durata dell’impulso generato dalla sezione di ingresso con Timer555, valore che è espresso in mS.
Questo valore che subisce continuamente piccole variazioni legate ai processi biologici viene memorizzato nei suoi valori minimi e massimi. Attraverso questi valori si effettua quindi una normalizzazione rispetto al valore minimo e massimo delle note che si vogliono riprodurre.
Questo significa che, sapendo che nel protocollo MIDI ogni nota delle ottave corrispondenti al campo audio è identificata da un numero che varia da 0 a 127, il range di variazione dell’impulso letto viene amplificato adattandolo a questi valori delle note. Quindi ogni variazione che genera un passaggio da una nota a quelle successive o precedenti può produrre la generazione di un valore MIDI.
Questo valore, insieme al valore della sua Velocity (intensità), viene quindi inviato sull’uscita MIDI con messaggi seriali secondo il protocollo.
Attraverso i potenziometri inseriti è possibile controllare i valori del Volume di uscita, della Soglia della variazione di generazione delle note e della Estensione delle ottave di generazione.
Il primo (colore Blu) imposta il valore della Velocity tra 0 e 127 determinando il volume di uscita.
Il controllo della Soglia (colore Bianco) imposta invece il valore oltre il quale la variazione del segnale prodotto in ingresso generi la nota.
Il valore prodotto dal potenziometro della Estensione delle ottave (colore Arancione) modifica i valori MIDI minimo e massimo nella normalizzazione per la generazione in base alle variazioni dovute al segnale di ingresso, modificando di fatto il numero di ottave entro il quale questa generazione avviene, da un massimo di 9 ad un minimo di una (quella centrale).
Con il pulsante BTN1 viene selezionata la produzione della nota singola o della sua triade maggiore, mentre con BTN2 si possono selezionare i modi Cromatico, Maggiore, Minore o Minore Diatonico entro i quali generare le note.
Il programma gestisce inoltre la visualizzazione di queste impostazioni attraverso una serie di led.
I quattro led da 5mm indicano il modo scelto, mentre quelli da 3mm la tonalità (da sinistra da DO a SI, il led verde l’eventuale #).
Volendo utilizzare direttamente la porta USB di Arduino, che nella versione2 è un MEGA 2560, come uscita MIDI da collegare direttamente al Sintetizzatore per la riproduzione dei suoni, occorre, una volta caricato lo scheck, sostituire il Firmware nel processore della seriale della scheda con quello MIDI.
Per farlo si deve installare una applicazione DFU (Device Firmware Update) come ATMEL Flip e fare l’upload del firmware Arduino_MIDI. Per utilizzare l’applicazione DFU occorre prima di tutto cortocircuitare l’ingresso Reset2 di Arduino a GND (Pulsante DFU della scheda BIO Sound) e quindi collegare ATMEL Flip alla scheda selezionando USB (Ctrl+U), caricare il file del firmware e lanciare RUN.
Nel caso dobbiate apportare modifiche al programma Arduino dovete ripristinare il firmware originale a seconda della scheda utilizzata (Arduino UNO Rev3, Arduino MEGA 2560).
Listato programma:
/* BIOSound - Generazione MIDI con le piante (e non solo :)
*
* Versione v3 .- 24 Maggio 2023
* scheda: Arduino Mega 2560
* autore: Fabrizio Silvetti fabriziosilvetti.com
*
* Collegamenti Arduino:
* -----------------------------------------------------
* pin 3,3v pin 13 -> SEL1 C
* pin 5v pin 12 -> SEL2 C#
* pin GND pin 11 -> SEL3 D
* pin GND pin 10 -> SEL4 D#
* pin Vin pin 9 -> SEL5 E
* pin A0 -> BTN1 pin 8 -> SEL6 F
* pin A1 -> BTN2 pin 7 -> SEL7 F#
* pin A2 -> SEL12 B pin 6 -> SEL8 G
* pin A3 -> EST_OTT pin 5 -> SEL9 G#
* pin A4 -> VOLUME pin 4 -> SEL10 A
* pin A5 -> SOGLIA pin 3 -> SEL11 A#
* pin A6 pin 2 -> IN_555
* pin A7 pin 1 -> MIDI_OUT
* pin A8 -> LED_BLUE pin 0
* pin A9 -> LED_RED pin 14 -> LED_TON_#
* pin A10 -> LED_YELLOW pin 15 -> LED_TON_C
* pin A11 -> LED_GREEN pin 16 -> LED_TON_D
* pin A12 pin 17 -> LED_TON_E
* pin A13 pin 18 -> LED_TON_F
* pin A14 pin 19 -> LED_TON_G
* pin A15 pin 20 -> LED_TON_A
* pin 21 -> LED_TON_B
* -----------------------------------------------------
*
* Il programma legge la durata impulso (proporzionale alla freq
* dell'astabile con 555) generato dalla variazione della impedenza in ingresso.
* Normalizzato ai suoi valori Max e min, viene utilizzato per la creazione delle note.
* Nella creazione note si tiene conto di:
* - estensione ottave (scelto con pot Arancio, 1 - 9)
* - tonalità (scelta con selettore Rosso, C, C#, D, D#, E, F, F#, G, G#, A, A#, B)
* - modo (scelta con BTN2, Chromatic, Major, Minor, Minor Diatonic)
* - histeresi (scelta con pot Bianco, 0 - 50, e utilizzata come variazione minima dalla nota precedente per creazione nota)
* - volume (scelto con pot Blu, 0 - 127)
* Le note vengono create in MIDI, dove nota==1 -> C0(16Hz) e nota==127 -> B9(8350Hz).
* Con BTN1 vengono creati accordi Maggiori sulla nota.
*/
const byte btn1Pin = A0; //btn1 Polifonia
const byte btn2Pin = A1; //btn2 Tonalità
const byte volPin = A5; //pin pot volume
const byte histPin = A3; //pin pot Histeresi (soglia)
const byte octPin = A4; //pin pot Estensione Ottave
const byte in_555 = 2; //pin collegato all'Out del 555
//leds scala scelta
const byte led_blue_chrom = A8; //scala Chromatica
const byte led_red_mag = A9; //scala Maggiore
const byte led_yellow_min_dia = A10; //scala Minore Diatonica
const byte led_green_min= A11; //scala Minore
//leds tonalità
const byte led_diesis = 14;
const byte led_C = 15;
const byte led_D = 16;
const byte led_E = 17;
const byte led_F = 18;
const byte led_G = 19;
const byte led_A = 20;
const byte led_B = 21;
/* Selettore tonalità
* ------------------
* ton seq_in_Ard
* C 011111111111
* C# 101111111111
* D 110111111111
* D# 111011111111
* E 111101111111
* F 111110111111
* F# 111111011111
* G 111111101111
* G# 111111110111
* A 111111111011
* A# 111111111101
* B 111111111110
*/
const int C_pin = 3;
const int Cd_pin = 4;
const int D_pin = 5;
const int Dd_pin = 6;
const int E_pin = 7;
const int F_pin = 8;
const int Fd_pin = 9;
const int G_pin = 10;
const int Gd_pin = 11;
const int A_pin = 12;
const int Ad_pin = 13;
const int B_pin = A2;
// ------------------
//Generazione nota con elaborazione_segnale()
unsigned long _pulse;
unsigned long maxSignal = 0;
unsigned long minSignal = 1000000;
int mediaSignal, deltaSignal, notaSignal;
int nota, nota_temp;
unsigned long loopMillis = 0;
bool btn_isPressed = false;
//Impostazione note MIDI
byte _channel = 1; //setting channel to 11 or 12 often helps simply computer midi routing setups
byte _velocity = 0; // 0 -> 127
int _estensione_ottave;
int noteMin; //C0 - keyboard note minimum
int noteMax; //C7 - keyboard note maximum
int tonalita; // 1->C, 2->C#, 3->D, 4-D#, 5->E, 6->F, 7->F#, 8->G, 9->G#, 10->A, 11->A#, 12->B
int tipo_scala = 0; //Maggiore
int indice_nota;
int nota_base_tonalita[13];
//int nota_base_tonalita[13] = {0,60,61,62,63,64,65,66,67,68,69,70,71};
int scale[4][13] = { // scale[tipo][nota]
{12, 1,2,3,4,5,6,7,8,9,10,11,12}, //Chromatic
{7, 1, 3, 5, 6, 8, 10, 12}, //Major
{7, 1, 3, 4, 6, 8, 9, 11}, //DiaMinor
//{7, 1, 2, 2, 5, 6, 9, 11}, //Indian
{7, 1, 3, 4, 6, 8, 9, 11} //Minor
};
//per test Serial
int ottave[8] = {0,1,2,3,4,5,6,7};
String note_ottave[8][13] = { //A4 = 440 Hz
{"0","C0","C0#","D0","D0#","E0","F0","F2#","G0","G0#","A0","A0#","B0"}, //12->C0(16Hz) a 107->B7(3951Hz)
{"1","C1","C1#","D1","D1#","E1","F1","F1#","G1","G1#","A1","A1#","B1"},
{"2","C2","C2#","D2","D2#","E2","F2","F2#","G2","G2#","A2","A2#","B2"},
{"3","C3","C3#","D3","D3#","E3","F3","F3#","G3","G3#","A3","A3#","B3"},
{"4","C4","C4#","D4","D4#","E4","F4","F4#","G4","G4#","A4","A4#","B4"},
{"5","C5","C5#","D5","D5#","E5","F5","F5#","G5","G5#","A5","A5#","B5"},
{"6","C6","C6#","D6","D6#","E6","F6","F6#","G6","G6#","A6","A6#","B6"},
{"7","C7","C7#","D7","D7#","E7","F7","F7#","G7","G7#","A7","A7#","B7"}
};
//utilizzo checkBattery
byte controlNumber = 80; //set to mappable control, low values may interfere with other soft synth controls!!
byte controlVoltage = 1; //output PWM CV on controlLED, pin 17, PB3, digital 11 *lowpass filter
long batteryLimit = 3000; //voltage check minimum, 3.0~2.7V under load; causes lightshow to turn off (save power)
byte checkBat = 1;
unsigned long previousMillis = 0;
unsigned long currentMillis = 1;
unsigned long batteryCheck = 0; //battery check delay timer
// utilizzo potenziometro creazione isteresi generazione nota
int _threshold;
int threshMin = 0;
int threshMax = 50; // valore max isteresi per esecuzione nota
int knobMin = 1;
int knobMax = 1023;
void setup()
{
pinMode(btn1Pin, INPUT_PULLUP);
pinMode(btn2Pin, INPUT_PULLUP);
pinMode(histPin, INPUT);
pinMode(volPin, INPUT);
pinMode(in_555, INPUT);
pinMode(C_pin, INPUT_PULLUP);
pinMode(Cd_pin, INPUT_PULLUP);
pinMode(D_pin, INPUT_PULLUP);
pinMode(Dd_pin, INPUT_PULLUP);
pinMode(E_pin, INPUT_PULLUP);
pinMode(F_pin, INPUT_PULLUP);
pinMode(Fd_pin, INPUT_PULLUP);
pinMode(G_pin, INPUT_PULLUP);
pinMode(Gd_pin, INPUT_PULLUP);
pinMode(A_pin, INPUT_PULLUP);
pinMode(Ad_pin, INPUT_PULLUP);
pinMode(B_pin, INPUT_PULLUP);
pinMode(led_blue_chrom, OUTPUT);
pinMode(led_red_mag, OUTPUT);
pinMode(led_yellow_min_dia, OUTPUT);
pinMode(led_green_min, OUTPUT);
pinMode(led_diesis, OUTPUT);
pinMode(led_C, OUTPUT);
pinMode(led_D, OUTPUT);
pinMode(led_E, OUTPUT);
pinMode(led_F, OUTPUT);
pinMode(led_G, OUTPUT);
pinMode(led_A, OUTPUT);
pinMode(led_B, OUTPUT);
Serial.begin(31250); //initialize at MIDI rate
//Serial.begin(9600); //for TEST 555
}
void loop()
{
loopMillis = millis(); //controllo istante di ingresso loop
//checkBattery(); //on low power, shutoff lightShow, continue MIDI operation
while(millis() <= (loopMillis + 2000))
{
checkKnob(); // check isteresi potenziometro
scelta_tonalita();
//impostazione nota minima e massima (estensione ottave)//
noteMin = nota_base_tonalita[1]; //
noteMax = noteMin + (12 * _estensione_ottave); //
elaborazione_segnale(); // elaborazione nota
creazione_nota();
}
//Reset valori maxSignal e minSignal
maxSignal = 0;
minSignal = 1000000;
}
void elaborazione_segnale() {
_pulse = pulseInLong(in_555,HIGH); //for TEST 555
// determinazione delta SignalIn
if(_pulse > maxSignal) maxSignal = _pulse;
if(_pulse < minSignal) minSignal = _pulse;
deltaSignal = maxSignal - minSignal;
mediaSignal = (maxSignal + minSignal) / 2;
notaSignal = _pulse - minSignal;
nota = map(notaSignal, 0, deltaSignal, noteMin, noteMax);
if(nota < noteMin) nota = noteMin;
if(nota > noteMax) nota = noteMax;
/*
Serial.print("nota = ");Serial.println(nota); //for TEST 555
Serial.print("_pulse = ");Serial.println(_pulse);
Serial.print("maxSignal = ");Serial.println(maxSignal);
Serial.print("minSignal = ");Serial.println(minSignal);
delay(500);
*/
}
void creazione_nota()
{
if(nota >= (nota_temp + _threshold) || nota <= (nota_temp - _threshold)) //Isteresi note
{
//Serial.print("NOTA = ");Serial.println(nota);
int base = nota_base_tonalita[tonalita]; // nota iniziale ottave
int ottava = nota/12 - 1; // 0->C0, 1->C1, 2->C2, 3->C3, 4->C4, 5->C5, 6->C6, 7->C7
int nota_ottava = (nota%12) + 1; // determino la nota all'interno dell'ottava
lettura_scelta_scala();
/*
Serial.println("-----------------------------");
Serial.print("base = ");Serial.println(base);
Serial.print("nota = "); Serial.print(nota); Serial.print(" - "); Serial.println(note_ottave[ottava][nota_ottava]);
Serial.print("ottava = "); Serial.println(ottava);
Serial.print("nota_ottava = "); Serial.println(nota_ottava);
Serial.print("valori scala = ");
*/
for(int i=1; i<=scale[tipo_scala][0]; i++)
{
/*
Serial.print((scale[tipo_scala][i] - 1) + base); Serial.print(",");
Serial.print((scale[tipo_scala][i] - 1) + base + 12); Serial.print(",");
Serial.print((scale[tipo_scala][i] - 1) + base + 24); Serial.print(",");
Serial.print((scale[tipo_scala][i] - 1) + base + 36); Serial.print(",");
Serial.print((scale[tipo_scala][i] - 1) + base + 48); Serial.print(",");
Serial.print((scale[tipo_scala][i] - 1) + base + 60); Serial.print(",");
*/
// Verifico se la nota è nella tonalità
if(nota == ((scale[tipo_scala][i] - 1) + base)
|| nota == ((scale[tipo_scala][i] - 1) + base + 12)
|| nota == ((scale[tipo_scala][i] - 1) + base + 24)
|| nota == ((scale[tipo_scala][i] - 1) + base + 36)
|| nota == ((scale[tipo_scala][i] - 1) + base + 48)
|| nota == ((scale[tipo_scala][i] - 1) + base + 60)
|| nota == ((scale[tipo_scala][i] - 1) + base + 72)
|| nota == ((scale[tipo_scala][i] - 1) + base + 84))
{
// creazione note
midiSerial(144, _channel, nota, _velocity);
if(!digitalRead(btn1Pin)) //creazione polifonia con BTN1
{
midiSerial(144, _channel+1, nota+5, _velocity); // 3 maggiore
midiSerial(144, _channel+2, nota+8, _velocity); // 5
midiSerial(144, _channel+3, nota+10, _velocity); // 7 minore
}
//interruzione note precedentemente create
else
{
midiSerial(144, _channel+1, nota_temp+5, 0);
midiSerial(144, _channel+2, nota_temp+8, 0);
midiSerial(144, _channel+3, nota_temp+10, 0);
}
midiSerial(144, _channel, nota_temp, 0);
nota_temp = nota; //memorizzo valore precedente nota
delay(50); // ?
//Serial.println(""); Serial.print("NOTA = "); Serial.print(nota); Serial.print(" - "); Serial.println(note_ottave[ottava][nota_ottava]); // for TEST 555
break;
}
else
{
midiSerial(144, _channel, nota, 0);
if(!digitalRead(btn1Pin)) //creazione polifonia con BTN1
{
midiSerial(144, _channel+1, nota+5, 0); // 3 maggiore
midiSerial(144, _channel+2, nota+8, 0); // 5
midiSerial(144, _channel+3, nota+10, 0); // 7 minore
}
else
{
midiSerial(144, _channel+1, nota_temp+5, 0);
midiSerial(144, _channel+2, nota_temp+8, 0);
midiSerial(144, _channel+3, nota_temp+10, 0);
}
//Serial.println("NOTA FUORI TONALITà -------------------");
}
//Serial.println("");
}
}
}
void scelta_tonalita()
{
int _C = digitalRead(C_pin);
int _Cd = digitalRead(Cd_pin);
int _D = digitalRead(D_pin);
int _Dd = digitalRead(Dd_pin);
int _E = digitalRead(E_pin);
int _F = digitalRead(F_pin);
int _Fd = digitalRead(Fd_pin);
int _G = digitalRead(G_pin);
int _Gd = digitalRead(Gd_pin);
int _A = digitalRead(A_pin);
int _Ad = digitalRead(Ad_pin);
int _B = digitalRead(B_pin);
if(_C == 0) {
tonalita = 1;
digitalWrite(led_C, HIGH);
digitalWrite(led_D, LOW);
digitalWrite(led_E, LOW);
digitalWrite(led_F, LOW);
digitalWrite(led_G, LOW);
digitalWrite(led_A, LOW);
digitalWrite(led_B, LOW);
digitalWrite(led_diesis, LOW);
}
if(_Cd == 0) {
tonalita = 2;
digitalWrite(led_C, HIGH);
digitalWrite(led_D, LOW);
digitalWrite(led_E, LOW);
digitalWrite(led_F, LOW);
digitalWrite(led_G, LOW);
digitalWrite(led_A, LOW);
digitalWrite(led_B, LOW);
digitalWrite(led_diesis, HIGH);
}
if(_D == 0) {
tonalita = 3;
digitalWrite(led_C, LOW);
digitalWrite(led_D, HIGH);
digitalWrite(led_E, LOW);
digitalWrite(led_F, LOW);
digitalWrite(led_G, LOW);
digitalWrite(led_A, LOW);
digitalWrite(led_B, LOW);
digitalWrite(led_diesis, LOW);
}
if(_Dd == 0) {
tonalita = 4;
digitalWrite(led_C, LOW);
digitalWrite(led_D, HIGH);
digitalWrite(led_E, LOW);
digitalWrite(led_F, LOW);
digitalWrite(led_G, LOW);
digitalWrite(led_A, LOW);
digitalWrite(led_B, LOW);
digitalWrite(led_diesis, HIGH);
}
if(_E == 0) {
tonalita = 5;
digitalWrite(led_C, LOW);
digitalWrite(led_D, LOW);
digitalWrite(led_E, HIGH);
digitalWrite(led_F, LOW);
digitalWrite(led_G, LOW);
digitalWrite(led_A, LOW);
digitalWrite(led_B, LOW);
digitalWrite(led_diesis, LOW);
}
if(_F == 0) {
tonalita = 6;
digitalWrite(led_C, LOW);
digitalWrite(led_D, LOW);
digitalWrite(led_E, LOW);
digitalWrite(led_F, HIGH);
digitalWrite(led_G, LOW);
digitalWrite(led_A, LOW);
digitalWrite(led_B, LOW);
digitalWrite(led_diesis, LOW);
}
if(_Fd == 0) {
tonalita = 7;
digitalWrite(led_C, LOW);
digitalWrite(led_D, LOW);
digitalWrite(led_E, LOW);
digitalWrite(led_F, HIGH);
digitalWrite(led_G, LOW);
digitalWrite(led_A, LOW);
digitalWrite(led_B, LOW);
digitalWrite(led_diesis, HIGH);
}
if(_G == 0) {
tonalita = 8;
digitalWrite(led_C, LOW);
digitalWrite(led_D, LOW);
digitalWrite(led_E, LOW);
digitalWrite(led_F, LOW);
digitalWrite(led_G, HIGH);
digitalWrite(led_A, LOW);
digitalWrite(led_B, LOW);
digitalWrite(led_diesis, LOW);
}
if(_Gd == 0) {
tonalita = 9;
digitalWrite(led_C, LOW);
digitalWrite(led_D, LOW);
digitalWrite(led_E, LOW);
digitalWrite(led_F, LOW);
digitalWrite(led_G, HIGH);
digitalWrite(led_A, LOW);
digitalWrite(led_B, LOW);
digitalWrite(led_diesis, HIGH);
}
if(_A == 0) {
tonalita = 10;
digitalWrite(led_C, LOW);
digitalWrite(led_D, LOW);
digitalWrite(led_E, LOW);
digitalWrite(led_F, LOW);
digitalWrite(led_G, LOW);
digitalWrite(led_A, HIGH);
digitalWrite(led_B, LOW);
digitalWrite(led_diesis, LOW);
}
if(_Ad == 0) {
tonalita = 11;
digitalWrite(led_C, LOW);
digitalWrite(led_D, LOW);
digitalWrite(led_E, LOW);
digitalWrite(led_F, LOW);
digitalWrite(led_G, LOW);
digitalWrite(led_A, HIGH);
digitalWrite(led_B, LOW);
digitalWrite(led_diesis, HIGH);
}
if(_B == 0) {
tonalita = 12;
digitalWrite(led_C, LOW);
digitalWrite(led_D, LOW);
digitalWrite(led_E, LOW);
digitalWrite(led_F, LOW);
digitalWrite(led_G, LOW);
digitalWrite(led_A, LOW);
digitalWrite(led_B, HIGH);
digitalWrite(led_diesis, LOW);
}
//Serial.print("selettore = "); Serial.print(_C);Serial.print(_Cd);Serial.print(_D);Serial.print(_Dd);Serial.print(_E);Serial.print(_F);Serial.print(_Fd);Serial.print(_G);Serial.print(_Gd);Serial.print(_A);Serial.print(_Ad);Serial.println(_B);
//Serial.print("tonalità = "); Serial.println(tonalita);
}
void lettura_scelta_scala() {
//shift scala sul button release
if(!digitalRead(btn2Pin)) btn_isPressed = true;
if(digitalRead(btn2Pin) && btn_isPressed == true)
{
btn_isPressed = false;
tipo_scala ++;
if(tipo_scala > 3) tipo_scala = 0;
}
if(tipo_scala == 0)
{
digitalWrite(led_blue_chrom,HIGH);
digitalWrite(led_red_mag,LOW);
digitalWrite(led_yellow_min_dia,LOW);
digitalWrite(led_green_min,LOW);
}
else if(tipo_scala == 1)
{
digitalWrite(led_blue_chrom,LOW);
digitalWrite(led_red_mag,HIGH);
digitalWrite(led_yellow_min_dia,LOW);
digitalWrite(led_green_min,LOW);
}
else if(tipo_scala == 2)
{
digitalWrite(led_blue_chrom,LOW);
digitalWrite(led_red_mag,LOW);
digitalWrite(led_yellow_min_dia,HIGH);
digitalWrite(led_green_min,LOW);
}
else if(tipo_scala == 3)
{
digitalWrite(led_blue_chrom,LOW);
digitalWrite(led_red_mag,LOW);
digitalWrite(led_yellow_min_dia,LOW);
digitalWrite(led_green_min,HIGH);
}
else
{
digitalWrite(led_blue_chrom,LOW);
digitalWrite(led_red_mag,LOW);
digitalWrite(led_yellow_min_dia,LOW);
digitalWrite(led_green_min,LOW);
}
//Serial.print("tipo_scala = "); Serial.println(tipo_scala);
}
void checkKnob() {
//funzione lettura potenziometri
_velocity = analogRead(volPin);
_threshold = analogRead(histPin);
_estensione_ottave = 1024 - analogRead(octPin);
//set estensione_ottave
if(_estensione_ottave < 114) {
_estensione_ottave = 1;
nota_base_tonalita[0] = 0;
for(int i=60; i<72; i++) nota_base_tonalita[i-59] = i; //0,C4,C4#,D4,D4#,E4,F4,F4#,G4,G4#,A4,A4#,B4
/*Serial.print("nota_base_tonalita[] = ");
Serial.print(nota_base_tonalita[1]);
Serial.print(nota_base_tonalita[2]);
Serial.print(nota_base_tonalita[3]);
Serial.print(nota_base_tonalita[4]);
Serial.print(nota_base_tonalita[5]);
Serial.print(nota_base_tonalita[6]);
Serial.print(nota_base_tonalita[7]);
Serial.print(nota_base_tonalita[8]);
Serial.print(nota_base_tonalita[9]);
Serial.print(nota_base_tonalita[10]);
Serial.print(nota_base_tonalita[11]);
Serial.println(nota_base_tonalita[12]);*/
}
else if(_estensione_ottave >= 114 && _estensione_ottave < 228) {
_estensione_ottave = 2;
nota_base_tonalita[0] = 0;
for(int i=54; i<66; i++) nota_base_tonalita[i-53] = i; //0,F3#,G3,G3#,A3,A3#,B3,C4,C4#,D4,D4#,E4,F4
}
else if(_estensione_ottave >= 228 && _estensione_ottave < 352) {
_estensione_ottave = 3;
nota_base_tonalita[0] = 0;
for(int i=48; i<60; i++) nota_base_tonalita[i-47] = i; //0,C3,C3#,D3,D3#,E3,F3,F3#,G3,G3#,A3,A3#,B3
}
else if(_estensione_ottave >= 352 && _estensione_ottave < 446) {
_estensione_ottave = 4;
nota_base_tonalita[0] = 0;
for(int i=42; i<54; i++) nota_base_tonalita[i-41] = i; //0,F2#,G2,G2#,A2,A2#,B2,C3,C3#,D3,D3#,E3,F3
}
else if(_estensione_ottave >= 466 && _estensione_ottave < 580) {
_estensione_ottave = 5;
nota_base_tonalita[0] = 0;
for(int i=36; i<48; i++) nota_base_tonalita[i-35] = i; //0,C2,C2#,D2,D2#,E2,F2,F2#,G2,G2#,A2,A2#,B2
}
else if(_estensione_ottave >= 580 && _estensione_ottave < 694) {
_estensione_ottave = 6;
nota_base_tonalita[0] = 0;
for(int i=30; i<42; i++) nota_base_tonalita[i-29] = i; //0,F1#,G1,G1#,A1,A1#,B1,C2,C2#,D2,D2#,E2,F2
}
else if(_estensione_ottave >= 694 && _estensione_ottave < 808) {
_estensione_ottave = 7;
nota_base_tonalita[0] = 0;
for(int i=24; i<36; i++) nota_base_tonalita[i-23] = i; //0,C1,C1#,D1,D1#,E1,F1,F1#,G1,G1#,A1,A1#,B1
}
else if(_estensione_ottave >= 808 && _estensione_ottave < 922) {
_estensione_ottave = 8;
nota_base_tonalita[0] = 0;
for(int i=18; i<30; i++) nota_base_tonalita[i-17] = i; //0,F0#,G0,G0#,A0,A0#,B0,C1,C1#,D1,D1#,E1,F1
}
else {
_estensione_ottave = 9;
nota_base_tonalita[0] = 0;
for(int i=12; i<24; i++) nota_base_tonalita[i-11] = i; //0,C0,C0#,D0,D0#,E0,F0,F0#,G0,G0#,A0,A0#,B0
}
//set threshold to knobValue mapping
_velocity = map(_velocity, 0, 255, 127, 0);
_threshold = map(_threshold, knobMin, knobMax, threshMax, threshMin);
//Serial.print("_estensione_ottave = "); Serial.println(_estensione_ottave);
//Serial.print("_velocity = "); Serial.println(_velocity);
//Serial.print("_threshold = "); Serial.println(_threshold);
}
long readVcc() { //https://code.google.com/p/tinkerit/wiki/SecretVoltmeter
long result;
// Read 1.1V reference against AVcc
ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
delay(2); // Wait for Vref to settle
ADCSRA |= _BV(ADSC); // Convert
while (bit_is_set(ADCSRA,ADSC));
result = ADCL;
result |= ADCH<<8;
result = 1126400L / result; // Back-calculate AVcc in mV
return result;
}
void checkBattery(){
//check battery voltage against internal 1.1v reference
//if below the minimum value, turn off the light show to save power
//don't check on every loop, settle delay in readVcc() slows things down a bit
if(batteryCheck < currentMillis){
batteryCheck = currentMillis+10000; //reset for next battery check
if(readVcc() < batteryLimit) { //if voltage > valueV
//battery failure
if(checkBat) { //first battery failure
//for(byte j=0;j