Vintage Rotary Phone MIDI Controller – Part 3

This is the first musical application of my vintage rotary phone.  I’m using it as a simple MIDI note generator.  Remember, I really wanted to keep this as a potentially working phone when not plugged into an Arduino.

This builds on the previous parts in this series.

  • Part 1 – Understanding the telephone hardware and interfacing to an Arduino.
  • Part 2 – Decoding the rotary dial from the Arduino.
  • Part 3 – Rotary phone MIDI note controller.
  • Part 4 – Rotary phone MIDI program change.
  • Part 5 – Rotary phone MIDI random note sequencer.
  • Part 6 – Rotary phone to MIDI adaptor.
  • Part 7 – Rotary phone multi-mode applications.

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

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

Parts list

  • Arduino Uno
  • “GPO” or “BT” original 746 rotary telephone
  • Optional: Scrap ADSL filter
  • 120kΩ resistor
  • Arduino MIDI interface (e.g. one of these or these)
  • Breadboard and jumper wires

The Circuit

ArduinoRotaryPhoneMIDI_bb

Pin D2 from the Arduino is connected to the telephone RED wire and GND is connected to WHITE as described in part 1 of this series.

Now I am also adding a MIDI module to connect to 5V, GND, RX and TX, although in this case I’m only actually going to be using the TX pin.  For this project you could actually get away with a simple MIDI 5-pn DIN socket and two resistors for the OUT (as described here) but I’m using one of my Ready-Made MIDI Modules.

Of course, get hear a sound I also need a MIDI sound module of some description to receive the MIDI codes and produce a sound.  In the video I’m using my Roland MT-32 as usual.

IMG_5916

The Code

I’m using the same basic idea as described in part 2 of this series but I’ve updated it slightly.  The original test code was just called from the Arduino’s loop, but I’m going to want to do a range of other things now, so I’ve arranged things so that the rotary dial code is called from a timer using the TimerOne library with a period that I think will ensure all pulses are properly decoded.  I’ve chosen 20mS.

In order to make finding out what the rotary phone is doing a little easier, I’ve hidden away all the functionality behind a set of functions as follows:

  • rotarySetup() – as you might expect, this is called from the Arduino’s setup() routine to initialise everything.  It relies on two defines that are user-tweakable:
    • PULSE_PIN – specifies which Arduino IO pin to use for the telephone.
    • PULSE_SCAN – specifies the period for the rotary telephone scanning routine.
  • rotaryLoop() – this is actually just a test routine that allows the printing of the main status variables (to give the Serial plotter display from part 2) from the Arduino’s loop() function if required.
  • rotaryDial() – this is the main logic function, but isn’t meant to be “user callable”.  This is the function called by the TimerOne library each timer period.
  • rotaryDigit() – returns the last digit read or NO_DIGIT if no digit has been read or the phone is on the hook, etc.
  • rotaryNewDigit() – this will only return the last digit read once.  Once it has been read, further calls will just return NO_DIGIT until a new digit is dialed in.
  • rotaryOffHook() – returns the status of the phone handset – false if still on the hook; true if it has been removed.

To do something musical, I’ve defined a set of 10 notes that will start playing when the associated number is dialed.  The idea is to use these to play a sustained voice, to keep the notes playing until the handset is replaced.

I’ve chosen a range of notes from the pentatonic scale in C.

#define NUM_NOTES 10
int notes[NUM_NOTES] = {36, 48, 55, 60, 62, 64, 67, 69, 72, 79};

The basic logic of the main loop is as follows.

IF there is a new digit read THEN
   Send the associated MIDI NoteOn message for that digit

IF phone is placed back on the hook THEN
   Send a MIDI NoteOff message for all notes for all digits

It is relatively simple, but with the right voice, can be quite effective.  I’m playing my MT-32 Atmosphere voice in the video.

The above code has one note configured per digit, but with a minor enhancement you can get each digit to cycle through a range of notes.  The basic idea is to create a two dimensional list of notes with one dimension being the digit and the second dimension being a “step”.  Every time a digit is dialed, the next “step” is played.  This allows repeatedly playing the same digit to move through the steps.  Each digit maintains its own “step” count.

#define NUM_NOTES 10
#define NUM_STEPS 3
int notes[NUM_NOTES][NUM_STEPS] = {
/* "0" */ {36, 43, 48,},
/* "1" */ {48, 52, 55,},
/* "2" */ {55, 57, 60,},
/* "3" */ {60, 72, 64,},
/* "4" */ {62, 64, 69,},
/* "5" */ {64, 67, 76,},
/* "6" */ {67, 72, 79,},
/* "7" */ {69, 45, 81,},
/* "8" */ {72, 48, 60,},
/* "9" */ {79, 67, 55,},
};

I’m not sure of the application of this yet, and if I’m not careful it essentially becomes random as there are too many note and step combinations to keep track of!  But it might be a fit of fun with the right sets of notes.

The example code shows both.  The simplest case just has NUM_STEPS set to 1.

Find it on GitHub here.

Closing Thoughts

I couldn’t resist doing something fairly straightforward with MIDI now I had the basics sorted and I’m pretty pleased with these results.

Building on this, ideally I’d get that rotary dial handling code refactored off into its own library somehow to allow it to be used in more applications.

Kevin

Leave a comment