Secure Digital Card Password Safe Instructions

 

This program is stateless. Each key and switch has a defined action. 

The information on the display is limited to 4 rows and 10 columns in order to use the better-looking Adafruit  9-point font. 

On boot the display on the photograph appears.

The keys with letters and all the other keys each have defined functions:

  • Letter keys: Each loads the contents of a specific file into memory. Each file contains data on sites whose first letter is one of the 3 on the key pressed. The middle entry is elected.
  • 1: Shows username and password of the selected site.
  • 0: Sets the site selected to the first entry.
  • *: Shuts down power.
  • #: Shows  battery voltage.

The UP switch selects the entry  lower  in alphabetical order.

The DOWN switch selects the entry higher in alphabetical order.

Any change in the site selection triggers a display of site name and password.

Power also times out, with the countdown reset on any selection change.

Secure Digital Card Password Safe Program Includes and  Defines

/*PassworShow

          Operation:

    Switch UP = Power On Key * = power OFF

    Key # = display battery voltage

    Keys 2 - 9 = load corresponding files K02.txt - K09.txt into memory

    Switch DOWN = show next record syte name

    Switch UP = show preious record syte name

    Key 0 = go to first record

    Key 1 = show username and password

    John aunders 2/9/2025

*/


#include <SPI.h>

#include <SD.h>

#include <Wire.h>

#include <Adafruit_GFX.h>

#include <Adafruit_SSD1306.h>

#include "Fonts/FreeMono9pt7b.h"

#include “masterTables.h”


#define OLED_RESET     -1 // Reset pin # (or -1 if sharing Arduino reset pin)

#define SCREEN_ADDRESS 0x3C ///< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32

#define SCREEN_WIDTH 128 // OLED display width, in pixels

#define SCREEN_HEIGHT 64 // OLED display height, in pixels

#define COL_1_PIN  2        //connections to the 4x3 matrixed keypad

#define COL_2_PIN  3

#define COL_3_PIN  5

#define ROW_1_PIN  6

#define ROW_2_PIN  7

#define ROW_3_PIN  8

#define ROW_4_PIN  9

#define swUp_PIN   A0

#define TEST_PIN   A1

#define swDown_PIN A2

#define SDCARD_SS_PIN 10

#define POWER_PIN 4


#define LOOP_DELAY 100

#define SHUTDOWN_LOOPS 150


const int numFiles = 8;

char SD_ID = ' ';


Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);


File myFile;

char fileContent[15][35];


String filenames[numFiles] = {

  // 0      1      2      3      4      5      6      7

  "K02.txt", "K03.txt", "K04.txt", "K05.txt", "K06.txt", "K07.txt", "K08.txt", "K09.txt"

};

const float refVolt = 4.975;

const int colPins[3] =  {COL_1_PIN, COL_2_PIN, COL_3_PIN};

const int rowPins[4] = {ROW_1_PIN, ROW_2_PIN, ROW_3_PIN, ROW_4_PIN};


int row0 = 10;

int row3 = 43;


struct keys {

  int col_inx;

  int row_inx;

  char keyChar;

};


const keys keyVals[12] = {       //The index of this table is the result

  {0, 0, '1'}, {1, 0, '2'}, {2, 0, '3'},

  {0, 1, '4'}, {1, 1, '5'}, {2, 1, '6'},

  {0, 2, '7'}, {1, 2, '8'}, {2, 2, '9'},

  {0, 3, '*'}, {1, 3, '0'}, {2, 3, '#'}

};

Secure Digital Card Password Safe Setup

void setup() {

  // Open serial communications and wait for port to open:

  for (int l = 0; l < 4; l++) {

    pinMode(rowPins[l], INPUT_PULLUP);      //Stop polling is a key is depressed

  }

  for (int m = 0; m < 3; m++) {

    pinMode(colPins[m], OUTPUT);      //Stop polling is a key is depressed

  }

  pinMode(swUp_PIN, INPUT_PULLUP);

  pinMode(swDown_PIN, INPUT_PULLUP);

  pinMode(POWER_PIN, OUTPUT);

  digitalWrite(POWER_PIN, HIGH);

  display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS);

  display.setRotation(2);

  display.setFont(&FreeMono9pt7b);

  display.setTextColor(WHITE);

  display.clearDisplay();

  display.setCursor(0, row0);

  if (!SD.begin(SDCARD_SS_PIN)) {

    display.println("No SD Card");

    display.display();

    delay(3000);

    digitalWrite(POWER_PIN, LOW);

    while (1);

  }

  myFile = SD.open("ID.TXT", FILE_READ);

  if (myFile) {

    SD_ID = myFile.read();

    myFile.close();

    if (SD_ID == 'F') {

      display.print("SD card ID is ");

      display.println(SD_ID);

      display.setCursor(0, row3);

      display.println("Press a    lettter key");

      display.display();

    }

    else {

      display.print("Wrong SD card:");

      display.println(SD_ID);

      display.display();

      delay(9000);

      digitalWrite(POWER_PIN, LOW);

      while (1);

    }

  }

}

