#include <Toggle.h>
#include "RTClib.h"
#include <Keypad.h>
#include <SD.h>
#define CS_PIN 10
const char * logFileName = "data.txt";
const uint8_t ROWS = 4;
const uint8_t COLS = 3;
char keys[ROWS][COLS] = {
{ '1', '2', '3'},
{ '4', '5', '6'},
{ '7', '8', '9'},
{ '*', '0', '#'}
};
uint8_t colPins[COLS] = { 5, 4, 3 }; // Pins connected to C1, C2, C3, C4
uint8_t rowPins[ROWS] = { 9, 8, 7, 6 }; // Pins connected to R1, R2, R3, R4
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
const byte dumpButtonPin = 2;
Toggle dumpButton;
RTC_DS1307 rtc;
void dumpData() {
File logFile = SD.open(logFileName);
if (logFile) {
Serial.println(logFileName);
while (logFile.available()) {
Serial.write(logFile.read());
}
logFile.close();
Serial.println("\n------------");
} else {
Serial.println("error opening log file!");
}
}
void handleKeypad() {
const byte codeLength = 4;
static char code[codeLength + 1];
static byte codePos = 0;
char key = keypad.getKey();
if (key != NO_KEY) {
if ((codePos == codeLength - 1) && (key == '#' || key == '*')) { // if we have the 4 digits and user validates
File logFile = SD.open(logFileName, FILE_WRITE); // and save it at the end of the file
if (logFile) {
Serial.print("writing "); Serial.println(code);
DateTime now = rtc.now();
logFile.print(now.year());
logFile.print('/');
if (now.month() < 10) logFile.write('0');
logFile.print(now.month());
logFile.print('/');
if (now.day() < 10) logFile.write('0');
logFile.print(now.day());
logFile.print("\t");
logFile.print(now.hour());
logFile.print(':');
if (now.minute() < 10) logFile.write('0');
logFile.print(now.minute());
logFile.print(':');
if (now.second() < 10) logFile.write('0');
logFile.print(now.second());
logFile.print('\t');
logFile.println(code);
logFile.close();
} else {
Serial.println("error opening log file for writing!");
}
codePos = 0;
} else {
if (key != '#' && key != '*') {
code[codePos++] = key;
code[codePos] = '\0'; // make it a correct c-string
if (codePos >= codeLength) codePos = codeLength - 1; // don't overflow
Serial.println(code);
}
}
}
}
void setup() {
dumpButton.begin(dumpButtonPin);
Serial.begin(115200);
Serial.print("Initializing SD card... ");
if (!SD.begin(CS_PIN)) {
Serial.println("Card initialization failed!");
while (true);
}
Serial.println("initialization done.");
if (! rtc.begin()) {
Serial.println("Couldn't find RTC");
Serial.flush();
abort();
}
if (! rtc.isrunning()) {
Serial.println("RTC is NOT running, let's set the time!");
// When time needs to be set on a new device, or after a power loss, the
// following line sets the RTC to the date & time this sketch was compiled
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
// This line sets the RTC with an explicit date & time, for example to set
// January 25, 2024 at 2pm you would call:
// rtc.adjust(DateTime(2024, 1, 25, 14, 0, 0));
}
DateTime now = rtc.now();
Serial.print("Date: ");
Serial.print(now.year());
Serial.print('/');
if (now.month() < 10) Serial.write('0');
Serial.print(now.month());
Serial.print('/');
if (now.day() < 10) Serial.write('0');
Serial.println(now.day());
Serial.print("Time: ");
Serial.print(now.hour());
Serial.print(':');
if (now.minute() < 10) Serial.write('0');
Serial.print(now.minute());
Serial.print(':');
if (now.second() < 10) Serial.write('0');
Serial.println(now.second());
Serial.println("System ready to log codes.");
}
void loop() {
// pressing the button dumps the data from the log file
dumpButton.poll();
if (dumpButton.onPress()) dumpData();
// keypad management
handleKeypad();
}
show log file.