Amitabh Shrivastava
Published © CERN-OHL

Secret Payphone STEM Library

What if an unassuming payphone housed a tiny STEM library? Dial STEM to learn!

IntermediateShowcase (no instructions)20 hours1,289
Secret Payphone STEM Library

Things used in this project

Hardware components

Arduino Nano R3
Arduino Nano R3
×1
Solenoid Lock
×1
DC-DC converter 12V to 5V
×1
Mosfet switch module
×1
Rotary potentiometer (generic)
Rotary potentiometer (generic)
×1
SparkFun Snappable Protoboard
SparkFun Snappable Protoboard
×1
Solder Sleeve, Heat Shrinkable
Solder Sleeve, Heat Shrinkable
×1

Hand tools and fabrication machines

Soldering iron (generic)
Soldering iron (generic)
Woodworking tools

Story

Read more

Custom parts and enclosures

CAD

Schematics

Schematic

Compatible with any AtMega 328 board eg Arduino UNO, NanoR3 etc

Code

Code

Arduino
#include <Keypad.h>

#include "Talkie.h"
#include "Vocab_Tinkrmind.h"
const int speaker1 = 3;
const int speaker2 = 11;

const byte ROWS = 4;  // Four rows
const byte COLS = 3;  // Three columns

char keys[ROWS][COLS] = {
  { '1', '2', '3' },
  { '4', '5', '6' },
  { '7', '8', '9' },
  { '*', '0', '#' }
};

byte rowPins[ROWS] = { 8, 10, A1, 7 };  // Connect to the row pinouts of the keypad
byte colPins[COLS] = { 5, 6, 12 };      // Connect to the column pinouts of the keypad

Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);

const int receiver = 4;    // Connect button 1 to this pin
const int doorSwitch = 2;  // Connect button 2 to this pin
const int solenoid = A0;

boolean button1State = false;
boolean button2State = false;
boolean lastButton1State = false;
boolean lastButton2State = false;

unsigned long lastDebounceTime = 0;
unsigned long debounceDelay = 50;

boolean sendValue = false;
unsigned long sendValueStartTime = 0;
const unsigned long sendValueDuration = 30000;  // 30 seconds

char last_key;
char password[] = { '7', '8', '3', '6' };
int password_success = 0;
int alertedListener = 0;
int offTheHook = 0;

void (*resetFunc)(void) = 0;  //declare reset function @ address 0

void keyPress() {
  digitalWrite(speaker2, LOW);
  tone(speaker1, 1300);
  delay(100);
  tone(speaker1, 440);
}

void dialTone(){
  digitalWrite(speaker2, LOW);
  tone(speaker1, 440);
}

void stopSpeaker(){
  digitalWrite(speaker2, LOW);
  noTone(speaker1);
}

void setup() {
  Serial.begin(115200);
  pinMode(receiver, INPUT_PULLUP);
  pinMode(doorSwitch, INPUT_PULLUP);
  pinMode(solenoid, OUTPUT);
  digitalWrite(solenoid, LOW);
}

// void loop(){
//   if(digitalRead(doorSwitch) == 0){
//     Serial.println("door switch alert");
//   }
//   if(digitalRead(receiver) == 1){
//     Serial.println("receiver alert");
//   }
// }

unsigned long offTheHookTime = millis();
int enterPasswordPrompt = 0;

void loop() {
  //check if receiver is on hook
  if (digitalRead(receiver) == 0 && offTheHook == 0) {
    delay(250);
    if (digitalRead(receiver) == 0) {
      // phone is off the hook
      Serial.println("Receiver off the hook");
      offTheHook = 1;
      offTheHookTime = millis();
      enterPasswordPrompt = 0;
      dialTone();
      alertedListener = 0;
      password_success = 0;
    }
  }

  if (digitalRead(receiver) == 1 && offTheHook == 1) {
    // receiver put back on
    Serial.println("Receiver back on");
    offTheHook = 0;
    stopSpeaker();
  }

  if (offTheHook) {
    if (millis() - offTheHookTime > 2000 && enterPasswordPrompt == 0) {

      enterPasswordPrompt = 1;
    }

    // Read keypad
    char key = keypad.getKey();
    if (key) {
      keyPress();
      if (key == password[password_success]) {
        Serial.println(key);
        password_success++;
      } else {
        password_success = 0;
      }
      if (password_success == 4) {
        Serial.println("Password correct");
        openDoor();
        password_success = 0;
      }
    }

    if (alertedListener == 0) {
      Serial.println("#");
      alertedListener = 1;
    }
    if (Serial.available()) {
      char c = Serial.read();
      if (c == '*') {
        Serial.println("User said Secret Stem");
        openDoor();
      }
    }
  }
}

