Discomatic

Introduzione

Discomatic è un progetto didattico che come obiettivo ha quello di realizzare un riproduttore musicale di file MIDI attraverso il suono emesso dal movimento dei motori di vecchi floppy disk.
Il progetto è nato dalla voglia di scoprire nuovi modi di fare musica attraverso strumenti non convenzionali, dalle nostre ricerche in tal senso ci siamo imbattuti in numerosi progetti che hanno lo scopo di fare musica con i lettori di floppy disk ma per nessuno di essi è mai stato creato un progetto stand alone, cioè che funzionasse senza l’ausilio di un computer esterno e che potesse essere facilmente trasportabile.
Per questo motivo Discomatic vuole essere un riproduttore di musica portatile e indipendente.
Per far produrre i suoni ai lettori di floppy disk ci siamo avvalsi di un software open source specializzato in questo, chiamato Moppy , tale software è stato installato su un Raspberry pi su cui è stato installato il sistema operativo Raspbian con kernel Linux.

Raspberry pi

Il Raspberry pi è il cuore del Discomatic, esso alimenta le due schede arduino utilizzate per questo progetto (un arduino uno e un arduino nano), gestisce l’arduino uno che controlla i lettori di floppy disk e permette di controllare tutto il sistema con la GUI (con GUI o graphical user interface s’intende l’interfaccia grafica di un programma) di Moppy.
L’ arduino nano utilizzato nel progetto gestisce i led RGB collegati alla struttura in base alla lettura di un pin dell’arduino uno su cui viene mandato in uscita il settimo canale del file MIDI.
Di conseguenza il controllo dell’accensione e dello spegnimento dei led viene effettuato grazie a un canale inserito da noi nei file midi, quindi completamente configurabile.
Nei file MIDI che non sono stati modificati da noi e che hanno il settimo canale configurato suoneranno comunque seguendo il ritmo dello strumento o delle note presenti su di esso.
L’intero progetto è stato realizzato interamente su una lastra di plexiglass modellata ad hoc su cui è stato montato anche un alimentatore da 10 Ampere in grado di alimentare i 6 lettori di floppy disk e il Raspberry.

MIDI

MIDI è una tecnologia nata negli anni ’80 che permette di pilotare uno strumento musicale tramite un segnale digitale. Per collegare due dispositivi tramite MIDI si utilizza l’omonima interfaccia, che può essere sotto forma di connettore MIDI o USB. L’interfaccia MIDI supporta fino a 16 canali per dispositivo. In questo progetto sono stati utilizzati dei file MIDI per dare le istruzioni alla scheda Arduino necessarie per far produrre i suoni ai lettori floppy.

Perché usare i file MIDI?

I file MIDI sono stati utilizzati perché tramite programmi detti “sequencer” si è in grado di comporre della musica e di esportarla non come segnale audio, quindi come vera e propria musica ascoltabile, ma come istruzioni per lo strumento musicale come fosse uno spartito musicale, ma digitale.

Come fare suonare un floppy?

I lettori di floppy disk (chiamati in modo più comune semplicemente floppy) per la lettura e la scrittura sui floppy disk utilizzano una testina che si muove su un’ asse grazie a uno step motor (motore passo passo), tale motore è in grado di produrre una certa quantità di note in base alla frequenza in ingresso al lettore di floppy disk.
Gli step motor a differenza di un motore elettrico comune (che può assumere tutti gli angoli possibili) ha un numero predefinito di
angoli in cui può essere, anche se non può assumere tutte le posizioni possibili (comunque molte, generalmente) è comunque molto più preciso di un motore elettrico dato che è possibile fare dei movimenti molto più
brevi.
La frequenza e di conseguenza la nota prodotta dal motore sono determinate da Moppy che pilota un arduino che invia il segnale al floppy.
Per produrre una canzone, quindi una serie di note in parallelo e in serie basta aggiungere tanti floppy quante sono le note che bisogna riprodurre in parallelo.
In questo progetto sono stati utilizzati 6 lettori di floppy e sono stati realizzati ad hoc i file MIDI utilizzati.

Amplificazione delle note dei floppy

I lettori floppy in sé e per se sono perfettamente in grado di produrre una certa quantità di note ma con un volume non abbastanza forte da essere sentito in un luogo troppo grande.
Per questo motivo abbiamo deciso di utilizzare un microfono da chitarra acustica (che capta le vibrazioni sulla superficie su cui è a contatto) a contatto con la struttura di sostegno dei floppy collegato a un’ amplificatore e una cassa per amplificare le note prodotte dai floppy.
Il collegamento fra il microfono e la cassa ha un delay (tempo che impiega il segnale ad arrivare da una parte all’altra della linea di comunicazione) molto basso in modo da impedire l’effetto riverbero (cioè che l’audio in uscita dalle casse sia in ritardo di una certa quantità di tempo, abbastanza da renderlo percepibile, rispetto a quello in uscita dai floppy).

