Hi,
I am currently attempting to wire up a GPO746 rotary dial phone to an Arduino Mega for part of a part I am organising.
I am very new to this, so any help would be greatly appreciated.
The idea is to dial a correct number sequence (62442) to play an audio file from an SD card module. Any other five digit number dialled will play an alternative audio file from the SD card.
I have followed the instructions on this video; Call Me! Rotary Telephone + Arduino Escape Room Puzzle - YouTube which uses a vintage GPO746, mine is a new one.
When I use this code;
#define DEBUG
#include <SPI.h>
#include <SD.h>
// buffSize declaration in pcmComfig.h was increased to 254 to reduce crackle
#include <TMRpcm.h>
const byte phonePin = 6; // Red wire from phone
const byte hookPin = 8; // Green wire from phone
const byte chipSelectPin = 53;
const unsigned long debounceDelay = 5; //ms
const unsigned long maxPulseInterval = 500; // ms
const int numDigitsInPhoneNumber = 5;
//GLOBALS
TMRpcm tmrpcm;
//the char representation of the number dialled to (1+ to allow for string-terminating character \0)
char number[numDigitsInPhoneNumber + 1];
//the digit currently being dialled
int currentDigit;
//how many pulses have been detected for the current digit
int pulseCount;
//states in which the telephone can be
typedef enum { ON_HOOK, OFF_HOOK, DIALLING, CONNECTED } stateType;
//assume that the handest starts "on hook"
stateType state = ON_HOOK;
//keep track of last pin
int previousPinReading = HIGH;
//the time at which the pin last changed value
unsigned long timePinChanged;
//and the current time
unsigned long now = millis ();
void setup() {
// both pins will initially be set as inputs
pinMode(phonePin, INPUT_PULLUP);
pinMode(hookPin, INPUT_PULLUP);
Serial.begin (9600);
Serial.println (F("Serial connection started"));
if (!SD.begin(chipSelectPin)) { //sees if card is present and intialise
Serial.println("SD card initialisation failed!");
return; //don't do anything more if not
}
tmrpcm.setVolume(4);
tmrpcm.quality(1);
Serial.println("Setup Complete");
}
void loop() {
// put your main code here, to run repeatedly:
int hookValue = digitalRead(hookPin);
if(hookValue == 0 && state == ON_HOOK) {
#ifdef DEBUG
Serial.println("Receiver Lifted");
#endif
state = OFF_HOOK;
}
else if(hookValue == 1 && state != ON_HOOK) {
#ifdef DEBUG
Serial.println("Receiver Replaced");
#endif
state = ON_HOOK;
pulseCount = 0;
currentDigit = 0;
tmrpcm.stopPlayback();
pinMode(phonePin, INPUT_PULLUP);
}
if(state == OFF_HOOK || state == DIALLING) {
now = millis();
int pinReading = digitalRead (phonePin);
if (pinReading != previousPinReading) {
state = DIALLING;
if (now - timePinChanged < debounceDelay) {
return;
}
if(pinReading == HIGH) {
pulseCount++;
}
timePinChanged = now;
previousPinReading = pinReading;
}
if (((now - timePinChanged) >= maxPulseInterval) && pulseCount > 0) {
if (currentDigit < numDigitsInPhoneNumber) {
if (pulseCount == 10) { pulseCount = 0; }
#ifdef DEBUG
Serial.println (F("Digit dialled: "));
Serial.println (pulseCount);
#endif
number[currentDigit] = pulseCount | '0';
currentDigit++;
number[currentDigit] = 0;
}
if (currentDigit == numDigitsInPhoneNumber) {
#ifdef DEBUG
Serial.println (F("Number dialled: "));
Serial.println (number);
#endif
if(strcmp(number, "62442") == 0) {
#ifdef DEBUG
Serial.println (F("Playing Sound"));
#endif
pinMode(phonePin, OUTPUT);
tmrpcm.speakerPin = 6;
tmrpcm.play("clue");
while(!digitalRead(hookPin)){ delay(1000); }
}
else {
pinMode(phonePin, OUTPUT);
tmrpcm.speakerPin = 6;
tmrpcm.play ("fail");
delay(2500);
}
state = CONNECTED;
}
pulseCount=0;
}
}
}
Once I run the program and lift and replace the receiver only once, the serial monitor displays, the following, it indicates three distinct lifts and replace despite only doing once, and also does not recognise the dial being used at all.
Serial connection started
Setup Complete
Receiver Lifted
Receiver Replaced
Receiver Lifted
Receiver Replaced
Receiver Lifted
Receiver Replaced
If I modify the code in this manner:
#define DEBUG
#include <SPI.h>
#include <SD.h>
#include <TMRpcm.h>
const byte phonePin = 6; // Red wire from phone
const byte hookPin = 8; // Green wire from phone
const byte chipSelectPin = 53;
const unsigned long debounceDelay = 10; //ms
const unsigned long maxPulseInterval = 250; // ms
const int numDigitsInPhoneNumber = 5;
TMRpcm tmrpcm;
char number[numDigitsInPhoneNumber + 1];
int currentDigit = 0;
int pulseCount = 0;
typedef enum { ON_HOOK, OFF_HOOK, DIALLING, CONNECTED }
stateType;
stateType state = ON_HOOK;
int previousPinReading = LOW;
unsigned long timePinChanged = 0;
unsigned long now = millis ();
void setup() {
Serial.begin (9600);
Serial.println (F("Serial connection started"));
pinMode(hookPin, INPUT_PULLUP);
pinMode(phonePin, INPUT_PULLUP);
if (!SD.begin(chipSelectPin)) { //sees if card is present and intialise
Serial.println("SD card initialisation failed!");
return; //don't do anything more if not
}
tmrpcm.setVolume(4);
tmrpcm.quality(1);
Serial.println("Setup Complete");
}
void loop() {
int pinReadingOn = digitalRead(phonePin);
int hookValue = digitalRead(hookPin);
if(hookValue == 0 && state == ON_HOOK) {
#ifdef DEBUG
Serial.println("Receiver Lifted");
#endif
state = OFF_HOOK;
delay(100);
}
else if(hookValue == 1 && state != ON_HOOK && pinReadingOn != HIGH) {
#ifdef DEBUG
Serial.println("Receiver Replaced");
#endif
state = ON_HOOK;
delay(100);
pulseCount = 0;
currentDigit = 0;
tmrpcm.stopPlayback();
pinMode(phonePin, INPUT_PULLUP);
}
if(state == OFF_HOOK || state == DIALLING) {
now = millis();
int pinReading = digitalRead (phonePin);
if (pinReading != previousPinReading) {
state = DIALLING;
if (now - timePinChanged < debounceDelay) {
return;
}
if(pinReading == HIGH) {
pulseCount++;
}
timePinChanged = now;
previousPinReading = pinReading;
}
if (((now - timePinChanged) >= maxPulseInterval) && pulseCount > 0) {
if (currentDigit < numDigitsInPhoneNumber) {
if (pulseCount == 10) { pulseCount = 0; }
#ifdef DEBUG
Serial.println (F("Digit dialled: "));
Serial.println (pulseCount);
#endif
number[currentDigit] = pulseCount | '0';
currentDigit++;
number[currentDigit] = 0;
pulseCount = 0;
}
if (currentDigit == numDigitsInPhoneNumber) {
#ifdef DEBUG
Serial.println (F("Number dialled: "));
Serial.println (number);
#endif
if(strcmp(number, "62442") == 0) {
#ifdef DEBUG
Serial.println (F("Playing Sound"));
#endif
pinMode(phonePin, OUTPUT);
tmrpcm.speakerPin = 6;
tmrpcm.play("clue");
while(!digitalRead(hookPin)){ delay(1000); }
}
else {
pinMode(phonePin, OUTPUT);
tmrpcm.speakerPin = 6;
tmrpcm.play ("fail");
delay(2500);
}
state = CONNECTED;
}
pulseCount=0;
}
}
}
When I run the program and lift and replace the receiver the following is displayed, it only recognises the one lift and replace but gets them the wrong way round, and displays digit 1 despite not dialling a number. Dialling a number on the dial is still not recognised.
Serial connection started
Setup Complete
Receiver Replaced
Receiver Lifted
Digit dialled:
1
I have attached an image of the setup, I have run jumper wires directly to the circuit board to eliminate any issues with the phone cable.
Any help would be amazing, thank you so much in advance.
Dan