SHARE
TWEET

Untitled

a guest Mar 24th, 2019 75 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /*
  2.    "Call me!
  3.    Arduino telephone puzzle
  4. */
  5. //DEFINES
  6. #define DEBUG
  7.  
  8. //INCLUDES
  9. #include <SPI.h> // Generic spi interface, which is used to access the card reader
  10. #include <SD.h> // Provides functionality for reading/writing to SD cards
  11. //Provides audio playback functionality
  12. //Download from https://github.com/TMRh20/TMRpcm
  13. //Note that the buffsize declaration in pcmConfig.h was increased to 254 in order to reduce crackle.
  14. #include <TMRpcm.h>
  15.  
  16. //CONSTANTS
  17. //Configuration
  18. //Also plug in white wire from telephone to arduino GND
  19.  
  20. const byte phonePin = 9; // Red wire from telephone
  21. const byte hookPin = 8; // Green wire from telephone
  22. //const byte unusedPin = 10; //unused wire
  23. const byte lockPin = 2; // Connected to relay
  24. const byte chipSelectPin = 4;
  25. const unsigned long debounceDelay = 10; // ms
  26. // The max separation (in ms) between pulses of a digit being dialed
  27. const unsigned long maxPulseInterval = 250; //ms
  28. const int numDigitsInPhoneNumber = 5;
  29.  
  30. //Globals
  31. //Declare a global TMRpcm object for controlling audio playback
  32. TMRpcm tmrpcm;
  33. //The char representation of the number dialed (+1 to allow for string-terminating character \0)
  34. char number[numDigitsInPhoneNumber + 1];
  35. //The digit number currently being dialed
  36. int currentDigit;
  37. //How many pulses have been detected for the current digit
  38. int pulseCount;
  39. //States in which the telephone can be
  40. typedef enum { ON_HOOK, OFF_HOOK, DIALING, CONNECTED } stateType;
  41.  
  42. //Assume that the handset starts on hook (ie placed on the base unit)
  43. stateType state = ON_HOOK;
  44.  
  45. //In order to record "pulses" on the line, we keep track of the last pin reading...
  46. int previousPinReading = HIGH;
  47. //...the time at which the pin last changed value
  48. unsigned long timePinChanged;
  49. //...and the current time
  50. unsigned long now = millis ();
  51.  
  52.  
  53. void setup() {
  54.   // Both pins will initially be set as inputs (with internal pullup resistors), although
  55.   // may be reassigned as outputs later
  56.   pinMode(phonePin, INPUT_PULLUP);
  57.   pinMode(hookPin, INPUT_PULLUP);
  58.   //pinMode(unusedPin, INPUT_PULLUP);
  59.  
  60.   //The lock pin will receive a low signal to release
  61.   digitalWrite(lockPin, HIGH);
  62.   pinMode(lockPin, OUTPUT);
  63.  
  64.   //Start the serial connection
  65.   Serial.begin(9600);
  66.   Serial.println(F("Serial connection started"));
  67.  
  68.   //Open the connection to the SD card
  69.    if (!SD.begin(chipSelectPin)) { //see if the card is present and can be initialized
  70.     Serial.println("SD card initialization failed!");
  71.     return; // dont do anything more if not
  72.    }
  73.  
  74.   // Volume range from 0 to 7
  75.   tmrpcm.setVolume(4);
  76.   //Enable 2x oversampling tmrpcm.quality(1);
  77.  
  78.   tmrpcm.quality(1);
  79.   Serial.println("Setup complete");
  80.  
  81. }
  82.  
  83. void loop() {
  84.   // Is the reciever lifted off the handset?
  85.   int hookValue = digitalRead(hookPin);
  86.  
  87.   // Is the reciever lifed, but wasnt previously
  88.   if (hookValue == 0 && state == ON_HOOK) {
  89.     // Print some debug info
  90. #ifdef DEBUG
  91.     Serial.println("Receiver Lifted");
  92. #endif
  93.  
  94.     // Update the state
  95.     state = OFF_HOOK;
  96.  
  97.   }
  98.  
  99.   //If the receiver is on the hook, but wasn't previously
  100.  
  101.   else if (hookValue == 1 && state != ON_HOOK) {
  102.     // Print some debug info
  103. #ifdef DEBUG
  104.     Serial.println("Receiver Replaced");
  105. #endif
  106.  
  107.     //Update the puzzle state
  108.     state = ON_HOOK;
  109.  
  110.     //Clear any information about the number we were dialing
  111.     pulseCount = 0;
  112.     currentDigit = 0;
  113.  
  114.     //Stop any audio
  115.     tmrpcm.stopPlayback();
  116.  
  117.     //Put the pin back into input state
  118.     pinMode(phonePin, INPUT_PULLUP);
  119.   }
  120.  
  121.   if (state == OFF_HOOK || state == DIALING) {
  122.     //Record the current timestampp
  123.     now = millis();
  124.  
  125.     //Test the value of the phone pin
  126.     int pinReading = digitalRead (phonePin);
  127.  
  128.     //If the value has changed
  129.     if (pinReading != previousPinReading) {
  130.  
  131.       //The user is dialing a number
  132.       state = DIALING;
  133.  
  134.       // "Debouncing" method to ignore jittery fluctuations in readings
  135.       // If the time elapsed since the last time this pin was changed is only a small amount of time
  136.       if (now - timePinChanged < debounceDelay) {
  137.         // Don't do anything
  138.         return;
  139.       }
  140.  
  141.       // A HIGH signal means that a dialing pulse has been detected
  142.       if (pinReading == HIGH) {
  143.         pulseCount++;
  144.       }
  145.  
  146.       // Update the stored time and reading values for further comparison
  147.       timePinChanged = now;
  148.       previousPinReading = pinReading;
  149.     }
  150.  
  151.     // We've recorded a sequence of pulses and the time since the last pulse was detected
  152.     // is longer than the maxPulseInterval
  153.     if (((now - timePinChanged) >= maxPulseInterval) && pulseCount > 0) {
  154.  
  155.       // If we haven't yet dialed a complete number
  156.       if (currentDigit < numDigitsInPhoneNumber) {
  157.         // The digit '0' is represented by 10 pulses
  158.         if (pulseCount == 10) {
  159.           pulseCount = 0;
  160.         }
  161.  
  162. #ifdef DEBUG
  163.         Serial.print (F("Digit dialed: "));
  164.         Serial.print (pulseCount);
  165. #endif
  166.  
  167.         // Append the most recent digit dialed onto the end of the number array
  168.         number[currentDigit] = pulseCount | '0';
  169.  
  170.         // Increment the counter
  171.         currentDigit++;
  172.  
  173.         // Initialize the next value
  174.         number[currentDigit] = 0;
  175.       }
  176.  
  177.       //If we've dialed the correct number of digits
  178.       if (currentDigit == numDigitsInPhoneNumber) {
  179.  
  180.         // print some debug information
  181. #ifdef DEBUG
  182.         Serial.print (F("Number dialed: "));
  183.         Serial.println (number);
  184. #endif
  185.  
  186.         // This number plays a recorded message
  187.         if (strcmp(number, "21807") == 0) {
  188. #ifdef DEBUG
  189.           Serial.println (F("Playing sound"));
  190. #endif
  191.           // Now, we set the pin as OUTPUT for the audio signal
  192.           pinMode(phonePin, OUTPUT);
  193.           // Set the TMRPCM library to use the pin for output
  194.           tmrpcm.speakerPin = 9; // Must be 5, 6,   11 or 46 on MEGA, 9 on UNO, NANO
  195.           //Play the appropriate sound file
  196.           tmrpcm.play("music");
  197.           // Wait until the receiver is replaced on the handset
  198.           while (!digitalRead(hookPin)) {
  199.             delay(1000);
  200.           }
  201.         }
  202.         //This number unlocks the maglock
  203.         else if (strcmp(number, "12345") == 0) {
  204. #ifdef DEBUG
  205.           Serial.println (F("Releasing lock"));
  206. #endif
  207.           digitalWrite(lockPin, LOW);
  208.           delay(100);
  209.           digitalWrite(lockPin, HIGH);
  210.         }
  211.         // If an incorrect number was dialed
  212.         else {
  213.           //Set the pin as OUTPUT
  214.           pinMode(phonePin , OUTPUT);
  215.           // Set the TMRPCM library to use the pin for output
  216.           tmrpcm.speakerPin = 9; //Must be 5, 6, 11 or 46 on MEGA 9 on UNO or NANO
  217.           // Play the appropriate sound file
  218.           tmrpcm.play("BOMB.WAV");
  219.           // Now we wait for the audio to play
  220.           delay(2500);
  221.         }
  222.  
  223.         //Set the puzzle state to complete
  224.         state = CONNECTED;
  225.       }
  226.       //This digit has been processed, so we reset the pulse counter  for the next digit.
  227.       pulseCount = 0;
  228.     }
  229.  
  230.   }
  231.  
  232. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top