Ok, this has been done before, but anyway – here's my take on it! Most conversions have been pretty invasive on the vintage phone. I wanted a simple and clean conversion, keeping the phone intact and the mess inside to a minimum. The biggest issue would be supplying high voltage power to the bell ringer, but searching for solutions I stumbled upon the thing called SLIC – Subscriber Line Interface Circuit. Basically it would supply the phone with a built in local phone line, taking care of ringing and everything. The cheapest one I could find was the QCX601, so I ordered one of those. Hooked it up to an Arduino Pro Mini with code based on the datasheet specs, together with a SIM800 breakout module, and it worked like a charm! Well, almost :) When routing the audio with everything else via the SLIC, there was a horrible amount of GSM interference in the receiver during calls. Oh, well... no biggie. When connected directly to the SIM800 board, the interference was gone.
Now this needed some more attention. The switch hook pin (SHK) of the QCX601 not only tells us if the receiver is on hook or not. Due to the way pulse dialing works, it also presents us with the pulses from the rotary dial. To keep track of everything that's happening on that pin, we have to do some timing work again.
With the receiver on hook SHK is LOW, and off hook SHK is HIGH, so pulses coming in will be SHK going low about 60 milliseconds for every pulse. If the time since the last pulse is more than 500 ms we know we just got a complete digit. For accuracy and immunity against false pulses we want 10 to 15 ms of debouncing, so that's another timing thing to the list. To know when we have a complete number, we assume that ten digits is a complete number (you can easily change this) and if the number is shorter, it will be dialed anyway if there are no new pulses for six seconds. Finally, if we put the receiver back on hook for two seconds or more, the dialing should be aborted and we should go back to the idle state. So, we have a bunch of timings to define...
#define tNewDig 500 // time since last SHK rising edge before counting for next digit#define tHup 2000 // time since last SHK falling edge before hanging up/flushing number#define tComplete 6000 // time since last SHK rising edge before starting call#define tDebounce 15 // debounce time
And then the code being looped while in the number getting state:
// count groups of pulses on SHK (loop disconnect) until complete number// if single digit, fetch stored number// then make callif (pulses && (unsignedlong)(currentMillis - lastShkRise) > tNewDig) {
// if there are pulses, check rising edge timer for complete digit timeout
digit = pulses - 1; // one pulse is zero, ten pulses is nine (swedish system)// for systems where ten pulses is zero, use code below instead:// digit = pulses % 10;
Serial.println(digit); // just for debug// add digit to number string
number += (int)digit;
digits++;
pulses = 0;
}
if ((shkState == LOW) && (edge == 0)) {
edge = 1;
} elseif((shkState == HIGH) && (edge == 1)) {
pulses++;
Serial.print(". "); // just for debug . . . . .
edge = 0;
}
if ((digits && (shkState == HIGH) && ((unsignedlong)(currentMillis - lastShkRise) > tComplete)) || digits == 10) {
// if completed number (full 10 digits or timeout with at least one digit)// check if shortnumber/fave and then tell GSM board to initiate call if (digits == 1) getFave();
Serial.print("Number complete, calling: ");
Serial.println(number);
number.toCharArray(numArray, 11);
#if defined(GSM_MODULE)
call.Call(numArray);
#endif
state = ACTIVE_CALL;
}
if ((shkState == LOW) && (unsignedlong)(currentMillis - lastShkFall) > tHup) {
// reciever on hook, flush everything and go to idle state
flushNumber();
Serial.println("On hook. Flushing everything. Going idle.");
state = IDLE_WAIT;
}
Like that. As you can see, I also put in a speed dial function where single digit numbers are checked against a list with the getFave() function and replaced with complete numbers. Also, you can see the default state of the code is for use with Swedish phones where the dial goes from 0 to 9. That's the line saying...
digit = pulses - 1;
Most likely you don't want that, so you should use this line instead...
digit = pulses % 10;
That % in there (modulo) makes the digit value the remainder when dividing the number of pulses by ten. Basically it's using wrap around to get 0 instead of 10. I stole this little gem, I admit that. Looks so much nicer than the if-based alternative, and I got smarter by looking the % thing up ;)
As for the debouncing of SHK, it's done whatever state we are in, and it looks like this. The currentMillis used for all timings is set here too.
currentMillis = millis(); // get snapshot of timefor debouncing and timing
// readand debounce hook pin
currentShkReading = digitalRead(shkPin);
if (currentShkReading != lastShkReading) {
//reset debouncing timer
lastShkDebounce...
Ok, so the main things I had to do dealing with the SLIC module was to have it create the ring signal, and to make the pulses and states of the switch hook pin control the actions of the phone. The ringing was the easier part, as it was pretty much exactly described in the QCX601 datasheet.
Early on I had decided to base my code on timings using the millis() function, so the "ringing" took this form, based on that diagram:
// Ringing interval // How much time has passed, accounting for rollover with subtraction!if ((unsignedlong)(currentMillis - ringPreviousMillis) >= ringInterval) {
digitalWrite (rcPin,1); // Ring// Use the snapshot to set track time until next event
ringPreviousMillis = currentMillis;
}
if (digitalRead(rcPin) && ((unsignedlong)(currentMillis - ringPreviousMillis) >= ringDuration)) {
digitalWrite(rcPin, 0); // Silent after ring duration
}
// 25Hz oscillation // How much time has passed, accounting for rollover with subtraction!if ((unsignedlong)(currentMillis - oscPreviousMillis) >= oscInterval) {
// It's time to do something!if (digitalRead(rcPin)) {
digitalWrite(hzPin, !digitalRead(hzPin)); // Toggle the 25Hz pin
}
// Use the snapshot to set track time until next event
oscPreviousMillis = currentMillis;
}
The rflPin is set to be LOW all the time, and the timings are defined like this for typical Swedish ringing:
Plan the placement of components inside the telephone. I had no
problem fitting the SIM800 mini board with antenna on the right, and the
rest of the stuff on the left side. Using perf board, you can create a
nice and compact PCB to fit in there, maybe even screw in place with a
bracket.
2
Step 2
Program your Arduino Pro Mini. You need to download and install the SIM900 library first. Then you edit the project Arduino code to set these two things:
1: The kind of rotary dial you have. In Sweden where I live, the dial starts with 0 and ends with 9. This means that one pulse sent is a zero, and ten pulses equals number nine. If this is the case with your phone, you don't have to change anything. Otherwise, you edit the code where it says..
digit = pulses - 1; // one pulse is zero, ten pulses is nine (swedish system)
//for systems where ten pulses is zero, use code below instead:
// digit = pulses % 10;
...into...
//digit = pulses - 1; // one pulse is zero, ten pulses is nine (swedish system)
//for systems where ten pulses is zero, use code below instead:
digit = pulses % 10;
That way, it sets the digit to the number of pulses sent, unless there are ten pulses, in which case the digit should be zero. 2: Set your own favourite numbers in the getFave() function for speed dial. Just edit the numbers. Add more favourite numbers if you like. Just follow the pattern of the previous numbers. (To use a speed dial, you pick up the receiver, dial the single digit number and wait six seconds for number collection routine to time out. You can set a shorter time out if you want to. It's the tComplete number in milliseconds in the code.)
Hook up your Pro Mini using the FTDI programmer and upload the sketch.
3
Step 3
Solder stuff together (or use pins and dupont connectors where suitable) according to the schematic. Using a socket for the Pro Mini is a good idea. Makes it easy to replace it or remove it for re-programming.
The project seems interesting - however I think I’m taking the easy way out to give my Ericsson Dialog new life in 2019 - I’m connecting it to a GSM gateway that understands pulse dialing. The questions I have are -
1) is the voltage (12V or so) a regular gateway would supply enough to ring the bell of the Dialog?
2) I’m stuck at the very first step - how to open the phone for replacing the phone socket plug wire with a modular plug wire? How do you open this thing?
I know it has been some time since you completed and posted your conversion but if you by any chance still remember/reads this thread. I would like to know if you had to do anything about the original speaker in the phone? Did you swap it for another speaker element or are you using the original one? And how are you driving it? When i drive mine straight from my Adafruit Phona, the volume is still so low that its basically impossible to hear anything :)
Hi, I guess that depends a lot on how hard the speaker element is to drive, and what the Adafriut Phona is capable of. I used the original speaker, and it worked fine with the GSM board I was using. If you are using a SLIC board like I did, you could try running the audio through the SLIC, not removing the handset wires from their original screw posts in the telephone. I got more interference that way, but it worked that too.
ola
I am building this
but it has problems reconizing the on-hook switch
and the serial gets spammed with sim900 data
can you help me?