Sunday, 16 September 2012

My DIY Arduino MIDI controller - 7. STUCK! (Help needed)

Ok, so... I've been away for some time because I had to focus on other projects, mostly professional but also musical (released a *free* EP in June, check it out @ rec72.net, it's 6 tracks of melodic electronica!) or vacational:

Florence, Italy

Anyway, I decided I should get back to work on my controller and started to proceed but I got quickly stuck with the next step: sending CC messages, which is kindof essential to a MIDI controller innit...

The problem is this: I'm trying to send CC messages on MIDI channel 1, on control number 16 (I tried various control numbers and got the same problem each time). My software (Reason 6) does receive MIDI data, but I get erratic values on erratic control numbers.

I tried the serial.write command as well as the MIDI Library v3.2, without success. Here is the very simple code, using the library:

#include 

// Variables:
int cc = 0;
int AnalogValue = 0; // define variables for the controller data
int lastAnalogValue = 0; // define the "lastValue" variables

void setup() {
  //  launch MIDI
  MIDI.begin(4);
}

void loop() {
  AnalogValue = analogRead(0);
  //  convert to a range from 0 to 127:
  cc = AnalogValue/8;
  // check if analog input has changed
  if (lastAnalogValue != cc) {
    MIDI.sendControlChange(16,cc,1);
    // update lastAnalogValue variable
    lastAnalogValue = cc;
  }  //  endif
}

I posted on the Arduino forums but got no useful reply yet, so I thought I might as well tell it here and maybe some charitable soul would post a comment to help me troubleshoot this issue... I did output my sensor value to the serial monitor and it was just as expected, nothing wrong there. Maybe I should use a delay at startup to prevent unwanted current to go to the serial port while the sketch uploads... I'll try that ASAP.

<< Previous: 6. MIDI communication, Part I: Most basic stuff :)

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:
  Serial.begin(31250);
}

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

Monday, 2 April 2012

My DIY Arduino MIDI controller - 5. Finding more pins, part III: the shift register

As I said in a previous post, I might need to expand the digital outs as well as the analog ins, so I followed Grumpy_Mike's advice on the Arduino forums and got a 74HC595 shift register to control my LEDs instead of the 4051. The 8 bit shift register is a very convenient way to drive 8 LEDs with only 3 digital pins: you just send it a series of 8 HIGHs or LOWs and it lights on/off the LEDs accordingly when you tell it so. Looks exactly like what I need. I followed this ShiftOut tutorial to learn how to handle the chip, then I modified the second code example from the tutorial to make something like this:



This is the circuit:


And the code I came up with, slightly modified from the tutorial:

/*
  Shift Register Example
 for 74HC595 shift register

 This sketch turns reads serial input and uses it to set the pins
 of a 74HC595 shift register.

 Hardware:
 * 74HC595 shift register attached to pins 2, 3, and 4 of the Arduino,
 as detailed below.
 * LEDs attached to each of the outputs of the shift register

 Created 22 May 2009
 Created 23 Mar 2010
 by Tom Igoe
 
 Modified 1 Apr 2012 by Yann Guillermou

 */

//Pin connected to latch pin (ST_CP) of 74HC595
const int latchPin = 8;
//Pin connected to clock pin (SH_CP) of 74HC595
const int clockPin = 12;
////Pin connected to Data in (DS) of 74HC595
const int dataPin = 11;

// the bits you want to send (a byte is 8 bits, one per LED)
byte bitsToSend = 0;

void setup() {
  //set pins to output because they are addressed in the main loop
  pinMode(latchPin, OUTPUT);
  pinMode(dataPin, OUTPUT);  
  pinMode(clockPin, OUTPUT);
}

void loop() {
  for (int i = 0; i < 8; i++) {
    registerToggle(i);
    delay(100);
  }
}

// This method sends bits to the shift register:
void registerToggle(int pin) {
  //  turn of the output so the pins don't light up
  //  while we're shifting bits
  digitalWrite(latchPin, LOW);
  
  // read bit state
  int state = bitRead(bitsToSend, pin);
  
  // change bit state
  state = -state + 1;
  
  // toggle the bit in bitsToSend:
  bitWrite(bitsToSend, pin, state);
  
  // shift the bits out:
  shiftOut(dataPin, clockPin, MSBFIRST, bitsToSend);

  // turn on the output so the LEDs can light up:
  digitalWrite(latchPin, HIGH);
}

