Arduino MIDI Rotary Encoder Step Sequencer – Part 3

I am continuing my experiments with different ways of visualising a step sequencer and this comes from from a suggestion by Twitter user @AxWax – using a NeoPixel ring.

Warning! I strongly recommend using old or second hand equipment for your experiments.  I am not responsible for any damage to expensive instruments!

These are the key Arduino tutorials for the main concepts used in this project:

If you are new to Arduino, see the Getting Started pages.

Parts list

  • Arduino Uno
  • 1x rotary encoder “breakout” (switched encoder type)
  • NeoPixel style ring of LEDS – any size
  • One of the Arduino MIDI Interfaces or Ready-Made MIDI Modules
  • Breadboard and jumper wires (optional)
  • Additional power supply for the NeoPixels if you are using a large ring!

The Circuit

ArduinoMIDIRE7SegmentController-Part3_bb

NeoPixels are the Adafruit branded sets of WS2812 programmable red-green-blue LEDs.  Each LED has a chip inside that can be told, using a single connection, the proportions of red, blue and green to illuminate.  And each chip can be linked to the next one.  This means a whole string of full colour LEDs can be linked together and individually programmed using just a single IO pin from an Arduino.  You can read all about them here: https://learn.adafruit.com/adafruit-neopixel-uberguide.

I’ve hooked mine up to D6, but before I could use it I had to solder some jumper wires to the ring. I’ve soldered all four connections but we won’t need to use DOUT this time – that is to connect to more LEDS in the future.

IMG_5482

Now an Arduino Uno would not be able to deliver the required current to illuminate a whole ring of NeoPixels at full brightness – a ring of 12 RGB LEDs is essentially asking the Arduino to supply enough current for 36 LEDs from its 5V pin, which can only deliver a maximum of 500mA.  For this reason NeoPixels are often powered from a separate power supply.

In my case, I’m only illuminating a single RGB LED a time and I’ve turned the brightness right down using software, so I can get away with powering the ring from the Arduino.

The other connections are to the rotary encoder – once again plugged in directly to A0 to A4 and using A0 and A1 as GND and VCC respectively – and the MIDI interface on RX/TX/5V/GND.

IMG_5481

The Code

The vast majority of the code is the same as for the Arduino MIDI Rotary Encoder Step Sequencer using the tweaks I mentioned in Part 2.

Having the display code broken out into the initDisplay and scanDisplay functions is making it quite easy to slot in new display techniques.  This time I’m using the Adafruit NeoPixel library.  It is worth checking everything works using one of the built-in examples.  The “strandtest” example is one of the simpler ones – just edit the pin and number of LEDS to match your own setup.

The functionality I’m going for is as follows:

  • In step edit mode, the current step being changed will turn blue.
  • In note edit mode, the colour of the current step will change with the pitch of the note.
  • Any silent current playing step will be illuminated by a low-brightness “white” LED setting.
  • Any playing note will be displayed with its associated colour as used when storing the note in edit mode.

The operation of the rotary encoder is the same as in the previous projects.

I’m only really making use of a few elements from the NeoPixel library.  First the initialisation code to include and setup the library.

#include <Adafruit_NeoPixel.h>

#define NUM_STEPS 12

#define LED_PIN 6
#define LED_COUNT NUM_STEPS
Adafruit_NeoPixel strip(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);

#define LED_STEP_ON strip.Color(0,50,50)
#define LED_STEP_OFF strip.Color(0,0,0)
//#define LED_PLAY_ON strip.Color(0,255,0) // Uncomment this for a single "on" colour
#define LED_PLAY_OFF strip.Color(15,15,15)

I’m setting things up so that the number of LEDs and number of steps is the same – 12 in my case.  The actual initialisation line has to be set up for the specific type of NeoPixels you have.  There is a full description in the Adafruit tutorial and in some of the example code.

I’ve also defined some macros to specify the red-green-blue values for specific events in the code.  These are using the NeoPixel’s .Color(r,g,b) method which creates a value suitable to using in the other routines whenever a colour needs to be specified.

The initDisplay function needs to enable the LED strip and turn the brightness right down, so it doesn’t draw too much current from the Arduino.  The brightness setting goes from 0 (off) to 255 (full brightness).  I’m using 20.

void initDisplay() {
  strip.begin(); // INITIALIZE NeoPixel strip object (REQUIRED)
  strip.show(); // Turn OFF all pixels ASAP
  strip.setBrightness(20); // Set BRIGHTNESS fairly low to keep current usage low
}

The the scanDisplay function has to determine the current mode and clear the LEDs, turn on the current step as required for that mode, then activate the LEDs.

scanDisplay()
  Clear the strip
  IF in Note mode THEN
    Set the current step's LED according to the current step's note
  IF in Step mode THEN
    Light up the current step's LED
  IF in Play mode THEN
    IF the step has a note THEN
      Light up the step LED using the colour corresponding to the note

  Activate the LED strip

I particularly wanted a rainbow effect for the range of notes.  The way to do that, according to the Adafruit tutorial, is to use the “hue” option for setting colours.  This maps the values 0 to 65535 onto the colour spectrum – see the discussion of “HSV (Hue-Saturation-Value) Colors” here for details.  All I need to do is map the range of MIDI notes onto the colour scale, which I do using the Arduino’s map function and the Adafruit ColorHSV function as follows:

uint32_t note2led (byte note) {
  if (note != 0) {
    return strip.ColorHSV(map(note, MIN_NOTE, MAX_NOTE, 0, 65535));
  } else {
    return 0;
  }
}

I can use this function in both edit and play modes to give a consistent mapping between notes and colours.

Find it on GitHub here.

Closing Thoughts

I’ve been thinking about bringing NeoPixels into some of my projects for a while, so when AxWax mentioned them, that was it – I had to try them.  And I think this is perhaps my favourite version of the step sequencer so far.

I’ve built it using a 12-LED ring as that is what I had to hand already, but it should easily support 16, 24 or even one of those large 60 LED rings if you don’t mind entering all the different steps by hand using the encoder!  For anything more than 12 though I strongly recommend, in fact I probably insist, that you use an independent power support rather than drive them directly from your Arduino.

This would also be a great candidate for a “step sequencer shield” especially if I was able to mount the rotary encoder in the centre of the ring.

Kevin

Leave a comment