HomeMadeGarbage
Published © LGPL

MIDI Slide Whistle "MEMIDION" Next Stage

I modified the "MEMIDION" MIDI slide whistle.

IntermediateFull instructions providedOver 4 days6,531

Things used in this project

Hardware components

Arduino UNO
Arduino UNO
×1
Arduino Pro Mini 328 - 3.3V/8MHz
SparkFun Arduino Pro Mini 328 - 3.3V/8MHz
×1
TAMIYA Track and Wheel
×1
TAMIYA Single Gearbox
×1
ToF Range Finder Sensor VL6180
×1
KORG nanoKEY2
×1
5V Boost DC/DC XCL101C501BR-G
×1
Mini USB Host Shield
×1
Slide Whistle
×1
NeoPixel strip
NeoPixel strip
×1
Motor Driver DRV8835
×1

Software apps and online services

Arduino IDE
Arduino IDE

Story

Read more

Code

midi06.ino

Arduino
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

The library for NeoPixel is below.
https://github.com/adafruit/Adafruit_NeoPixel
#include <usbh_midi.h>
#include <usbhub.h>
#include <SPI.h>

#include <Wire.h>
#include <VL6180X.h>

#include <Adafruit_NeoPixel.h>

#include <SoftwareSerial.h>
SoftwareSerial mySerial(7, 9); // RX, TX

USB Usb;
USBH_MIDI  Midi(&Usb);

uint8_t Note, oldNote;

VL6180X sensor;

int meas;
int aim = 50;
int diff = 6;

#define PIN A3
#define NUM_LEDS 24
#define BRIGHTNESS 30
int num;

int modeState = 0;

Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_LEDS, PIN, NEO_GRBW + NEO_KHZ800);

void setup() {
  Serial.begin(115200);
  mySerial.begin(9600);

  pinMode(8, INPUT);

  Wire.begin();

  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
  digitalWrite(2, LOW);
  digitalWrite(3, LOW);
  
  sensor.init();
  sensor.configureDefault();
  sensor.setTimeout(500);

  strip.setBrightness(BRIGHTNESS);
  strip.begin();
  strip.show();

  if (Usb.Init() == -1) {
    while (1); //halt
  }
  
  delay( 200 );
}

void loop() {
  if(modeState != digitalRead(8)){
    modeState = digitalRead(8);
    Serial.print("Mode : ");
    Serial.println(modeState);
  }

  //Instrument Mode
  Usb.Task();
  if (Usb.getUsbTaskState() == USB_STATE_RUNNING && modeState == 0) {
    char buf[20];
    uint8_t bufMidi[64];
    uint16_t  rcvd;

    if (Midi.RecvData( &rcvd,  bufMidi) == 0 && bufMidi[0] == 9) {
      Note = bufMidi[2];
      Serial.print("Instrument Mode : ");
      Serial.println(Note);
      MotorInitialMove();
    }
  }

  //Sound Source Mode
  if (mySerial.available() && modeState == 1){
    Note =  mySerial.read();
    Serial.print("Sound Source Mode : ");
    Serial.println(Note);
    MotorInitialMove();
  }

  //Slide distance setting
  if(Note == 57) aim = 16;  //A
  if(Note == 58) aim = 23;  //A#
  if(Note == 59) aim = 35;  //B
  if(Note == 60) aim = 49;  //C
  if(Note == 61) aim = 57;  //C#
  if(Note == 62) aim = 64;  //D
  if(Note == 63) aim = 75;  //D#
  if(Note == 64) aim = 83;  //E
  if(Note == 65) aim = 91; //F
  if(Note == 66) aim = 100; //F#
  if(Note == 67) aim = 106; //G
  if(Note == 68) aim = 111; //G#
  if(Note == 69) aim = 119; //A
  if(Note == 70) aim = 124; //A#
  if(Note == 71) aim = 129; //B
  if(Note == 72) aim = 132; //C
  

  //Distance sensor measurement
  meas = sensor.readRangeSingleMillimeters();
  Serial.print("Range Sensor : ");
  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);
  }

  //LED On
  num = map(meas, 16, 132, 3, 20);
  for(int i=num; i<strip.numPixels(); i++) {
    strip.setPixelColor(i, Wheel(255/strip.numPixels() * i));
    //delay(100);
  }
  strip.show();
  
  //LED Off
  strip.clear();

  oldNote = Note;
}

//Initial operation of the motor
void MotorInitialMove() {
  if(Note > oldNote){
    digitalWrite(2, HIGH);
    digitalWrite(3, LOW);
  }else{
    digitalWrite(2, LOW);
    digitalWrite(3, HIGH);
  }
  delay(50);
      
  digitalWrite(2, LOW);
  digitalWrite(3, LOW);
}

// Input a value 0 to 255 to get a color value.
// The colours are a transition r - g - b - back to r.
uint32_t Wheel(byte WheelPos) {
  WheelPos = 255 - WheelPos;
  if(WheelPos < 85) {
    return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3,0);
  }
  if(WheelPos < 170) {
    WheelPos -= 85;
    return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3,0);
  }
  WheelPos -= 170;
  return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0,0);
}

Credits

HomeMadeGarbage

HomeMadeGarbage

56 projects • 283 followers
We are family. hobby is D.I.Y!!

Comments