The mod' consisted in making the bitsToSend variable global because I wanted to be able to toggle an LED without affecting the others, and above all keep track of each LED state. I also replaced the registerWrite() function by this registerToggle() function, just to check if I had understood well enough how to do.

This code only loops and toggles the LEDs on then off but with the registerToggle() and registerWrite() functions you can easily tell the chip which LED to turn on or off, this way it is as easy as a digitalWrite().

Next post will be about MIDI out, as I got a couple of breadboard friendly MIDI connectors!

<< Previous: 4. Finding more pins, part II + LDR Calibration

Sunday, 25 March 2012

My DIY Arduino MIDI controller - 4. Finding more pins, part II + LDR Calibration

What I want to do at this point is to develop an Arduino sketch that allows me to:

  • Read from sensors and display the result on a serial monitor
  • Use a tact switch for each sensor to toggle between 3 different modes: continuous reading, freeze (so that I can take my hand off the LDR and its value remains the same), and LDR calibration, because I want to be able to use the controller under various ambient light conditions. To prevent accidental calibration, the switch will be have to be hold down for 1/2 second. Shorter presses will toggle between continuous reading and freeze.

I started by writing a short sketch that allows the user to toggle between 3 modes: reading, calibrating and serial out, for just one LDR, no matter how long the switch was pressed, it was just cycling through the different modes.

During the calibration mode, the LDR was read and its minimum and maximum values were stored until the user changed the mode. This is done by simply comparing the current reading to the minimum value, and each time the reading is lower than the minimum, the minimum is set to the current reading. Same logic for max.

The reading and serial out modes worked the same but used different displays: the value of the LDR was read, then mapped to a 0-255 range according to the calibration values. In reading mode, the reading was sent to an LED through a PWM pin. In serial out mode, it was sent to the serial monitor.

Things started to get a lot more complicated when I decided to add in the same time the freeze function (measuring as well the time each switch was pressed for entering calibration mode instead of just cycling through the 3 modes), and several sensors through a 4051 multiplexer. The code was well thought (for a beginner like me) but I stupidily forgot to set all the pin modes in the setup which caused some weird errors. Had to check the circuit with a voltmetre and spent numerous hours (I swear) trying to debug the code... Note to self: always check the basic stuff before checking the complex parts of a code!

This is the circuit:

