Phone-Modding Part 4 – The End?

Previously on…

All right. Time to open the last page:

First up, connecting the handset to the amplifier. See the photo:

I cut the wires from the jack for the handset, stripped the two that were for the speaker, added some shrink tubing (probably unnecessary) and connected them to the out jacks on the amplifier. I don’t think it matters which is which, or I got lucky. I believe the other two wires are for the microphone. I wasn’t able to disassemble the handset to be sure, but it worked fine.

Next, the switch hook connection. Again, this ends up being a lot easier with a newer phone.

This was a bit more complicated. There is a connection between the EN pin on the Feather and ground that will either be connected or disconnected when you set the handset down on the cradle. I’m still a little confused as to the reason. I feel like there should be a connection from EN(able) to ground to make it work. But there’s not normally a connection to that, so it would never work. It appears that the connection of EN to ground kills the program.

The switch itself has different connectors that are normally open or normally closed that change position with the handset is put in the cradle. I managed to find the two pins on this switch that made it work.

Last connection is for the regular USB power.

The usb cable is threaded through the hole in the back that would normally be where the phone connects to the wall. I tied a knot in this to prevent tension on the USB cable from possibly disconnecting the pins. The cable has all the pins a USB cable would need, but we only need two. First, the red wire is our 5 volt source that will power everything up for us. That needs to connect to the USB pin on the Feather. The black wire needs to connect to our ground.

And that’s it. Make sure the jumper wires don’t get in the way of the cradle switch. Put the keypad back in position. Connect the handset to the handset jack. And put the top of the phone back on. Screw it all back together, and you’re done. Plug the usb cable into something that’ll give it power, lift the handset, and it works!



Next up, troubleshooting.

Phone-Modding Part 3 – Circuitry and Phone Guts

Previously on Phone-Modding

Next up we’re going to take that phone apart! But first, remember to refer to the source!

So it shows the circuit a few different ways. There’s an illustration of the circuit on a breadboard. (is it right? I’m not sure!) There’s a diagram! (Is that right? Some is, but some is definitely broken!) Then there’s a bunch of pictures. (How about those? They’re what I used, so yes?)

The first set of photos are for the amplifier. You should have already soldered a set of 5 pins to this, and two pins for the audio out connector. The 5 pins are (left to right) A+, A-, SD, Vin, Gnd. A- and Gnd need to get to a common ground. Vin connects to a 3 volt source. And SD doesn’t need to connect to anything. A+ connects via a series of two resistors to the TX connector on the Feather. Between the two resistors place the capacitor, and connect it to ground. Note the capacitor has a positive and negative side. Negative side goes to ground.

Next is the keypad. The instructions have a lot of desoldering and adding pins, etc. None of that is necessary.

Looking at the second photo first, you can see the rows and columns of the keypad next to the cable (while they are labeled in this case, they may not be. See upcoming “Troubleshooting” page for help if they aren’t). If you look at the first photo, you can see the end of the cable popping up behind the keypad with a bunch of jumpers going into it.

Also, as you can see in the phone here, I have removed everything except for the connector for the handset, the connector and switch for the disconnect hook, and the keypad. You can get rid of everything else. You’re going to need that space for the little self-adhesive breadboards.

Anyway, one nice thing about not doing it the way they say to, is it doesn’t lock you into using the pins on the Feather that the instructions recommend. And one of the reasons that we want to avoid that is that the SD card interface likes to use some of the pins that the instructions use for the keypad. To summarize:

Keypad Columns/RowsInstructions My Circuit
Connect jumpers from the keypad cable to the Feather.

Since we’re here, lets also talk about the SD card reader.

Once you solder the pins onto the board, you may be confused, since there are a LOT of pins. You only need the first six. 3V, Gnd, Clk, SO, SI, and CS.

3V connects to the same 3 volt source you’re using for the amplifier. That also connects to the 3V pin on the Feather. Gnd connects to the same ground you’re using for the amplifier. Again, this also connects to the Gnd pin on the Feather.

CLK connects to the SCK pin on the Feather. SO connects to the Feather’s MI pin. SI connects to the MO pin. (Remember MISO and MOSI). Finally, the CS pin needs to connect to a data pin on the Feather. I used D10.

Side note: Some of the pins on the Feather use the same data addresses. My understanding is that this could theoretically cause issues if you have two pins with the same address trying to operate at the same time. I chose all the pins so that they wouldn’t conflict with any other pins.

Next up, More Phone Guts?

Phone-Modding Part 2, the Python and the Program

Part 1

Again, I highly recommend reviewing the previously linked site for how to get python up and running. Here’s a link to the next section:

