MEMIDION can be controlled directly by MIDI controller by using USB host shield.
Structure
Place the Arduino pro mini on the Mini USB Host Shield and connect it to MIDI controller
Arduino IDE Code
Move the slider of the whistle with the MIDI signal from the MIDI keyboard. The slide amount is controlled by the measurement value of distance sensor VL6180X.
I used the following as a USB MIDI library
https://github.com/felis/USB_Host_Shield_2.0
I programmed with reference to the following
https://github.com/felis/USB_Host_Shield_2.0/tree/master/examples/USBH_MIDI/USBH_MIDI_dump
The library for distance sensor VL6180X is below.
https://github.com/pololu/vl6180x-arduino
#include <usbh_midi.h>
#include <usbhub.h>
#include <SPI.h>
#include <Wire.h>
#include <VL6180X.h>
USB Usb;
USBH_MIDI Midi(&Usb);
uint8_t Note, oldNote;
VL6180X sensor;
int meas;
int aim = 50;
int diff = 5;
void MIDI_poll();
void setup() {
Serial.begin(115200);
Wire.begin();
pinMode(2, OUTPUT);
pinMode(3, OUTPUT);
sensor.init();
sensor.configureDefault();
sensor.setTimeout(500);
if (Usb.Init() == -1) {
while (1); //halt
}
delay( 200 );
}
void loop() {
Usb.Task();
if ( Usb.getUsbTaskState() == USB_STATE_RUNNING ) {
MIDI_poll();
}
}
// Poll USB MIDI Controler and drive motor
void MIDI_poll() {
char buf[20];
uint8_t bufMidi[64];
uint16_t rcvd;
if (Midi.RecvData( &rcvd, bufMidi) == 0 ) {
if(bufMidi[0] == 9){
Note = bufMidi[2];
Serial.println(Note);
//Initial operation of the motor
if(Note > oldNote){
digitalWrite(2, HIGH);
digitalWrite(3, LOW);
}else{
digitalWrite(2, LOW);
digitalWrite(3, HIGH);
}
delay(50);
digitalWrite(2, LOW);
digitalWrite(3, LOW);
}
}
//Slide distance setting
if(Note == 57) aim = 22; //A
if(Note == 58) aim = 33; //A#
if(Note == 59) aim = 41; //B
if(Note == 60) aim = 52; //C
if(Note == 61) aim = 62; //C#
if(Note == 62) aim = 71; //D
if(Note == 63) aim = 81; //D#
if(Note == 64) aim = 90; //E
if(Note == 65) aim = 97; //F
if(Note == 66) aim = 103; //F#
if(Note == 67) aim = 109; //G
if(Note == 68) aim = 116; //G#
if(Note == 69) aim = 121; //A
if(Note == 70) aim = 126; //A#
if(Note == 71) aim = 129; //B
if(Note == 72) aim = 133; //C
//Distance sensor measurement
meas = sensor.readRangeSingleMillimeters();
//Serial.println(meas);
//Motor operation
if(meas > (aim - diff) && meas < (aim + diff)){
digitalWrite(2, LOW);
digitalWrite(3, LOW);
}else if(meas > aim){
digitalWrite(2, LOW);
digitalWrite(3, HIGH);
}else if(meas < aim){
digitalWrite(2, HIGH);
digitalWrite(3, LOW);
}
oldNote = Note;
}
Discussions
Become a Hackaday.io Member
Create an account to leave a comment. Already have an account? Log In.