working version of song control with initialization from sd card

Dependencies:   MFRC522 NRF2401P SDFileSystem SPI_TFT_ILI9341 TFT_fonts mbed

Fork of Song_Control by Malcolm McCulloch

Files at this revision

API Documentation at this revision

Comitter:
dxyang
Date:
Mon Feb 29 14:38:13 2016 +0000
Parent:
7:0aee09577ad3
Child:
9:72e93d9ddc8c
Commit message:
added posho functionality screens (lockout, one user at a time)

Changed in this revision

hub.cpp Show annotated file Show diff for this revision Revisions of this file
--- a/hub.cpp	Mon Feb 29 11:39:29 2016 +0000
+++ b/hub.cpp	Mon Feb 29 14:38:13 2016 +0000
@@ -79,7 +79,8 @@
     waitForRfid,
     batterySelectAction,
     batterySelectNumberForPickup,
-    batterySelectNumberForDropoff
+    batterySelectNumberForDropoff,
+    poshoSelectKilograms
 };
 enum HubScreenStageH currentScreenH = initialScanRfid;
 
@@ -106,7 +107,8 @@
 // Data is being logged and collected
 // these actions depend on a known user using the system
 enum HubActionForLoggingH {
-    hubAction_RfidScanned,
+    hubAction_BatteryRfidScanned,
+    hubAction_PoshoRfidScanned,
     hubAction_Exit,
     hubAction_OneBatteryDropped,
     hubAction_TwoBatteryDropped,
@@ -116,6 +118,23 @@
     hubAction_ThreeBatteryPicked
 };
 
+// any rfid can log errors regarding an unknown tag being read
+enum HubLoggingRfidSourceH {
+    source_battery,
+    source_posho,
+    source_incubator
+};
+
+// price per kilogram of material to be used with the posho
+int poshoPricePerKgH;
+
+// flag for if the posho is already in use; multiple people cannot use at once
+char flagPoshoAlreadyInUseH = 0;
+Ticker tickPoshoInUseClearH;
+int timeForOneKgH;
+int timeForTwoKgH;
+int timeForThreeKgH;
+
 /*************************************************************************************************/
 /* Set a flag when an interrupt is detected */
 /*************************************************************************************************/
@@ -179,12 +198,21 @@
 void int1sH()
 { flag1sH=1; }
 
+/**
+ *  interrupt to clear the posho is in use flag after a designated time
+ */
+void interruptPoshoInUseClearH()
+{ 
+    flagPoshoAlreadyInUseH = 0;
+    tickPoshoInUseClearH.detach();
+}
+
 /*************************************************************************************************/
 /* Transfer Info */
 /*************************************************************************************************/
 /**
-* Sends a time stamp
-*/
+ * Sends a time stamp
+ */
 void txTimeH()
 {
 #ifdef debug
@@ -199,8 +227,8 @@
 }
 
 /**
-* Sends max Current
-*/
+ * Sends max Current
+ */
 void txCurrentH()
 {
 #ifdef debug
@@ -214,8 +242,8 @@
 }
 
 /**
-* Slow interrupt routine for every 1 second
-*/
+ * Slow interrupt routine for every 1 second
+ */
 void do1sH()
 {
     flag1sH = 0;
@@ -234,19 +262,28 @@
 }
 
 /**
-* Sends a signal to a locker that the current user is picking up numBatteries batteries
-*/
+ * Sends a signal to a locker that the current user is picking up numBatteries batteries
+ * @param numBatteries - int representing number of batteries user is picking up
+ */
 void txBatteryPickUp(int numBatteries) {
 
 }
 
 /**
-* Sends a signal to a locker that the current user is dropping off numBatteries batteries
-*/
+ * Sends a signal to a locker that the current user is dropping off numBatteries batteries
+ * @param numBatteries - int representing number of batteries user is dropping off
+ */
 void txBatteryDropOff(int numBatteries) {
 
 }
 