I followed the instructions on here closely and had no problem getting python running and connecting to the board. I used a short USB type C connector to connect the feather to my computer. I never needed to use safe mode or anything. It just worked.

Next is the code:

I highly recommend getting Mu, which is a tool to assist in programming with python on boards like this. Here’s a link with help on doing that:

In the video I posted, showing the system working, I am using Mu. I have the program stopped at the beginning, and then using the REPL, I start the program, which causes the dial tone to start playing. Basically, you connect your Feather to the computer. You start Mu. You open a serial connection to the Feather in Mu. And finally, you hit Ctrl-C to stop the program. You hit Ctrl-D to restart it.

Another great thing about Mu is that it will check the code for you. For example, several of the lines in the code provided are too long according to Mu. Also, be careful with spaces around comments.

In addition to the code provided with the instructions on building the phone, we also need code for our SD Card reader. Here’s where I went for help:

Which is different from this:

Note that there are a number of confusing and contradictory bits. The code I ended up using seemed the simplest, and it ultimately worked.

Returning to the main guide for the phone, the last thing mentioned on the program page is regarding modifying audio files so that they’ll work with the program.

Make sure you follow the instructions closely when making your audio files. I accidentally used a 24000 hz instead of 20000 hz for one file, and the program wouldn’t open it.

Finally, here’s the code I used. It works so far.

# SPDX-FileCopyrightText: 2022 John Park for Adafruit Industries
# Modified By Ariock for beekeepers
# SPDX-License-Identifier: MIT
# DTMF keypad phone Dial-a-Song
import time
import random
import board
import keypad
from audiocore import WaveFile
from audiopwmio import PWMAudioOut as AudioOut  # for RP2040 etc
import audiomixer
import busio
import sdcardio
import storage

# Use the board's primary SPI bus
# spi = board.SPI()
# Or, use an SPI bus on specific pins:
spi = busio.SPI(board.SCK, board.MOSI, board.MISO)
# old spi = busio.SPI(board.SCK, MOSI=board.MOSI, MISO=board.MISO)
# spi = busio.SPI(board.SD_SCK, MOSI=board.SD_MOSI, MISO=board.SD_MISO)

# For breakout boards, you can choose any GPIO pin that's convenient:
cs = board.D10
# Boards with built in SPI SD card slots will generally have a
# pin called SD_CS:
# cs = board.SD_CS

sdcard = sdcardio.SDCard(spi, cs)
vfs = storage.VfsFat(sdcard)

storage.mount(vfs, "/sd")

# time.sleep(3)  # let USB settle during development, remove when on battery