Secure Digital Card Password Safe Loop


void loop() {

  static int numSites = 0;

  static int siteInx = 100;

  static int oldInx = 100;

  static int upTic = 1;

  static int downTic = 1;

  static int loopCount = 0;

  char key;

  int swVal;

  if(loopCount++ > SHUTDOWN_LOOPS) {

    digitalWrite(POWER_PIN, LOW);

    while (1);;

  }

  key = getKey();

  if ((key >= '2') && (key <= '9')) {

    numSites = readFile(key);

    siteInx = numSites / 2;

  }

  if ((siteInx != oldInx) && (numSites > 0)) {

    showSiteName(siteInx);

    oldInx = siteInx;

    loopCount = 0;

  }

  if ((key == '1') && (numSites > 0)) {

    showSitePassword(siteInx);

  }

  if (key == '*') {

    digitalWrite(POWER_PIN, LOW);

    while (1);

  }

  if (key == '0') {

    siteInx = 0;

  }

  if (key == '#') {

    showStatus();

  }

  swVal = digitalRead(swUp_PIN);

  if ((swVal == 0) && (upTic == 1)) {

    siteInx--;

    loopCount = 0;

    if (siteInx < 0) {

      siteInx = numSites - 1;

    }

  }

  upTic = swVal;


  swVal = digitalRead(swDown_PIN);

  if ((swVal == 0) && (downTic == 1)) {

    siteInx++;

    loopCount = 0;

    if (siteInx >= numSites) {

      siteInx = 0;

    }

  }

  downTic = swVal;

  delay(LOOP_DELAY);

}

Secure Digital Card Password Safe Functions

char getKey(void) {      //130 microsec for no key pressed

  int keyIndex = 12;    //Default output if no key depressed

  int selRow = 4;

  int selCol = 3;

  int i, j;

  bool tic;           //True if a key has ben depressed

  char retVal = 'z';

  tic = false;

  for (i = 0; i < 3; i++) {

    digitalWrite(colPins[i], LOW);      //Poll the columns

    for (j = 0; j < 4; j++) {

      if (digitalRead(rowPins[j]) == LOW) { // A key press goes to 2.4 milliseconds

        selRow = j;

        selCol = i;

        tic = true;

        break;          //When a key press is detected

      }

    }

    digitalWrite(colPins[i], HIGH);       //Stop polling is a key is depressed


  }

  if (tic) {    //Find the match if a key press detected

    for (int k = 0; k < 12; k++) {

      if ((selRow == keyVals[k].row_inx) && (selCol == keyVals[k].col_inx)) {

        keyIndex = k;

        retVal = keyVals[keyIndex].keyChar;

        break;

      }

    }

  }

  return retVal;

}

void showStatus(void) {

  int raw;

  float battVolt;

  raw = analogRead(TEST_PIN);

  battVolt = ((float)raw * refVolt) / 512.0;

  display.clearDisplay();

  display.setCursor(0, row0);

  display.print("Battery =   ");

  display.print(battVolt, 2);

  display.println(" V");

  display.display();

}


int readFile(char fileChar) {

  char readVal;

  int charIndex = 0;

  int siteIndex = 0;

  int fileInx = fileChar - '2';

  myFile = SD.open(filenames[fileInx]);

  if (myFile) {

    while (myFile.available())  {

      readVal = myFile.read();

      fileContent[siteIndex][charIndex++] = readVal;

      if (readVal == '\n') {

        fileContent[siteIndex][charIndex] = 0;

        siteIndex++;

        charIndex = 0;

      }

    }

    myFile.close();

  }

  return siteIndex;

}


void showSiteName(int siteIndex) {

  int charIndex = 6;

  int indx;

  display.clearDisplay();

  display.setCursor(0, row0);

  do {

    display.write(fileContent[siteIndex][charIndex]);

  } while (fileContent[siteIndex][charIndex++] > 0);

  display.setCursor(0, row3);

  indx = 10 * fileContent[siteIndex][2] + fileContent[siteIndex][3] - 528;

  display.print(plates[indx]);

  indx = 10 * fileContent[siteIndex][4] + fileContent[siteIndex][5] - 528;

  display.println(caps[indx]);

  display.display();

}


void showSitePassword(int siteIndex) {

  int indx;

  display.clearDisplay();

  display.setCursor(0, row0);

  indx = 10 * fileContent[siteIndex][0] + fileContent[siteIndex][1] - 528;

  display.println(unames[indx]);

  display.setCursor(0, row3);

  indx = 10 * fileContent[siteIndex][2] + fileContent[siteIndex][3] - 528;

  display.print(plates[indx]);

  indx = 10 * fileContent[siteIndex][4] + fileContent[siteIndex][5] - 528;

  display.println(caps[indx]);

  display.display();

}