+ = ?
We're off to Hacking At Random next month, where the nice folks from EventPhone will be running the customary DECT network providing wireless digital telephony to a few thousand geeks camping out in a field.
In the past we've each taken a DECT handset from our respective homes which we've dutifully carried around, but this year I thought it'd be nice to provide a telephone which we could use in our home-from-home: the Echo Base village.
You could be forgiven for thinking that this task should only really involve finding another handset to leave on the table in our shared living-room-tent, and fundamentally you'd be right. However, being British and thereby genetically predisposed to going to unreasonable lengths to bring civilisation to a muddy field in a faraway land, I wanted something a bit homelier, and nothing says homelier in a more homeliererer way than the sweet tinkling ring of a 1960's GPO rotary telephone.
A very nice lady on Freecycle gave me a cream GPO model 746 phone (just like the one above) for the eminently reasonable price of free, and I picked up a Phillips CD245 DECT handset from ebay for a couple of quid. So far so good. Since I wanted to this to be a portable phone I ordered a 1100mAh LiPoly battery and charger board from RoboSavvy, along with an Arduino Pro Mini, and a USB Serial breakout board for programming and debugging.
To make the ringer work I figured it was unlikely that I'd want to re-use the original whacking great big solenoid arrangement which is built like a soviet tank but likely to flatten my little LiPo battery after just a couple of incoming phone calls, so instead I ordered a few replacement mobile phone vibrate motors from the interwebs for a couple of quid, despite not yet being entirely sure about how I was going to use them.
First things first: the dialer
After ripping the rotary phone apart and giving it a damn good clean, I decided to start with working out how to decode the rotary dialer.
It turns out that the dialer is a marvelous bit of design:
The white wheel in the middle is connected to the finger wheel on the front (where you poke in your finger and turn to dial a number), and when you release the wheel and allow it to rotate back to its home position, the cam peaks around the edge of the wheel push against the little white lever you can see on the right, which in turn momentarily breaks a connection between two of the wires leading into the unit. There is one cam-lobe per number on the front, and sure enough when you dial 5 on the front, the little white lever causes 5 momentary breaks in the circuit.
That magical little white wheel has another trick up its sleeve too: on the face of the wheel there's a small sticky-outy bit -- please forgive my use of deep technical jargon -- which holds a spring switch closed when the dial is in its home position, but when you rotate the dial to dial a number, the spring switch is allowed to remain open until the dial rotates fully home.
Here's a plot from my 'scope which makes things a lot easier to see:
The upper trace shows the output of the switch on the right which counts the number the user dialed, the lower trace is the rotor-is-at-home-position signal. On the left you can clearly see where I started dialing by rotating the wheel, then I pulled my finger out and let go and you see the 5 pulses on the right, quickly followed by the home signal going high again.
With these two signals I'll be able to know when the user has dialed and number, and which number they dialed.
Next: How to spoof key presses on the DECT handset ?
Unfortunately there isn't yet a Pokie-Finger Arduino shield, so I had to find another way to spoof the key presses on the handset.
To scan a bunch of keys you could have a wire for each key which you watch to see if they has been pressed, but people worked out a long time ago that you can do it cheaper if you arrange the key connections in a matrix and multiplex the scanning. What this means is that for a 3x4 matrix (like a phone keypad) you'd have 4 outputs (say A to D) and 3 inputs (1-3) arranged as a grid, with a key at each intersection. To scan for key-presses you bring output A high and then check each input in turn, if you see a non-zero voltage on an input then you know that the pressed key must be connected to output A and the input on which you saw the voltage, otherwise you put output A low and bring output B high, check each input, and so on.
Armed with my trusty multimeter set on continuity beep mode, I traced the key matrix on the circuit board of the DECT handset, this is what it looks like:
Using my 'scope I found out that the Orange, Red, Light Green, and Purple lines were the outputs, and the other lines the inputs.
Here's a scope plot of two of the output lines, it seems that there's some sort of synchronization pulse which goes out on all lines simultaneously, but just after that you can see the real key scanning pulses which are indeed staggered as expected.
So, the obvious way to spoof key-presses would be to have an NPN transistor connected across each of the key connectors, then applying a small voltage to the base of the transistor would allow it to conduct the scanning pulses through, so in theory it should be almost indistinguishable from the real thing.
This would work, but maybe there's a better way...
Since I'm using a Arduino as the brains of this project, rather than pass on the actual key scan pulse, I can connect the handset's output and input lines directly to my Arduino, detect when the scanning pulses are present and then if I want to press a key I can bring high the Arduino pin connected to the handset input line which corresponds to the key I want to "press". It turns out that this works fine, but is very timing sensitive, so much so that while I could use the PinChange interrupt to detect the start of the keyscan pulse, I needed to have a tight busy loop inside the ISR to copy the pin state to the right output. This is fine though because we'll only be in this state for short amounts of time, and only when we're trying to dial a number on the handset.
With the approach sorted, I used the multimeter to find points on the reverse of the DECT handset circuit board which were connected to the various key contacts - these turned out to be a mix of test points and through-hole vias, so without further ado I soldered a bunch of fly leads to the newly discovered points:
On/Off hook switch:
I decided the easiest thing to do here was to re-use the existing micro-switch setup which I removed from the original board and placed onto some prototyping board.
The original ringer in these phones consists of a hammer striking against two bells. The hammer itself is moved by two great big solenoids which are driven by the 50v ringing voltage which is sent down the line when there's an incoming call. I'm sure it'd be possible to build some sort of ladder circuit to generate the required voltage to drive the solenoids from my 3.7v battery, but I think the current necessary to shift the weight of the hammer around would not be good for the battery life of the phone.
Instead, I ordered a couple of of the vibrating motors that you find inside mobile phones and pagers, and I constructed a pair of spring mounts which would hold the motor heads next to, but not quite touching, the edge of the bells. When voltage is applied to the motors and they spin up, the vibration on the end of the springy mount causes the motors to shift about by 4-5mm which brings the head into contact with the bell edge. For now it seems to work quite well, although I suspect that the stress of the collisions of the spinning weight and the bell probably doesn't bode well for the longevity of the motors. On the other hand they were only a quid each...
To drive the motors, I used a couple of BC485 NPN transistors switched by a couple of Arduino outputs. I kept the motors on separate outputs so that I could vary the duty time of each motor to make distinct ring sounds that could be used to indicate status etc., currently I just drive them in unison.
It turns out, by the way, that in the UK the BT standard ringer pattern is 0.4s on, 0.2s off, 0.4s on, 2s off, rinse, repeat.
Detecting incoming calls
I spent quite a while poking around with my 'scope trying to find a way to detect when the DECT handset was in ringing mode, I found some very bizarre 4-level digital signaling going on, but nothing particularly useful, until I came across a signal that does almost what I'm after.
Again, I used the pin-change interrupts to monitor this pulse, by saving off the count from one of the Arduino's timer registers at the rising edge, and comparing it with the current timer count at the falling edge we can determine the pulse length asynchronously.
Pulling it all together
Now it was just a matter of fixing everything together, I used the prototyping board which holds the off-hook micro-switch as a base, mounted the Arduino to it using a bunch of pins soldered through, and soldered the various fly leads in to the appropriate places.
I reused the grommet from the phone socket lead to make a power socket housing which fits in more-or-less with the style of the rest of the phone.
Put it all back together, and voilà !
In case you're interested or you want to make your own Rotary DECT Phone, the source code for the Arduino is available here.