The blue wires go to the select pins of the 4051. The orange wires go to the switches (for which I'm using a pull-down resistor). The yellow wires go to the LEDs through 220Ω resistors. The green wires connect the sensors (a tact switch, a LDR and a pot) to the 4051 y0, y1 and y2 pins. There is another green wire that connects the 4051 output to the Arduino analog pin 0.


And the final code, which I tried to comment as much as possible. This is not supposed to be a tutorial but if my efforts can help somebody else, I'll be happy:

/*
    This script calibrates and reads from sensors using a 4051
*/

// switch & sensor management
const int sensors_number = 3;   // number of sensors to use
boolean last_switch_state[] = {0, 0, 0};
boolean current_switch_state[sensors_number];
int sensor_min[] = {0, 0, 0};      // default min value
int sensor_max[] = {1023, 1023, 1023};// default max value
int sensor_value[sensors_number];            // needs to be global to work with switch{} below
int output_sensor_value[sensors_number];     // needs to be global if we want to freeze it
int last_sensor_value[sensors_number];       // because we will only send data if there is a change in the reading

// time management
long debounce_millis[sensors_number];
int debounce_threshold = 50;    // above 20ms the reading will be considered valid
long high_press_timer[sensors_number];
int calibration_trigger = 500;  // a 500ms press will activate calibration mode
int startup_delay = 1500;       // ms to wait at startup

//  LED management
long led_timer[sensors_number];
int led_blinking_time = 300;    // blinking time set to 300ms
boolean led_state[] = {0, 0, 0};  // default LED state

// modes
/* 0 = reading
   1 = freeze
   2 = calibration */
int sensor_mode[] = {0, 0, 0};

// Arduino pins
int switchPin[] = {2, 3, 4};
int ledPin[] = {8, 12, 13};
int commonPin = 0;       // the pin we will read from, connected to the 4051
int s0 = 5;              // these following 3 are connected to the 4051 select pins
int s1 = 6;
int s2 = 7;

// the bits we will write to select the 4051 to read from
boolean r0;
boolean r1;
boolean r2;

void setup() {
  // pins setting
  for (int i = 0; i < sensors_number; i++) {
    pinMode(ledPin[i], OUTPUT);
    pinMode(switchPin[i], INPUT);
  }
  pinMode(s0, OUTPUT);
  pinMode(s1, OUTPUT);
  pinMode(s2, OUTPUT);

  // initialize serial communication
  Serial.begin(9600);
  Serial.println(sensor_mode[0]);
  
  // LED check and delay before reading switches
  for (int i = 0; i < sensors_number; i++) {
    digitalWrite(ledPin[i], HIGH);
  }
  delay(startup_delay);
  for (int i = 0; i < sensors_number; i++) {
    digitalWrite(ledPin[i], led_state[i]);
  }
}


void loop() {
  
  // we will repeat the whole thing once per sensor
  for (int i = 0; i < sensors_number; i++) {
  
    // these bits are sent to the 4051 to tell it which of its pins we want to read
    // according to the value of 'i'
    r0 = bitRead(i,0); // we convert the sensor number into a 3 bit number
    r1 = bitRead(i,1); // if 0: r0 = 0, r1 = 0, r2 = 0
    r2 = bitRead(i,2); // if 1: r0 = 1, r1 = 0, r2 = 0
    digitalWrite(s0, r0);
    digitalWrite(s1, r1);
    digitalWrite(s2, r2);
  
    /*****************************************
        READING SWITCH AND SELECTING MODES
    *****************************************/
  
    // read switch
    current_switch_state[i] = digitalRead(switchPin[i]);
  
    // if state changed
    if (current_switch_state[i] != last_switch_state[i])
      debounce_millis[i] = millis();

    // if the counter is above the debouncing threshold
    if ((millis() - debounce_millis[i]) > debounce_threshold) {
       
      // if switch is HIGH (pressed)
      if (current_switch_state[i] == HIGH) {
        // if high press timer not set, set it
        if (high_press_timer[i] == 0) high_press_timer[i] = millis();
        //  if it is set, compare to calibration activation threshold. If over (and mode not already 2):
        else if ((millis() - high_press_timer[i] >= calibration_trigger) && (sensor_mode[i] != 2)) {
          // reset previous end values
          sensor_min[i] = analogRead(commonPin);
          sensor_max[i] = analogRead(commonPin);
          // activate calibration mode
          sensor_mode[i] = 2;
          // start led blink timer
          led_timer[i] = millis();
          led_state[i] = -led_state[i] + 1;  // toggle led_state to show we're entering calibration mode
        }
      }

      // if switch is LOW (released)
      else {
        // if we had a short press
        if (  millis()-high_press_timer[i] < calibration_trigger
              && millis()-high_press_timer[i] > 0) {
          // go from calibration to freeze mode if applicable
          if (sensor_mode[i] == 2) sensor_mode[i] = 1;  // will be toggled to 0 in the next line
          // and toggle anyway (so eventually we get from calibration to continuous reading mode)
          sensor_mode[i] = -sensor_mode[i] + 1;
          led_state[i] = sensor_mode[i];  // so if mode = 0, led is off, and if mode = 1 led is on
        }
        // we then reset the high press timer to enable calibration mode again
        high_press_timer[i] = 0;
      }
    }
  
    // save switch state
    last_switch_state[i] = current_switch_state[i];
  
    /***********
        MODES
    ***********/

    switch (sensor_mode[i]) {
  
      // continuous reading mode
      case 0:
        // read sensor
        sensor_value[i] = analogRead(commonPin);
        // in case the value is beyond the min or max
        sensor_value[i] = constrain(sensor_value[i], sensor_min[i], sensor_max[i]);
        // then map to calibration values
        output_sensor_value[i] = map(sensor_value[i], sensor_min[i], sensor_max[i], 0, 255);
    
      // freeze and continuous reading modes
      case 1:
        //Serial.println(String(i) + ": " + String(output_sensor_value[i]));
        Serial.print(String(i) + ": " + output_sensor_value[i]);
        if (i == sensors_number - 1) Serial.println();
        else Serial.print(" --- ");
        break;

      // calibration mode    
      case 2:
        // read sensor
        sensor_value[i] = analogRead(commonPin);
        // store new values if applicable
        if (sensor_value[i] < sensor_min[i]) sensor_min[i] = sensor_value[i];
        if (sensor_value[i] > sensor_max[i]) sensor_max[i] = sensor_value[i];
        // print current ends
        int p0 = r0;
        int p1 = r1;
        int p2 = r2;
        Serial.println(String(i)+" ("+String(p0)+String(p1)+String(p2)+") "+"> Current: "+String(sensor_value[i])+" - Min: " + String(sensor_min[i]) + " - Max: " + String(sensor_max[i]));
        // toggle the led if the time has come
        if (millis() - led_timer[i] > led_blinking_time) {
          led_state[i] = -led_state[i] + 1;
          // and reset the timer for the next blink
          led_timer[i] = millis();
        }
      
    }  // endswitch
  
    // print mode
    digitalWrite(ledPin[i], led_state[i]);
    
  }  // endfor
}

Oh, and I made small wire jumpers! That looks so much sexier!



<< Previous: 3. Finding more pins, part I: the 4051

Saturday, 10 March 2012

My DIY Arduino MIDI controller - 3. Finding more pins, part I: the 4051

The first thing I tried when I understood I would need more pins than what I have on my Arduino Uno, was the 4051 multiplexer. The way this chip works is rather simple, the Arduino playground explains it better than I could:

If you use the 4051 as a Multiplexer: You can choose between 8 different inputs and select just one you want to read at the time.
If you use the 4051 as a Demultiplexer you can choose between 8 different outputs and select just one you want to write at the time.

3 of its pins are connected to the Arduino, and by writing these pins HIGH or LOW you select which of the 4051 in-/output pins you are going to read or write. It's a simple binary to decimal conversion. For example if you want to select pin 5 of the 4051, you can refer to the following table:

000 => pin 0
001 => pin 1
010 => pin 2
011 => pin 3
100 => pin 4
101 => pin 5
110 => pin 6
111 => pin 7

That is to say you will write the select pin 1 HIGH, the second LOW and the third HIGH (101 is the binary for 5). Once you've done that you can write or read the common pin.

I first used the 4051 to connect 7 switches & pots to the 8 in-/outputs of the 4051, and I seemed to successfully read from them, but then I tried to use 4 switches (reading) and 4 LEDs (writing) with the same chip and it didn't work the way I expected.

This is the wiring...

The blue wires connect the Arduino to the 4051 select pins. By writing these HIGH or LOW we will tell the 4051 which of its 8 in-/outputs we want to play with.
The orange wires connect the switches to the pins 0-3 of the 4051.
The brown wires connect the red LEDs to the pins 4-7 of the 4051.
The white wire is the one we will use to read/write to the selected 4051 pin.
The green wires connect the yellow LEDs to Arduino pins.
In real life it looks like this



...and the code I used:

int r0;
int r1;
int r2;

//  4051 pins
int commonPin = 8;
int s0 = 2;
int s1 = 4;
int s2 = 7;

//  LEDs directly connected to Arduino pins
int regularLed[] = {9, 10, 11, 12};

boolean switchVal[] = {LOW, 0, 0, 0};
boolean lastSwitchVal[] = {0, 0, 0, 0};
boolean ledState[] = {0, 0, 0, 0};

//  setup
void setup() {
  pinMode(s0, OUTPUT);
  pinMode(s1, OUTPUT);
  pinMode(s2, OUTPUT);

  for (int i = 0; i <= 3; i++) {
    pinMode(regularLed[i], OUTPUT);
  }
  
  Serial.begin(9600);
}

//  loop
void loop () {

  for (int i=0; i<=7; i++) {

    // select the bit  
    r0 = bitRead(i,0);
    r1 = bitRead(i,1);
    r2 = bitRead(i,2);
    digitalWrite(s0, r0);
    digitalWrite(s1, r1);
    digitalWrite(s2, r2);

    //  Read from switches on pins 0 to 3
    pinMode(commonPin, INPUT);
    if (i <= 3) {
      
      //  Read switch
      switchVal[i] = digitalRead(commonPin);

      //  Light Arduino LEDs up accordingly to switch state
      digitalWrite(regularLed[i], switchVal[i]);

      //  If the state of the switch has changed
      if (switchVal[i] != lastSwitchVal[i]) {

        //  Toggle middle LED state if switch is pressed (not if released)
        if (switchVal[i] == 1) toggleLed(i);  //  1 = HIGH
        
        /*  Debug data
        Serial.println("s"+String(i)+" = "+String(int(lastSwitchVal[i]))+">"+String(int(switchVal[i])));
        for (int j = 0; j <= 3; j++) {
          if (j != 3)
            Serial.print(int(ledState[j]));
          else
            Serial.println(int(ledState[j]));
        }*/
        
        //  Save new switch state
        lastSwitchVal[i] = switchVal[i];
      }
    }

   //  As we will be reading from pins 4 to 7 we change the common pin state
   pinMode(commonPin, OUTPUT);

    //  Write to LEDs on pins 4 to 7
    if (i >= 4) {
      digitalWrite(commonPin, ledState[i - 4]);
      /*if (i != 7)
        Serial.print(String(int(ledState[i-4])));
      else
        Serial.println(String(int(ledState[i-4])));*/
      //delay(125);
    }
  }
}

//  toggles ledState[x] 0 / 1
void toggleLed(int l) {
  ledState[l] = -ledState[l] + 1; //  -0 + 1 = 1  |  -1 + 1 = 0
}

What this code does is that when a switch is pressed:
  • The corresponding yellow LED is on (and off when the switch is not pressed), I'm just writing the switch state to the LED.
  • The corresponding middle LED state is toggled on/off (nothing happens on switch release).


The yellow LEDs light up as I press switches 1 & 2 (works with all switches ;)

It worked fine at first when the code was sending serial data to the monitor, but when I commented the serial commands out, it started behaving strange. The reading seemed to be normal but the LEDs were lit in a strange fashion. When I pressed the first switch, both first & second LED turned on, but I knew from my previous try that the LED states were written correctly, because I had send them over the serial port. So it was not due to a mistake in my code.


Switch 1 has been pressed and LEDs 1 & 2 are lit, instead of only LED 1.

How come? I got the answer from the Arduino forums: Grumpy_Mike said
This is because you are writing the digital select lines one at a time and in the process you put false data briefly on the the chip. You need to write all these bits at the same time using direct port access or bit manipulation. But as I said it is totally the wrong chip anyway, use a shift register and don't put in that capacitor they have in the tutorial.
So I guess I'll try to use the 4051 for reading only (pots and LDRs), and I ordered a couple of 74HC595 shift registers from Sparkfun (along with pots, SPDT switches, RGB LEDs, MIDI connectors, resistors, a thumb joystick with its breakout board & solderless headers, wire & heat shrink!).

So next post will be about the 74HC595 8 bit shift register, unless they take too much time to arrive, in which case I could post about the LDR calibration.

<< Previous: 2. The first problems

Tuesday, 6 March 2012

My DIY Arduino MIDI controller - 2. The first problems

The first problems:
There's one thing I might find annoying with LDRs: If I want to increase for instance the filter cutoff frequency of a synthesizer by casting a shadow over a LDR with my hand, the frequency would suddenly drop down as I remove my hand, unlike a potentiometer which would remain at its position after tweaking. Although that sounds like a cool thing to be able to go instantly from high to low position (which you can't do with a rotary pot), I thought it would be even better to be able to "freeze" the reading of the LDR by pressing a button. To do that I will therefore need 4 switches, one per LDR, and 4 LEDs to tell if freeze is active for each LDR.