void openDoor() {
  Serial.println("Unlocking door");
  digitalWrite(solenoid, HIGH);
  unsigned long start = millis();
  Talkie voice;
  voice.say(spWELCOMETOTHESTEMLIBRARY);
  voice.terminate();
  while (millis() - start < 3000 && digitalRead(doorSwitch) == 1) {
    //door not opened and time has been less than 10 sec
  }
  Serial.println("Re-locking door");
  digitalWrite(solenoid, LOW);
  dialTone();

  // while(digitalRead(receiver) == 0){
  // }
  // Serial.println("On the hook");
  // offTheHook = 0;
  // noTone(speaker);
}

Vocab_Tinkrmind.h

C Header File
// Talkie library
// Copyright 2011 Peter Knight
// This code is released under GPLv2 license.
//
// Amitabh Shrivastava(@tinkrmind) sounds for Hackster.io STEM Library Aug 2023
//

#ifndef _TALKIE_VOCAB_TINKRMIND_H
#define _TALKIE_VOCAB_TINKRMIND_H

#include <Arduino.h>

extern const uint8_t spWHATSTHEPASSWORD[] PROGMEM;
extern const uint8_t spWELCOMETOTHESTEMLIBRARY[] PROGMEM;
#endif // _TALKIE_VOCAB_TINKRMIND_H

Vocab_Tinkrmind.cpp

C/C++
// Talkie library
// Copyright 2011 Peter Knight
// This code is released under GPLv2 license.
//
// Amitabh Shrivastava(@tinkrmind) sounds for Hackster.io STEM Library Aug 2023
//

#include <Arduino.h>

