Faire sortir du SON – part 2 le DAC (Convertisseur MIDI → CV/Gate Arduino)

Après les mauvais résultats du filtre RC, je me suis penché sur le DAC, qui a donné des résultats bien plus probants. Avec une liaison SPI, quelque calculs sur la valeurs à envoyer au DAC et un simple SPI.transfer(), on arrive à faire sortir une tension. Par exemple, ce code passe en revue toutes les valeurs possibles que le DAC peut accepter :

Plus d’infos sur le DAC et le SPI ici : http://tronixstuff.wordpress.com/2011/06/15/tutorial-arduino-and-the-spi-bus-part-ii/ (en anglais)

#include "SPI.h"

word outputValue = 0; // word = 16 bits

byte data = 0;

int a;

void setup()

{

//set pin(s) to input and output

pinMode(10, OUTPUT); //verrou du DAC

SPI.begin(); //démarrage de la liaison SPI

SPI.setBitOrder(MSBFIRST);

}

void dac(int a)

{

outputValue = a;

digitalWrite(10, LOW);

data = highByte(outputValue); //on enverra les données en 2 octets : selection du premier octet

data = 0b00001111 & data;

data = 0b00010000 | data; //on ajoute les paramètres du DAC à envoyer

SPI.transfer(data);

data = lowByte(outputValue);

SPI.transfer(data); //deuxième octet

digitalWrite(10, HIGH);

delay(100);

}

void loop()

{

for(int a=0; a<=3800; a++)

{

dac(a);

}

}

 

Pour accorder le DAC, j’ai fais le choix d’utiliser un tableau de valeurs, afin 1) d’éviter des calculs à l’Arduino et 2) une gestion plus facile de l’accordage (à mon sens). Pour cela, j’ai utilisé un bouton poussoir, un accordeur, et un peu de code. Chaque pression sur le bouton incrémentait ma variable a, et avec l’accordeur, je notais les valeurs où la note était juste. J’ai fait ça pour une dizaine de note, et en ai déduit les autres.

La partie MIDI est simple : un callback pour simplement le NoteOn et NoteOff, et une variable qui évite de couper la note en cours si on reçoit un message NoteOff d’une note différente. Plus d’info sur la librairie MIDI que j’ai utilisé ici : http://playground.arduino.cc/Main/MIDILibrary (en anglais)

Pour le montage de l’Arduino sur la breadboard, cette page http://arduino.cc/en/Main/Standalone (en anglais) vous ravira, et pour l’envoi des programmes sur l’ATMega dans le circuit, j’ai utilisé https://www.sparkfun.com/tutorials/200 (en anglais)

Le code « final » est là. Ce code permet, à l’heure actuelle :

  • L’accord note par note

  • la conversion de signaux MIDI de type NoteOn et NoteOff en signaux CV/Gate

 

#include <MIDI.h>

#include <SPI.h>

byte

commandByte;

byte noteByte;

byte velocityByte;

byte pitchOld;

byte noteOn = 144;

int deja;

byte noteJouee;

byte data;

int pitchOut;

#define DATAOUT 11 // DAC pin

#define SPICLOCK 13

#define DAC 10

#define GATE 8

int transpo=0;

// ACCORD DE CHAQUE NOTE

float note[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,92,178,266,351,438,524,611,698,787,874,960,1048,1137,1224,1307,1399,1485,1570,1659,1748,1835,1921,2010,2097,2183,2270,2357,2444,2525,2618,2707,2792,2879,2967,3053,3140,3227,3316,3402,3488,3576,3661,3750,3837,3924,4011}; //cet accordage est donné à titre indicatif, il marche chez moi. Il vous faudra sûrement le refaire.

void preDAC(int pitch) //Calculs avant d'envoyer au DAC

{

if (pitch+transpo >=36 && pitch+transpo<=82)

{

pitchOut = note[pitch+transpo];

dac_Out(pitchOut);

}

}

void dac_Out(int pitchOut) // Envoie au DAC

{

digitalWrite(10, LOW);

data = highByte(pitchOut);

data = 0b00001111 & data;

data = 0b00010000 | data; //paramètres du DAC

SPI.transfer(data);

data = lowByte(pitchOut);

SPI.transfer(data);

digitalWrite(10, HIGH);

}

// Callback Note On

void NOn(byte channel, byte pitch, byte velocity)

{

if (deja==0)

{

deja=1;

noteJouee = pitch;

if (pitch+transpo >=36 && pitch+transpo<=82)

{

digitalWrite(GATE, HIGH);

preDAC(pitch);

}

}

else

{

if (pitch+transpo >=36 && pitch+transpo<=82)

{

digitalWrite(GATE, LOW);

noteJouee = pitch;

preDAC(pitch);

digitalWrite(GATE, HIGH);

}

}

}

// Callback Note Off

void NOff(byte channel, byte pitch, byte velocity)

{

if (noteJouee==pitch && deja==1)

{

digitalWrite(GATE, LOW);

deja=0;

}

}

void setup()

{

pinMode(GATE,OUTPUT);

digitalWrite(GATE,LOW);

SPI.begin();

SPI.setBitOrder(MSBFIRST);

pinMode(DATAOUT, OUTPUT);

pinMode(SPICLOCK,OUTPUT);

pinMode(DAC,OUTPUT);

digitalWrite(DAC,LOW);

delay(10);

MIDI.begin(0);

MIDI.setHandleNoteOn(NOn);

MIDI.setHandleNoteOff(NOff);

}

void loop()

{

MIDI.read();

}


 

La vidéo ici :

Le schéma :
IMG_20130617_215739

Laisser un commentaire