Another problem about LDRs is that they will return different values according to the ambient light, and I want to be able to use my controller under a maximum range of light conditions (daylight from the window, artificial lamp on the desk, or just the light from the computer screen...) Therefore I will have to calibrate it whenever the ambient light changes, which will require another button to toggle the calibration mode on/off. I will also have to tell the user when calibration is on and which LDR is being calibrated. I decided I would just turn the LEDs off when the sensor is in use, turn them on when the sensor is "frozen" and I'll make them blink during calibration. It might be a good thing to add a potentiometer to adjust their brightness so that they don't influence calibration.

The problem I'm facing now is that my Arduino board has only got 13 digital in/outs, and 6 analog inputs. The digital in/out pins can be used to detect the presses of switches, or light LEDs (you can think of them as switches that are either on or off). Pins 1 and 2 will be used for MIDI communication, so we have 11 pins left for LEDs & buttons/switches, each of which require 1 pin. The analog inputs allow us to connect a total of 6 sensors and potentiometers.

A rotary pot, a LDR and a few tact switches
My digital needs so far are:
- 5 switches/buttons for LDR options
- 1 "panic" button that would turn all notes off
- 1 reset button if possible
- 4 LEDs
- 4 (at least) triggering buttons (if I wanted to use velocity I would have to get analog sensors instead)

