Arduino VS1053 General MIDI Synth – Part 3

Having prototyped a patch changer for my Arduino VS1053 General MIDI Synth this shows how that can be achieved in a slightly more useful manner using a shift register to control the 7-segment display. It also follows through a build using my Arduino MIDI Proto Shield PCB.

Warning! I strongly recommend using an old or second hand keyboard for your MIDI 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
  • VS1053 shield (see photos)
  • 1x rotary encoder
  • 1x 3-digit 7-segment display – alternatively, we can just use 3 digits from a 4-digit display
  • 3x 1kΩ resistors
  • 74HC595 shift register
  • Optional (but recommended): 16-way DIP socket
  • Optional (but recommended): 1x 100nF capacitor
  • Optional: 3x 10nF capacitors
  • Optional: Arduino MIDI Proto Shield PCB and associated components
  • OR: Proto shield with solderless breadboard (e.g. Adafruit Proto Shield for Arduino) and an Arduino MIDI Interface or Ready-Made MIDI Module

IMG_6502

The Circuit

ArduinoMIDIVS1053SynthPC595_bb

The main point of this project is to use my Arduino MIDI Proto Shield PCB, but the same circuit could be used with solderless breadboard as shown above.  This is largely the same as the previous version, but all of the segments of the 7-segment LED display are now driven by the 74HC595, which only requires three connections to the Arduino as shown:

  • A5 – DS
  • A4 – STCP
  • A3 – SHCP

The segment wiring is in the following order: 6,7,2,3,4,5,1 – these are the Qn outputs of the 595.  Note that Q0 is unused.

This is wired up to use three digits (D2, D3, D4) of a very common 4-digit 7-segment display – digit 1 is unused.  The digit wiring is in the following order: 4,3,5 – these are directly connected (via resistors) to the Arduino digital IO pins D4, D3, and D5.

Arduino MIDI Proto PCB Version

ArduinoMIDIProto7SegmentREVS1053_bb

As stated above, the main point of this project is to use my Arduino MIDI Proto Shield PCB, so the above diagram shows how the prototyping area will be populated.  I was really after re-using the very small, neat 3-digit display I had in my generic program changer, but unfortunately, I’ve not been able to source any more.

What I have been able to find however are a number of 0.28″ three-digit, common cathode, displays with decimal points (that I don’t need) and an 11-pin arrangement as follows:

D1-A--F-D2-D3--B
|              |
E--D-DP--C--G--+

Which is essentially the same pin-out as the very common 4-digit displays just without D4.

Now recall that the VS1053 uses quite a number of Arduino pins, so the complete Arduino pin usage is as follows:

  • D0 – RX to MIDI
  • D1 – TX to MIDI
  • D2 – VS1053 DREQ
  • D3 – Digit 1
  • D4 – Digit 2
  • D5 – Digit 3
  • D6 – VS1053 X-Cs
  • D7 – VS1053 X_DCS
  • D8 – VS1053 X_RESET
  • D9 – VS1053 CS
  • D10 – SS (unused but must be an OUTPUT to enable SPI)
  • D11 – COPI (used to be called MOSI) to VS1053
  • D12 – CIPO (used to be called MISO) to VS1053
  • D13 – SCK to VS1053
  • A0 – Rotary Encoder B
  • A1 – Rotary Encoder A
  • A2 – Rotary Encoder switch
  • A3 – 595 SH_CP
  • A4 – 595 ST_CP
  • A5 – 595 DS

Build Steps:

IMG_6487

Part build the Arduino MIDI Proto Shield PCB – specifically the low-lying components and the 8-pin DIP socket.  Do not solder on the MIDI sockets or Arduino header pins yet.

Bend the six legs of the 7-segment display, leaving the five legs straight, to get it to fit the board as shown below.

IMG_6488IMG_6489

Verify the positioning of the main components to get an idea of where everything will be going.  By bending the legs of the display, it should fit in the holes as shown in the Fritzing diagram above and as indicated below.

Solder the LED current limiting resistors to D3-D5.  See photos for the rather unusual physical arrangement(!) to allow them to fit under the edge of the 7-segment display.

IMG_6491 - Resistors

