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

Committer:
dxyang
Date:
Mon Feb 29 10:55:39 2016 +0000
Revision:
5:88c516cf34e6
Parent:
3:86773d65ed58
Child:
6:00a132a076d5
working battery drop off/pickup

Who changed what in which revision?

UserRevisionLine numberNew contents of line
epgmdm 1:c2232b1eaf31 1 /**
epgmdm 1:c2232b1eaf31 2 * All the code associated to run the mbed as a hub.
epgmdm 1:c2232b1eaf31 3 * Link with locker
epgmdm 1:c2232b1eaf31 4 */
epgmdm 1:c2232b1eaf31 5 #include "mbed.h"
epgmdm 1:c2232b1eaf31 6 #include "utils.h"
epgmdm 2:d1eae91343a9 7 #include "NRF2401P.h"
dxyang 3:86773d65ed58 8
dxyang 3:86773d65ed58 9 #include "MFRC522.h"
dxyang 3:86773d65ed58 10 #include "SPI_TFT_ILI9341.h"
dxyang 3:86773d65ed58 11 #include "Arial24x23.h"
dxyang 3:86773d65ed58 12 #include "SDFileSystem.h"
dxyang 3:86773d65ed58 13
epgmdm 1:c2232b1eaf31 14 #define debug
epgmdm 1:c2232b1eaf31 15
dxyang 3:86773d65ed58 16 /*************************************************************************************************/
dxyang 3:86773d65ed58 17 /* Global variables */
dxyang 3:86773d65ed58 18 /*************************************************************************************************/
epgmdm 1:c2232b1eaf31 19 // tx nRF2401
epgmdm 2:d1eae91343a9 20 extern char txBuff[];
epgmdm 2:d1eae91343a9 21 extern NRF2401P nrf1;
epgmdm 2:d1eae91343a9 22 extern int channel;
epgmdm 1:c2232b1eaf31 23 long long addrLcker=0xBBBBBBBBBB;
dxyang 3:86773d65ed58 24
dxyang 3:86773d65ed58 25 // MFRC522 RfChip (SPI_MOSI, SPI_MISO, SPI_SCLK, SPI_CS, MF_RESET);
dxyang 3:86773d65ed58 26 MFRC522 BatteryRfChipH (PTD2, PTD3, PTD1, PTE25, PTB3);
dxyang 3:86773d65ed58 27 MFRC522 PoshoRfChipH (PTD2, PTD3, PTD1, PTB10, PTB11);
dxyang 3:86773d65ed58 28 MFRC522 IncubatorRfChipH (PTD2, PTD3, PTD1, PTC11, PTC10);
dxyang 3:86773d65ed58 29
dxyang 3:86773d65ed58 30 // tickers and flags for checking rfid statuses
dxyang 3:86773d65ed58 31 Ticker tickBatteryRfidH;
dxyang 3:86773d65ed58 32 Ticker tickPoshoRfidH;
dxyang 3:86773d65ed58 33 Ticker tickIncubatorRfidH;
dxyang 3:86773d65ed58 34 char flagBatteryRfidH = 0;
dxyang 3:86773d65ed58 35 char flagPoshoRfidH = 0;
dxyang 3:86773d65ed58 36 char flagIncubatorRfidH = 0;
dxyang 3:86773d65ed58 37
dxyang 3:86773d65ed58 38 //SPI_TFT_ILI9341(PinName mosi, PinName miso, PinName sclk,
dxyang 3:86773d65ed58 39 // PinName cs, PinName reset, PinName dc, const char* name ="TFT");
dxyang 3:86773d65ed58 40 SPI_TFT_ILI9341 TFT_H(PTD2, PTD3, PTD1, PTB2, PTB20, PTB18,"TFT");
dxyang 3:86773d65ed58 41
dxyang 3:86773d65ed58 42 // button interrupt signals and respective flags
dxyang 3:86773d65ed58 43 InterruptIn buttonOneH(PTC3);
dxyang 3:86773d65ed58 44 InterruptIn buttonTwoH(PTC2);
dxyang 3:86773d65ed58 45 InterruptIn buttonThreeH(PTA2);
dxyang 3:86773d65ed58 46 InterruptIn buttonFourH(PTB23);
dxyang 3:86773d65ed58 47 char flagButtonOneH = 0;
dxyang 3:86773d65ed58 48 char flagButtonTwoH = 0;
dxyang 3:86773d65ed58 49 char flagButtonThreeH = 0;
dxyang 3:86773d65ed58 50 char flagButtonFourH = 0;
dxyang 3:86773d65ed58 51
dxyang 3:86773d65ed58 52 // ticker that causes time to be displayed
dxyang 3:86773d65ed58 53 Ticker tickTimeCheckH;
dxyang 3:86773d65ed58 54 char flagTimeCheckH = 0;
dxyang 3:86773d65ed58 55
dxyang 3:86773d65ed58 56 // ticker that causes an interrupt to update the user table every 1/2 an hour
dxyang 3:86773d65ed58 57 Ticker tickerUpdateUserTableH;
dxyang 3:86773d65ed58 58 char flagUpdateUserTableH = 0;
dxyang 3:86773d65ed58 59
dxyang 3:86773d65ed58 60 // ticker that goes off every second
dxyang 3:86773d65ed58 61 unsigned char flag1sH = 0;
dxyang 3:86773d65ed58 62 Ticker tick1sHub;
dxyang 3:86773d65ed58 63
dxyang 3:86773d65ed58 64 // Maximum current that each cube can consume.
dxyang 3:86773d65ed58 65 float currentMaxH = 1.5;
dxyang 3:86773d65ed58 66
dxyang 3:86773d65ed58 67 // A hubUser can be assigned any of four lockers, each with a unique locker address
dxyang 3:86773d65ed58 68 enum LockerAddressH {
dxyang 3:86773d65ed58 69 lockerUnassigned,
dxyang 3:86773d65ed58 70 lockerOne,
dxyang 3:86773d65ed58 71 lockerTwo,
dxyang 3:86773d65ed58 72 lockerThree,
dxyang 3:86773d65ed58 73 lockerFour
dxyang 3:86773d65ed58 74 };
dxyang 3:86773d65ed58 75
dxyang 3:86773d65ed58 76 // The hub display screen can involve multiple stages
dxyang 3:86773d65ed58 77 enum HubScreenStageH {
dxyang 3:86773d65ed58 78 initialScanRfid,
dxyang 3:86773d65ed58 79 waitForRfid,
dxyang 3:86773d65ed58 80 batterySelectAction,
dxyang 3:86773d65ed58 81 batterySelectNumberForPickup,
dxyang 3:86773d65ed58 82 batterySelectNumberForDropoff
dxyang 3:86773d65ed58 83 };
dxyang 3:86773d65ed58 84 enum HubScreenStageH currentScreenH = initialScanRfid;
dxyang 3:86773d65ed58 85
dxyang 3:86773d65ed58 86 // hubUser struct containing the users uid, rfid, number of batteries, current account credit,
dxyang 3:86773d65ed58 87 // an enum corresponding to a locker channel address, and pod ID within a locker
dxyang 3:86773d65ed58 88 struct hubUserH {
dxyang 3:86773d65ed58 89 uint32_t uid;
dxyang 3:86773d65ed58 90 uint32_t rfid;
dxyang 3:86773d65ed58 91 int32_t accountCredit;
dxyang 3:86773d65ed58 92 enum LockerAddressH lockerID;
dxyang 3:86773d65ed58 93 int32_t podID;
dxyang 3:86773d65ed58 94 int32_t batteriesOut;
dxyang 3:86773d65ed58 95 int32_t batterySubscription;
dxyang 3:86773d65ed58 96 };
dxyang 3:86773d65ed58 97
dxyang 3:86773d65ed58 98 // community ID should be defined somewhere and accessible globally
dxyang 3:86773d65ed58 99 uint32_t communityID_H = 1;
dxyang 3:86773d65ed58 100
dxyang 3:86773d65ed58 101 // array to store all users and index of end of the current list
dxyang 3:86773d65ed58 102 hubUserH allUsersH[256];
dxyang 3:86773d65ed58 103 uint8_t userCountH = 0;
dxyang 3:86773d65ed58 104 uint8_t currentUserH;
dxyang 3:86773d65ed58 105
dxyang 3:86773d65ed58 106 // Data is being logged and collected
dxyang 3:86773d65ed58 107 // these actions depend on a known user using the system
dxyang 3:86773d65ed58 108 enum HubActionForLoggingH {
dxyang 3:86773d65ed58 109 hubAction_RfidScanned,
dxyang 3:86773d65ed58 110 hubAction_Exit,
dxyang 3:86773d65ed58 111 hubAction_OneBatteryDropped,
dxyang 3:86773d65ed58 112 hubAction_TwoBatteryDropped,
dxyang 3:86773d65ed58 113 hubAction_ThreeBatteryDropped,
dxyang 3:86773d65ed58 114 hubAction_OneBatteryPicked,
dxyang 3:86773d65ed58 115 hubAction_TwoBatteryPicked,
dxyang 3:86773d65ed58 116 hubAction_ThreeBatteryPicked
dxyang 3:86773d65ed58 117 };
dxyang 3:86773d65ed58 118
dxyang 3:86773d65ed58 119 /*************************************************************************************************/
dxyang 3:86773d65ed58 120 /* Set a flag when an interrupt is detected */
dxyang 3:86773d65ed58 121 /*************************************************************************************************/
dxyang 3:86773d65ed58 122 /**
dxyang 3:86773d65ed58 123 * Time check interrupt
dxyang 3:86773d65ed58 124 */
dxyang 3:86773d65ed58 125 void interruptTimeCheckH()
dxyang 3:86773d65ed58 126 { flagTimeCheckH = 1; }
dxyang 3:86773d65ed58 127
dxyang 3:86773d65ed58 128 /**
dxyang 3:86773d65ed58 129 * Update user table interrupt
dxyang 3:86773d65ed58 130 */
dxyang 3:86773d65ed58 131 void interruptUpdateUserTableH()
dxyang 3:86773d65ed58 132 { flagUpdateUserTableH = 1; }
dxyang 3:86773d65ed58 133
dxyang 3:86773d65ed58 134 /**
dxyang 3:86773d65ed58 135 * Battery RFID reader interrupt
dxyang 3:86773d65ed58 136 */
dxyang 3:86773d65ed58 137 void interruptBatteryRfidH()
dxyang 3:86773d65ed58 138 { flagBatteryRfidH = 1; }
dxyang 3:86773d65ed58 139
dxyang 3:86773d65ed58 140 /**
dxyang 3:86773d65ed58 141 * Posho RFID reader interrupt
dxyang 3:86773d65ed58 142 */
dxyang 3:86773d65ed58 143 void interruptPoshoRfidH()
dxyang 3:86773d65ed58 144 { flagPoshoRfidH = 1; }
dxyang 3:86773d65ed58 145
dxyang 3:86773d65ed58 146 /**
dxyang 3:86773d65ed58 147 * Incubator RFID reader interrupt
dxyang 3:86773d65ed58 148 */
dxyang 3:86773d65ed58 149 void interruptIncubatorRfidH()
dxyang 3:86773d65ed58 150 { flagIncubatorRfidH = 1; }
dxyang 3:86773d65ed58 151
dxyang 3:86773d65ed58 152 /**
dxyang 3:86773d65ed58 153 * buttone one interrupt
dxyang 3:86773d65ed58 154 */
dxyang 3:86773d65ed58 155 void interruptButtonOneH()
dxyang 3:86773d65ed58 156 { flagButtonOneH = 1; }
dxyang 3:86773d65ed58 157
dxyang 3:86773d65ed58 158 /**
dxyang 3:86773d65ed58 159 * buttone two interrupt
dxyang 3:86773d65ed58 160 */
dxyang 3:86773d65ed58 161 void interruptButtonTwoH()
dxyang 3:86773d65ed58 162 { flagButtonTwoH = 1; }
dxyang 3:86773d65ed58 163
dxyang 3:86773d65ed58 164 /**
dxyang 3:86773d65ed58 165 * buttone three interrupt
dxyang 3:86773d65ed58 166 */
dxyang 3:86773d65ed58 167 void interruptButtonThreeH()
dxyang 3:86773d65ed58 168 { flagButtonThreeH = 1; }
dxyang 3:86773d65ed58 169
dxyang 3:86773d65ed58 170 /**
dxyang 3:86773d65ed58 171 * buttone four interrupt
dxyang 3:86773d65ed58 172 */
dxyang 3:86773d65ed58 173 void interruptButtonFourH()
dxyang 3:86773d65ed58 174 { flagButtonFourH = 1; }
dxyang 3:86773d65ed58 175
epgmdm 2:d1eae91343a9 176 /**
epgmdm 2:d1eae91343a9 177 * Fast interrupt routine for every 1 second
epgmdm 2:d1eae91343a9 178 */
epgmdm 2:d1eae91343a9 179 void int1sH()
dxyang 3:86773d65ed58 180 { flag1sH=1; }
dxyang 3:86773d65ed58 181
dxyang 3:86773d65ed58 182 /*************************************************************************************************/
dxyang 3:86773d65ed58 183 /* Transfer Info */
dxyang 3:86773d65ed58 184 /*************************************************************************************************/
epgmdm 2:d1eae91343a9 185 /**
epgmdm 2:d1eae91343a9 186 * Sends a time stamp
epgmdm 2:d1eae91343a9 187 */
epgmdm 2:d1eae91343a9 188 void txTimeH()
epgmdm 2:d1eae91343a9 189 {
epgmdm 2:d1eae91343a9 190 #ifdef debug
epgmdm 2:d1eae91343a9 191 printf("Send time \n\r");
epgmdm 2:d1eae91343a9 192 #endif
epgmdm 2:d1eae91343a9 193 time_t now= time(NULL);
epgmdm 2:d1eae91343a9 194 sprintf(txBuff,"T %X",now);
epgmdm 2:d1eae91343a9 195 nrf1.transmitData(txBuff,strlen(txBuff));
epgmdm 2:d1eae91343a9 196 #ifdef debug
epgmdm 2:d1eae91343a9 197 printf("Tx %s [nrf:%s] \n\r", txBuff,nrf1.statusString());
epgmdm 2:d1eae91343a9 198 #endif
epgmdm 2:d1eae91343a9 199 }
epgmdm 2:d1eae91343a9 200
epgmdm 2:d1eae91343a9 201 /**
epgmdm 2:d1eae91343a9 202 * Sends max Current
epgmdm 2:d1eae91343a9 203 */
epgmdm 2:d1eae91343a9 204 void txCurrentH()
epgmdm 2:d1eae91343a9 205 {
epgmdm 2:d1eae91343a9 206 #ifdef debug
epgmdm 2:d1eae91343a9 207 printf("Send current \n\r");
epgmdm 2:d1eae91343a9 208 #endif
epgmdm 2:d1eae91343a9 209 sprintf(txBuff,"I %04X", *((int *) &currentMaxH));
epgmdm 2:d1eae91343a9 210 nrf1.transmitData(txBuff,strlen(txBuff));
epgmdm 2:d1eae91343a9 211 #ifdef debug
epgmdm 2:d1eae91343a9 212 printf("Tx %s [nrf:%s] \n\r", txBuff,nrf1.statusString());
epgmdm 2:d1eae91343a9 213 #endif
epgmdm 2:d1eae91343a9 214 }
epgmdm 1:c2232b1eaf31 215
epgmdm 2:d1eae91343a9 216 /**
epgmdm 2:d1eae91343a9 217 * Slow interrupt routine for every 1 second
epgmdm 2:d1eae91343a9 218 */
epgmdm 2:d1eae91343a9 219 void do1sH()
epgmdm 2:d1eae91343a9 220 {
dxyang 3:86773d65ed58 221 flag1sH = 0;
epgmdm 2:d1eae91343a9 222 #ifdef debug
epgmdm 2:d1eae91343a9 223 printf("Hub 1s \n\r");
epgmdm 2:d1eae91343a9 224 #endif
epgmdm 2:d1eae91343a9 225
epgmdm 2:d1eae91343a9 226 time_t now= time(NULL);
epgmdm 2:d1eae91343a9 227 if ((now % 60)==0){
epgmdm 2:d1eae91343a9 228 txTimeH();
epgmdm 2:d1eae91343a9 229 }
epgmdm 2:d1eae91343a9 230 txCurrentH();
epgmdm 2:d1eae91343a9 231 #ifdef debug
epgmdm 2:d1eae91343a9 232 printf("Tx %s [nrf:%s] \n\r", txBuff,nrf1.statusString());
epgmdm 2:d1eae91343a9 233 #endif
epgmdm 2:d1eae91343a9 234 }
dxyang 5:88c516cf34e6 235 /*************************************************************************************************/
dxyang 5:88c516cf34e6 236 /* Initialization */
dxyang 5:88c516cf34e6 237 /*************************************************************************************************/
epgmdm 2:d1eae91343a9 238 /**
dxyang 3:86773d65ed58 239 * Initialize system on reset and set the time from the terminal
dxyang 3:86773d65ed58 240 */
dxyang 3:86773d65ed58 241 void initializeTimeH()
dxyang 3:86773d65ed58 242 {
epgmdm 2:d1eae91343a9 243 // get the current time from the terminal
epgmdm 2:d1eae91343a9 244 struct tm t;
epgmdm 2:d1eae91343a9 245 printf("Enter current date :\n\r");
epgmdm 2:d1eae91343a9 246 printf("YYYY MM DD [enter]\n\r");
epgmdm 2:d1eae91343a9 247 scanf("%d %d %d", &t.tm_year, &t.tm_mon, &t.tm_mday);
epgmdm 2:d1eae91343a9 248 printf("Enter current time:\n\r");
epgmdm 2:d1eae91343a9 249 printf("HH MM SS [enter]\n\r");
epgmdm 2:d1eae91343a9 250 scanf("%d %d %d", &t.tm_hour, &t.tm_min, &t.tm_sec);
epgmdm 2:d1eae91343a9 251
epgmdm 2:d1eae91343a9 252 // adjust for tm structure required values
epgmdm 2:d1eae91343a9 253 t.tm_year = t.tm_year - 1900;
epgmdm 2:d1eae91343a9 254 t.tm_mon = t.tm_mon - 1;
epgmdm 2:d1eae91343a9 255
epgmdm 2:d1eae91343a9 256 // set the time
epgmdm 2:d1eae91343a9 257 set_time(mktime(&t));
dxyang 3:86773d65ed58 258 #ifdef debug
dxyang 3:86773d65ed58 259 printf("Time initialized\n\r");
dxyang 3:86773d65ed58 260 #endif
dxyang 3:86773d65ed58 261 }
dxyang 3:86773d65ed58 262
dxyang 3:86773d65ed58 263 /**
dxyang 3:86773d65ed58 264 * Initialize all the interrupts
dxyang 3:86773d65ed58 265 */
dxyang 3:86773d65ed58 266 void initializeInterruptsH()
dxyang 3:86773d65ed58 267 {
dxyang 3:86773d65ed58 268 tickTimeCheckH.attach(&interruptTimeCheckH, 5.0);
dxyang 3:86773d65ed58 269 tickBatteryRfidH.attach(&interruptBatteryRfidH, 1.0);
dxyang 3:86773d65ed58 270 tickPoshoRfidH.attach(&interruptPoshoRfidH, 1.0);
dxyang 3:86773d65ed58 271 tickIncubatorRfidH.attach(&interruptIncubatorRfidH, 1.0);
dxyang 3:86773d65ed58 272 tickerUpdateUserTableH.attach(&interruptUpdateUserTableH, 1800.0);
dxyang 3:86773d65ed58 273 buttonOneH.rise(&interruptButtonOneH);
dxyang 3:86773d65ed58 274 buttonTwoH.rise(&interruptButtonTwoH);
dxyang 3:86773d65ed58 275 buttonThreeH.rise(&interruptButtonThreeH);
dxyang 3:86773d65ed58 276 buttonFourH.rise(&interruptButtonFourH);
dxyang 3:86773d65ed58 277 tick1sHub.attach(&int1sH, 10.0);
dxyang 3:86773d65ed58 278
dxyang 3:86773d65ed58 279 #ifdef debug
dxyang 3:86773d65ed58 280 printf("Interrupts initialized\n\r");
dxyang 3:86773d65ed58 281 #endif
dxyang 3:86773d65ed58 282 }
dxyang 3:86773d65ed58 283
dxyang 3:86773d65ed58 284 /**
dxyang 3:86773d65ed58 285 * Initialize RFID readers
dxyang 3:86773d65ed58 286 */
dxyang 3:86773d65ed58 287 void initializeRfidReadersH()
dxyang 3:86773d65ed58 288 {
dxyang 3:86773d65ed58 289 BatteryRfChipH.PCD_Init();
dxyang 3:86773d65ed58 290 PoshoRfChipH.PCD_Init();
dxyang 3:86773d65ed58 291 IncubatorRfChipH.PCD_Init();
dxyang 3:86773d65ed58 292
dxyang 3:86773d65ed58 293 #ifdef debug
dxyang 3:86773d65ed58 294 uint8_t tempA = BatteryRfChipH.PCD_ReadRegister(MFRC522::VersionReg);
dxyang 3:86773d65ed58 295 printf("Battery MFRC522 version: %d\n\r", tempA & 0x07);
dxyang 3:86773d65ed58 296 printf("\n\r");
dxyang 3:86773d65ed58 297 uint8_t tempB = PoshoRfChipH.PCD_ReadRegister(MFRC522::VersionReg);
dxyang 3:86773d65ed58 298 printf("Posho MFRC522 version: %d\n\r", tempB & 0x07);
dxyang 3:86773d65ed58 299 printf("\n\r");
dxyang 3:86773d65ed58 300 uint8_t tempC = IncubatorRfChipH.PCD_ReadRegister(MFRC522::VersionReg);
dxyang 3:86773d65ed58 301 printf("Incubator MFRC522 version: %d\n\r", tempC & 0x07);
dxyang 3:86773d65ed58 302 printf("\n\r");
dxyang 3:86773d65ed58 303 #endif
dxyang 3:86773d65ed58 304
dxyang 3:86773d65ed58 305 #ifdef debug
dxyang 3:86773d65ed58 306 printf("RFID readers initialized\n\r");
dxyang 3:86773d65ed58 307 #endif
dxyang 3:86773d65ed58 308 }
dxyang 3:86773d65ed58 309
dxyang 3:86773d65ed58 310 /**
dxyang 3:86773d65ed58 311 * Initialize LCD screen
dxyang 3:86773d65ed58 312 */
dxyang 3:86773d65ed58 313 void initializeLCD_H()
dxyang 3:86773d65ed58 314 {
dxyang 3:86773d65ed58 315 TFT_H.background(Black); // set background to black
dxyang 3:86773d65ed58 316 TFT_H.foreground(White); // set chars to white
dxyang 3:86773d65ed58 317 TFT_H.cls(); // clear the screen
dxyang 3:86773d65ed58 318 TFT_H.set_font((unsigned char*) Arial24x23);
dxyang 3:86773d65ed58 319 TFT_H.set_orientation(3); //Portrait, wiring on left
dxyang 3:86773d65ed58 320 #ifdef debug
dxyang 3:86773d65ed58 321 printf("LCD initialized\n\r");
dxyang 3:86773d65ed58 322 #endif
dxyang 3:86773d65ed58 323 }
dxyang 3:86773d65ed58 324
dxyang 3:86773d65ed58 325 /**
dxyang 3:86773d65ed58 326 * Creates a new user by defining user attributes.
dxyang 3:86773d65ed58 327 * @param rfid - uint32_t corresponding to unique id of the RFID tag
dxyang 3:86773d65ed58 328 * @param accountCredit - int32 for user account balance (can be negative)
dxyang 3:86773d65ed58 329 * @param locker - int32_t for which locker (originaly 1-4) user is assigned
dxyang 3:86773d65ed58 330 * @param batterySubscription - max batteries user can get (can be 0)
dxyang 3:86773d65ed58 331 * @param batteriesOut - number of batteries user has out (usually 0 initially)
dxyang 3:86773d65ed58 332 * @param podID - pod associated with the user (originally 0-15) *must be 0 indexed*
dxyang 3:86773d65ed58 333 */
dxyang 3:86773d65ed58 334 void createNewUserH(uint32_t rfid, int32_t accountCredit, int32_t locker,
dxyang 3:86773d65ed58 335 int32_t batterySubscription, int32_t batteriesOut, int32_t podID)
dxyang 3:86773d65ed58 336 {
dxyang 3:86773d65ed58 337 allUsersH[userCountH].rfid = rfid;
dxyang 3:86773d65ed58 338 allUsersH[userCountH].accountCredit = accountCredit;
dxyang 3:86773d65ed58 339 switch(locker) {
dxyang 3:86773d65ed58 340 case 1:
dxyang 3:86773d65ed58 341 allUsersH[userCountH].lockerID = lockerOne;
dxyang 3:86773d65ed58 342 break;
dxyang 3:86773d65ed58 343 case 2:
dxyang 3:86773d65ed58 344 allUsersH[userCountH].lockerID = lockerTwo;
dxyang 3:86773d65ed58 345 break;
dxyang 3:86773d65ed58 346 case 3:
dxyang 3:86773d65ed58 347 allUsersH[userCountH].lockerID = lockerThree;
dxyang 3:86773d65ed58 348 break;
dxyang 3:86773d65ed58 349 case 4:
dxyang 3:86773d65ed58 350 allUsersH[userCountH].lockerID = lockerFour;
dxyang 3:86773d65ed58 351 break;
dxyang 3:86773d65ed58 352 default:
dxyang 3:86773d65ed58 353 allUsersH[userCountH].lockerID = lockerUnassigned;
dxyang 3:86773d65ed58 354 break;
dxyang 3:86773d65ed58 355 }
dxyang 3:86773d65ed58 356 allUsersH[userCountH].batterySubscription = batterySubscription;
dxyang 3:86773d65ed58 357 allUsersH[userCountH].batteriesOut = batteriesOut;
dxyang 3:86773d65ed58 358 allUsersH[userCountH].podID = podID;
dxyang 3:86773d65ed58 359
dxyang 3:86773d65ed58 360 // generate the user id, a 32 byte value
dxyang 3:86773d65ed58 361 // [community byte 1][community byte 2][locker byte 3][podID (1/2 byte) | 0000 (1/2 byte)]
dxyang 3:86773d65ed58 362 uint32_t actualUid = ((((uint32_t)communityID_H << 16) | ((uint32_t)locker << 8)) |
dxyang 3:86773d65ed58 363 ((uint32_t)podID << 4));
dxyang 3:86773d65ed58 364 allUsersH[userCountH].uid = actualUid;
dxyang 3:86773d65ed58 365
dxyang 3:86773d65ed58 366 userCountH++;
dxyang 3:86773d65ed58 367
dxyang 3:86773d65ed58 368 #ifdef debug
dxyang 3:86773d65ed58 369 printf("UserID (decimal):%u\n\r", actualUid);
dxyang 3:86773d65ed58 370 printf("**************************\n\r");
dxyang 3:86773d65ed58 371 #endif
dxyang 3:86773d65ed58 372 }
dxyang 3:86773d65ed58 373
dxyang 3:86773d65ed58 374 /**
dxyang 3:86773d65ed58 375 * Initialize system with users from users.txt on SD card
dxyang 3:86773d65ed58 376 */
dxyang 3:86773d65ed58 377 void initializeUsersFromSD_H()
dxyang 3:86773d65ed58 378 {
dxyang 3:86773d65ed58 379 spiSD();
dxyang 3:86773d65ed58 380 FILE *fp = fopen("/sd/users.txt", "r");
dxyang 3:86773d65ed58 381
dxyang 3:86773d65ed58 382 if (fp == NULL) {
dxyang 3:86773d65ed58 383 #ifdef debug
dxyang 3:86773d65ed58 384 printf("User text file can't be opened");
dxyang 3:86773d65ed58 385 #endif
dxyang 3:86773d65ed58 386 return;
dxyang 3:86773d65ed58 387 }
dxyang 3:86773d65ed58 388
dxyang 3:86773d65ed58 389 // the first line of the user file has the headers for the following roles - get to the next line
dxyang 3:86773d65ed58 390 char line[180];
dxyang 3:86773d65ed58 391 if (fgets(line, 180, fp) != NULL) {
dxyang 3:86773d65ed58 392 #ifdef debug
dxyang 3:86773d65ed58 393 printf("Format of text file:\n\r%s\n\r", line);
dxyang 3:86773d65ed58 394 printf("**************************\n\r");
dxyang 3:86773d65ed58 395 #endif
dxyang 3:86773d65ed58 396 }
dxyang 3:86773d65ed58 397
dxyang 3:86773d65ed58 398 // read a set of six values at a time, corresponding to a line, from the user text file. Generate a user per line.
dxyang 3:86773d65ed58 399 uint32_t rfid;
dxyang 3:86773d65ed58 400 int32_t accountCredit;
dxyang 3:86773d65ed58 401 int32_t locker;
dxyang 3:86773d65ed58 402 int32_t batterySubscription;
dxyang 3:86773d65ed58 403 int32_t batteriesOut;
dxyang 3:86773d65ed58 404 int32_t podID;
dxyang 3:86773d65ed58 405 while (fscanf(fp, "%u %d %d %d %d %d", &rfid, &accountCredit, &locker, &batterySubscription, &batteriesOut, &podID) != EOF) {
dxyang 3:86773d65ed58 406 #ifdef debug
dxyang 3:86773d65ed58 407 printf("rfid: %u\n\r accountCredit: %d\n\r locker: %d\n\r batterySubscription: %d\n\r batteriesOut: %d\n\r podID: %d\n\r",
dxyang 3:86773d65ed58 408 rfid, accountCredit, locker, batterySubscription, batteriesOut, podID);
dxyang 3:86773d65ed58 409 #endif
dxyang 3:86773d65ed58 410 createNewUserH(rfid, accountCredit, locker, batterySubscription, batteriesOut, podID);
dxyang 3:86773d65ed58 411 }
dxyang 3:86773d65ed58 412 #ifdef debug
dxyang 3:86773d65ed58 413 printf("Users created\n\r");
dxyang 3:86773d65ed58 414 #endif
dxyang 3:86773d65ed58 415 }
dxyang 3:86773d65ed58 416
dxyang 3:86773d65ed58 417 /*************************************************************************************************/
dxyang 3:86773d65ed58 418 /* Logging */
dxyang 3:86773d65ed58 419 /*************************************************************************************************/
dxyang 3:86773d65ed58 420 /**
dxyang 3:86773d65ed58 421 * Log an action from a selection of predefined actions done by the current user
dxyang 3:86773d65ed58 422 * Actions used with this method should require a known user to be using system
dxyang 3:86773d65ed58 423 * @param action - enumerated HubActionForLogging that selects from predefined actions
dxyang 3:86773d65ed58 424 */
dxyang 3:86773d65ed58 425 void logActionWithUserInfoH(enum HubActionForLoggingH action)
dxyang 3:86773d65ed58 426 {
dxyang 3:86773d65ed58 427 // Append to a log text file
dxyang 3:86773d65ed58 428 spiSD();
dxyang 3:86773d65ed58 429 char * name = "/sd/HubLog.txt";
dxyang 3:86773d65ed58 430 FILE *fp;
dxyang 3:86773d65ed58 431 fp = fopen(name, "a");
dxyang 3:86773d65ed58 432
dxyang 3:86773d65ed58 433 // get the time and append it to an output buffer
dxyang 3:86773d65ed58 434 time_t seconds = time(NULL);
dxyang 3:86773d65ed58 435 char logLine[180];
dxyang 3:86773d65ed58 436 sprintf(logLine, "%x", seconds);
dxyang 3:86773d65ed58 437
dxyang 3:86773d65ed58 438 // append relevant information for action
dxyang 3:86773d65ed58 439 switch (action) {
dxyang 3:86773d65ed58 440 case hubAction_RfidScanned:
dxyang 3:86773d65ed58 441 strcat(logLine, " R ");
dxyang 3:86773d65ed58 442 break;
dxyang 3:86773d65ed58 443 case hubAction_Exit:
dxyang 3:86773d65ed58 444 strcat(logLine, " X ");
dxyang 3:86773d65ed58 445 break;
dxyang 3:86773d65ed58 446 case hubAction_OneBatteryDropped:
dxyang 3:86773d65ed58 447 strcat(logLine, " D 1 ");
dxyang 3:86773d65ed58 448 break;
dxyang 3:86773d65ed58 449 case hubAction_TwoBatteryDropped:
dxyang 3:86773d65ed58 450 strcat(logLine, " D 2 ");
dxyang 3:86773d65ed58 451 break;
dxyang 3:86773d65ed58 452 case hubAction_ThreeBatteryDropped:
dxyang 3:86773d65ed58 453 strcat(logLine, " D 3 ");
dxyang 3:86773d65ed58 454 break;
dxyang 3:86773d65ed58 455 case hubAction_OneBatteryPicked:
dxyang 3:86773d65ed58 456 strcat(logLine, " P 1 ");
dxyang 3:86773d65ed58 457 break;
dxyang 3:86773d65ed58 458 case hubAction_TwoBatteryPicked:
dxyang 3:86773d65ed58 459 strcat(logLine, " P 2 ");
dxyang 3:86773d65ed58 460 break;
dxyang 3:86773d65ed58 461 case hubAction_ThreeBatteryPicked:
dxyang 3:86773d65ed58 462 strcat(logLine, " P 3 ");
dxyang 3:86773d65ed58 463 break;
dxyang 3:86773d65ed58 464 }
dxyang 3:86773d65ed58 465
dxyang 3:86773d65ed58 466 // append general user information
dxyang 3:86773d65ed58 467 char rfidBuffer[20];
dxyang 3:86773d65ed58 468 char uidBuffer[20];
dxyang 3:86773d65ed58 469 char acctBalanceBuffer[20];
dxyang 3:86773d65ed58 470 sprintf(rfidBuffer, "%u ", allUsersH[currentUserH].rfid);
dxyang 3:86773d65ed58 471 sprintf(uidBuffer, "%u ", allUsersH[currentUserH].uid);
dxyang 3:86773d65ed58 472 sprintf(acctBalanceBuffer, "%d\n", allUsersH[currentUserH].accountCredit);
dxyang 3:86773d65ed58 473 strcat(logLine, rfidBuffer);
dxyang 3:86773d65ed58 474 strcat(logLine, uidBuffer);
dxyang 3:86773d65ed58 475 strcat(logLine, acctBalanceBuffer);
dxyang 3:86773d65ed58 476
dxyang 3:86773d65ed58 477 // write the line to the log file and close the file
dxyang 3:86773d65ed58 478 fputs(logLine, fp);
dxyang 3:86773d65ed58 479 fclose(fp);
dxyang 3:86773d65ed58 480
dxyang 3:86773d65ed58 481 #ifdef debug
dxyang 3:86773d65ed58 482 printf("%s\n\r", logLine);
dxyang 3:86773d65ed58 483 #endif
dxyang 3:86773d65ed58 484
dxyang 3:86773d65ed58 485 }
dxyang 3:86773d65ed58 486
dxyang 3:86773d65ed58 487 /**
dxyang 3:86773d65ed58 488 * Log an error - RFID not associated with a known user is scanned
dxyang 3:86773d65ed58 489 * @param unknownRfid - uint32 for the unique ID of the unknown rfid tag
dxyang 3:86773d65ed58 490 */
dxyang 3:86773d65ed58 491 void logErrorUnknownRfidScannedH(uint32_t unknownRfid)
dxyang 3:86773d65ed58 492 {
dxyang 3:86773d65ed58 493 // Append to a log text file
dxyang 3:86773d65ed58 494 char * name = "/sd/HubLog.txt";
dxyang 3:86773d65ed58 495 spiSD();
dxyang 3:86773d65ed58 496 FILE *fp;
dxyang 3:86773d65ed58 497 fp = fopen(name, "a");
dxyang 3:86773d65ed58 498
dxyang 3:86773d65ed58 499 // get the time and append it to an output buffer
dxyang 3:86773d65ed58 500 time_t seconds = time(NULL);
dxyang 3:86773d65ed58 501 char logLine[180];
dxyang 3:86773d65ed58 502 sprintf(logLine, "%x", seconds);
dxyang 3:86773d65ed58 503
dxyang 3:86773d65ed58 504 // RFID action
dxyang 3:86773d65ed58 505 strcat(logLine, " R X ");
dxyang 3:86773d65ed58 506
dxyang 3:86773d65ed58 507 // include just the RFID (indicates that no known user was found)
dxyang 3:86773d65ed58 508 char rfidBuffer[20];
dxyang 3:86773d65ed58 509 sprintf(rfidBuffer, "%u ", unknownRfid);
dxyang 3:86773d65ed58 510 strcat(logLine, rfidBuffer);
dxyang 3:86773d65ed58 511 strcat(logLine, "\n");
dxyang 3:86773d65ed58 512
dxyang 3:86773d65ed58 513 // write the line to the log file and close the file
dxyang 3:86773d65ed58 514 fputs(logLine, fp);
dxyang 3:86773d65ed58 515 fclose(fp);
dxyang 3:86773d65ed58 516
dxyang 3:86773d65ed58 517 #ifdef debug
dxyang 3:86773d65ed58 518 printf("%s\n\r", logLine);
dxyang 3:86773d65ed58 519 #endif
epgmdm 2:d1eae91343a9 520
epgmdm 2:d1eae91343a9 521 }
epgmdm 2:d1eae91343a9 522
dxyang 3:86773d65ed58 523 /*************************************************************************************************/
dxyang 5:88c516cf34e6 524 /* Housekeeping - flag clearing, cancelling, check time, update user table */
dxyang 3:86773d65ed58 525 /*************************************************************************************************/
dxyang 3:86773d65ed58 526 /*
dxyang 3:86773d65ed58 527 * Reset all user initiated flags. Useful after sequences of events where flags may have
dxyang 3:86773d65ed58 528 * piled up from misc inputs and you don't want the system to act seemingly sporadically.
dxyang 3:86773d65ed58 529 */
dxyang 3:86773d65ed58 530 void clearAllUserInitiatedFlagsH() {
dxyang 3:86773d65ed58 531 flagButtonOneH = 0;
dxyang 3:86773d65ed58 532 flagButtonTwoH = 0;
dxyang 3:86773d65ed58 533 flagButtonThreeH = 0;
dxyang 3:86773d65ed58 534 flagButtonFourH = 0;
dxyang 3:86773d65ed58 535 flagBatteryRfidH = 0;
dxyang 3:86773d65ed58 536 flagPoshoRfidH = 0;
dxyang 3:86773d65ed58 537 flagIncubatorRfidH = 0;
dxyang 3:86773d65ed58 538 }
epgmdm 2:d1eae91343a9 539
dxyang 3:86773d65ed58 540 /*
dxyang 3:86773d65ed58 541 * User presses the button corresponding to an exit. Returns to home screen
dxyang 3:86773d65ed58 542 * after logging the action.
dxyang 3:86773d65ed58 543 */
dxyang 3:86773d65ed58 544 void cancelPressedH() {
dxyang 3:86773d65ed58 545 clearAllUserInitiatedFlagsH();
dxyang 3:86773d65ed58 546 currentScreenH = initialScanRfid;
dxyang 3:86773d65ed58 547 logActionWithUserInfoH(hubAction_Exit);
dxyang 3:86773d65ed58 548 }
dxyang 3:86773d65ed58 549
dxyang 3:86773d65ed58 550 /**
dxyang 3:86773d65ed58 551 * Do if time check flag is set
dxyang 3:86773d65ed58 552 * reads the unix time, converts into human readable format, and displays on PC
dxyang 3:86773d65ed58 553 */
dxyang 3:86773d65ed58 554 void doTimeCheckH()
dxyang 3:86773d65ed58 555 {
dxyang 3:86773d65ed58 556 flagTimeCheckH = 0;
dxyang 3:86773d65ed58 557 time_t seconds = time(NULL);
dxyang 3:86773d65ed58 558 printf("%s\n\r", ctime(&seconds));
dxyang 3:86773d65ed58 559 }
dxyang 3:86773d65ed58 560
dxyang 3:86773d65ed58 561 /**
dxyang 3:86773d65ed58 562 * Do if update user table flag is set
dxyang 3:86773d65ed58 563 */
dxyang 3:86773d65ed58 564 void doUpdateUserTableH()
dxyang 3:86773d65ed58 565 {
dxyang 3:86773d65ed58 566 flagUpdateUserTableH = 0;
dxyang 3:86773d65ed58 567 // Write to a users.txt file
dxyang 3:86773d65ed58 568 spiSD();
dxyang 3:86773d65ed58 569 char * name = "/sd/users.txt";
dxyang 3:86773d65ed58 570 FILE *fp;
dxyang 3:86773d65ed58 571 fp = fopen(name, "w");
dxyang 3:86773d65ed58 572
dxyang 3:86773d65ed58 573 // output the header for the users.txt file
dxyang 3:86773d65ed58 574 fputs("rfid accountCredit locker batterySubscription batteriesOut podID\n", fp);
dxyang 3:86773d65ed58 575
dxyang 3:86773d65ed58 576 // output buffer
dxyang 3:86773d65ed58 577 char logLine[180];
dxyang 3:86773d65ed58 578
dxyang 3:86773d65ed58 579 for (int i = 0; i < userCountH; i++) {
dxyang 3:86773d65ed58 580 // get all the needed information in strings
dxyang 3:86773d65ed58 581 sprintf(logLine, "%u ", allUsersH[i].rfid);
dxyang 3:86773d65ed58 582 char accountCreditBuffer[20];
dxyang 3:86773d65ed58 583 char* lockerBuffer;
dxyang 3:86773d65ed58 584 char batterySubscriptionBuffer[20];
dxyang 3:86773d65ed58 585 char batteriesOutBuffer[20];
dxyang 3:86773d65ed58 586 char podIdBuffer[20];
dxyang 3:86773d65ed58 587
dxyang 3:86773d65ed58 588 sprintf(accountCreditBuffer, "%d ", allUsersH[i].accountCredit);
dxyang 3:86773d65ed58 589 switch (allUsersH[i].lockerID) {
dxyang 3:86773d65ed58 590 case lockerOne:
dxyang 3:86773d65ed58 591 lockerBuffer = "1 ";
dxyang 3:86773d65ed58 592 break;
dxyang 3:86773d65ed58 593 case lockerTwo:
dxyang 3:86773d65ed58 594 lockerBuffer = "2 ";
dxyang 3:86773d65ed58 595 break;
dxyang 3:86773d65ed58 596 case lockerThree:
dxyang 3:86773d65ed58 597 lockerBuffer = "3 ";
dxyang 3:86773d65ed58 598 break;
dxyang 3:86773d65ed58 599 case lockerFour:
dxyang 3:86773d65ed58 600 lockerBuffer = "4 ";
dxyang 3:86773d65ed58 601 break;
dxyang 3:86773d65ed58 602 case lockerUnassigned:
dxyang 3:86773d65ed58 603 default:
dxyang 3:86773d65ed58 604 lockerBuffer = "0 ";
dxyang 3:86773d65ed58 605 break;
dxyang 3:86773d65ed58 606 }
dxyang 3:86773d65ed58 607 sprintf(batterySubscriptionBuffer, "%d ", allUsersH[i].batterySubscription);
dxyang 3:86773d65ed58 608 sprintf(batteriesOutBuffer, "%d ", allUsersH[i].batteriesOut);
dxyang 3:86773d65ed58 609 sprintf(podIdBuffer, "%d\n", allUsersH[i].podID);
dxyang 3:86773d65ed58 610
dxyang 3:86773d65ed58 611 // concatenate all the strings
dxyang 3:86773d65ed58 612 strcat(logLine, accountCreditBuffer);
dxyang 3:86773d65ed58 613 strcat(logLine, lockerBuffer);
dxyang 3:86773d65ed58 614 strcat(logLine, batterySubscriptionBuffer);
dxyang 3:86773d65ed58 615 strcat(logLine, batteriesOutBuffer);
dxyang 3:86773d65ed58 616 strcat(logLine, podIdBuffer);
dxyang 3:86773d65ed58 617
dxyang 3:86773d65ed58 618 // write the line to the log file
dxyang 3:86773d65ed58 619 fputs(logLine, fp);
dxyang 3:86773d65ed58 620
dxyang 3:86773d65ed58 621 #ifdef debug
dxyang 3:86773d65ed58 622 printf("%s\n\r", logLine);
dxyang 3:86773d65ed58 623 #endif
dxyang 3:86773d65ed58 624 }
dxyang 3:86773d65ed58 625 fclose(fp);
dxyang 3:86773d65ed58 626 }
epgmdm 2:d1eae91343a9 627
dxyang 5:88c516cf34e6 628 /*************************************************************************************************/
dxyang 5:88c516cf34e6 629 /* Battery Services */
dxyang 5:88c516cf34e6 630 /*************************************************************************************************/
epgmdm 1:c2232b1eaf31 631 /**
dxyang 3:86773d65ed58 632 * Do if Battery RFID flag is set. Read RFID tag and check user status.
dxyang 3:86773d65ed58 633 * If there's a valid battery subscription, display drop off and/or pick up.
dxyang 3:86773d65ed58 634 * Otherwise, returns to initial screen.
dxyang 3:86773d65ed58 635 */
dxyang 3:86773d65ed58 636 void doBatteryRfidH()
dxyang 3:86773d65ed58 637 {
dxyang 3:86773d65ed58 638 flagBatteryRfidH = 0;
dxyang 3:86773d65ed58 639
dxyang 3:86773d65ed58 640 // is there a new readable card?
dxyang 3:86773d65ed58 641 if (!BatteryRfChipH.PICC_IsNewCardPresent()) {
dxyang 3:86773d65ed58 642 return;
dxyang 3:86773d65ed58 643 }
dxyang 3:86773d65ed58 644
dxyang 3:86773d65ed58 645 if (!BatteryRfChipH.PICC_ReadCardSerial()) {
dxyang 3:86773d65ed58 646 #ifdef debug
dxyang 3:86773d65ed58 647 printf("Card not readable\n\r");
dxyang 3:86773d65ed58 648 #endif
dxyang 3:86773d65ed58 649 return;
dxyang 3:86773d65ed58 650 }
dxyang 3:86773d65ed58 651
dxyang 3:86773d65ed58 652 // get the id of the scanned tag
dxyang 3:86773d65ed58 653 uint8_t tempReadingRfid[4];
dxyang 3:86773d65ed58 654 for(uint8_t i = 0; i < BatteryRfChipH.uid.size; i++) {
dxyang 3:86773d65ed58 655 tempReadingRfid[i] = BatteryRfChipH.uid.uidByte[i];
dxyang 3:86773d65ed58 656 }
dxyang 3:86773d65ed58 657
dxyang 3:86773d65ed58 658 // concatenate the 4 bytes into a single integer via bit shifting
dxyang 3:86773d65ed58 659 uint32_t actualRfid = ((((uint32_t)tempReadingRfid[0] << 24) |
dxyang 3:86773d65ed58 660 ((uint32_t)tempReadingRfid[1] << 16)) |
dxyang 3:86773d65ed58 661 (((uint32_t)tempReadingRfid[2] << 8) |
dxyang 3:86773d65ed58 662 ((uint32_t)tempReadingRfid[3] << 0)));
dxyang 3:86773d65ed58 663
dxyang 3:86773d65ed58 664 // find the user info
dxyang 3:86773d65ed58 665 char foundUserFlag = 0;
dxyang 3:86773d65ed58 666 for (int i = 0; i < userCountH; i++) {
dxyang 3:86773d65ed58 667 if (allUsersH[i].rfid == actualRfid) {
dxyang 3:86773d65ed58 668 currentUserH = i;
dxyang 3:86773d65ed58 669 foundUserFlag = 1;
dxyang 3:86773d65ed58 670 break;
dxyang 3:86773d65ed58 671 }
dxyang 3:86773d65ed58 672 }
dxyang 3:86773d65ed58 673
dxyang 3:86773d65ed58 674 // if the user is found, set the global variable for current user interacting with the system
dxyang 3:86773d65ed58 675 // if the user isn't found, log that an rfid without a user was used and display
dxyang 3:86773d65ed58 676 if (!foundUserFlag) {
dxyang 3:86773d65ed58 677 #ifdef debug
dxyang 3:86773d65ed58 678 printf("User not found\n\r");
dxyang 3:86773d65ed58 679 printf("ID:%u\n\r", actualRfid);
dxyang 3:86773d65ed58 680 #endif
dxyang 3:86773d65ed58 681 // log the error interaction
dxyang 3:86773d65ed58 682 logErrorUnknownRfidScannedH(actualRfid);
dxyang 3:86773d65ed58 683
dxyang 3:86773d65ed58 684 // let user know tag wasn't found
dxyang 3:86773d65ed58 685 TFT_H.cls();
dxyang 3:86773d65ed58 686 TFT_H.locate(0,0);
dxyang 3:86773d65ed58 687 TFT_H.printf("User not found\n\r");
dxyang 3:86773d65ed58 688 TFT_H.printf("ID:%u\n\r", actualRfid);
dxyang 3:86773d65ed58 689 wait(1);
dxyang 3:86773d65ed58 690 currentScreenH = initialScanRfid;
dxyang 3:86773d65ed58 691 return;
dxyang 3:86773d65ed58 692 }
dxyang 3:86773d65ed58 693
dxyang 3:86773d65ed58 694 // log user scan
dxyang 3:86773d65ed58 695 logActionWithUserInfoH(hubAction_RfidScanned);
dxyang 3:86773d65ed58 696
dxyang 3:86773d65ed58 697 // Display info about the user
dxyang 3:86773d65ed58 698 char authorizationFlag = 0;
dxyang 3:86773d65ed58 699 TFT_H.cls();
dxyang 3:86773d65ed58 700 TFT_H.locate(0,0);
dxyang 3:86773d65ed58 701 TFT_H.printf("UserID: %u\n\r", actualRfid);
dxyang 3:86773d65ed58 702 TFT_H.printf("Balance:%d\n\r", allUsersH[currentUserH].accountCredit);
dxyang 3:86773d65ed58 703 if (allUsersH[currentUserH].batterySubscription > 0) {
dxyang 3:86773d65ed58 704 authorizationFlag = 1;
dxyang 3:86773d65ed58 705 }
dxyang 3:86773d65ed58 706 TFT_H.printf("Authorization:%s\n\r", (authorizationFlag)? "YES":"NO");
dxyang 3:86773d65ed58 707
dxyang 3:86773d65ed58 708 #ifdef debug
dxyang 3:86773d65ed58 709 printf("User:");
dxyang 3:86773d65ed58 710 for(uint8_t i = 0; i < BatteryRfChipH.uid.size; i++)
dxyang 3:86773d65ed58 711 {
dxyang 3:86773d65ed58 712 uint8_t uidByte = BatteryRfChipH.uid.uidByte[i];
dxyang 3:86773d65ed58 713 printf(" %d", uidByte);
dxyang 3:86773d65ed58 714 }
dxyang 3:86773d65ed58 715 printf("\n\rUserID: %u\n\r", actualRfid);
dxyang 3:86773d65ed58 716 #endif
dxyang 3:86773d65ed58 717
dxyang 3:86773d65ed58 718 // if not authorized for batteries, return to main screen
dxyang 3:86773d65ed58 719 wait(1);
dxyang 3:86773d65ed58 720 if (!authorizationFlag) {
dxyang 3:86773d65ed58 721 currentScreenH = initialScanRfid;
dxyang 3:86773d65ed58 722 return;
dxyang 3:86773d65ed58 723 }
dxyang 3:86773d65ed58 724
dxyang 3:86773d65ed58 725 // otherwise, ask user if the user wants to pick up or drop off batteries?
dxyang 3:86773d65ed58 726 TFT_H.locate(0,160);
dxyang 3:86773d65ed58 727 TFT_H.printf("Battery Action?\n\r");
dxyang 3:86773d65ed58 728 TFT_H.locate(0,200);
dxyang 3:86773d65ed58 729
dxyang 3:86773d65ed58 730 uint8_t maxBatteries = allUsersH[currentUserH].batterySubscription;
dxyang 3:86773d65ed58 731 uint8_t outBatteries = allUsersH[currentUserH].batteriesOut;
dxyang 3:86773d65ed58 732
dxyang 3:86773d65ed58 733 if ((maxBatteries - outBatteries) == 0) { // can only drop off
dxyang 3:86773d65ed58 734 TFT_H.printf(" drop exit");
dxyang 3:86773d65ed58 735 } else if (outBatteries == 0) { // can only pick up
dxyang 3:86773d65ed58 736 TFT_H.printf(" pick exit");
dxyang 3:86773d65ed58 737 } else { // can pickup or dropoff
dxyang 3:86773d65ed58 738 TFT_H.printf(" pick drop exit");
dxyang 3:86773d65ed58 739 }
dxyang 3:86773d65ed58 740
dxyang 3:86773d65ed58 741 // go to action selecting screen and clear buttons beforehand
dxyang 3:86773d65ed58 742 currentScreenH = batterySelectAction;
dxyang 3:86773d65ed58 743 clearAllUserInitiatedFlagsH();
dxyang 3:86773d65ed58 744 return;
dxyang 3:86773d65ed58 745 }
dxyang 3:86773d65ed58 746
dxyang 3:86773d65ed58 747 /**
dxyang 3:86773d65ed58 748 * Do if user selects to pickup a battery. Determines how many batteries
dxyang 3:86773d65ed58 749 * a user can pickup based off user info and displays corresponding text
dxyang 3:86773d65ed58 750 */
dxyang 3:86773d65ed58 751 void batteryPickUpH() {
dxyang 3:86773d65ed58 752 TFT_H.cls();
dxyang 3:86773d65ed58 753 TFT_H.locate(0,0);
dxyang 3:86773d65ed58 754 TFT_H.printf("UserID: %u\n\r\n\r", allUsersH[currentUserH].rfid);
dxyang 3:86773d65ed58 755
dxyang 3:86773d65ed58 756 TFT_H.printf("Action: PICK UP\n\r");
dxyang 3:86773d65ed58 757 TFT_H.locate(0,160);
dxyang 3:86773d65ed58 758 TFT_H.printf("How many batteries?\n\r");
dxyang 3:86773d65ed58 759 TFT_H.locate(0,200);
dxyang 3:86773d65ed58 760 switch (allUsersH[currentUserH].batterySubscription - allUsersH[currentUserH].batteriesOut) {
dxyang 3:86773d65ed58 761 case 1: {
dxyang 3:86773d65ed58 762 TFT_H.printf(" 1 exit");
dxyang 3:86773d65ed58 763 break;
dxyang 3:86773d65ed58 764 }
dxyang 3:86773d65ed58 765 case 2: {
dxyang 3:86773d65ed58 766 TFT_H.printf(" 1 2 exit");
dxyang 3:86773d65ed58 767 break;
dxyang 3:86773d65ed58 768 }
dxyang 3:86773d65ed58 769 case 3: {
dxyang 3:86773d65ed58 770 TFT_H.printf(" 1 2 3 exit");
dxyang 3:86773d65ed58 771 break;
dxyang 3:86773d65ed58 772 }
dxyang 3:86773d65ed58 773 }
dxyang 3:86773d65ed58 774
dxyang 3:86773d65ed58 775 // go to wait for selection input and reset button flags
dxyang 3:86773d65ed58 776 currentScreenH = batterySelectNumberForPickup;
dxyang 3:86773d65ed58 777 clearAllUserInitiatedFlagsH();
dxyang 3:86773d65ed58 778 return;
dxyang 3:86773d65ed58 779 }
dxyang 3:86773d65ed58 780
dxyang 3:86773d65ed58 781 /**
dxyang 3:86773d65ed58 782 * Do if user selects to dropoff a battery. Determines how many batteries
dxyang 3:86773d65ed58 783 * a user can pickup based off user info and displays corresponding text
dxyang 3:86773d65ed58 784 */
dxyang 3:86773d65ed58 785 void batteryDropOffH() {
dxyang 3:86773d65ed58 786 TFT_H.cls();
dxyang 3:86773d65ed58 787 TFT_H.locate(0,0);
dxyang 3:86773d65ed58 788 TFT_H.printf("UserID: %u\n\r\n\r", allUsersH[currentUserH].rfid);
dxyang 3:86773d65ed58 789
dxyang 3:86773d65ed58 790 TFT_H.printf("Action: DROP OFF\n\r");
dxyang 3:86773d65ed58 791 TFT_H.locate(0,160);
dxyang 3:86773d65ed58 792 TFT_H.printf("How many batteries?\n\r");
dxyang 3:86773d65ed58 793 TFT_H.locate(0,200);
dxyang 3:86773d65ed58 794 switch (allUsersH[currentUserH].batteriesOut) {
dxyang 3:86773d65ed58 795 case 1: {
dxyang 3:86773d65ed58 796 TFT_H.printf(" 1 exit");
dxyang 3:86773d65ed58 797 break;
dxyang 3:86773d65ed58 798 }
dxyang 3:86773d65ed58 799 case 2: {
dxyang 3:86773d65ed58 800 TFT_H.printf(" 1 2 exit");
dxyang 3:86773d65ed58 801 break;
dxyang 3:86773d65ed58 802 }
dxyang 3:86773d65ed58 803 case 3: {
dxyang 3:86773d65ed58 804 TFT_H.printf(" 1 2 3 exit");
dxyang 3:86773d65ed58 805 break;
dxyang 3:86773d65ed58 806 }
dxyang 3:86773d65ed58 807 }
dxyang 3:86773d65ed58 808
dxyang 3:86773d65ed58 809 // go to wait for selection input and reset button flags
dxyang 3:86773d65ed58 810 currentScreenH = batterySelectNumberForDropoff;
dxyang 3:86773d65ed58 811 clearAllUserInitiatedFlagsH();
dxyang 3:86773d65ed58 812 return;
dxyang 3:86773d65ed58 813 }
dxyang 3:86773d65ed58 814
dxyang 3:86773d65ed58 815 /**
dxyang 3:86773d65ed58 816 * Do after use selects number of batteries to drop off.
dxyang 3:86773d65ed58 817 * Logs the action, changes user info, transmits instructions to other systems
dxyang 3:86773d65ed58 818 * @param numBatteries - int for number of batteries selected to drop off
dxyang 3:86773d65ed58 819 */
dxyang 3:86773d65ed58 820 void batteryDropOffH(int numBatteries) {
dxyang 3:86773d65ed58 821 switch(numBatteries) {
dxyang 3:86773d65ed58 822 case 1:
dxyang 3:86773d65ed58 823 logActionWithUserInfoH(hubAction_OneBatteryDropped);
dxyang 3:86773d65ed58 824 allUsersH[currentUserH].batteriesOut--;
dxyang 3:86773d65ed58 825 break;
dxyang 3:86773d65ed58 826 case 2:
dxyang 3:86773d65ed58 827 logActionWithUserInfoH(hubAction_TwoBatteryDropped);
dxyang 3:86773d65ed58 828 allUsersH[currentUserH].batteriesOut -= 2;
dxyang 3:86773d65ed58 829 break;
dxyang 3:86773d65ed58 830 case 3:
dxyang 3:86773d65ed58 831 logActionWithUserInfoH(hubAction_ThreeBatteryDropped);
dxyang 3:86773d65ed58 832 allUsersH[currentUserH].batteriesOut -= 3;
dxyang 3:86773d65ed58 833 break;
dxyang 3:86773d65ed58 834 }
dxyang 3:86773d65ed58 835
dxyang 3:86773d65ed58 836 currentScreenH = initialScanRfid;
dxyang 3:86773d65ed58 837 return;
dxyang 3:86773d65ed58 838 }
dxyang 3:86773d65ed58 839
dxyang 3:86773d65ed58 840 /**
dxyang 3:86773d65ed58 841 * Do after use selects number of batteries to pick up.
dxyang 3:86773d65ed58 842 * Logs the action, changes user info, transmits instructions to other systems
dxyang 3:86773d65ed58 843 * @param numBatteries - int for number of batteries selected to pick up
dxyang 3:86773d65ed58 844 */
dxyang 3:86773d65ed58 845 void batteryPickUpH(int numBatteries) {
dxyang 3:86773d65ed58 846 switch(numBatteries) {
dxyang 3:86773d65ed58 847 case 1:
dxyang 3:86773d65ed58 848 logActionWithUserInfoH(hubAction_OneBatteryPicked);
dxyang 3:86773d65ed58 849 allUsersH[currentUserH].batteriesOut++;
dxyang 3:86773d65ed58 850 break;
dxyang 3:86773d65ed58 851 case 2:
dxyang 3:86773d65ed58 852 logActionWithUserInfoH(hubAction_TwoBatteryPicked);
dxyang 3:86773d65ed58 853 allUsersH[currentUserH].batteriesOut += 2;
dxyang 3:86773d65ed58 854 break;
dxyang 3:86773d65ed58 855 case 3:
dxyang 3:86773d65ed58 856 logActionWithUserInfoH(hubAction_ThreeBatteryPicked);
dxyang 3:86773d65ed58 857 allUsersH[currentUserH].batteriesOut += 3;
dxyang 3:86773d65ed58 858 break;
dxyang 3:86773d65ed58 859 }
dxyang 3:86773d65ed58 860
dxyang 3:86773d65ed58 861 currentScreenH = initialScanRfid;
dxyang 3:86773d65ed58 862 return;
dxyang 3:86773d65ed58 863 }
dxyang 3:86773d65ed58 864
dxyang 5:88c516cf34e6 865 /*************************************************************************************************/
dxyang 5:88c516cf34e6 866 /* Misc Services */
dxyang 5:88c516cf34e6 867 /*************************************************************************************************/
dxyang 3:86773d65ed58 868 /**
dxyang 3:86773d65ed58 869 * Do if Posho RFID flag is set. Add posho functionality later.
dxyang 3:86773d65ed58 870 */
dxyang 3:86773d65ed58 871 void doPoshoRfidH()
dxyang 3:86773d65ed58 872 {
dxyang 3:86773d65ed58 873 flagPoshoRfidH = 0;
dxyang 3:86773d65ed58 874 }
dxyang 3:86773d65ed58 875
dxyang 3:86773d65ed58 876 /**
dxyang 3:86773d65ed58 877 * Do if Incubator RFID flag is set. Add incubator functionality later.
dxyang 3:86773d65ed58 878 */
dxyang 3:86773d65ed58 879 void doIncubatorRfidH()
dxyang 3:86773d65ed58 880 {
dxyang 3:86773d65ed58 881 flagIncubatorRfidH = 0;
dxyang 3:86773d65ed58 882 }
dxyang 3:86773d65ed58 883
dxyang 3:86773d65ed58 884 /*************************************************************************************************/
dxyang 3:86773d65ed58 885 /* Public Methods */
dxyang 3:86773d65ed58 886 /*************************************************************************************************/
dxyang 3:86773d65ed58 887 /**
dxyang 3:86773d65ed58 888 * Initialise for a hub
epgmdm 1:c2232b1eaf31 889 * fp is the config file if additonal information is needed.
epgmdm 1:c2232b1eaf31 890 */
epgmdm 1:c2232b1eaf31 891 void initialiseHub(FILE *fp){
epgmdm 1:c2232b1eaf31 892 #ifdef debug
dxyang 3:86773d65ed58 893 printf("Initializing Hub\n\r");
epgmdm 1:c2232b1eaf31 894 #endif
epgmdm 1:c2232b1eaf31 895
epgmdm 1:c2232b1eaf31 896 // Read in hub address and channel
epgmdm 1:c2232b1eaf31 897 if (fscanf (fp,"%x %*c %*s",&channel )!=1) writeError("Hub config: cannot read channel");
epgmdm 1:c2232b1eaf31 898 if (fscanf (fp,"%llx %*c %*s",&addrLcker )!=1) writeError("Hub config: cannot read hub address");
epgmdm 1:c2232b1eaf31 899
epgmdm 1:c2232b1eaf31 900 #ifdef debug
epgmdm 1:c2232b1eaf31 901 printf(" Channel:%x, Hub Address %llx \n\r",channel, addrLcker);
epgmdm 1:c2232b1eaf31 902 #endif
epgmdm 2:d1eae91343a9 903
epgmdm 2:d1eae91343a9 904 // Setup nrf
epgmdm 2:d1eae91343a9 905 #ifdef debug
epgmdm 2:d1eae91343a9 906 printf("Steup doNrf \n\r");
epgmdm 2:d1eae91343a9 907 #endif
epgmdm 2:d1eae91343a9 908 spiNrf();
epgmdm 2:d1eae91343a9 909 nrf1.quickTxSetup(channel, addrLcker);
epgmdm 2:d1eae91343a9 910 #ifdef debug
epgmdm 2:d1eae91343a9 911 nrf1.printDetails();
epgmdm 2:d1eae91343a9 912 nrf1.checkStatus();
epgmdm 2:d1eae91343a9 913 printf("Setup doNrf complete [nrf:%s]\n\r",nrf1.statusString());
epgmdm 2:d1eae91343a9 914 #endif
epgmdm 2:d1eae91343a9 915
dxyang 3:86773d65ed58 916 // Other initialization routines
dxyang 3:86773d65ed58 917 initializeTimeH();
dxyang 3:86773d65ed58 918 initializeInterruptsH();
dxyang 3:86773d65ed58 919 initializeRfidReadersH();
dxyang 3:86773d65ed58 920 initializeLCD_H();
dxyang 3:86773d65ed58 921 initializeUsersFromSD_H();
epgmdm 1:c2232b1eaf31 922 }
epgmdm 2:d1eae91343a9 923
dxyang 3:86773d65ed58 924 void loopHub(){
dxyang 3:86773d65ed58 925 while (true) {
dxyang 3:86773d65ed58 926 // put interrupts here that should supercede anything else
dxyang 3:86773d65ed58 927 if (flag1sH) { do1sH(); }
epgmdm 1:c2232b1eaf31 928
dxyang 3:86773d65ed58 929 // put interrupts here that may be active depending on screen stage
dxyang 3:86773d65ed58 930 switch(currentScreenH) {
dxyang 3:86773d65ed58 931 case initialScanRfid: {
dxyang 3:86773d65ed58 932 TFT_H.cls();
dxyang 3:86773d65ed58 933 TFT_H.locate(0,0);
dxyang 3:86773d65ed58 934 TFT_H.printf("Please scan your ID");
dxyang 3:86773d65ed58 935 currentScreenH = waitForRfid;
dxyang 3:86773d65ed58 936 clearAllUserInitiatedFlagsH();
dxyang 3:86773d65ed58 937 }
dxyang 3:86773d65ed58 938 case waitForRfid: {
dxyang 3:86773d65ed58 939 if (flagTimeCheckH) doTimeCheckH();
dxyang 3:86773d65ed58 940 if (flagBatteryRfidH) doBatteryRfidH();
dxyang 3:86773d65ed58 941 if (flagPoshoRfidH) doPoshoRfidH();
dxyang 3:86773d65ed58 942 if (flagIncubatorRfidH) doIncubatorRfidH();
dxyang 3:86773d65ed58 943 if (flagUpdateUserTableH) doUpdateUserTableH();
dxyang 3:86773d65ed58 944 break;
dxyang 3:86773d65ed58 945 }
dxyang 3:86773d65ed58 946 case batterySelectAction: {
dxyang 3:86773d65ed58 947 uint8_t maxBatteries = allUsersH[currentUserH].batterySubscription;
dxyang 3:86773d65ed58 948 uint8_t outBatteries = allUsersH[currentUserH].batteriesOut;
dxyang 3:86773d65ed58 949
dxyang 3:86773d65ed58 950 if ((maxBatteries - outBatteries) == 0) {
dxyang 3:86773d65ed58 951 if (flagButtonOneH) batteryDropOffH();
dxyang 3:86773d65ed58 952 if (flagButtonFourH) cancelPressedH();
dxyang 3:86773d65ed58 953 } else if (outBatteries == 0) {
dxyang 3:86773d65ed58 954 if (flagButtonOneH) batteryPickUpH();
dxyang 3:86773d65ed58 955 if (flagButtonFourH) cancelPressedH();
dxyang 3:86773d65ed58 956 } else {
dxyang 3:86773d65ed58 957 if (flagButtonOneH) batteryPickUpH();
dxyang 3:86773d65ed58 958 if (flagButtonThreeH) batteryDropOffH();
dxyang 3:86773d65ed58 959 if (flagButtonFourH) cancelPressedH();
dxyang 3:86773d65ed58 960 }
epgmdm 1:c2232b1eaf31 961
dxyang 3:86773d65ed58 962 break;
dxyang 3:86773d65ed58 963 }
dxyang 3:86773d65ed58 964 case batterySelectNumberForDropoff: {
dxyang 3:86773d65ed58 965 switch (allUsersH[currentUserH].batteriesOut) {
dxyang 3:86773d65ed58 966 case 1: {
dxyang 3:86773d65ed58 967 if (flagButtonOneH) batteryDropOffH(1);
dxyang 3:86773d65ed58 968 if (flagButtonFourH) cancelPressedH();
dxyang 3:86773d65ed58 969 break;
dxyang 3:86773d65ed58 970 }
dxyang 3:86773d65ed58 971 case 2: {
dxyang 3:86773d65ed58 972 if (flagButtonOneH) batteryDropOffH(1);
dxyang 3:86773d65ed58 973 if (flagButtonTwoH) batteryDropOffH(2);
dxyang 3:86773d65ed58 974 if (flagButtonFourH) cancelPressedH();
dxyang 3:86773d65ed58 975 break;
dxyang 3:86773d65ed58 976 }
dxyang 3:86773d65ed58 977 case 3: {
dxyang 3:86773d65ed58 978 if (flagButtonOneH) batteryDropOffH(1);
dxyang 3:86773d65ed58 979 if (flagButtonTwoH) batteryDropOffH(2);
dxyang 3:86773d65ed58 980 if (flagButtonThreeH) batteryDropOffH(3);
dxyang 3:86773d65ed58 981 if (flagButtonFourH) cancelPressedH();
dxyang 3:86773d65ed58 982 break;
dxyang 3:86773d65ed58 983 }
dxyang 3:86773d65ed58 984 }
dxyang 3:86773d65ed58 985 break;
dxyang 3:86773d65ed58 986 }
dxyang 3:86773d65ed58 987 case batterySelectNumberForPickup: {
dxyang 3:86773d65ed58 988 switch (allUsersH[currentUserH].batterySubscription - allUsersH[currentUserH].batteriesOut) {
dxyang 3:86773d65ed58 989 case 1: {
dxyang 3:86773d65ed58 990 if (flagButtonOneH) batteryPickUpH(1);
dxyang 3:86773d65ed58 991 if (flagButtonFourH) cancelPressedH();
dxyang 3:86773d65ed58 992 break;
dxyang 3:86773d65ed58 993 }
dxyang 3:86773d65ed58 994 case 2: {
dxyang 3:86773d65ed58 995 if (flagButtonOneH) batteryPickUpH(1);
dxyang 3:86773d65ed58 996 if (flagButtonTwoH) batteryPickUpH(2);
dxyang 3:86773d65ed58 997 if (flagButtonFourH) cancelPressedH();
dxyang 3:86773d65ed58 998 break;
dxyang 3:86773d65ed58 999 }
dxyang 3:86773d65ed58 1000 case 3: {
dxyang 3:86773d65ed58 1001 if (flagButtonOneH) batteryPickUpH(1);
dxyang 3:86773d65ed58 1002 if (flagButtonTwoH) batteryPickUpH(2);
dxyang 3:86773d65ed58 1003 if (flagButtonThreeH) batteryPickUpH(3);
dxyang 3:86773d65ed58 1004 if (flagButtonFourH) cancelPressedH();
dxyang 3:86773d65ed58 1005 break;
dxyang 3:86773d65ed58 1006 }
dxyang 3:86773d65ed58 1007 }
dxyang 3:86773d65ed58 1008 break;
dxyang 3:86773d65ed58 1009 }
dxyang 3:86773d65ed58 1010 }
epgmdm 2:d1eae91343a9 1011 }
epgmdm 1:c2232b1eaf31 1012 }