MOPPY SOFTWARE

Moppy è un programma open source, scritto da SammyIAm che permette di trasformare una scheda Arduino in uno strumento musicale in grado di leggere files MIDI e di riprodurli utilizzando dei lettori floppy.
Moppy è composto da due parti. La prima è un programma, da eseguire su un computer, che si occupa di tradurre i file midi alla scheda Arduino e di fornire un’interfaccia utente.
La seconda parte è un programma da eseguire sulla scheda Arduino che le permetterà di potersi interfacciare con un computer(sul quale è in esecuzione l’altro programma) e con i lettori floppy per farli suonare.

Programma Arduino Moppy
Moppy.ino


/****************************************/
/*    __  __                            */
/*   |  \/  |                           */
/*   | \  / | ___  _ __  _ __  _   _    */
/*   | |\/| |/ _ \| '_ \| '_ \| | | |   */
/*   | |  | | (_) | |_) | |_) | |_| |   */
/*   |_|  |_|\___/| .__/| .__/ \__, |   */
/*                | |   | |     __/ |   */
/*                |_|   |_|    |___/    */
/*                                      */
/****************************************/

/* This file left intentionally blank to appease the Arduino IDE.
 *  
 * FOR GENERAL CONFIGURATION OPTIONS SEE MoppyConfig.h
 *  
 * See MoppyCore.cpp for the top level code.  Most of the functional
 * code can be found in the src folder in the sketch directory, but
 * this should be opened using a text editor or different IDE as
 * the Arduino IDE does weird things if you start trying to use 
 * sub-directories.
 */

MoppyConfig.h


/*
 * MoppyConfig.h
 */

#ifndef SRC_MOPPYCONFIG_H_
#define SRC_MOPPYCONFIG_H_

////
// Moppy Device configuration
////

// Play a startup sound when the Arduino is initialized.  Helpful
// for debugging purposes, but can be turned off once everything
// is working
#define PLAY_STARTUP_SOUND true

// Device address for this Arduino (only messages sent to this address
// will be processed.
#define DEVICE_ADDRESS 0x01

// Minimum and maximum sub-addresses that messages will be processed for.
// E.g. if you have 8 drives this would be 1 and 8.  If you have 16, 1 and 16.
#define MIN_SUB_ADDRESS 1
#define MAX_SUB_ADDRESS 8

#endif /* SRC_MOPPYCONFIG_H_ */

MoppyCore.cpp


#include 

/**********
 * MoppyInstruments handle the sound-creation logic for your setup.  The
 * instrument class provides a systemMessage handler function and a deviceMessage
 * handler function for handling messages received by the network.
 *
 * Uncomment the appropriate instrument class for your setup
 */

// Floppy drives directly connected to the Arduino's digital pins
#include "src/MoppyInstruments/FloppyDrives.h"
FloppyDrives instrument = FloppyDrives();


//Uncomment the 2 next lines and comment the 2 lines above this comment to switch to L298N mode
//#include "src/MoppyInstruments/L298N.h"
//L298N instrument = L298N(); // please see src/MoppyInstruments/L298N.h for pinout and additionnal info


// A single device (e.g. xylophone, drums, etc.) connected to shift registers
//#include "src/MoppyInstruments/ShiftRegister.h"
//ShiftRegister instrument = ShiftRegister();

/**********
 * MoppyNetwork classes receive messages sent by the Controller application,
 * parse them, and use the data to call the appropriate handler as implemented
 * in the instrument class defined above.
 *
 * Uncomment the appropriate networking class for your setup
 */

// Standard Arduino HardwareSerial implementation
#include "src/MoppyNetworks/MoppySerial.h"
MoppySerial network = MoppySerial(instrument.systemMessage, instrument.deviceMessage);

//// UDP Implementation using some sort of network stack?  (Not implemented yet)
// #include "src/MoppyNetworks/MoppyUDP.h"
// MoppyUDP network = MoppyUDP(instrument.systemMessage, instrument.deviceMessage);


//The setup function is called once at startup of the sketch
void setup()
{
	// Call setup() on the instrument to allow to to prepare for action
    instrument.setup();

    // Tell the network to start receiving messages
    network.begin();
}

// The loop function is called in an endless loop
void loop()
{
	// Endlessly read messages on the network.  The network implementation
	// will call the system or device handlers on the intrument whenever a message is received.
    network.readMessages();
}

Software Arduino LED RGB

