Arduino MIDI 7 Segment Controller – Part 2

As mentioned in my previous post,  the Arduino MIDI 7 Segment Controller is ripe for turning into a self-contained module.  To keep it all relatively small, I opted to build an add-on board for an Arduino Nano.

2021-01-17 18.44.58

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 Nano
  • 4 digit 7 segment display (common cathode or common anode type)
  • 2x buttons
  • 4x 1kΩ resistors
  • Male normal and right angle headers
  • 21×7 proto board

The Circuit

NanoMIDI7SegmentController_bb

The main idea here is to build a board containing the LED display (I don’t have a Fritzing part for my display, so I’ve mocked one up here to show the rough dimensions and pinout) and the two buttons which can go back-to-back with a Nano.  In this case the Nano will go upside down i.e. USB socket and ATmega on the bottom.

In order to see which of the headers match with the Nano’s pinouts, I’ve included the respective pin headers for reference in the diagram above.  This is presented from the top of the LED board looking down (so the Arduino would be underneath the proto board, upside down).  Have a look at the following photos and you’ll get the idea.

2021-01-16 14.08.51

The first step was to put on the headers that will link the proto board to the Nano.  I opted to push the spacers right to the ends of the pins (see photo above) and soldered on the “wrong side” – i.e. the long side.  This is because I’ll be attaching wires to them from underneath as part of the build.

Once fixed on, I pulled the spacers off and used them on the reverse side as supports for the pins so that when I’m soldering wires to them later on they won’t unsolder or move around.

2021-01-16 14.14.39

Once the headers were in place I added the two buttons.  Note that the buttons I used only had two solder tags (again see the photos), unlike the normal ones I often use that have four.  You can use the wider ones, but you might need to move things around or use a longer piece of proto board if you do.

2021-01-16 14.21.30

Finally in this stage I added the three-way, right angled header to act as the MIDI link and the two-way angled header to act as power for some analog IO (more on that later).  I also added the long ground link for the two buttons, linking into the Arduino’s GND pin on the digital IO side of the board.

2021-01-16 14.52.25

The analog power pins need to be linked to the Arduino’s 5V and GND.  Handily one of them is right next to 5V so I just solder jumpered the headers together on the LED side of the board.  To reach GND needed an additional jumper wire, which again I opted to put on the LED side of the board.  See the photo below.

The LED display was the added to the board. It is important to get the orientation right – in the photo below we are seeing it from the top.  As a check, the six pins of the LED display should line up with the gap in the headers on the analog side of the Arduino Nano.  Look again at the Fritzing diagram to see what I mean.

2021-01-16 14.53.05

At this point the board can be flipped over and the LED display linked up to the appropriate pins to connect to the Nano.  The wires below are coded as follows:

  • Red – 5V power to the MIDI link.
  • Black – GND to the buttons – plus one short section of uninsulated GND to the MIDI link.
  • Orange – TX to the MIDI link.
  • Purple – LED links to the segment IO pins.
  • Resistors – 1kΩ resistors for LED links to the digit IO pins.

On the digital side of the Nano, five of the LED display legs are folder over and linked directly to the nearest IO pin.  The last one required a resistor as it is a digit pin.

2021-01-17 14.17.20

So why not just folder over the other side of the LED display too?  There are two reasons:

  • First, this side has three digit pins that all require a resistor.
  • I wanted to leave the analog pins free to be used as continuous controller inputs if I wanted to.

To achieve the latter, I decided I’d solder right angle headers directly to A2-A7 on the Nano. I needed two extra IO pins for the buttons, so opted to use A0 and A1 in “digital pin” mode for those.  All that was needed to support external analog links is some power, hence the additional jumper for 5V and GND.

2021-01-17 15.12.02

At this point the board can be tested and then the Nano soldered on.

