#include #include #include #include "beerbox.h" #include #include #include #include #include Adafruit_Fingerprint finger = Adafruit_Fingerprint(&Serial2); LiquidCrystal_I2C lcd(0x38, 8, 2); // 0x38 for PCF***A on address 000 #define debug 1 //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; 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); 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(str)) { 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; } 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; } 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; //if(debug)print_person(box, &aperson,&Serial); print_person_JSON(box,&aperson,&Serial,false); read.close(); return aperson; } void print_person(Beerbox *box, Person *aperson, HardwareSerial* com) { 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); for (int i = 0; i < box->maxDrink; i++) { 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); } } } 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(); box->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)&&(entry.name()[0]=='P')) { box->personCount++; //Yeah it is a person! } } entry.close(); } //now store them //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 break; } if (!entry.isDirectory()) { int8_t len = strlen(entry.name()); if ((strstr(strlwr(entry.name() + (len - 4)), ".per"))&&(entry.name()[0]=='P')) { //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 Persons!"); return readPersons; }