Then add the 14-pin DIP socket and the 7-segment LED, but only solder the LED pins that connect to the resistors and the unused “DP” pin for the moment.  The rest can come later.

Now the rest of the connections between the 595 and the LED can be made on the underside of the board.  This is followed by the GND and then 5V lines, which include the 100nF capacitor for the 595 too.  Note that I forgot the additional 5V connection to the 595’s MR pin (pin 10), which I had to add later – see the Fritzing diagram.  It would make much more sense to include that now too.

Next the rotary encoder and its three capacitors can be fixed.  I took off the two structural tags at the sides and am relying just on the five electrical connections to hold it in place.

Finally, the six connections to A0-A5 can be added.  A0 to A2 to the encoder and A3 to A5 to the 595.  Then the MIDI sockets can be soldered onto the top of the PCB followed by the Arduino headers themselves to complete the MIDI shield.

The Code

This is essentially the same code as the last project but has been updated to use the version of the SevSeg library that supports a shift register (see: https://github.com/bridystone/SevSegShift).

Seven Segment Library Configuration

The configuration for the SevSegShift library for use with my PCB is as follows (for details of how it works, see the above-mentioned previous project):

// Set up the LED display
#define SR_PIN_DS   A5
#define SR_PIN_STCP A4
#define SR_PIN_SHCP A3
#define SR_NUM 1 // Number of shift registers
#define SR_ARD_DIGITS true // True if digits directly connected to Arduino; False if via shift register
SevSegShift disp(SR_PIN_DS, SR_PIN_SHCP, SR_PIN_STCP, SR_NUM, SR_ARD_DIGITS);

// Pin definitions for the display
//
//  = A =
// F     B
//  = G =
// E     C
//  = D =
//
// Pattern repeated for three digits (1,2,3) each with a common cathode.
// Note: Cathode should be connected to the "digit" pins via a resistor (1k).
//
// Digit Order: D1-D2-D3-D4
//
// Pinout of my 12-pin display.
//
// D1-A--F-D2-D3--B
// |              |
// E--D-DP--C--G--+
//
#define NUM_DIGITS   3
#define NUM_SEGMENTS 7
byte digitPins[NUM_DIGITS] = {3,4,5}; // Arduino pins: Order: D1,D2,D3
byte segmentPins[NUM_SEGMENTS] = {1,2,5,6,7,3,4}; // Shift Reg pins: Order: A,B,C,D,E,F,G (DP not used)
#define RESISTORS_ON_SEGMENTS false // Resistors on segments (true) or digits (false)
#define HARDWARE_CONFIG COMMON_CATHODE // COMMON_CATHODE or COMMON_ANODE (or others)
#define UPDATE_WITH_DELAYS false // false recommended apparently
#define LEADING_ZEROS true // Set true to show leading zeros
#define NO_DECIMAL_POINT true // Set true if no DP or not connected

The configuration for the rotary encoder is as follows:

// Rotary Encoder
#define RE_A  A0 // "CLK"
#define RE_B  A1 // "DT"
#define RE_SW A2 // "SW"
RotaryEncoder encoder(RE_A, RE_B, RotaryEncoder::LatchMode::FOUR3);

If you are using the solderless breadboard version then the ordering and pin numbers will be different, so be sure to use the arrangement that matches your wiring!

In terms of the MIDI configuration, I’m using the standard MIDI library serial port, which means I get MIDI THRU functionality by default.

Note that the program change messages are only being sent to the VS1053 though.

Otherwise, the main logic is pretty much the same as before.

Find it on GitHub here.

Closing Thoughts

I’m really pleased with this project.  This is exactly the kind of thing I had in mind when I created my MIDI proto shield and it is a really neat add-on to the VS1053 shield itself.  The only minor disappointment was not being able to find more of those smaller 3-digit displays, but I’ll keep looking.  The 0.28″ ones aren’t too bad.

Future enhancements could include:

  • Building-back in support for VS1003 modules too (as per my earlier experiments).
  • Utilising the switch on the encoder – possibly enabling different modes: e.g. one mode for the VS1053, one mode to send to MIDI OUT.
  • I’ve not wired the decimal point up, but thinking about it now, I could use the “dot” as an indicator of mode.
  • I could create a version that can send different MIDI CC messages too.

Kevin

Leave a comment