extern const uint8_t spWHATSTHEPASSWORD[]    PROGMEM = {0xc0,0x3a,0x91,0x76,0xd0,0x2c,0x8a,0xe9,0x4d,0xd8,0x05,0xeb,0x31,0xa9,0x0d,0x7e,0x06,0xa3,0xc3,0x94,0x3a,0xf9,0x4c,0x9c,0xb4,0x6c,0xea,0x18,0xc3,0x69,0xcc,0x94,0xb8,0x42,0xc8,0xd2,0xb2,0x48,0x62,0x4b,0x26,0x4a,0x53,0x22,0x8b,0xb5,0x19,0x4b,0x2d,0x4b,0x22,0xbe,0x1e,0x23,0xb5,0x34,0x2e,0x7b,0x46,0x88,0x90,0x10,0x3b,0xe4,0x6f,0x56,0x5c,0x53,0xe2,0x84,0x3f,0x7a,0x73,0xa9,0x8a,0xad,0x26,0x1f,0xcc,0xb4,0x3a,0x34,0x7a,0x8c,0x37,0xe7,0x2a,0xd3,0xe8,0x71,0xc6,0x9c,0x33,0x23,0x8b,0x28,0x86,0x48,0x51,0x8b,0x5c,0x86,0x54,0xa2,0x54,0xb3,0x72,0x19,0x52,0x8f,0xa6,0x2e,0xd3,0xa9,0x49,0xc3,0x9b,0x26,0x2d,0xa7,0x22,0x76,0x4b,0x1a,0x17,0x6d,0xf2,0x98,0x3d,0x39,0xdd,0x94,0x2a,0x53,0xf0,0x14,0xd3,0xd8,0x22,0x2b,0x26,0xd2,0xc2,0x62,0xab,0xbb,0xa6,0x6a,0x77,0xb6,0x6d,0x8a,0x9a,0x27,0xcb,0xc4,0xae,0x2a,0x75,0xf0,0x0c,0xcf,0x4a,0xae,0xd1,0x31,0xca,0x3c,0x27,0xb9,0x21,0x04,0x4b,0xf5,0xba,0xec,0x86,0xe8,0x35,0x25,0x6a,0xb6,0xab,0xa3,0x93,0xd4,0xac,0x51,0xa6,0xc8,0x96,0x53,0x27,0x26,0xb3,0x3c,0x5b,0x4e,0xe9,0x6a};
// extern const uint8_t spWELCOMETOTHESTEMLIBRARY[]    PROGMEM = {0x80,0x1a,0xae,0x34,0xad,0xac,0x36,0x69,0xb4,0xd6,0x90,0x8c,0x3a,0xa1,0x88,0xd6,0x43,0x23,0x47,0x8f,0x2c,0xba,0x48,0xf5,0x3e,0x3d,0x92,0x14,0x22,0xd9,0xa7,0x4a,0x0b,0x63,0x8a,0xe4,0x9a,0xc8,0xc9,0xb7,0x25,0x93,0xb6,0x4d,0x85,0xc0,0x84,0x5e,0xcc,0x08,0xa5,0x02,0x6f,0x73,0xd8,0x3c,0x32,0x0b,0x42,0xf4,0xd0,0x0e,0xb1,0xc2,0x2f,0x8d,0x4d,0xd3,0xe2,0x04,0xaf,0x6c,0x0b,0x4d,0x8e,0x9b,0xd2,0xe0,0x25,0x2d,0xbb,0x72,0x2a,0x7c,0xb4,0xf0,0xec,0x4a,0xa6,0xb1,0x5e,0xd3,0xac,0x22,0xab,0xd6,0x1b,0x29,0xf5,0x4a,0xac,0x3a,0x6f,0xa5,0xd4,0x2b,0x96,0xe8,0x9d,0xd3,0x92,0xca,0x98,0xac,0x77,0x4e,0x4b,0x3a,0x2a,0x91,0x41,0x5b,0x1d,0x1d,0x0b,0x85,0x46,0x6e,0xb4,0xad,0xcc,0x12,0x9a,0xa2,0x60,0xd7,0xd0,0x24,0x00,0xe4,0xef,0xd9,0x8c,0xdc,0xed,0xb8,0xab,0x65,0x33,0xca,0x48,0x6c,0xea,0x60,0xa4,0xbc,0xdb,0x94,0x6a,0xbc,0xd1,0xd4,0x9a,0x50,0x64,0x14,0xd6,0xd2,0xaa,0x4d,0x8b,0x31,0x49,0x09,0xa9,0xac,0xec,0xfa,0x68,0x2c,0x65,0x26,0x92,0x19,0xa2,0xb3,0x90,0x0b,0xcb,0x6a,0x2c,0x4a,0x5d,0xd2,0x6b,0xab,0x7b,0x04,0x0b,0x09,0x89,0xa3,0x9e,0x91,0x32,0x35,0xd5,0x0a,0xf3,0x87,0x8f,0x54,0x93,0x38,0xc8,0x9b,0x52,0x8c,0x5d,0xed,0xb2,0x67,0xa6,0x70,0x71,0x8d,0xeb,0xca,0xee,0x55,0xa5,0xb2,0x6a,0xe9,0x5a,0xe0,0xd0,0x89,0xca,0x69,0x68,0x99,0x53,0xda,0xab,0x84,0xbe,0x44,0x29,0x6e,0xaf,0xac,0xea,0xe0,0xa5,0xb8,0x3c,0x8e,0x2a,0xad,0xd7,0xe2,0xb2,0xda,0x2e,0x8f,0x4a,0x5b,0x42,0x93,0x9a,0x2c,0x68,0x6b,0x71,0x4d,0x6b,0x72,0x13,0xa3,0xc5,0xbd,0x89,0x2b,0x4c,0xec,0x36,0xd3,0x39,0xa1,0x0c,0xd9,0x43,0xaa,0xc6,0x94,0x32,0x0d,0x4d,0x99,0x32,0xdb,0x8a,0x5c,0xb4,0xac,0x32,0x4c,0xcb,0x4b,0xe2,0xf4,0xac,0x32,0x29,0x8f,0x81,0x27,0x33,0xcb,0xa8,0xd2,0x05,0x19,0x37,0x15,0xcb,0x2a,0x1f,0x38,0xd3,0xc4,0xac,0xa8,0xab,0x15,0x97,0x94,0xda,0xa6,0x6f,0xd1,0x82,0x9d,0x92,0x99,0x21,0x45,0x0a,0xe9,0x68,0x6c,0xc6,0x94,0x28,0x65,0x75,0xb6,0x19,0x53,0xe2,0x90,0xd5,0xd9,0x66,0xca,0x99,0x9d,0x57,0x17,0x8b,0x37,0x27,0x76,0x5e,0x5b,0x2c,0x9e,0x9a,0x30,0x64,0x7d,0xb1,0x29,0x7b,0x25,0xa7,0xf5,0x27,0xee,0xed,0x45,0x58,0x26,0x6e,0xbb,0x67,0x44,0x61,0x9e,0xbc,0x6d,0xb2,0x11,0x99,0x65,0x6a,0x92,0x1a,0x7a,0x40,0xcd,0xa9,0x82,0xac,0xcf,0x8a,0x72,0x4a,0x4d,0x93,0x36,0x29,0x52,0x73,0xab,0x42,0xea,0xe1,0x54,0x35,0x2c,0x31,0xfa,0x47,0x50,0xd3,0x50,0xbb};