Or if you follow me on Twitter, you’ll know that I soldered the Nano on, then after checking for short, fired it and and burnt out my LED display as I’d got this far before realising I hadn’t included any current limiting resistors in your build!  Doh.  That is also why I don’t have any intermediate steps for the build in photos – all the photos I took had nice neat purple wires and no resistors…

After unsoldering and prizing away the Nano again (one dead Nano as the board was now bent) and then cutting out and unsoldering what was left of the LED display… well, you see the results above.

Once shown to all work using solderless breadboard connections to another Nano via jumper wires, I took the plunge once more and soldered on the Nano properly.

Initially I was going to make the analog connections fully pin compatible with my Simple Potentiometer Breakout, but then I decided it would be nicer to be able to use all six free analog pins on the Nano, so didn’t bother worrying about 5V and GND as much, hence having the signal pins directly on the Nano and then 5V and GND from the proto board.

2021-01-17 11.23.32

The Code

The code is essentially the same code as the Arduino MIDI 7 Segment Controller but using the new pinout for the LED display links and some additional potentiometer code to send out MIDI control change messages.

byte digitPins[NUM_DIGITS] = {13,10,9,2}; // Order: D1,D2,D3,D4
byte segmentPins[NUM_SEGMENTS] = {12,8,4,6,7,11,3,5}; // Order: A,B,C,D,E,F,G,DP

The use of potentiometers is optional.  There is a list at the top of which MIDI control message to send for any pots.  If any of the six pots are not required, then the code NOPOT is used instead.

int midiCCPots[NUMPOTS] = {
0x01, // Modulation wheel (0 to 127)
0x02, // Breath Controller (0 to 127)
0x04, // Foot Controller (0 to 127)
0x07, // Channel Volume (0 to 127)
NOPOT, // Pot not used
NOPOT, // Pot not used
};

Is is important to only have pots listed you plan to actually connect up.  Otherwise, a floating analog input may keep sending spurious control messages out over the MIDI link.  If you temporarily aren’t using a pot, then connecting that analog input to GND should be ok to disable it.

MIDI control messages send values between 0 and 127, but potentiometers read 0 to 1023.  On reading, I divide by two, three times using “>> 3” to scale it appropriately. I also keep track of the last value read so that a MIDI CC message is only transmitted if the value actually changes.  Finally, to keep the time handling analog IO to a minimum, I only read one potentiometer on each time through the loop().

Find it on GitHub here.

Closing Thoughts

This was quite a frustrating build for me for some reason.  Pretty much if it could go wrong, for some reason it did!  I had a number of issues while making it, not least of which was getting right to the end and realising I’d forgotten to include the resistors!  Here were the other challenges that came my way.  

When testing things I forgot to change the type of display in some of the SevSeg example code.  Telling it to use COMMON_ANODE when you needed COMMON_CATHODE really messes up the display (I thought I’d damaged another one).

Then I thought there was a problem with the potentiometers, as they were all coming back with 1023, but that turned out to be me managing to knock off the GND pin so they had no reference ground.

Then I thought there was a fault on the final board as every time I pressed a button it reset!  Well it turns out having an Arduino upside down is fine until you put some pressure on it and inadvertently push the RESET button… I’ve now unsoldered the button on my Nano and added a couple of spacers so it sat neatly on the bench.

But then I could see the MIDI lights on permanently, so I thought that adding spacers had somehow caused a short in the MIDI link (one of the spacer holes is right next to the TX pin).  But that turned out to be a potentiometer in exactly the right position so that the value was continually fluctuating between two values after scaling to the 0 to 127 range.  This meant it was constantly sending out MIDI data over the link! A slight turn of the pot sorted that one out.

And then if that wasn’t enough, I found that in use I managed to get the receiving module in a “hung” state (it was my Arduino MIDI VS1003 Shield – Part 2) and was just about to give up on the whole thing… when I remembered I was using a dumb MIDI merge and tweaking pots whilst playing the keyboard would almost certainly result in corrupt MIDI data being received…

So, I got there in the end.

Kevin

Leave a comment