+/**
+ * Sends a signal to a services mbed to schedule the posho/husker for use for x kilograms
+ * @param numKilograms - int representing number of kilograms user is processing
+ */
+void txPoshoSerialUse(int numKilograms) {
+
+}
 
 /*************************************************************************************************/
 /* Initialization */
@@ -425,11 +462,51 @@
 #endif
        createNewUserH(rfid, accountCredit, locker, batterySubscription, batteriesOut, podID);
     }
+    fclose(fp);
+
 #ifdef debug
         printf("Users created\n\r");
 #endif
 }
 
+/**
+ *  Initialize posho functionality 
+ */
+void initializePoshoFunctionality() {
+    spiSD();
+    FILE *fp = fopen("/sd/poshoInit.txt", "r");
+    
+    if (fp == NULL) {
+#ifdef debug
+        printf("User text file can't be opened");
+#endif
+        return;
+    }
+
+    // read a price per kg value.
+    int32_t poshoPricePerKg;
+    int32_t timeForOneKg;
+    int32_t timeForTwoKg;
+    int32_t timeForThreeKg;
+
+    if (fscanf(fp,"%d %*c %*s",&poshoPricePerKg)!= 1) writeError("Posho: cannot read price to use");
+    if (fscanf(fp,"%d %*c %*s",&timeForOneKg)!= 1) writeError("Posho: cannot read time to use");
+    if (fscanf(fp,"%d %*c %*s",&timeForTwoKg)!= 1) writeError("Posho: cannot read time to use");
+    if (fscanf(fp,"%d %*c %*s",&timeForThreeKg)!= 1) writeError("Posho: cannot read time to use");
+    fclose(fp);
+
+    poshoPricePerKgH = poshoPricePerKg;
+    timeForOneKgH = timeForOneKg;
+    timeForTwoKgH = timeForTwoKg;
+    timeForThreeKgH = timeForThreeKg;
+
+#ifdef debug
+        printf("Posho values initialized\n\r");
+        printf("Price per kg: %d\n\r", poshoPricePerKgH);
+        printf("Time for 1: %d, 2: %d, and 3: %d kilograms\n\r", timeForOneKgH, timeForTwoKgH, timeForThreeKgH);
+#endif
+}
+
 /*************************************************************************************************/
 /* Logging */
 /*************************************************************************************************/