km = keypad.KeyMatrix(
    # 2500 phone ignoring first column store/redial/memory. reverse mount Feather RP2040
    column_pins=(board.A3, board.A2, board.A1,),

numbers = {
            "8675309" : "songs/beepbox.wav",
            "6358393" : "songs/streetchicken.wav",
            "5551212" : "songs/carpeter.wav",
            "7654321" : "songs/daisy.wav",
            "9255292" : "/sd/week1_subject2.wav",  # walkawa
            "2772643" : "/sd/week1_subject3.wav",  # arrange
            "2696338" : "/sd/week1_subject1.wav",  # boymeet
            "4423273" : "/sd/week1_subject5.wav",  # ihadare
            "9486377" : "/sd/week2_subject2.wav",  # witness
            "7332888" : "/sd/week2_subject3.wav",  # redbutt
            "4376636" : "/sd/week2_subject1.wav",  # ifsomeo
            "6537743" : "/sd/week2_subject5.wav",  # oldspie
            "8446546" : "/sd/week3_subject2.wav",  # thinkin
            "2442536" : "/sd/week3_subject3.wav",  # chicken
            "8293778" : "/sd/week3_subject1.wav",  # taxessu
            "2762259" : "/sd/week3_subject5.wav",  # apocaly
            "2443640" : "/sd/week4_subject2.wav",  # bigdog0
            "8682559" : "/sd/week4_subject3.wav",  # totally
            "2834800" : "/sd/week4_subject1.wav",  # audit00
            "7327848" : "/sd/week4_subject4.wav",  # recruit
            "3644620" : "/sd/week4_subject5.wav",  # enigma0
            "2264000" : "/sd/week5_subject2.wav",  # bang000
            "2274660" : "/sd/week5_subject3.wav",  # casino0
            "2765343" : "/sd/week5_subject1.wav",  # asoldie
            "9333464" : "/sd/week5_subject4.wav",  # wedding
            "3333464" : "/sd/week5_subject5.wav",  # feeding
            "4232732" : "/sd/week6_subject2.wav",  # icecrea
            "2332470" : "/sd/week6_subject3.wav",  # affair0
            "7867699" : "/sd/week6_subject1.wav",  # stormyw
            "5867370" : "/sd/week6_subject4.wav",  # jumper0
            "6926672" : "/sd/week6_subject5.wav",  # myconsc
            "2444373" : "/sd/week7_subject2.wav",  # biggerd
            "9276463" : "/sd/week7_subject3.wav",  # yasmine
            "7533777" : "/sd/week7_subject1.wav",  # sleepsp
            "5278786" : "/sd/week7_subject4.wav",  # laststo
            "3475662" : "/sd/week7_subject5.wav",  # diploma
            "3863725" : "/sd/week8_subject2.wav",  # funeral
            "2672547" : "/sd/week8_subject3.wav",  # coralis
            "4475423" : "/sd/week8_subject1.wav",  # girlhad
            "6965353" : "/sd/week8_subject4.wav",  # myoldke
            "7378587" : "/sd/week8_subject5.wav",  # results
            "2797825" : "/sd/week9_subject2.wav",  # crystal
            "3384500" : "/sd/week9_subject3.wav",  # devil00
            "7383693" : "/sd/week9_subject1.wav",  # sevenye
            "2526246" : "/sd/week9_subject4.wav",  # clamcho
            "9687325" : "/sd/week9_subject5.wav",  # youreal
            "5646464" : "/sd/week10_subject2.wav",  # joining
            "3264597" : "/sd/week10_subject3.wav",  # familyr
            "5377397" : "/sd/week10_subject1.wav",  # jerseys
            "7358282" : "/sd/week10_subject4.wav",  # relucta
            "8742645" : "/sd/week10_subject5.wav",  # triangl
            "4376370" : "/sd/week11.wav",  # heroes0
            "6637646" : "/sd/week12_subject2.wav",  # onepoin
            "3426233" : "/sd/week12_subject3.wav",  # fiancee
            "5878254" : "/sd/week12_subject1.wav",  # justali
            "7328466" : "/sd/week12_subject4.wav"  # section

ringing = "songs/full_ring.wav"
wrong_number = "songs/blank_number.wav"
dial_tone = "songs/dial_tone_loop.wav"
busy_signal = "songs/busy_loop.wav"

button_tones = [
                "dtmf/tt_1.wav", "dtmf/tt_2.wav",  "dtmf/tt_3.wav",
                "dtmf/tt_4.wav", "dtmf/tt_5.wav", "dtmf/tt_6.wav",
                "dtmf/tt_7.wav", "dtmf/tt_8.wav", "dtmf/tt_9.wav",
                "dtmf/tt_star.wav", "dtmf/tt_0.wav", "dtmf/tt_pound.wav"

digits_entered = 0  # counter
dialed = []  # list of digits user enters to make one 7 digit number
dialed_str = ""  # stores the phone number string for dictionary comparison

audio = AudioOut(board.TX)  # PWM out pin
mixer = audiomixer.Mixer(
mixer.voice[0].level = 1.0  # dial tone voice
mixer.voice[1].level = 1.0  # touch tone voice
mixer.voice[2].level = 0.0  # song/message voice
mixer.voice[3].level = 0.0  # busy signal

wave_file0 = open(dial_tone, "rb")
wave0 = WaveFile(wave_file0)
mixer.voice[0].play(wave0, loop=True)  # play dial tone

wave_file2 = open(wrong_number, "rb")
wave2 = WaveFile(wave_file2)

wave_file3 = open(busy_signal, "rb")
wave3 = WaveFile(wave_file3)
mixer.voice[3].play(wave3, loop=True)  # play dial tone

def reset_number():
    # pylint: disable=global-statement
    global digits_entered, dialed, dialed_str
    digits_entered = 0
    dialed = []
    dialed_str = ""

while True:

    event =  # check for keypad presses
    if event:
        if event.pressed:
            mixer.voice[0].level = 0.0  # mute the dial tone
            wave_file1 = open(button_tones[event.key_number], "rb")  # play Touch Tone
            wave1 = WaveFile(wave_file1)
            if event.key_number == 9 or event.key_number == 11:  # check fr special keys
                if event.key_number == 9:  # pressed the '*' key
                    reset_number()   # or make some cool new function for this key
                if event.key_number == 11:  # pressed the '#' key
                    reset_number()  # or make some cool new function for this key

            else:  # number keys
                if digits_entered < 7:  # adding up to full number
                    # convert event to number on the keypad button, add to string
                    if event.key_number < 9:  # 1-9 on keypad
                    if event.key_number == 10:  # the 0 key, ignore '*' and "#'
                    dialed_str = "".join(str(n) for n in dialed)
                    digits_entered = digits_entered + 1  # increment counter

                if digits_entered == 7:  # a full number has been entered
                    if not mixer.voice[2].playing:
                        dialed_str = "".join(str(n) for n in dialed)
                        if dialed_str in numbers:  # check if string is in directory
                            value = numbers[dialed_str]

                            wave_file2 = open(ringing, "rb")  # ring before it answers
                            wave2 = WaveFile(wave_file2)
                            mixer.voice[2].level = 1.0
                            mixer.voice[2].play(wave2, loop=True)

                            time.sleep(random.uniform(4.0, 9.5))  # random ring b4 answr

                            wave_file2 = open(value, "rb")  # answered
                            wave2 = WaveFile(wave_file2)
                            mixer.voice[2].level = 1.0
                            mixer.voice[2].play(wave2, loop=True)

                        else:  # number is not in directory
                            weighted_coin_toss = random.randint(0, 4)
                            if weighted_coin_toss < 3:  # favor the "not in service" msg
                                mixer.voice[2].level = 1.0
                                mixer.voice[3].level = 1.0


                    if mixer.voice[2].playing:
                        reset_number()  # stop #s dialed during play doing anything

The next section is on modding the phone itself.

Modding a Touch-Tone Phone to Play .wav Files

Happy 20th anniversary of ilovebees! I was thinking about this the other day and as my mind wandered, I thought, “Wouldn’t it be cool if you could have a touch tone phone, and if you dialled a number, it would play one of the audio clips from the ARG?” And then I searched for it, and found this link:

Later I found a better link. The one above has broken links to the software needed, but this one works better:

And after a month on and off (mostly off) I have a working phone. Check my instagram for a video of the working circuit/program.

I’m going to get more detailed about what I did, what worked, what didn’t, what had to change, etc. so if you’re interested in doing this yourself, you’ll avoid the problems I ran into. Probably the big one for me is that I had no experience soldering electronics. It is not easy. It is absolutely necessary. But it is nowhere near as necessary as I made it. I ruined a couple of electronics components because I tried to pack too much into a small space.

Let’s talk about the bits and bobs you’ll need to make this. Refer to the website above.

  1. Adafruit Feather RP2040. Absolutely necessary. Comes with a set of posts that you’ll need to solder to the board. This is necessary, but if you’re careful, not terribly difficult. (<$20)
  2. Featherwind Doubler. Not necessary. It comes with some items that can make your life easier. Instead of the posts that come with the Feather, it has headers. Basically posts that have openings on the other end that other posts (or jumper wires) can be put into.
  3. Audio Amplifier. Necessary. Also comes with posts. And a connector for the phone receiver. (<$10)
  4. Battery. Not necessary. I got it, plugged it into the board far too early, and burned out the board. You need to be done before you plug the battery in. It may be obvious to you, but it wasn’t to me.
  5. Terminal Blocks and Wire ferrules. Both unnecessary.
  6. USB Adapter. Necessary. This is nice because the wires have connectors like the headers. (<$20)
  7. Jumper Wires. Necessary if you want to minimize soldering. (<$10 for over 100 jumpers)
  8. Resistors/Capacitors. Necessary. I had these from other kits I’ve gotten over the years. (<$30 for hundreds of resistors and 10 capacitors)
  9. Telephone. Obviously. I didn’t get the model they have here. I went with “Home Intuition Classic Corded Phone for Hearing Impaired Telephone for Seniors with Extra Loud Ringer” from Amazon. One nice thing about it is that it’s a newer phone, so a lot of the connectors inside will easily accept jumper wires from item 7 above. (Approx $40)
  10. Another thing I recommend getting is several Mini Breadboards. They can take the place of the Doubler in item 2 above. Again, I had several of these from previous kits. They are great because they have an adhesive backing that allows you to easily attach them inside the phone. (<$10 for six)
  11. For this project you’re also going to need a “MicroSD SPI or SDIO Card Breakout Board” (Get one that is only 3 Volts, not 5V) and a MicroSD card to hold all of the files. It turns out that the Feather has very limited onboard memory. The project is designed/programmed to play wav files and not mp3s. Even if playing of mp3s was possible, they’re still too large to fit on the Feather. All of the ARG audio files as mp3s are a total of 130 MB, and after converting them to wavs, they’re 819 MB. (<$20 for the board and a 32 GB MicroSD)

Total price is pretty close to $150 (assuming you have solder and a soldering gun, spare USB cables to plug the feather into your computer, a computer, etc)

I’m going to make this guide parallel the source material, with each section making up another page. Next up, the Python and the Program