Background

Robinhood is an anti-capitalist, community-based project that currently runs two grocery stores in Berlin. Instead of accumulating capital, as regular businesses do, the stores donate 100% of their profits to fight extreme poverty and climate change.

Employees and volunteers are always present in the store to explain the Robinhood concept to newcomers. In addition, the founders had the idea of putting an old rotary dial phone in front of the store, where people can sit down, compose a number, and hear a short recorded presentation of what Robinhood is about. Depending on the number, the explanation is given by different people and/or in different languages. This project details how the rotary phone was modified to achieve that goal.

This blog post was very helpful during the project.


System design

On the diagram above, the original phone components are on the left, and the green dashed line symbolizes what is enclosed in the phone case.

Phone circuits

The phone's original electronics are quite straightforward. Several parts aren't useful for this project (specifically the phone line and the ringing circuitry in the lower part of the case), so I'm not going to describe them.

Hardware

Components

The hardware selection is the following:

Schematic

Wired perfboard

Assembled phone

The perfboard with Crumb168 and audio board (upside down compared to the perfboard picture above), plus the LiPo battery, fit where the ringing circuit and the bells used to be. I set up a USB cable connected to the audio board and coming out of the back of the phone case. Placing the board's USB port near one of the phone's preexisting openings wasn't possible, and I didn't want to cut a new opening somewhere for fear of damaging the case.

Software

The software is available on GitHub. I tried to match the phone's behavior to what an uninformed user could expect: you pick up the phone, hear a dial tone, dial a number, listen to what your interlocutor says, they hang up, you hear a busy tone, you hang up. There are a few timers here and there, for example to wait a few seconds between the other side hanging up (i.e. the audio file ending) and playing the busy tone, because it makes for a less abrupt experience.

Decoding dialed digits

Possibly the only non-trivial part when developing the software was decoding the dialed digits. As mentioned earlier, the dial provides a signal indicating that dialing has started, and the other encodes the dialed digit. Both signals are referenced to the common wire. In this project, "common" is tied to ground, and the two signal wires are connected to two separate MCU pins configured with pull-up resistors. This gives the graphs pictured above.

There is a normally open switch between the dialing wire and the common wire. The switch closes when the user turns the dial clockwise (i.e. starts dialing a digit, t0 on the graph). It opens again some time after the dial is released. On this phone model, the switch opens again before the dialing is finished (i.e. before the dial has gone back to its original position).

Conversely, there is a normally closed switch between the digit wire and the common wire. While the dial turns back to its original position (between t1 and t2), the switch opens once for each digit increment. For example, the graph above shows that the signal has 6 edges (rising or falling, it doesn't matter) while the wheel is turning back, which encodes the digit 6.

The software only starts monitoring the dial signals while the dial tone is playing. First, the signals are debounced with an algorithm based on this post by Jack Ganssle. I found experimentally that the signals can be considered stable if they kept the same level for at least 5 samples at a sampling period of 5 ms.

When a falling edge occurs on the debounced "dialing" signal, the program starts counting the edges of the "digit" signal. Every time a digit is successfully decoded, it is stored as part of the dialed number. The software keeps monitoring the dial signals as long as any edge has happened not too long ago (in the current version, 3 seconds). Once that delay has passed without any activity, an internal state indicates that a complete number is ready to use.

Communication between MCU and audio board

Adafruit's audio board can be controlled by serial communication, as explained in the tutorial. I used AVR-UART-lib to set up the MCU's UART0. The software provides a function to play an OGG file stored on the audio board's flash memory by name. Together with the number decoding described above, this enables matching a number to an audio file. For example, if the number "157" is dialed by the user, the MCU asks the audio board to play the file "157.OGG". If the file doesn't exist, the software makes the audio board play the busy tone.

Limitations

Summary

The phone is used intuitively like a real phone. New audio files linked to an arbitrary number can be stored on the audio board's Flash memory via the USB cable at the back, without having to change anything to the software.

It was a fun little project, and I heard that people visiting the store enjoyed using the phone. Working with ye olde electronics like this is pretty cool, because all the components are easy to understand, and you can see that everything is assembled by hand. Plus, the feeling of using a rotary dial is very satisfying :)