MEMIDION can be controlled directly by MIDI controller by using USB host shield.
Structure
![](https://cdn.hackaday.io/images/5038251536466629406.png)
Place the Arduino pro mini on the Mini USB Host Shield and connect it to MIDI controller
![](https://cdn.hackaday.io/images/2799531536466915606.jpg)
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.