beerbox/beerbox.ino

424 lines
9.8 KiB
Arduino
Raw Normal View History

2015-07-13 14:49:36 +00:00
#include <SPI.h>
2015-09-18 17:32:11 +00:00
#include <Wire.h>
2015-07-13 14:49:36 +00:00
#include <SD.h>
#include "beerbox.h"
2015-09-18 17:32:11 +00:00
#include <LiquidCrystal_I2C.h>
2015-07-13 17:09:27 +00:00
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
2015-07-16 13:39:44 +00:00
#include <Adafruit_Fingerprint.h>
2015-09-18 17:32:11 +00:00
2015-07-16 13:39:44 +00:00
Adafruit_Fingerprint finger = Adafruit_Fingerprint(&Serial2);
2015-09-18 17:32:11 +00:00
LiquidCrystal_I2C lcd(0x38, 8, 2); // 0x38 for PCF***A on address 000
2015-07-16 13:39:44 +00:00
#define debug 1 //General debug out on/off
2015-07-13 14:49:36 +00:00
File myFile;
const int chipSelect = 53;
char toprint[255]; // General print Buffer
2015-07-13 17:09:27 +00:00
Beerbox *box;
2015-07-13 14:49:36 +00:00
//int maxDrink = 1; // TODO add this to the box struct
2015-09-18 17:32:11 +00:00
int lastButtonState = 1;
2015-09-18 17:32:11 +00:00
int currentDrink = 0;
int lastPersonIndex = -1;
2015-07-13 14:49:36 +00:00
Person* persons;
String rfID;
2015-07-13 14:49:36 +00:00
unsigned long oldTime = 0;
2015-11-19 19:38:42 +00:00
unsigned long ledTime = 0;
2015-07-13 14:49:36 +00:00
void setup() {
2015-07-16 13:39:44 +00:00
//generall debugging
2015-07-13 14:49:36 +00:00
Serial.begin(115200);
2015-07-13 17:38:17 +00:00
2015-09-18 17:32:11 +00:00
//LCD init
lcd.init();
2015-09-19 09:46:46 +00:00
pinMode(2, INPUT_PULLUP);
2015-09-18 17:32:11 +00:00
2015-11-19 19:38:42 +00:00
pinMode(3, OUTPUT);
pinMode(led, OUTPUT);
//tone(3,440,5000);
2015-07-16 13:39:44 +00:00
//Fingerprint init
finger.begin(57600);
if (finger.verifyPassword()) {
2016-07-04 13:37:55 +00:00
if(debug)Serial.println("Found fingerprint sensor!");
2015-07-16 13:39:44 +00:00
} else {
2016-07-04 13:37:55 +00:00
if(debug)Serial.println("Did not find fingerprint sensor :(");
2015-07-16 13:39:44 +00:00
while (1);
2015-07-13 14:49:36 +00:00
}
2015-07-13 17:38:17 +00:00
2015-07-16 13:39:44 +00:00
// RFID Reader init
Serial1.begin(9600);
// BLE Com init
//Serial3.begin(115200);
Serial3.begin(115200);
2015-07-16 13:39:44 +00:00
2016-07-04 13:37:55 +00:00
if(debug)Serial.print("Initializing SD card...");
2015-07-13 14:49:36 +00:00
// On the Ethernet Shield, CS is pin 4. It's set as an output by default.
2015-07-13 17:38:17 +00:00
// Note that even if it's not used as the CS pin, the hardware SS pin
// (10 on most Arduino boards, 53 on the Mega) must be left as an output
// or the SD library functions will not work.
2015-07-13 14:49:36 +00:00
pinMode(SS, OUTPUT);
if (!SD.begin(chipSelect)) {
2016-07-04 13:37:55 +00:00
if(debug)Serial.println("initialization failed!");
2015-07-13 14:49:36 +00:00
return;
}
2016-07-04 13:37:55 +00:00
if(debug)Serial.println("initialization done.");
2015-07-13 17:38:17 +00:00
2015-09-19 09:46:46 +00:00
//check_for_file("p001", "per");
2015-07-13 17:38:17 +00:00
2015-07-13 17:09:27 +00:00
box = new Beerbox;
box = read_beerbox(box);
2015-07-13 14:49:36 +00:00
persons = readAllPersons();
2015-09-19 09:46:46 +00:00
lcd.print("Drink: _");
2015-09-18 17:32:11 +00:00
lcd.setCursor(0, 1);
lcd.print(box->drinks[0].name);
currentDrink = 0;
box->waiting = false;
2015-11-19 19:38:42 +00:00
//turnOn led
digitalWrite(led,HIGH);
ledTime = millis();
2015-07-13 14:49:36 +00:00
}
void loop() {
2015-07-16 13:39:44 +00:00
checkFinger();
checkRFID();
2015-09-18 17:32:11 +00:00
checkButton();
2015-07-13 17:38:17 +00:00
boxTimer();
2015-11-19 19:38:42 +00:00
ledTimer();
bluetoothCommands();
serialCom();
2015-07-13 14:49:36 +00:00
}//end loop
2015-07-16 13:39:44 +00:00
2015-07-13 14:49:36 +00:00
2015-07-13 17:38:17 +00:00
void check_for_file(String filename, String extension) {
2015-07-13 14:49:36 +00:00
String str = filename + '.' + extension;
char* buf = NULL;
str.toCharArray(buf, str.length() + 1);
2015-07-13 17:38:17 +00:00
if (SD.exists(str)) {
2016-07-04 13:37:55 +00:00
if(debug)Serial.println(str + " exists.");
2015-07-13 14:49:36 +00:00
}
else {
2016-07-04 13:37:55 +00:00
if(debug)Serial.println(str + " doesn't exist.");
2015-07-13 14:49:36 +00:00
}
}
2015-07-13 17:09:27 +00:00
//BEYOND THIS POINT IS THE LEYER OF BEERBOX -- ENTER AT YOUR OWN RISK######################################
2015-07-13 17:09:27 +00:00
char tmp_filename[FILE_NAME_LEN + FILE_EXTENSION_LEN + 2];
2015-07-13 17:38:17 +00:00
Beerbox* read_beerbox(Beerbox *box) {
2015-07-13 17:09:27 +00:00
File read;
int num_read = 0;
int index;
char tmp[(DRINK_NAME_MAX_LENGTH + 1) * NUM_OF_DRINKS];
int i = 0;
read = SD.open("bb.con", FILE_READ);
2015-07-13 17:38:17 +00:00
if (read == false) {
2015-07-13 17:09:27 +00:00
2016-07-04 13:37:55 +00:00
if(debug)Serial.print("error while reading!\n");
if(debug)Serial.print("-ABORT!\n\n");
2015-07-13 17:38:17 +00:00
while (1);
2015-07-13 17:09:27 +00:00
}
2015-09-19 09:46:46 +00:00
//get drinks
2015-07-13 17:38:17 +00:00
for (i = 0 ; i < NUM_OF_DRINKS ; i++) {
2015-07-13 17:09:27 +00:00
read_line_from_file(read, tmp, sizeof(tmp));
2015-07-13 17:38:17 +00:00
if (strlen(tmp)) {
sscanf(tmp, " drink number %d: %s", &index, &box->drinks[i].name);
2015-07-13 17:09:27 +00:00
read_line_from_file(read, tmp, sizeof(tmp));
2015-07-13 17:38:17 +00:00
sscanf(tmp, " %*s %d ", &box->drinks[i].price);
2015-07-13 17:09:27 +00:00
2015-07-13 17:38:17 +00:00
} else {
strcpy(box->drinks[i].name, "slot empty");
box->drinks[i].price = -1;
2015-07-13 17:09:27 +00:00
}
}
2015-07-13 17:38:17 +00:00
for (i = 0; (i < NUM_OF_DRINKS) && (box->drinks[i].price != -1); i++) {
sprintf(toprint, "drink number %i: %s\nprice: %d\n", i , box->drinks[i].name, box->drinks[i].price);
2016-07-04 13:37:55 +00:00
if(debug)Serial.println(toprint);
2015-07-13 17:09:27 +00:00
}
2015-07-13 17:38:17 +00:00
if (i < NUM_OF_DRINKS) {
sprintf(toprint, "Slots %d - %d are not in use!\n", i + 1, NUM_OF_DRINKS);
box->maxDrink = i;
2016-07-04 13:37:55 +00:00
if(debug)Serial.println(toprint);
2015-07-13 17:09:27 +00:00
}
read.close();
return box;
}
bool personExists(char *filename){
if((strcmp(strlwr(filename + (strlen(filename) - 4)), ".per")==0)&&(filename[0]=='P')){
//valid person name
if(SD.exists(filename))return true;
}
return false;
}
2015-07-13 17:38:17 +00:00
Person read_person(Beerbox *box, char *filename) {
2015-07-13 17:09:27 +00:00
Person aperson;
File read;
char tmp[25];//longest line is rfid_uuid
2015-07-13 17:09:27 +00:00
2015-09-19 09:46:46 +00:00
//giving the full filename here, since it makes stuff easier
2016-07-04 13:37:55 +00:00
//if(debug)Serial.print("The filename is: ");
//if(debug)Serial.println(filename);
2015-09-19 09:46:46 +00:00
read = SD.open(filename, FILE_READ);
2015-07-13 17:38:17 +00:00
if (read == false) {
2015-07-13 17:09:27 +00:00
2016-07-04 13:37:55 +00:00
if(debug)Serial.print("error while reading!\n");
if(debug)Serial.print("ABORT!\n\n");
2015-07-13 17:38:17 +00:00
while (-1);
2015-07-13 17:09:27 +00:00
}
strcpy(aperson.file_name, filename);
//reset momentary array
2015-09-19 09:46:46 +00:00
for (int i = 0; i < NUM_OF_DRINKS; i++) {
2015-07-13 17:09:27 +00:00
aperson.drinks_taken[i] = -1;
}
//First read all the metadata
//name
2015-07-13 17:09:27 +00:00
read_line_from_file(read, tmp, sizeof(tmp));
strcpy(aperson.name, tmp);
//rfid_uuid
2015-07-13 17:32:39 +00:00
memset(aperson.rfid_uuid, 0, 13);
2015-07-13 17:09:27 +00:00
read_line_from_file(read, tmp, sizeof(tmp));
sscanf(tmp, "rfid_uuid: %12s", &aperson.rfid_uuid);
//if(debug)Serial.println(aperson.rfid_uuid);
read_line_from_file(read, tmp, sizeof(tmp));
sscanf(tmp, "finger_uuid: %d", &aperson.finger_uuid);
2016-07-04 13:37:55 +00:00
//if(debug)Serial.println(aperson.finger_uuid);
//credits_left
2015-07-13 17:09:27 +00:00
read_line_from_file(read, tmp, sizeof(tmp));
sscanf(tmp, "credits_left: %d", &aperson.credits_left);
2016-07-04 13:37:55 +00:00
//if(debug)Serial.println(aperson.credits_left);
2015-07-13 17:09:27 +00:00
2015-07-13 17:38:17 +00:00
while (read_line_from_file(read, tmp, sizeof(tmp)), strlen(tmp) > 0) {
int tmpCount = 0;
int tmpDrink = 0;
sscanf(tmp, "drink_Count_%d: %d", &tmpDrink, &tmpCount);
if (strlen(tmp)) {
2016-07-04 13:37:55 +00:00
//if(debug)Serial.print("drink: ");
//if(debug)Serial.print(tmpDrink);
//if(debug)Serial.print(" count: ");
//if(debug)Serial.println(tmpCount);
aperson.drinks_taken[tmpDrink] = tmpCount;
2015-07-13 17:09:27 +00:00
}
}
if (aperson.finger_uuid > box->maxID) box->maxID = aperson.finger_uuid;
//if(debug)print_person(box, &aperson,&Serial);
print_person_JSON(box,&aperson,&Serial,false);
2015-07-13 17:09:27 +00:00
read.close();
return aperson;
}
void print_person(Beerbox *box, Person *aperson, HardwareSerial* com) {
2015-07-13 17:09:27 +00:00
sprintf(toprint, "\nPerson is called \"%s\" and has the filename \"%s\".\n", aperson->name, aperson->file_name);
com->write(toprint);
sprintf(toprint, "rfid_uuid: %s\n", aperson->rfid_uuid);
com->write(toprint);
sprintf(toprint, "finger_uuid: %u\n", aperson->finger_uuid);
com->print(toprint);
sprintf(toprint, "credits_left: %u\n", aperson->credits_left);
com->print(toprint);
2015-07-13 17:09:27 +00:00
for (int i = 0; i < box->maxDrink; i++) {
2015-07-13 17:38:17 +00:00
if (aperson->drinks_taken[i] != -1) {
sprintf(toprint, "\nDrink: %s\n", box->drinks[i].name);
com->write(toprint);
sprintf(toprint, "Drink %d: %d\n", i, aperson->drinks_taken[i]);
com->write(toprint);
sprintf(toprint, "Total: %d.%02d Euro\n", aperson->drinks_taken[i]*box->drinks[i].price / 100, (aperson->drinks_taken[i]*box->drinks[i].price) % 100);
com->write(toprint);
2015-07-13 17:09:27 +00:00
}
}
2015-07-13 17:38:17 +00:00
2015-07-13 17:09:27 +00:00
}
int update_pers_file() {
Person thisPerson = persons[lastPersonIndex];
2015-07-13 17:09:27 +00:00
File write;
char tmp[25];
2015-07-13 17:09:27 +00:00
2015-09-19 09:46:46 +00:00
int i = 0;
2016-07-04 13:37:55 +00:00
//if(debug)Serial.println(thisPerson.file_name);
write = SD.open(thisPerson.file_name, FILE_WRITE);
2015-07-13 17:38:17 +00:00
if (write == NULL) {
2016-07-04 13:37:55 +00:00
if(debug)Serial.print("error while reading!\n");
if(debug)Serial.print("ABORT!\n\n");
2015-07-13 17:38:17 +00:00
while (-1);
2015-07-13 17:09:27 +00:00
}
write.seek(0);
2015-07-13 17:09:27 +00:00
sprintf(tmp, "%s\n", thisPerson.name);
write.write(tmp, strlen(tmp));
sprintf(tmp, "rfid_uuid: %s\n", thisPerson.rfid_uuid);
2015-07-13 17:09:27 +00:00
write.write(tmp, strlen(tmp));
sprintf(tmp, "finger_uuid: %u\n", thisPerson.finger_uuid);
2015-07-13 17:09:27 +00:00
write.write(tmp, strlen(tmp));
sprintf(tmp, "credits_left: %u\n", thisPerson.credits_left);
2015-07-13 17:09:27 +00:00
write.write(tmp, strlen(tmp));
for (i = 0; i < box->maxDrink; i++) {
2015-07-13 17:09:27 +00:00
if (thisPerson.drinks_taken[i] != -1) {
sprintf(tmp, "\ndrink_Count_%d: %d\n", i, thisPerson.drinks_taken[i]);
2015-07-13 17:09:27 +00:00
write.write(tmp, strlen(tmp));
2016-07-04 13:37:55 +00:00
if(debug)Serial.println(tmp);
2015-07-13 17:09:27 +00:00
}
}
write.close();
return 0;
}
2015-07-13 17:38:17 +00:00
char* read_from_file_until(File stream, char *str, int max_len, char until) {
2015-07-13 17:09:27 +00:00
int i = 0;
int tmp_int = 0;
memset(str, 0, max_len);
2015-07-13 17:38:17 +00:00
for (i = 0; (tmp_int != until) && (i < (max_len - 1)) && (tmp_int != -1); i++) {
2015-07-13 17:09:27 +00:00
tmp_int = stream.read();
2016-07-04 13:37:55 +00:00
//if(debug)Serial.print("%c", tmp_int);
2015-07-13 17:09:27 +00:00
str[i] = tmp_int;
}
2015-07-13 17:38:17 +00:00
if (tmp_int == -1) {
2015-07-13 17:09:27 +00:00
//May occur more often as the function tries to read a certain number of drinks.
2016-07-04 13:37:55 +00:00
//if(debug)Serial.print("END OF FILE REACHED!\nABORT!!\n\n");
2015-07-13 17:09:27 +00:00
str[0] = 0;
return str;
}
2015-07-13 17:38:17 +00:00
if (str[0] != '\n')str[i - 1] = 0;
2015-07-13 17:09:27 +00:00
return str;
}
2015-07-13 17:38:17 +00:00
char *read_line_from_file(File stream, char *str, int max_len) {
2015-07-13 17:09:27 +00:00
2015-07-13 17:38:17 +00:00
do {
2015-07-13 17:09:27 +00:00
str = read_from_file_until(stream, str, max_len, '\n');
2015-07-13 17:38:17 +00:00
} while ((str[0] == '\n'));
2015-07-13 17:09:27 +00:00
return str;
}
2015-07-13 17:38:17 +00:00
2015-07-16 13:39:44 +00:00
2015-07-13 17:09:27 +00:00
Person* readAllPersons () {
2015-09-19 09:46:46 +00:00
File dir = SD.open("/");
dir.rewindDirectory();
box->personCount = 0;
//count the valid persons:
2015-09-19 09:46:46 +00:00
while (true) {
File entry = dir.openNextFile();
if (! entry) {// no more files
break;
}
if (!entry.isDirectory()) {
if ((strcmp(strlwr(entry.name() + (strlen(entry.name()) - 4)), ".per")==0)&&(entry.name()[0]=='P'))
{
box->personCount++; //Yeah it is a person!
}
}
entry.close();
}
//now store them
2016-07-04 13:37:55 +00:00
//if(debug)Serial.print("count:");
//if(debug)Serial.print(box->personCount);
Person* readPersons = new Person[box->personCount];
int counter = 0;
dir.rewindDirectory();
while (true) {
File entry = dir.openNextFile();
if (! entry) {// no more files
2015-09-19 09:46:46 +00:00
break;
}
if (!entry.isDirectory()) {
int8_t len = strlen(entry.name());
if ((strstr(strlwr(entry.name() + (len - 4)), ".per"))&&(entry.name()[0]=='P'))
2015-09-19 09:46:46 +00:00
{
//Yeah it is a person!
2016-07-04 13:37:55 +00:00
//if(debug)Serial.print("Person: ");
//if(debug)Serial.println(entry.name());
2015-09-19 09:46:46 +00:00
Person thisPerson = read_person(box, entry.name());
readPersons[counter] = thisPerson;
counter++;
2015-09-19 09:46:46 +00:00
}
}
entry.close();
}
dir.close();
if(debug)Serial.println("Read all Persons!");
return readPersons;
2015-09-19 09:46:46 +00:00
}