Programma di gestione accensione Leds RGB


// Dichiarazione delle costanti assegnate al numero dei pin
const int redPin = 3;
const int greenPin = 5;
const int bluePin = 6;
const int buttonPin = 2;
// Dichiarazione delle variabili usate all’interno della funzione cos
float redX = 0;
float greenX = 2.1;
float blueX = 4.2;
// Dichiarazione delle variabili usate per l’ingresso dei LED
float redValue;
float greenValue;
float blueValue;
// Dichiarazione delle variabili usate per l’abilitazione dell’uscita
float EX = 0;
float E = 0;
void setup() {
 // Inizializzazione delle uscite e degli ingressi
 pinMode(redPin, OUTPUT);
 pinMode(greenPin, OUTPUT);
 pinMode(bluePin, OUTPUT);
 pinMode(buttonPin, INPUT);
 // Inizializzazione della comunicazione delle porte seriali
 Serial.begin(9600);
}
void loop() {
/* Il programma rimane in un ciclo perpetuo finchè la condizione non
è verificata.
La condizione è verificata solo il "buttonPin" definito come il
piedino numero 6 dell'arduino ha in ingresso il valore digitale "1"
*/
 if(digitalRead(buttonPin) == HIGH){
  /* Se la condizione è verificata allora viene eseguita la funzione "LED()" */
  LED();
 }
}
void LED(){
 // Variabile ad incremento lineare di 0.1
 EX = 0;
 // Variabile non lineare di Enable dell’ingresso dei LED
 E = cos(EX);
 // Il ciclo while continua finché “E” non tende a 0
 while(E > 0.1){
  E = cos(EX);
  //Incremento di EX
  EX = EX + 0.1;
  // “redValue” assume valori non lineari da 0 a 2
  redValue = cos(redX)+1;
  // “redValue” assume valori non lineari da 0 a 254
  redValue = redValue * 127;
  // “redValue” assume valori non lineari da 0 a 254 in funzione di E
  redValue = redValue * E;
  // Mando in uscita il valore “redValue” sul pin “redPin”
  analogWrite(redPin, redValue);
  // Scrivo sul monitor seriale il valore di “redValue”
  Serial.print(redValue);
  Serial.print("-");
  // “greenValue” assume valori non lineari da 0 a 2
  greenValue = cos(greenX)+1;
  // “greenValue” assume valori non lineari da 0 a 254
  greenValue = greenValue * 127;
  // “greenValue” assume valori non lineari da 0 a 254 in funzione di
  //“E”
  greenValue = greenValue * E;
  // Mando in uscita il valore “greenValue” sul pin “greenPin”
  analogWrite(greenPin, greenValue);
  // Scrivo sul monitor seriale il valore di “greenValue”
  Serial.print(greenValue);
  Serial.print("-");
  // “blueValue” assume valori non lineari da 0 a 2
  blueValue = cos(blueX)+1;
  // “blueValue” assume valori non lineari da 0 a 254
  blueValue = blueValue * 127;
  // “blueValue” assume valori non lineari da 0 a 254 in funzione di
  //“E”
  blueValue = blueValue * E;
  // Mando in uscita il valore “blueValue” sul pin “bluePin”
  analogWrite(bluePin, blueValue);
  // Scrivo sul monitor seriale il valore di “blueValue”
  Serial.print(blueValue);
  Serial.print(" ");
  // Scrivo sul monitor seriale il valore di “E” e “EX”
  Serial.print(E);
  Serial.print(" ");
  Serial.print(EX);
  // Incremento le variabili all’interno delle funzioni cos
  redX = redX + 0.1;
  greenX = greenX + 0.1;
  blueX = blueX + 0.1;
  // Verifico che i valori delle variabili non siano superiori a 10 e
  //nel caso le reinizializzo a 0, così da non occupare la memoria
  //dell’arduino
  if(redX == 10){redX = 0;}
  if(greenX == 10){greenX = 0;}
  if(blueX == 10){blueX = 0;}
  // Leggo il valori di uscita dal pulsante
  int k = digitalRead(buttonPin);
  // Scrivo sul monitor seriale il valore di “k”
  Serial.print(" ");
  Serial.println(k);
  // Verifico se il bottone è stato premuto
  if(k == 1){
   // Se è stato premuto reinizializzo la varibile “EX” a 0
   EX = 0;
  }
  // inserisco un delay per permettere un cambio progressivo e non
  istantaneo del colore del LED
  delay(50);
 }
 // Finito il ciclo il LED RGB viene spento
 analogWrite(redPin, LOW);
 analogWrite(greenPin, LOW);
 analogWrite(bluePin, LOW);
}

Potrebbero interessarti anche...