extern const uint8_t spWELCOMETOTHESTEMLIBRARY[]    PROGMEM = {0x80,0x1a,0xae,0x34,0xad,0xac,0x36,0x69,0xb4,0xd6,0x90,0x8c,0x3a,0xa1,0x88,0xd6,0x43,0x23,0x47,0x8f,0x2c,0xba,0x48,0xf5,0x3e,0x3d,0x92,0x14,0x22,0xd9,0xa7,0x4a,0x0b,0x63,0x8a,0xe4,0x9a,0xc8,0xc9,0xb7,0x25,0x93,0xb6,0x4d,0x85,0xc0,0x84,0x5e,0xcc,0x08,0xa5,0x02,0x6f,0x73,0xd8,0x3c,0x32,0x0b,0x42,0xf4,0xd0,0x0e,0xb1,0xc2,0x2f,0x8d,0x4d,0xd3,0xe2,0x04,0xaf,0x6c,0x0b,0x4d,0x8e,0x9b,0xd2,0xe0,0x25,0x2d,0xbb,0x72,0x2a,0x7c,0xb4,0xf0,0xec,0x4a,0xa6,0xb1,0x5e,0xd3,0xac,0x22,0xab,0xd6,0x1b,0x29,0xf5,0x4a,0xac,0x3a,0x6f,0xa5,0xd4,0x2b,0x96,0xe8,0x9d,0xd3,0x92,0xca,0x98,0xac,0x77,0x4e,0x4b,0x3a,0x2a,0x91,0x41,0x5b,0x1d,0x1d,0x0b,0x85,0x46,0x6e,0xb4,0xad,0xcc,0x12,0x9a,0xa2,0x60,0xd7,0xd0,0x24,0x00,0xe4,0xef,0xd9,0x8c,0xdc,0xed,0xb8,0xab,0x65,0x33,0xca,0x48,0x6c,0xea,0x60,0xa4,0xbc,0xdb,0x94,0x6a,0xbc,0xd1,0xd4,0x9a,0x50,0x64,0x14,0xd6,0xd2,0xaa,0x4d,0x8b,0x31,0x49,0x09,0xa9,0xac,0xec,0xfa,0x68,0x2c,0x65,0x26,0x92,0x19,0xa2,0xb3,0x90,0x0b,0xcb,0x6a,0x2c,0x4a,0x5d,0xd2,0x6b,0xab,0x7b,0x04,0x0b,0x09,0x89,0xa3,0x9e,0x91,0x32,0x35,0xd5,0x0a,0xf3,0x87,0x8f,0x54,0x93,0x38,0xc8,0x9b,0x52,0x8c,0x5d,0xed,0xb2,0x67,0xa6,0x70,0x71,0x8d,0xeb,0xca,0xee,0x55,0xa5,0xb2,0x6a,0xe9,0x5a,0xe0,0xd0,0x89,0xca,0x69,0x68,0x99,0x53,0xda,0xab,0x84,0xbe,0x44,0x29,0x6e,0xaf,0xac,0xea,0xe0,0xa5,0xb8,0x3c,0x8e,0x2a,0xad,0xd7,0xe2,0xb2,0xda,0x2e,0x8f,0x4a,0x5b,0x42,0x93,0x9a,0x2c,0x68,0x6b,0x71,0x4d,0x6b,0x72,0x13,0xa3,0xc5,0xbd,0x89,0x2b,0x4c,0xec,0x36,0xd3,0x39,0xa1,0x0c,0xd9,0x43,0xaa,0xc6,0x94,0x32,0x0d,0x4d,0x99,0x32,0xdb,0x8a,0x5c,0xb4,0xac,0x32,0x4c,0xcb,0x4b,0xe2,0xf4,0xac,0x32,0x29,0x8f,0x81,0x27,0x33,0xcb,0xa8,0xd2,0x05,0x19,0x37,0x15,0xcb,0x2a,0x1f,0x38,0xd3,0xc4,0xac,0xa8,0xab,0x15,0x97,0x94,0xda,0xa6,0x6f,0xd1,0x82,0x9d,0x92,0x99,0x21,0x45,0x0a,0xe9,0x68,0x6c,0xc6,0x94,0x28,0x65,0x75,0xb6,0x19,0x53,0xe2,0x90,0xd5,0xd9,0x66,0xca,0x99,0x9d,0x57,0x17,0x8b,0x37,0x27,0x76,0x5e,0x5b,0x2c,0x9e,0x9a,0x30,0x64,0x7d,0xb1,0x29,0x7b,0x25,0xa7,0xf5,0x27,0xee,0xed,0x45,0x58,0x26,0x6e,0xbb,0x67,0x44,0x61,0x9e,0xbc,0x6d,0xb2,0x11,0x99,0x65,0x6a,0x92,0x1a,0x7a,0x40,0xcd,0xa9,0x82,0xac,0xcf,0x8a,0x72,0x4a,0x4d,0x93,0x36,0x29,0x52,0x73,0xab,0x42,0xea,0xe1,0x54,0x35,0x2c,0x31,0xfa,0x47,0x50,0xd3,0x50,0xbb,0xf0};

Credits

Amitabh Shrivastava

Amitabh Shrivastava

2 projects • 4 followers

Comments