That's already a total of 15 digital pins and I only have 11 of them left. Same for analog inputs. I've only got 6, to which I want to connect 1 slider pot, 4 LDRs and some rotary pots. Running out of pins on the analog side too! That said, you cannot browse Youtube looking for Arduino videos without noticing many project with 8x8 LED matrices or many pots, motors or whatever, so there definitely is a solution, which is what I'm working on at the moment, see next post!

<< Previous: 1. The Arduino

Monday, 5 March 2012

My DIY Arduino MIDI controller - 1. The Arduino

This first post will try to sum up everything I had to learn to get where I'm now: shift registers.

The Arduino
Photo by the Arduino Team
First thing I had to do was to understand what an Arduino is and how it works, how hard it is to get it to send MIDI data out, or to read from various sensors etc.

If you have no idea what an Arduino is, it is a programmable electronic device that can receive or send voltages. Basically you can plug potentiometers, pressure sensors, light dependent resistors, audio signals, etc. to its inputs, and LEDs, motors, LCD displays etc. to its outputs. You can as well get it to communicate to computer programs such as Pure Data, Processing and many more, using its USB port. Of course you can get it to send or receive MIDI data. It is easy to program, the upload is done via USB with the minimal Arduino IDE (Integrated Development Environment).

Some Arduino projects I found interesting on Youtube, that made my brain go crazy and think of all I could do with this little device (actually I couldn't find all the videos I watched then, but I added some other ones that can be inspiring too):
http://www.youtube.com/watch?v=v56zLOqhjV4
http://www.youtube.com/watch?v=FGl-ba7qSic
http://www.youtube.com/watch?v=D48kgIr0CJI
http://www.youtube.com/watch?v=92VIEDtQKVI
http://www.youtube.com/watch?v=-KDd_YY7fTI

Knowing nothing about electronics I ordered an Arduino starter kit and followed the lessons on http://www.ladyada.net/learn/arduino/index.html. That is where you learn the "Hello world" of the Arduino: blinking an LED. That's also where you learn everything you need to get started when you know nothing about micro controllers, computer programming or electronics, and it only takes a few hours.

After spending a couple of hours reading the basic tutorials on the official Arduino site, I learned how to:
- read and display data from a potentiometer, a light dependent resistor, a piezo,
- use a tact switch to increment a counter (useful when you want to use a button to browse through different options),
- communicate with Processing (for a different project).

I also learnt how to solder components on a PCB (Printed Circuit Board) thanks to Bleeplab's Pico Paso, which I ordered as a kit, since soldering will definitely be required, though I might have to deal with wires more than PCBs but it's still good to know the basics of PCB through-hole soldering.

I still need now to learn how to send MIDI data (already did but forgot), and how to connect more sensors, LEDs and switches than what the Arduino normally allows. This is what I'm working on at the moment and I'll post soon about my failures and successes at multiplying the Arduino's ins and outs!

<< Previous: 0. Intro

Sunday, 4 March 2012

My DIY Arduino MIDI controller - 0. Intro

Hello there,

A few months ago I decided to get a new MIDI controller. I browsed Thomann, Audiofanzine and various sites but I couldn't find a controller satisfying my needs. During my search I stumbled upon many Arduino projects that I found interesting, and I thought I might give it a try, though I knew nothing about electronics, and very little about programming.

I will post here the various stages of the creation process. I have no idea whether I'll succeed in this task or not but I thought it might be interesting to share...


The project:
After spending some time on the Internet learning how to master the basics of the Arduino world, my idea has evolved quite a lot, I even forgot what I wanted to do in the first place but where I'm heading at at the moment is: I want to build a MIDI controller that uses different kinds of sensors rather than common potentiometers. It has to be playful though and I don't see myself playing music with a temperature sensor. So the only sensor that seemed easy enough to use for a first project, and still be playable in a live situation, was the light dependent resistor (LDR). I am planning to use 4 of them, a couple (or a bunch) of rotary potentiometers, a slider potentiometer (always good to have a fader for master volume), and buttons to act as pads to trigger sounds, and why not a Playstation-like thumb joystick, because they spring back to the middle like a pitch wheel.

Next: 1. The Arduino >>