Payphone/Implementation

From Noisebridge Wiki
Jump to navigation Jump to search
static const uint8_t D0 = 16;
static const uint8_t D1 = 5;
static const uint8_t D2 = 4;
static const uint8_t D3 = 0;
static const uint8_t D4 = 2;
static const uint8_t D5 = 14;
static const uint8_t D6 = 12;
static const uint8_t D7 = 13;
static const uint8_t D8 = 15;



const int rowPin0 = D0;
//const int rowPin0 = 16;
const int rowPin1 = D1;
//const int rowPin1 = 5;
const int rowPin2 = D2;
//const int rowPin2 = 4;

const int rowPin3 = D3;
//const int rowPin3 = 0;
const int columnPin0 = D4;
//const int columnPin0 = 2;
const int columnPin1 = D5;
//const int columnPin1 = 14;
const int columnPin2 = D6;
//const int columnPin2 = 12;
const int strikePin = D7;
//const int strikePin = 13;
const int tonePin = D8;
const int columns[] = { columnPin0, columnPin1, columnPin2 };
const int rows[] = { rowPin0, rowPin1, rowPin2, rowPin3 };

char keys[][12] = { "zero.", "one.", "two.", "three.", "four.", "five.", "six.", "seven.", "eight.", "nine.", "star.", "pound." };
// int tones[12] = { 1209, 1336, 1477 }
int freq = 880;

const int matrix[4][3] =
  { 1, 2, 3, 
    4, 5, 6, 
    7, 8, 9, 
   10, 0, 11 };

const int rowIdentityMatrix[4][4] =
  { LOW, HIGH, HIGH, HIGH, 
  HIGH, LOW, HIGH, HIGH, 
  HIGH, HIGH, LOW, HIGH, 
  HIGH, HIGH, HIGH, LOW };

int canRegisterKeyPress[4][3] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };

int pinCodeRingBuffer[4];

int currentPinIndex = 0;

void setup() {
  Serial.begin(115200);
  Serial.println("Hello World");

  resetPinCode();

  pinMode(strikePin, OUTPUT);
  pinMode(columnPin0, INPUT_PULLUP);
  pinMode(columnPin1, INPUT_PULLUP);
  pinMode(columnPin2, INPUT_PULLUP);

  pinMode(rowPin0, OUTPUT);
  pinMode(rowPin1, OUTPUT);
  pinMode(rowPin2, OUTPUT);
  pinMode(rowPin3, OUTPUT);

  digitalWrite(rowPin0, HIGH);
  digitalWrite(rowPin1, HIGH);
  digitalWrite(rowPin2, HIGH);
  digitalWrite(rowPin3, HIGH);

  digitalWrite(strikePin, LOW);
}

void loop() {
  gateKeep(getCurrentKey());
}

int getCurrentKey() {
  int currentPressedKey = -1;
  for (int r = 0; r < 4; r++) {
    for (int i = 0; i < 4; i++) {
      digitalWrite(rows[i], rowIdentityMatrix[r][i]);
    }
    delay(2);

    for (int c = 0; c < 3; c++) {
      const bool pressingKey = digitalRead(columns[c]) == LOW;
      if (pressingKey && canRegisterKeyPress[r][c]) {
        canRegisterKeyPress[r][c] = false;
        currentPressedKey = matrix[r][c];
        Serial.println(currentPressedKey);
        tone(tonePin, freq);
      } else if (!pressingKey) {
        canRegisterKeyPress[r][c] = true;
      }
      delay(2);
    }
  }

  return currentPressedKey;
}

void gateKeep(int key) {
  if (key >= 0) {
    Serial.println(key);
    updateRingBuffer(key);
    maybeStrikeIt();
    noTone(tonePin);
  }
}

void updateRingBuffer(int key) {
  pinCodeRingBuffer[currentPinIndex] = key;
  currentPinIndex = (currentPinIndex + 1) % 4;
}

void maybeStrikeIt() {
  //    const int code[] = { 1, 8, 4, 8 };
  const int code[] = { 2, 6, 0, 0 };
  // Check if the strike should strike out
  for (int i = 0; i < 4; i++) {
    bool isValidMatch = true;
    for (int j = 0; j < 4; j++) {
      if (pinCodeRingBuffer[(i + j) % 4] != code[j]) {
        isValidMatch = false;
        break;
      }
    }
    if (isValidMatch) {
      grantEntryAccess();
      break;
    }
  }
}

void grantEntryAccess() {
  Serial.println("Door is opening");
  reallyStrikeIt();
}

void reallyStrikeIt() {
  digitalWrite(strikePin, HIGH);
  delay(2500);
  digitalWrite(strikePin, LOW);
  for (int i = 0; i < 2; i++) {
    digitalWrite(strikePin, HIGH);
    delay(250);
    digitalWrite(strikePin, LOW);
    delay(250);
  }

  resetPinCode();
}

void resetPinCode() {
  pinCodeRingBuffer[0] =
    pinCodeRingBuffer[1] =
    pinCodeRingBuffer[2] =
    pinCodeRingBuffer[3] = 99;
}