Close

4. Power supply simplification

A project log for MIDI Slide Whistle "MEMIDION"

I tried to make slide whistle move automatically by MIDI signal. This is MEMIDION.

homemadegarbageHomeMadeGarbage 09/26/2018 at 11:040 Comments

I simplified the power supply to handle portable. I adopted dry batteries.

Power supply schematic

It was difficult to completely eliminate the motor drive noise, so 5V DC / DC boost convertor and 3.3V LDO in the microcomputer were used for the control system power supply.

Structure

Using two dry batteries

Arduino IDE Code

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>

USB Usb;
USBH_MIDI  Midi(&Usb);

uint8_t Note, oldNote;

VL6180X sensor;

int meas;
int aim = 50;
int diff = 5;

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

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

void MIDI_poll();

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

  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() {
  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 = 19;  //A
  if(Note == 58) aim = 29;  //A#
  if(Note == 59) aim = 39;  //B
  if(Note == 60) aim = 49;  //C
  if(Note == 61) aim = 59;  //C#
  if(Note == 62) aim = 67;  //D
  if(Note == 63) aim = 78;  //D#
  if(Note == 64) aim = 85;  //E
  if(Note == 65) aim = 93; //F
  if(Note == 66) aim = 102; //F#
  if(Note == 67) aim = 109; //G
  if(Note == 68) aim = 112; //G#
  if(Note == 69) aim = 120; //A
  if(Note == 70) aim = 124; //A#
  if(Note == 71) aim = 129; //B 
  if(Note == 72) aim = 131; //C

  //Distance sensor measurement
  meas = sensor.readRangeSingleMillimeters();
  //Serial.println(meas);

  //LED On
  num = map(meas, 22, 133, 4, 23);
  for(int i=num; i<strip.numPixels(); i++) {
    strip.setPixelColor(i, Wheel(255/strip.numPixels() * i));
    //delay(100);
  } 
  strip.show();

  //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 Off 
  strip.clear();

  oldNote = Note;
}

// 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);
}

Operation

Discussions