beerbox/beerbox.ino
Lukas Bachschwell df94ff0654 moved maxID to beerbox struct and update in readPerson
moved drinksMax to beerbox struct and refactored to maxDrink
added if(debug) to all serial write and serial print statements

Moved BLE com to seperat file and added command and subcommandparsing
Added filename JSON method
2016-07-07 09:52:14 +02:00

421 lines
9.6 KiB
C++

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