Sunday, 8 April 2012

My DIY Arduino MIDI controller - 6. MIDI communication, Part I: Most basic stuff :)

Ok so I'm back to MIDI communication!

In case you want to follow my steps this is the list of the few components I use in this chapter:

  • 1 x tact switch
  • 2 x 10 kΩ resistors
  • 1 x 240 Ω resistor (220 ohm is supposed to be better)
  • 1 x female MIDI DIN socket (5 pins)
  • 1 x LDR
  • 1 x SPDT switch
  • Wire jumpers
  • 1 x Arduino!

I tried MIDI communication before I started the blog, and successfully sent notes over to Reason (a music software in case you don't know) via MIDI. I had already forgotten how to do so I checked again this basic tutorial. Since I (believe it or not) don't have 220 Ω resistors, I used a 240 Ω resistor instead, and it worked fine.

Next step is just for fun: sending notes according to the reading of a LDR (Light Dependent Resistor). I followed this tutorial (scroll down to the 6th chapter) and modified the code:
const int switchPin = 10;  // The switch is on Arduino pin 10
const int middleC = 60;    // Middle C (MIDI note value 60) is the lowest note we'll play
const int LEDpin = 13;     //  Indicator LED

// Variables:
byte note = 0;              // The MIDI note value to be played
int AnalogValue = 0;        // value from the analog input
int lastNotePlayed = 0;     // note turned on when you press the switch
int lastSwitchState = 0;    // state of the switch during previous time through the main loop
int currentSwitchState = 0;
int tempo = 480;

void setup() {
  //  set the states of the I/O pins:
  pinMode(switchPin, INPUT);
  pinMode(LEDpin, OUTPUT);
  //  Set MIDI baud rate:

void loop() {
  //  My potentiometer gave a range from 0 to 1023:
  AnalogValue = 1023-analogRead(0);
  //  convert to a range from 0 to 127:
  note = AnalogValue/8;
  currentSwitchState = digitalRead(switchPin);
  // Check to see that the switch is pressed:
  if (currentSwitchState == 1) {
    // set the note value based on the analog value, plus a couple octaves:
    note = note + 20; // you might want to change that value depending on the sensor you're using
    // start a note playing:
    noteOn(0x90, note, 0x40);
    delay(60000/tempo); // 60000 milliseconds = 1 min
    // play same note with a 0 velocity
    noteOn(0x90, note, 0x00);

//  plays a MIDI note.  Doesn't check to see that
//  cmd is greater than 127, or that data values are  less than 127:
void noteOn(byte cmd, byte data1, byte  data2) {
  Serial.print(cmd, BYTE);
  Serial.print(data1, BYTE);
  Serial.print(data2, BYTE);

The problem I have is on sketch upload (not on reset), the Arduino sends seemingly random notes to Reason, which I have to turn off by pressing them in Reason's integrated software keyboard. Looks like it is sending data interpreted as notes on, and no notes off (or not the good ones). Since the MIDI and Arduino to PC data are sent to the same pin, my MIDI device is receiving the data that the Arduino is sending to the PC during the sketch upload process, and apparently interprets it at notes ons. Shouldn't be a problem anyway after the prototyping stage, since we wouldn't upload the code to the final controller each time we use it. It should simply not be connected to a MIDI device during upload...

I'm currently studying MIDI control changes so I guess next post will get closer to what I actually want to do: control synth parameters using LDRs & pots.

<< Previous: 5. Finding more pins, part III: the shift register

No comments:

Post a Comment