Advertisement
Guest User

Untitled

a guest
Mar 24th, 2019
295
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.00 KB | None | 0 0
  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. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement