Tuesday, January 27, 2015

Part 4, Software Design Notes, BeatBuddy Tempo Pedal / MIDI Beat Clock Generator / OPEN SOURCE

See Part 1 for hardware design and schematic.

See Part 2, for parts list and build pictures.

See Part 3, for Arduino sketch.

This is Part 4, software design notes.

Software Design Notes:

Tip: open Part 3, sketch  in a another browser tab to follow along.

I used the TimerOne library because Timer1 can be set with microsecond resolution.  This timer is used for PWM control of D9 and D10, but I don't need PWM, on any pins, in this sketch. 

I used the SoftwareSerial library to drive the MIDI beat clock output (on D8), and the Seven Segment Serial Display (on D10).  

The constants LowMin and LowMax set the low range BPM limits.  Likewise, MidMin and MidMax set the mid range BPM limts; and HighMin and HighMax set the high range BPM limits.  The values show work well for me, but feel free to adjust to your liking.

MIDI_CLOCK() is the ISR, interrupt service routine, that sends the MIDI beat clock.

setTimer() is called whenever the pedal is moved.  It calculates, and sets the period for Timer1, in microseconds, based on the BPM from the pedal.

setup() is pretty straightforward.  MIDI serial baud rate is 31250.  Seven Segment Serial Display is 9600 baud.  I also setup the serial monitor port, useful while debugging the sketch.  

Timer1.attachInterrupt() sets up the timer hardware interrupt, and ISR, MIDI_CLOCK().

In the loop() function, we check switch S1, which enables the clock output.  If disabled, set the LED color to red, and detach the interrupt from the ISR.  If enabled, leave the LED color alone, and attach the interrupt to the ISR.  

Note, this code is repeatedly calling attachInterrupt or detachInterrupt, which is redundant but works fine.  A more elegant approach would only attach or detach once, when the enable/disable switch was changed.

The enable/disable switch serves a practical purpose.  First I turn it off, so the BeatBuddy is keeping its own time.  Then I recall a song on the BeatBuddy, and it displays the tempo that was saved with the song.  Then I enable the clock output and control the BeatBuddy tempo with the pedal.  

On the other hand, if I already know the desired tempo, or just want to play it by ear, I can just leave the enable/disable switch on all the time.

Regardless of the output on or off, we always want to read the range switch, S2, and pedal, and update the BPM display.  If the output is enabled, we also want to set the LED color to indicate the selected BPM range.

I use the map() and constrain() functions to convert the AnalogRead value (0 to 1023) to the desired BPM.  But instead of using the full (0 to 1023) range, I trimmed that down to (1 to 1010).  That's because of R1, 100 ohms in series with the expression pedal pot.  Depending on the current flowing through the pot, some voltage will be dropped across R1, and so the pot wiper voltage will not span the full (0 to 3.3V) range.  The output of the map() function might be slightly more or less than the selected range, so the constrain() function takes care of that. 

I've tested pots from 10K to 1Meg, and they work fine.  If you wanted to use a lower valued pot, say 1K or 2K, you may find the max BPM setting is a few BPM lower the max for that range.  In that case, you could change the "1010" values in the map() functions to "1000" for example.

But I wouldn't go lower than 1K for the expression pedal pot: power supply current will increase, and pedal sensitivity will decrease (because we'd be using less and less of the 3.3V range.)

If (newBPM != BPM), then the pedal was moved, so call setTimer() to update the Timer 1 period; and provide a debug message to the serial monitor port.  

If the pedal was not moved, we kill another 20 ms before looping again.  This value was chosen low enough so that the pedal is being read often enough that the BPM display tracks the pedal smoothly.  Increasing this value might cause the BPM display to lag a bit.  Decreasing it, or eliminating this delay, would still work, but there's no need to read the pedal pot a few hundred thousand times per second.  (Supply current would increase, for example).

The remaining functions support the RGB LED and 7 segment display.

In summary, the sketch reads the switches and the pedal, and sets Timer 1 accordingly.  When Timer 1 interrupt fires, it sends the MIDI Beat Clock.

Well, that wraps up this series on the BeatBuddy Tempo Pedal.  Happy hacking, and rock on!