L'Arduino communique en Midi. Pour installer le firmware Midi, suivre les instructions de la page Arduino et MIDI. Avec Pure Data, on contrôle l'ouverture des entrées et le mode des sorties (digital, pwm, servo). Si vous voulez utiliser plusieurs, il faudra peut-être changer le canal Midi dans le code, au début du fichier.
Code Arduino Uno : malinette_midi_uno.ino
/*
* Malinette Midi for Arduino Uno
*
* Open/Close Analog Sensors
* Outputs (Digital, PWM, Servo) except 0 and 1 (rx/tx)
*
* http://malinette.info
* Reso-nance Numérique
* 24/06/16
*
* modif : 13/12/2016
*/
#include <Servo.h>
#include <MIDI.h>
MIDI_CREATE_DEFAULT_INSTANCE();
const int channel = 4; // midi channel
const int anaNb = 4; // number of inputs
const int outNb = 13; // number of outputs (note that we have 11 outputs, we don't use rx/tx)
const int offsetAna = 20; // > ctlout 20 to control ana
const int offsetOut = 30; // > ctlout 30 to control out
const long interval = 30; // sampling rate
// SENSORS
int anaState[anaNb]; // analog on/off (O or 1);
int anaValues[anaNb]; // current analog values
int anaLastValues[anaNb]; // previous analog values
//OUT
int outState[outNb]; //modes (0,1,2,3) (none, digital, pwm, servo)
Servo servos[6];
// SAMPLING RATE
unsigned long currentMillis;
unsigned long previousMillis = 0;
// --------------- SETUP --------------- //
void setup()
{
// Setup output pins (start from 2)
for (int i = 2; i < outNb; i++) {
pinMode(i, OUTPUT);
}
// Set Callback function
MIDI.setHandleControlChange(handleControlChange);
// Initiate MIDI communications, listen to all channels
MIDI.begin(channel);
}
// --------------- LOOP --------------- //
void loop()
{
MIDI.read();
// Sampling rate
currentMillis = millis();
if(currentMillis - previousMillis >= interval)
{
previousMillis = currentMillis;
// Analog sensors loop
for (int i = 0; i < anaNb; i++)
{
if (anaState[i] > 0) { // Test on/off
anaValues[i] = (int) analogRead(i) / 8; // 10 bits > 7 bits
if (anaValues[i] != anaLastValues[i])
{
MIDI.sendControlChange(i, anaValues[i], channel);
anaLastValues[i] = anaValues[i];
}
}
}
}
}
// --------------- Receive Control Change --------------- //
void handleControlChange(byte channel, byte number, byte value)
{
// outputs
if(number < offsetAna) {
setOutValue(number, value);
}
// ana states
else if (number >= offsetAna && number < offsetOut) {
anaState[number-offsetAna] = value;
}
// outputs states
else if (number >= offsetOut) {
setOutState(number-offsetOut, value);
}
}
// --------------- SET OUTPUT --------------- //
void setOutValue(int number, int value) {
int state = outState[number];
if( state == 1) { // digital mode
if(value == 0) {digitalWrite(number, LOW);}
if(value >= 1) {digitalWrite(number, HIGH);}
} else if( state == 2){ // pwm mode
analogWrite(number, map(value,0,127,0,255));
} else if( state == 3){ // servo mode
if (servos[number].attached()) {servos[number].write(map(value,0,127,0,180));}
}
}
void setOutState(int number, int value) {
// Check last state to turn off
if ( outState[number] == 1) {digitalWrite(number, LOW);}
else if ( outState[number] == 2) {analogWrite(number, 0);}
if (value == 3) {
if (!servos[number].attached()) {servos[number].attach(number);}
} else {
if (servos[number].attached()) {servos[number].detach();}
}
outState[number] = value;
}
Code Arduino Leonardo : malinette_midi_leonardo.ino
/*
* Malinette Midi with Teensy or Leonardo
*
* Open/Close Analog Sensors
* Outputs (Digital, PWM, Servo) except 0 and 1 (rx/tx)
*
* http://malinette.info
* Reso-nance Numérique
* 24/06/16
*
* modif : 13/12/16
*/
#include <Servo.h>
const int channel = 4; // midi channel
const int anaNb = 4; // number of inputs
const int outNb = 13; // number of outputs (note that we have 11 outputs, we don't use rx/tx)
const int offsetAna = 20; // > ctlout 20 to control ana
const int offsetOut = 30; // > ctlout 30 to control ana
int rate = 30; // sampling rate
// SENSORS
int anaState[anaNb]; // Analog on/off (O or 1);
int anaValues[anaNb]; // current analog values
int anaLastValues[anaNb]; // previous analog values
//OUT
int outState[outNb]; //modes (0,1,2,3) (none, digital, pwm, servo)
Servo servos[6];
// SAMPLING RATE
elapsedMillis msec = 0;
// --------------- SETUP --------------- //
void setup()
{
// Setup output pins (start from 2)
for (int i = 2; i < outNb; i++) {
pinMode(i, OUTPUT);
}
// Set Callback function
usbMIDI.setHandleControlChange(handleControlChange);
// Initiate MIDI communications, listen to all channels
//usbMIDI.begin(channel);
}
// --------------- LOOP --------------- //
void loop()
{
// Sampling rate
if (msec >= rate) {
msec = 0;
// Analog sensors loop
for (int i = 0; i < anaNb; i++)
{
if (anaState[i] > 0) { // Test on/off
anaValues[i] = (int) analogRead(i) / 8; // 10 bits > 7 bits
if (anaValues[i] != anaLastValues[i])
{
usbMIDI.sendControlChange(i, anaValues[i], channel);
anaLastValues[i] = anaValues[i];
}
}
}
}
// MIDI Controllers should discard incoming MIDI messages.
// http://forum.pjrc.com/threads/24179-Teensy-3-Ableton-Analog-CC-causes-midi-crash
while (usbMIDI.read()) {
// ignore incoming messages
}
}
// --------------- Receive Control Change --------------- //
void handleControlChange(byte channel, byte number, byte value)
{
// outputs
if(number < offsetAna) {
setOutValue(number, value);
}
// ana states
else if (number >= offsetAna && number < offsetOut) {
anaState[number-offsetAna] = value;
}
// outputs states
else if (number >= offsetOut) {
setOutState(number-offsetOut, value);
}
}
// --------------- SET OUTPUT --------------- //
void setOutValue(int number, int value) {
int state = outState[number];
if( state == 1) { // digital mode
if(value == 0) {digitalWrite(number, LOW);}
if(value >= 1) {digitalWrite(number, HIGH);}
} else if( state == 2){ // pwm mode
analogWrite(number, map(value,0,127,0,255));
} else if( state == 3){ // servo mode
if (servos[number].attached()) {servos[number].write(map(value,0,127,0,180));}
}
}
void setOutState(int number, int value) {
// Check last state to turn off
if ( outState[number] == 1) {digitalWrite(number, LOW);}
else if ( outState[number] == 2) {analogWrite(number, 0);}
if (value == 3) {
if (!servos[number].attached()) {servos[number].attach(number);}
} else {
if (servos[number].attached()) {servos[number].detach();}
}
outState[number] = value;
}