@@ -454,8 +531,11 @@
 
     // append relevant information for action
     switch (action) {
-        case hubAction_RfidScanned:
-            strcat(logLine, " R ");
+        case hubAction_BatteryRfidScanned:
+            strcat(logLine, " R B ");
+            break;
+        case hubAction_PoshoRfidScanned:
+            strcat(logLine, " R P ");
             break;
         case hubAction_Exit:
             strcat(logLine, " X ");
@@ -505,7 +585,7 @@
  * Log an error - RFID not associated with a known user is scanned
  * @param unknownRfid - uint32 for the unique ID of the unknown rfid tag
  */
-void logErrorUnknownRfidScannedH(uint32_t unknownRfid)
+void logErrorUnknownRfidScannedH(uint32_t unknownRfid, HubLoggingRfidSourceH source)
 { 
     // Append to a log text file
     char * name = "/sd/HubLog.txt";
@@ -519,7 +599,17 @@
     sprintf(logLine, "%x", seconds);
 
     // RFID action
-    strcat(logLine, " R X ");
+    switch (source) {
+        case source_battery:
+            strcat(logLine, " R X B ");
+            break;
+        case source_posho:
+            strcat(logLine, " R X P");
+            break;
+        case source_incubator:
+            strcat(logLine, " R X I");
+            break;
+    }
 
     // include just the RFID (indicates that no known user was found)
     char rfidBuffer[20];
@@ -699,7 +789,7 @@
         printf("ID:%u\n\r", actualRfid);
 #endif
         // log the error interaction
-        logErrorUnknownRfidScannedH(actualRfid);
+        logErrorUnknownRfidScannedH(actualRfid, source_battery);
 
         // let user know tag wasn't found
         TFT_H.cls();
@@ -712,7 +802,7 @@
     }
     
     // log user scan
-    logActionWithUserInfoH(hubAction_RfidScanned, foundUserIndex);
+    logActionWithUserInfoH(hubAction_BatteryRfidScanned, foundUserIndex);
 
     // Display info about the user 
     char authorizationFlag = 0;
@@ -896,11 +986,153 @@
 /* Misc Services */
 /*************************************************************************************************/
 /**
- *  Do if Posho RFID flag is set. Add posho functionality later.
+ *  Do if Posho RFID flag is set. Reads rfid and checks user table for a positive balance. 
  */
 void doPoshoRfidH()
 {
     flagPoshoRfidH = 0;
+
+    // is there a new readable card?
+    if (!PoshoRfChipH.PICC_IsNewCardPresent()) {
+        return;
+    }
+
+    if (!PoshoRfChipH.PICC_ReadCardSerial()) {
+#ifdef debug
+        printf("Card not readable\n\r");
+#endif
+        return;
+    }
+    
+    // is the posho already in use?
+    if (flagPoshoAlreadyInUseH) {
+        TFT_H.cls();
+        TFT_H.locate(0,0);
+        TFT_H.printf("Posho in use\n\r");
+        wait(1);
+        currentScreenH = initialScanRfid;
+        return;
+    }
+
+    // get the id of the scanned tag 
+    uint8_t tempReadingRfid[4]; 
+    for(uint8_t i = 0; i < PoshoRfChipH.uid.size; i++) {
+        tempReadingRfid[i] = PoshoRfChipH.uid.uidByte[i];
+    }
+    
+    // concatenate the 4 bytes into a single integer via bit shifting
+    uint32_t actualRfid = ((((uint32_t)tempReadingRfid[0] << 24) | 
+                              ((uint32_t)tempReadingRfid[1] << 16)) | 
+                             (((uint32_t)tempReadingRfid[2] << 8) | 
+                              ((uint32_t)tempReadingRfid[3] << 0)));
+
+    // find the user info
+    char foundUserFlag = 0;
+    int foundUserIndex;
+    for (int i = 0; i < userCountH; i++) {
+        if (allUsersH[i].rfid == actualRfid) {
+            currentUserH = i;
+            foundUserIndex = i;
+            foundUserFlag = 1;
+            break;
+        }
+    }
+
+    // if the user is found, set the global variable for current user interacting with the system
+    // if the user isn't found, log that an rfid without a user was used and display
+    if (!foundUserFlag) {
+#ifdef debug
+        printf("User not found\n\r");
+        printf("ID:%u\n\r", actualRfid);
+#endif
+        // log the error interaction
+        logErrorUnknownRfidScannedH(actualRfid, source_posho);
+
+        // let user know tag wasn't found
+        TFT_H.cls();
+        TFT_H.locate(0,0);
+        TFT_H.printf("User not found\n\r");
+        TFT_H.printf("ID:%u\n\r", actualRfid);
+        wait(1);
+        currentScreenH = initialScanRfid;
+        return;
+    }
+    
+    // log user scan
+    logActionWithUserInfoH(hubAction_PoshoRfidScanned, foundUserIndex);
+
+    // Display info about the user 
+    char authorizationFlag = 0;
+    TFT_H.cls();
+    TFT_H.locate(0,0);
+    TFT_H.printf("UserID: %u\n\r", actualRfid);
+    int userAccountBalance = allUsersH[foundUserIndex].accountCredit;
+    TFT_H.printf("Balance:%d\n\r", userAccountBalance);
+    if (userAccountBalance > 1*poshoPricePerKgH) {
+        authorizationFlag = 1;
+    }
+    TFT_H.printf("Authorization:%s\n\r", (authorizationFlag)? "YES":"NO");
+
+
+    // if not authorized for batteries, return to main screen
+    wait(1);
+    if (!authorizationFlag) {
+        currentScreenH = initialScanRfid;
+        return;
+    }
+
+    // otherwise, ask user how may kg of material to process?
+    TFT_H.cls();
+    TFT_H.locate(0,0);
+    TFT_H.printf("UserID: %u\n\r\n\r", actualRfid);
+
+    TFT_H.printf("Action: Posho\n\r");
+    TFT_H.locate(0,160);
+    TFT_H.printf("How many kilos?\n\r");
+    TFT_H.locate(0,200);
+    if (userAccountBalance > 3*poshoPricePerKgH) {
+        TFT_H.printf("  1    2    3  exit");
+    } else if (userAccountBalance > 2*poshoPricePerKgH) {
+        TFT_H.printf("  1    2       exit");
+    } else {
+        TFT_H.printf("  1            exit");
+    }
+
+    // go to wait for selection input and reset button flags
+    currentScreenH = poshoSelectKilograms;
+    clearAllUserInitiatedFlagsH();
+    return;
+}
+
+/**
+ *  Prepare to active the posho and husker for serial use. Change user balance as necessary
+ *  and send corresponding signal.
+ *  @param numKilograms - int for number of kilograms to be processed
+ *  @param userIndex - int representing index of user in user table
+ */
+void poshoSerialUse(int numKilograms, int userIndex) {
+    flagPoshoAlreadyInUseH = 1;
+
+    switch (numKilograms) {
+        case 1:
+            tickPoshoInUseClearH.attach(&interruptPoshoInUseClearH, (float)timeForOneKgH);
+            break;
+        case 2:
+            tickPoshoInUseClearH.attach(&interruptPoshoInUseClearH, (float)timeForTwoKgH);
+            break;
+        case 3:
+            tickPoshoInUseClearH.attach(&interruptPoshoInUseClearH, (float)timeForThreeKgH);
+            break;
+    } 
+    allUsersH[userIndex].accountCredit -= numKilograms*poshoPricePerKgH;
+    TFT_H.cls();
+    TFT_H.locate(0,0);
+    TFT_H.printf("UserID: %u\n\r\n\r", allUsersH[userIndex].rfid);
+    TFT_H.printf("New balance: %d\n\r", allUsersH[userIndex].accountCredit);
+    txPoshoSerialUse(numKilograms);
+    wait(1);
+    currentScreenH = initialScanRfid;
+    return;
 }
 
 /**
@@ -949,6 +1181,7 @@
     initializeRfidReadersH();
     initializeLCD_H();
     initializeUsersFromSD_H();
+    initializePoshoFunctionality();
 }
 
 void loopHub(){
@@ -1037,6 +1270,21 @@
                 }
                 break;
             }
+            case poshoSelectKilograms: {
+                if (allUsersH[currentUserH].accountCredit > 3*poshoPricePerKgH) {
+                    if (flagButtonOneH) poshoSerialUse(1, currentUserH);
+                    if (flagButtonTwoH) poshoSerialUse(2, currentUserH);
+                    if (flagButtonThreeH) poshoSerialUse(3, currentUserH);
+                    if (flagButtonFourH) cancelPressedH(currentUserH);
+                } else if (allUsersH[currentUserH].accountCredit > 2*poshoPricePerKgH) {
+                    if (flagButtonOneH) poshoSerialUse(1, currentUserH);
+                    if (flagButtonTwoH) poshoSerialUse(2, currentUserH);
+                    if (flagButtonFourH) cancelPressedH(currentUserH);
+                } else {
+                    if (flagButtonOneH) poshoSerialUse(1, currentUserH);
+                    if (flagButtonFourH) cancelPressedH(currentUserH);
+                }
+            }
         }
     }
 }
\ No newline at end of file