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 11:04:16 2016 +0000
Revision:
6:00a132a076d5
Parent:
5:88c516cf34e6
Child:
7:0aee09577ad3
placeholder functions for transmitting battery pickup and dropoff added

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 6:00a132a076d5 235
dxyang 6:00a132a076d5 236 /**
dxyang 6:00a132a076d5 237 * Sends a signal to a locker that the current user is picking up numBatteries batteries
dxyang 6:00a132a076d5 238 */
dxyang 6:00a132a076d5 239 void txBatteryPickUp(int numBatteries) {
dxyang 6:00a132a076d5 240
dxyang 6:00a132a076d5 241 }
dxyang 6:00a132a076d5 242
dxyang 6:00a132a076d5 243 /**
dxyang 6:00a132a076d5 244 * Sends a signal to a locker that the current user is dropping off numBatteries batteries
dxyang 6:00a132a076d5 245 */
dxyang 6:00a132a076d5 246 void txBatteryDropOff(int numBatteries) {
dxyang 6:00a132a076d5 247
dxyang 6:00a132a076d5 248 }
dxyang 6:00a132a076d5 249
dxyang 6:00a132a076d5 250
dxyang 5:88c516cf34e6 251 /*************************************************************************************************/
dxyang 5:88c516cf34e6 252 /* Initialization */
dxyang 5:88c516cf34e6 253 /*************************************************************************************************/
epgmdm 2:d1eae91343a9 254 /**
dxyang 3:86773d65ed58 255 * Initialize system on reset and set the time from the terminal
dxyang 3:86773d65ed58 256 */
dxyang 3:86773d65ed58 257 void initializeTimeH()
dxyang 3:86773d65ed58 258 {
epgmdm 2:d1eae91343a9 259 // get the current time from the terminal
epgmdm 2:d1eae91343a9 260 struct tm t;
epgmdm 2:d1eae91343a9 261 printf("Enter current date :\n\r");
epgmdm 2:d1eae91343a9 262 printf("YYYY MM DD [enter]\n\r");
epgmdm 2:d1eae91343a9 263 scanf("%d %d %d", &t.tm_year, &t.tm_mon, &t.tm_mday);
epgmdm 2:d1eae91343a9 264 printf("Enter current time:\n\r");
epgmdm 2:d1eae91343a9 265 printf("HH MM SS [enter]\n\r");
epgmdm 2:d1eae91343a9 266 scanf("%d %d %d", &t.tm_hour, &t.tm_min, &t.tm_sec);
epgmdm 2:d1eae91343a9 267
epgmdm 2:d1eae91343a9 268 // adjust for tm structure required values
epgmdm 2:d1eae91343a9 269 t.tm_year = t.tm_year - 1900;
epgmdm 2:d1eae91343a9 270 t.tm_mon = t.tm_mon - 1;
epgmdm 2:d1eae91343a9 271
epgmdm 2:d1eae91343a9 272 // set the time
epgmdm 2:d1eae91343a9 273 set_time(mktime(&t));
dxyang 3:86773d65ed58 274 #ifdef debug
dxyang 3:86773d65ed58 275 printf("Time initialized\n\r");
dxyang 3:86773d65ed58 276 #endif
dxyang 3:86773d65ed58 277 }
dxyang 3:86773d65ed58 278
dxyang 3:86773d65ed58 279 /**
dxyang 3:86773d65ed58 280 * Initialize all the interrupts
dxyang 3:86773d65ed58 281 */
dxyang 3:86773d65ed58 282 void initializeInterruptsH()
dxyang 3:86773d65ed58 283 {
dxyang 3:86773d65ed58 284 tickTimeCheckH.attach(&interruptTimeCheckH, 5.0);
dxyang 3:86773d65ed58 285 tickBatteryRfidH.attach(&interruptBatteryRfidH, 1.0);
dxyang 3:86773d65ed58 286 tickPoshoRfidH.attach(&interruptPoshoRfidH, 1.0);
dxyang 3:86773d65ed58 287 tickIncubatorRfidH.attach(&interruptIncubatorRfidH, 1.0);
dxyang 3:86773d65ed58 288 tickerUpdateUserTableH.attach(&interruptUpdateUserTableH, 1800.0);
dxyang 3:86773d65ed58 289 buttonOneH.rise(&interruptButtonOneH);
dxyang 3:86773d65ed58 290 buttonTwoH.rise(&interruptButtonTwoH);
dxyang 3:86773d65ed58 291 buttonThreeH.rise(&interruptButtonThreeH);
dxyang 3:86773d65ed58 292 buttonFourH.rise(&interruptButtonFourH);
dxyang 3:86773d65ed58 293 tick1sHub.attach(&int1sH, 10.0);
dxyang 3:86773d65ed58 294
dxyang 3:86773d65ed58 295 #ifdef debug
dxyang 3:86773d65ed58 296 printf("Interrupts initialized\n\r");
dxyang 3:86773d65ed58 297 #endif
dxyang 3:86773d65ed58 298 }
dxyang 3:86773d65ed58 299
dxyang 3:86773d65ed58 300 /**
dxyang 3:86773d65ed58 301 * Initialize RFID readers
dxyang 3:86773d65ed58 302 */
dxyang 3:86773d65ed58 303 void initializeRfidReadersH()
dxyang 3:86773d65ed58 304 {
dxyang 3:86773d65ed58 305 BatteryRfChipH.PCD_Init();
dxyang 3:86773d65ed58 306 PoshoRfChipH.PCD_Init();
dxyang 3:86773d65ed58 307 IncubatorRfChipH.PCD_Init();
dxyang 3:86773d65ed58 308
dxyang 3:86773d65ed58 309 #ifdef debug
dxyang 3:86773d65ed58 310 uint8_t tempA = BatteryRfChipH.PCD_ReadRegister(MFRC522::VersionReg);
dxyang 3:86773d65ed58 311 printf("Battery MFRC522 version: %d\n\r", tempA & 0x07);
dxyang 3:86773d65ed58 312 printf("\n\r");
dxyang 3:86773d65ed58 313 uint8_t tempB = PoshoRfChipH.PCD_ReadRegister(MFRC522::VersionReg);
dxyang 3:86773d65ed58 314 printf("Posho MFRC522 version: %d\n\r", tempB & 0x07);
dxyang 3:86773d65ed58 315 printf("\n\r");
dxyang 3:86773d65ed58 316 uint8_t tempC = IncubatorRfChipH.PCD_ReadRegister(MFRC522::VersionReg);
dxyang 3:86773d65ed58 317 printf("Incubator MFRC522 version: %d\n\r", tempC & 0x07);
dxyang 3:86773d65ed58 318 printf("\n\r");
dxyang 3:86773d65ed58 319 #endif
dxyang 3:86773d65ed58 320
dxyang 3:86773d65ed58 321 #ifdef debug
dxyang 3:86773d65ed58 322 printf("RFID readers initialized\n\r");
dxyang 3:86773d65ed58 323 #endif
dxyang 3:86773d65ed58 324 }
dxyang 3:86773d65ed58 325
dxyang 3:86773d65ed58 326 /**
dxyang 3:86773d65ed58 327 * Initialize LCD screen
dxyang 3:86773d65ed58 328 */
dxyang 3:86773d65ed58 329 void initializeLCD_H()
dxyang 3:86773d65ed58 330 {
dxyang 3:86773d65ed58 331 TFT_H.background(Black); // set background to black
dxyang 3:86773d65ed58 332 TFT_H.foreground(White); // set chars to white
dxyang 3:86773d65ed58 333 TFT_H.cls(); // clear the screen
dxyang 3:86773d65ed58 334 TFT_H.set_font((unsigned char*) Arial24x23);
dxyang 3:86773d65ed58 335 TFT_H.set_orientation(3); //Portrait, wiring on left
dxyang 3:86773d65ed58 336 #ifdef debug
dxyang 3:86773d65ed58 337 printf("LCD initialized\n\r");
dxyang 3:86773d65ed58 338 #endif
dxyang 3:86773d65ed58 339 }
dxyang 3:86773d65ed58 340
dxyang 3:86773d65ed58 341 /**
dxyang 3:86773d65ed58 342 * Creates a new user by defining user attributes.
dxyang 3:86773d65ed58 343 * @param rfid - uint32_t corresponding to unique id of the RFID tag
dxyang 3:86773d65ed58 344 * @param accountCredit - int32 for user account balance (can be negative)
dxyang 3:86773d65ed58 345 * @param locker - int32_t for which locker (originaly 1-4) user is assigned
dxyang 3:86773d65ed58 346 * @param batterySubscription - max batteries user can get (can be 0)
dxyang 3:86773d65ed58 347 * @param batteriesOut - number of batteries user has out (usually 0 initially)
dxyang 3:86773d65ed58 348 * @param podID - pod associated with the user (originally 0-15) *must be 0 indexed*
dxyang 3:86773d65ed58 349 */
dxyang 3:86773d65ed58 350 void createNewUserH(uint32_t rfid, int32_t accountCredit, int32_t locker,
dxyang 3:86773d65ed58 351 int32_t batterySubscription, int32_t batteriesOut, int32_t podID)
dxyang 3:86773d65ed58 352 {
dxyang 3:86773d65ed58 353 allUsersH[userCountH].rfid = rfid;
dxyang 3:86773d65ed58 354 allUsersH[userCountH].accountCredit = accountCredit;
dxyang 3:86773d65ed58 355 switch(locker) {
dxyang 3:86773d65ed58 356 case 1:
dxyang 3:86773d65ed58 357 allUsersH[userCountH].lockerID = lockerOne;
dxyang 3:86773d65ed58 358 break;
dxyang 3:86773d65ed58 359 case 2:
dxyang 3:86773d65ed58 360 allUsersH[userCountH].lockerID = lockerTwo;
dxyang 3:86773d65ed58 361 break;
dxyang 3:86773d65ed58 362 case 3:
dxyang 3:86773d65ed58 363 allUsersH[userCountH].lockerID = lockerThree;
dxyang 3:86773d65ed58 364 break;
dxyang 3:86773d65ed58 365 case 4:
dxyang 3:86773d65ed58 366 allUsersH[userCountH].lockerID = lockerFour;
dxyang 3:86773d65ed58 367 break;
dxyang 3:86773d65ed58 368 default:
dxyang 3:86773d65ed58 369 allUsersH[userCountH].lockerID = lockerUnassigned;
dxyang 3:86773d65ed58 370 break;
dxyang 3:86773d65ed58 371 }
dxyang 3:86773d65ed58 372 allUsersH[userCountH].batterySubscription = batterySubscription;
dxyang 3:86773d65ed58 373 allUsersH[userCountH].batteriesOut = batteriesOut;
dxyang 3:86773d65ed58 374 allUsersH[userCountH].podID = podID;
dxyang 3:86773d65ed58 375
dxyang 3:86773d65ed58 376 // generate the user id, a 32 byte value
dxyang 3:86773d65ed58 377 // [community byte 1][community byte 2][locker byte 3][podID (1/2 byte) | 0000 (1/2 byte)]
dxyang 3:86773d65ed58 378 uint32_t actualUid = ((((uint32_t)communityID_H << 16) | ((uint32_t)locker << 8)) |
dxyang 3:86773d65ed58 379 ((uint32_t)podID << 4));
dxyang 3:86773d65ed58 380 allUsersH[userCountH].uid = actualUid;
dxyang 3:86773d65ed58 381
dxyang 3:86773d65ed58 382 userCountH++;
dxyang 3:86773d65ed58 383
dxyang 3:86773d65ed58 384 #ifdef debug
dxyang 3:86773d65ed58 385 printf("UserID (decimal):%u\n\r", actualUid);
dxyang 3:86773d65ed58 386 printf("**************************\n\r");
dxyang 3:86773d65ed58 387 #endif
dxyang 3:86773d65ed58 388 }
dxyang 3:86773d65ed58 389
dxyang 3:86773d65ed58 390 /**
dxyang 3:86773d65ed58 391 * Initialize system with users from users.txt on SD card
dxyang 3:86773d65ed58 392 */
dxyang 3:86773d65ed58 393 void initializeUsersFromSD_H()
dxyang 3:86773d65ed58 394 {
dxyang 3:86773d65ed58 395 spiSD();
dxyang 3:86773d65ed58 396 FILE *fp = fopen("/sd/users.txt", "r");
dxyang 3:86773d65ed58 397
dxyang 3:86773d65ed58 398 if (fp == NULL) {
dxyang 3:86773d65ed58 399 #ifdef debug
dxyang 3:86773d65ed58 400 printf("User text file can't be opened");
dxyang 3:86773d65ed58 401 #endif
dxyang 3:86773d65ed58 402 return;
dxyang 3:86773d65ed58 403 }
dxyang 3:86773d65ed58 404
dxyang 3:86773d65ed58 405 // the first line of the user file has the headers for the following roles - get to the next line
dxyang 3:86773d65ed58 406 char line[180];
dxyang 3:86773d65ed58 407 if (fgets(line, 180, fp) != NULL) {
dxyang 3:86773d65ed58 408 #ifdef debug
dxyang 3:86773d65ed58 409 printf("Format of text file:\n\r%s\n\r", line);
dxyang 3:86773d65ed58 410 printf("**************************\n\r");
dxyang 3:86773d65ed58 411 #endif
dxyang 3:86773d65ed58 412 }
dxyang 3:86773d65ed58 413
dxyang 3:86773d65ed58 414 // 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 415 uint32_t rfid;
dxyang 3:86773d65ed58 416 int32_t accountCredit;
dxyang 3:86773d65ed58 417 int32_t locker;
dxyang 3:86773d65ed58 418 int32_t batterySubscription;
dxyang 3:86773d65ed58 419 int32_t batteriesOut;
dxyang 3:86773d65ed58 420 int32_t podID;
dxyang 3:86773d65ed58 421 while (fscanf(fp, "%u %d %d %d %d %d", &rfid, &accountCredit, &locker, &batterySubscription, &batteriesOut, &podID) != EOF) {
dxyang 3:86773d65ed58 422 #ifdef debug
dxyang 3:86773d65ed58 423 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 424 rfid, accountCredit, locker, batterySubscription, batteriesOut, podID);
dxyang 3:86773d65ed58 425 #endif
dxyang 3:86773d65ed58 426 createNewUserH(rfid, accountCredit, locker, batterySubscription, batteriesOut, podID);
dxyang 3:86773d65ed58 427 }
dxyang 3:86773d65ed58 428 #ifdef debug
dxyang 3:86773d65ed58 429 printf("Users created\n\r");
dxyang 3:86773d65ed58 430 #endif
dxyang 3:86773d65ed58 431 }
dxyang 3:86773d65ed58 432
dxyang 3:86773d65ed58 433 /*************************************************************************************************/
dxyang 3:86773d65ed58 434 /* Logging */
dxyang 3:86773d65ed58 435 /*************************************************************************************************/
dxyang 3:86773d65ed58 436 /**
dxyang 3:86773d65ed58 437 * Log an action from a selection of predefined actions done by the current user
dxyang 3:86773d65ed58 438 * Actions used with this method should require a known user to be using system
dxyang 3:86773d65ed58 439 * @param action - enumerated HubActionForLogging that selects from predefined actions
dxyang 3:86773d65ed58 440 */
dxyang 3:86773d65ed58 441 void logActionWithUserInfoH(enum HubActionForLoggingH action)
dxyang 3:86773d65ed58 442 {
dxyang 3:86773d65ed58 443 // Append to a log text file
dxyang 3:86773d65ed58 444 spiSD();
dxyang 3:86773d65ed58 445 char * name = "/sd/HubLog.txt";
dxyang 3:86773d65ed58 446 FILE *fp;
dxyang 3:86773d65ed58 447 fp = fopen(name, "a");
dxyang 3:86773d65ed58 448
dxyang 3:86773d65ed58 449 // get the time and append it to an output buffer
dxyang 3:86773d65ed58 450 time_t seconds = time(NULL);
dxyang 3:86773d65ed58 451 char logLine[180];
dxyang 3:86773d65ed58 452 sprintf(logLine, "%x", seconds);
dxyang 3:86773d65ed58 453
dxyang 3:86773d65ed58 454 // append relevant information for action
dxyang 3:86773d65ed58 455 switch (action) {
dxyang 3:86773d65ed58 456 case hubAction_RfidScanned:
dxyang 3:86773d65ed58 457 strcat(logLine, " R ");
dxyang 3:86773d65ed58 458 break;
dxyang 3:86773d65ed58 459 case hubAction_Exit:
dxyang 3:86773d65ed58 460 strcat(logLine, " X ");
dxyang 3:86773d65ed58 461 break;
dxyang 3:86773d65ed58 462 case hubAction_OneBatteryDropped:
dxyang 3:86773d65ed58 463 strcat(logLine, " D 1 ");
dxyang 3:86773d65ed58 464 break;
dxyang 3:86773d65ed58 465 case hubAction_TwoBatteryDropped:
dxyang 3:86773d65ed58 466 strcat(logLine, " D 2 ");
dxyang 3:86773d65ed58 467 break;
dxyang 3:86773d65ed58 468 case hubAction_ThreeBatteryDropped:
dxyang 3:86773d65ed58 469 strcat(logLine, " D 3 ");
dxyang 3:86773d65ed58 470 break;
dxyang 3:86773d65ed58 471 case hubAction_OneBatteryPicked:
dxyang 3:86773d65ed58 472 strcat(logLine, " P 1 ");
dxyang 3:86773d65ed58 473 break;
dxyang 3:86773d65ed58 474 case hubAction_TwoBatteryPicked:
dxyang 3:86773d65ed58 475 strcat(logLine, " P 2 ");
dxyang 3:86773d65ed58 476 break;
dxyang 3:86773d65ed58 477 case hubAction_ThreeBatteryPicked:
dxyang 3:86773d65ed58 478 strcat(logLine, " P 3 ");
dxyang 3:86773d65ed58 479 break;
dxyang 3:86773d65ed58 480 }
dxyang 3:86773d65ed58 481
dxyang 3:86773d65ed58 482 // append general user information
dxyang 3:86773d65ed58 483 char rfidBuffer[20];
dxyang 3:86773d65ed58 484 char uidBuffer[20];
dxyang 3:86773d65ed58 485 char acctBalanceBuffer[20];
dxyang 3:86773d65ed58 486 sprintf(rfidBuffer, "%u ", allUsersH[currentUserH].rfid);
dxyang 3:86773d65ed58 487 sprintf(uidBuffer, "%u ", allUsersH[currentUserH].uid);
dxyang 3:86773d65ed58 488 sprintf(acctBalanceBuffer, "%d\n", allUsersH[currentUserH].accountCredit);
dxyang 3:86773d65ed58 489 strcat(logLine, rfidBuffer);
dxyang 3:86773d65ed58 490 strcat(logLine, uidBuffer);
dxyang 3:86773d65ed58 491 strcat(logLine, acctBalanceBuffer);
dxyang 3:86773d65ed58 492
dxyang 3:86773d65ed58 493 // write the line to the log file and close the file
dxyang 3:86773d65ed58 494 fputs(logLine, fp);
dxyang 3:86773d65ed58 495 fclose(fp);
dxyang 3:86773d65ed58 496
dxyang 3:86773d65ed58 497 #ifdef debug
dxyang 3:86773d65ed58 498 printf("%s\n\r", logLine);
dxyang 3:86773d65ed58 499 #endif
dxyang 3:86773d65ed58 500
dxyang 3:86773d65ed58 501 }
dxyang 3:86773d65ed58 502
dxyang 3:86773d65ed58 503 /**
dxyang 3:86773d65ed58 504 * Log an error - RFID not associated with a known user is scanned
dxyang 3:86773d65ed58 505 * @param unknownRfid - uint32 for the unique ID of the unknown rfid tag
dxyang 3:86773d65ed58 506 */
dxyang 3:86773d65ed58 507 void logErrorUnknownRfidScannedH(uint32_t unknownRfid)
dxyang 3:86773d65ed58 508 {
dxyang 3:86773d65ed58 509 // Append to a log text file
dxyang 3:86773d65ed58 510 char * name = "/sd/HubLog.txt";
dxyang 3:86773d65ed58 511 spiSD();
dxyang 3:86773d65ed58 512 FILE *fp;
dxyang 3:86773d65ed58 513 fp = fopen(name, "a");
dxyang 3:86773d65ed58 514
dxyang 3:86773d65ed58 515 // get the time and append it to an output buffer
dxyang 3:86773d65ed58 516 time_t seconds = time(NULL);
dxyang 3:86773d65ed58 517 char logLine[180];
dxyang 3:86773d65ed58 518 sprintf(logLine, "%x", seconds);
dxyang 3:86773d65ed58 519
dxyang 3:86773d65ed58 520 // RFID action
dxyang 3:86773d65ed58 521 strcat(logLine, " R X ");
dxyang 3:86773d65ed58 522
dxyang 3:86773d65ed58 523 // include just the RFID (indicates that no known user was found)
dxyang 3:86773d65ed58 524 char rfidBuffer[20];
dxyang 3:86773d65ed58 525 sprintf(rfidBuffer, "%u ", unknownRfid);
dxyang 3:86773d65ed58 526 strcat(logLine, rfidBuffer);
dxyang 3:86773d65ed58 527 strcat(logLine, "\n");
dxyang 3:86773d65ed58 528
dxyang 3:86773d65ed58 529 // write the line to the log file and close the file
dxyang 3:86773d65ed58 530 fputs(logLine, fp);
dxyang 3:86773d65ed58 531 fclose(fp);
dxyang 3:86773d65ed58 532
dxyang 3:86773d65ed58 533 #ifdef debug
dxyang 3:86773d65ed58 534 printf("%s\n\r", logLine);
dxyang 3:86773d65ed58 535 #endif
epgmdm 2:d1eae91343a9 536
epgmdm 2:d1eae91343a9 537 }
epgmdm 2:d1eae91343a9 538
dxyang 3:86773d65ed58 539 /*************************************************************************************************/
dxyang 5:88c516cf34e6 540 /* Housekeeping - flag clearing, cancelling, check time, update user table */
dxyang 3:86773d65ed58 541 /*************************************************************************************************/
dxyang 3:86773d65ed58 542 /*
dxyang 3:86773d65ed58 543 * Reset all user initiated flags. Useful after sequences of events where flags may have
dxyang 3:86773d65ed58 544 * piled up from misc inputs and you don't want the system to act seemingly sporadically.
dxyang 3:86773d65ed58 545 */
dxyang 3:86773d65ed58 546 void clearAllUserInitiatedFlagsH() {
dxyang 3:86773d65ed58 547 flagButtonOneH = 0;
dxyang 3:86773d65ed58 548 flagButtonTwoH = 0;
dxyang 3:86773d65ed58 549 flagButtonThreeH = 0;
dxyang 3:86773d65ed58 550 flagButtonFourH = 0;
dxyang 3:86773d65ed58 551 flagBatteryRfidH = 0;
dxyang 3:86773d65ed58 552 flagPoshoRfidH = 0;
dxyang 3:86773d65ed58 553 flagIncubatorRfidH = 0;
dxyang 3:86773d65ed58 554 }
epgmdm 2:d1eae91343a9 555
dxyang 3:86773d65ed58 556 /*
dxyang 3:86773d65ed58 557 * User presses the button corresponding to an exit. Returns to home screen
dxyang 3:86773d65ed58 558 * after logging the action.
dxyang 3:86773d65ed58 559 */
dxyang 3:86773d65ed58 560 void cancelPressedH() {
dxyang 3:86773d65ed58 561 clearAllUserInitiatedFlagsH();
dxyang 3:86773d65ed58 562 currentScreenH = initialScanRfid;
dxyang 3:86773d65ed58 563 logActionWithUserInfoH(hubAction_Exit);
dxyang 3:86773d65ed58 564 }
dxyang 3:86773d65ed58 565
dxyang 3:86773d65ed58 566 /**
dxyang 3:86773d65ed58 567 * Do if time check flag is set
dxyang 3:86773d65ed58 568 * reads the unix time, converts into human readable format, and displays on PC
dxyang 3:86773d65ed58 569 */
dxyang 3:86773d65ed58 570 void doTimeCheckH()
dxyang 3:86773d65ed58 571 {
dxyang 3:86773d65ed58 572 flagTimeCheckH = 0;
dxyang 3:86773d65ed58 573 time_t seconds = time(NULL);
dxyang 3:86773d65ed58 574 printf("%s\n\r", ctime(&seconds));
dxyang 3:86773d65ed58 575 }
dxyang 3:86773d65ed58 576
dxyang 3:86773d65ed58 577 /**
dxyang 3:86773d65ed58 578 * Do if update user table flag is set
dxyang 3:86773d65ed58 579 */
dxyang 3:86773d65ed58 580 void doUpdateUserTableH()
dxyang 3:86773d65ed58 581 {
dxyang 3:86773d65ed58 582 flagUpdateUserTableH = 0;
dxyang 3:86773d65ed58 583 // Write to a users.txt file
dxyang 3:86773d65ed58 584 spiSD();
dxyang 3:86773d65ed58 585 char * name = "/sd/users.txt";
dxyang 3:86773d65ed58 586 FILE *fp;
dxyang 3:86773d65ed58 587 fp = fopen(name, "w");
dxyang 3:86773d65ed58 588
dxyang 3:86773d65ed58 589 // output the header for the users.txt file
dxyang 3:86773d65ed58 590 fputs("rfid accountCredit locker batterySubscription batteriesOut podID\n", fp);
dxyang 3:86773d65ed58 591
dxyang 3:86773d65ed58 592 // output buffer
dxyang 3:86773d65ed58 593 char logLine[180];
dxyang 3:86773d65ed58 594
dxyang 3:86773d65ed58 595 for (int i = 0; i < userCountH; i++) {
dxyang 3:86773d65ed58 596 // get all the needed information in strings
dxyang 3:86773d65ed58 597 sprintf(logLine, "%u ", allUsersH[i].rfid);
dxyang 3:86773d65ed58 598 char accountCreditBuffer[20];
dxyang 3:86773d65ed58 599 char* lockerBuffer;
dxyang 3:86773d65ed58 600 char batterySubscriptionBuffer[20];
dxyang 3:86773d65ed58 601 char batteriesOutBuffer[20];
dxyang 3:86773d65ed58 602 char podIdBuffer[20];
dxyang 3:86773d65ed58 603
dxyang 3:86773d65ed58 604 sprintf(accountCreditBuffer, "%d ", allUsersH[i].accountCredit);
dxyang 3:86773d65ed58 605 switch (allUsersH[i].lockerID) {
dxyang 3:86773d65ed58 606 case lockerOne:
dxyang 3:86773d65ed58 607 lockerBuffer = "1 ";
dxyang 3:86773d65ed58 608 break;
dxyang 3:86773d65ed58 609 case lockerTwo:
dxyang 3:86773d65ed58 610 lockerBuffer = "2 ";
dxyang 3:86773d65ed58 611 break;
dxyang 3:86773d65ed58 612 case lockerThree:
dxyang 3:86773d65ed58 613 lockerBuffer = "3 ";
dxyang 3:86773d65ed58 614 break;
dxyang 3:86773d65ed58 615 case lockerFour:
dxyang 3:86773d65ed58 616 lockerBuffer = "4 ";
dxyang 3:86773d65ed58 617 break;
dxyang 3:86773d65ed58 618 case lockerUnassigned:
dxyang 3:86773d65ed58 619 default:
dxyang 3:86773d65ed58 620 lockerBuffer = "0 ";
dxyang 3:86773d65ed58 621 break;
dxyang 3:86773d65ed58 622 }
dxyang 3:86773d65ed58 623 sprintf(batterySubscriptionBuffer, "%d ", allUsersH[i].batterySubscription);
dxyang 3:86773d65ed58 624 sprintf(batteriesOutBuffer, "%d ", allUsersH[i].batteriesOut);
dxyang 3:86773d65ed58 625 sprintf(podIdBuffer, "%d\n", allUsersH[i].podID);
dxyang 3:86773d65ed58 626
dxyang 3:86773d65ed58 627 // concatenate all the strings
dxyang 3:86773d65ed58 628 strcat(logLine, accountCreditBuffer);
dxyang 3:86773d65ed58 629 strcat(logLine, lockerBuffer);
dxyang 3:86773d65ed58 630 strcat(logLine, batterySubscriptionBuffer);
dxyang 3:86773d65ed58 631 strcat(logLine, batteriesOutBuffer);
dxyang 3:86773d65ed58 632 strcat(logLine, podIdBuffer);
dxyang 3:86773d65ed58 633
dxyang 3:86773d65ed58 634 // write the line to the log file
dxyang 3:86773d65ed58 635 fputs(logLine, fp);
dxyang 3:86773d65ed58 636
dxyang 3:86773d65ed58 637 #ifdef debug
dxyang 3:86773d65ed58 638 printf("%s\n\r", logLine);
dxyang 3:86773d65ed58 639 #endif
dxyang 3:86773d65ed58 640 }
dxyang 3:86773d65ed58 641 fclose(fp);
dxyang 3:86773d65ed58 642 }
epgmdm 2:d1eae91343a9 643
dxyang 5:88c516cf34e6 644 /*************************************************************************************************/
dxyang 5:88c516cf34e6 645 /* Battery Services */
dxyang 5:88c516cf34e6 646 /*************************************************************************************************/
epgmdm 1:c2232b1eaf31 647 /**
dxyang 3:86773d65ed58 648 * Do if Battery RFID flag is set. Read RFID tag and check user status.
dxyang 3:86773d65ed58 649 * If there's a valid battery subscription, display drop off and/or pick up.
dxyang 3:86773d65ed58 650 * Otherwise, returns to initial screen.
dxyang 3:86773d65ed58 651 */
dxyang 3:86773d65ed58 652 void doBatteryRfidH()
dxyang 3:86773d65ed58 653 {
dxyang 3:86773d65ed58 654 flagBatteryRfidH = 0;
dxyang 3:86773d65ed58 655
dxyang 3:86773d65ed58 656 // is there a new readable card?
dxyang 3:86773d65ed58 657 if (!BatteryRfChipH.PICC_IsNewCardPresent()) {
dxyang 3:86773d65ed58 658 return;
dxyang 3:86773d65ed58 659 }
dxyang 3:86773d65ed58 660
dxyang 3:86773d65ed58 661 if (!BatteryRfChipH.PICC_ReadCardSerial()) {
dxyang 3:86773d65ed58 662 #ifdef debug
dxyang 3:86773d65ed58 663 printf("Card not readable\n\r");
dxyang 3:86773d65ed58 664 #endif
dxyang 3:86773d65ed58 665 return;
dxyang 3:86773d65ed58 666 }
dxyang 3:86773d65ed58 667
dxyang 3:86773d65ed58 668 // get the id of the scanned tag
dxyang 3:86773d65ed58 669 uint8_t tempReadingRfid[4];
dxyang 3:86773d65ed58 670 for(uint8_t i = 0; i < BatteryRfChipH.uid.size; i++) {
dxyang 3:86773d65ed58 671 tempReadingRfid[i] = BatteryRfChipH.uid.uidByte[i];
dxyang 3:86773d65ed58 672 }
dxyang 3:86773d65ed58 673
dxyang 3:86773d65ed58 674 // concatenate the 4 bytes into a single integer via bit shifting
dxyang 3:86773d65ed58 675 uint32_t actualRfid = ((((uint32_t)tempReadingRfid[0] << 24) |
dxyang 3:86773d65ed58 676 ((uint32_t)tempReadingRfid[1] << 16)) |
dxyang 3:86773d65ed58 677 (((uint32_t)tempReadingRfid[2] << 8) |
dxyang 3:86773d65ed58 678 ((uint32_t)tempReadingRfid[3] << 0)));
dxyang 3:86773d65ed58 679
dxyang 3:86773d65ed58 680 // find the user info
dxyang 3:86773d65ed58 681 char foundUserFlag = 0;
dxyang 3:86773d65ed58 682 for (int i = 0; i < userCountH; i++) {
dxyang 3:86773d65ed58 683 if (allUsersH[i].rfid == actualRfid) {
dxyang 3:86773d65ed58 684 currentUserH = i;
dxyang 3:86773d65ed58 685 foundUserFlag = 1;
dxyang 3:86773d65ed58 686 break;
dxyang 3:86773d65ed58 687 }
dxyang 3:86773d65ed58 688 }
dxyang 3:86773d65ed58 689
dxyang 3:86773d65ed58 690 // if the user is found, set the global variable for current user interacting with the system
dxyang 3:86773d65ed58 691 // if the user isn't found, log that an rfid without a user was used and display
dxyang 3:86773d65ed58 692 if (!foundUserFlag) {
dxyang 3:86773d65ed58 693 #ifdef debug
dxyang 3:86773d65ed58 694 printf("User not found\n\r");
dxyang 3:86773d65ed58 695 printf("ID:%u\n\r", actualRfid);
dxyang 3:86773d65ed58 696 #endif
dxyang 3:86773d65ed58 697 // log the error interaction
dxyang 3:86773d65ed58 698 logErrorUnknownRfidScannedH(actualRfid);
dxyang 3:86773d65ed58 699
dxyang 3:86773d65ed58 700 // let user know tag wasn't found
dxyang 3:86773d65ed58 701 TFT_H.cls();
dxyang 3:86773d65ed58 702 TFT_H.locate(0,0);
dxyang 3:86773d65ed58 703 TFT_H.printf("User not found\n\r");
dxyang 3:86773d65ed58 704 TFT_H.printf("ID:%u\n\r", actualRfid);
dxyang 3:86773d65ed58 705 wait(1);
dxyang 3:86773d65ed58 706 currentScreenH = initialScanRfid;
dxyang 3:86773d65ed58 707 return;
dxyang 3:86773d65ed58 708 }
dxyang 3:86773d65ed58 709
dxyang 3:86773d65ed58 710 // log user scan
dxyang 3:86773d65ed58 711 logActionWithUserInfoH(hubAction_RfidScanned);
dxyang 3:86773d65ed58 712
dxyang 3:86773d65ed58 713 // Display info about the user
dxyang 3:86773d65ed58 714 char authorizationFlag = 0;
dxyang 3:86773d65ed58 715 TFT_H.cls();
dxyang 3:86773d65ed58 716 TFT_H.locate(0,0);
dxyang 3:86773d65ed58 717 TFT_H.printf("UserID: %u\n\r", actualRfid);
dxyang 3:86773d65ed58 718 TFT_H.printf("Balance:%d\n\r", allUsersH[currentUserH].accountCredit);
dxyang 3:86773d65ed58 719 if (allUsersH[currentUserH].batterySubscription > 0) {
dxyang 3:86773d65ed58 720 authorizationFlag = 1;
dxyang 3:86773d65ed58 721 }
dxyang 3:86773d65ed58 722 TFT_H.printf("Authorization:%s\n\r", (authorizationFlag)? "YES":"NO");
dxyang 3:86773d65ed58 723
dxyang 3:86773d65ed58 724 #ifdef debug
dxyang 3:86773d65ed58 725 printf("User:");
dxyang 3:86773d65ed58 726 for(uint8_t i = 0; i < BatteryRfChipH.uid.size; i++)
dxyang 3:86773d65ed58 727 {
dxyang 3:86773d65ed58 728 uint8_t uidByte = BatteryRfChipH.uid.uidByte[i];
dxyang 3:86773d65ed58 729 printf(" %d", uidByte);
dxyang 3:86773d65ed58 730 }
dxyang 3:86773d65ed58 731 printf("\n\rUserID: %u\n\r", actualRfid);
dxyang 3:86773d65ed58 732 #endif
dxyang 3:86773d65ed58 733
dxyang 3:86773d65ed58 734 // if not authorized for batteries, return to main screen
dxyang 3:86773d65ed58 735 wait(1);
dxyang 3:86773d65ed58 736 if (!authorizationFlag) {
dxyang 3:86773d65ed58 737 currentScreenH = initialScanRfid;
dxyang 3:86773d65ed58 738 return;
dxyang 3:86773d65ed58 739 }
dxyang 3:86773d65ed58 740
dxyang 3:86773d65ed58 741 // otherwise, ask user if the user wants to pick up or drop off batteries?
dxyang 3:86773d65ed58 742 TFT_H.locate(0,160);
dxyang 3:86773d65ed58 743 TFT_H.printf("Battery Action?\n\r");
dxyang 3:86773d65ed58 744 TFT_H.locate(0,200);
dxyang 3:86773d65ed58 745
dxyang 3:86773d65ed58 746 uint8_t maxBatteries = allUsersH[currentUserH].batterySubscription;
dxyang 3:86773d65ed58 747 uint8_t outBatteries = allUsersH[currentUserH].batteriesOut;
dxyang 3:86773d65ed58 748
dxyang 3:86773d65ed58 749 if ((maxBatteries - outBatteries) == 0) { // can only drop off
dxyang 3:86773d65ed58 750 TFT_H.printf(" drop exit");
dxyang 3:86773d65ed58 751 } else if (outBatteries == 0) { // can only pick up
dxyang 3:86773d65ed58 752 TFT_H.printf(" pick exit");
dxyang 3:86773d65ed58 753 } else { // can pickup or dropoff
dxyang 3:86773d65ed58 754 TFT_H.printf(" pick drop exit");
dxyang 3:86773d65ed58 755 }
dxyang 3:86773d65ed58 756
dxyang 3:86773d65ed58 757 // go to action selecting screen and clear buttons beforehand
dxyang 3:86773d65ed58 758 currentScreenH = batterySelectAction;
dxyang 3:86773d65ed58 759 clearAllUserInitiatedFlagsH();
dxyang 3:86773d65ed58 760 return;
dxyang 3:86773d65ed58 761 }
dxyang 3:86773d65ed58 762
dxyang 3:86773d65ed58 763 /**
dxyang 3:86773d65ed58 764 * Do if user selects to pickup a battery. Determines how many batteries
dxyang 3:86773d65ed58 765 * a user can pickup based off user info and displays corresponding text
dxyang 3:86773d65ed58 766 */
dxyang 3:86773d65ed58 767 void batteryPickUpH() {
dxyang 3:86773d65ed58 768 TFT_H.cls();
dxyang 3:86773d65ed58 769 TFT_H.locate(0,0);
dxyang 3:86773d65ed58 770 TFT_H.printf("UserID: %u\n\r\n\r", allUsersH[currentUserH].rfid);
dxyang 3:86773d65ed58 771
dxyang 3:86773d65ed58 772 TFT_H.printf("Action: PICK UP\n\r");
dxyang 3:86773d65ed58 773 TFT_H.locate(0,160);
dxyang 3:86773d65ed58 774 TFT_H.printf("How many batteries?\n\r");
dxyang 3:86773d65ed58 775 TFT_H.locate(0,200);
dxyang 3:86773d65ed58 776 switch (allUsersH[currentUserH].batterySubscription - allUsersH[currentUserH].batteriesOut) {
dxyang 3:86773d65ed58 777 case 1: {
dxyang 3:86773d65ed58 778 TFT_H.printf(" 1 exit");
dxyang 3:86773d65ed58 779 break;
dxyang 3:86773d65ed58 780 }
dxyang 3:86773d65ed58 781 case 2: {
dxyang 3:86773d65ed58 782 TFT_H.printf(" 1 2 exit");
dxyang 3:86773d65ed58 783 break;
dxyang 3:86773d65ed58 784 }
dxyang 3:86773d65ed58 785 case 3: {
dxyang 3:86773d65ed58 786 TFT_H.printf(" 1 2 3 exit");
dxyang 3:86773d65ed58 787 break;
dxyang 3:86773d65ed58 788 }
dxyang 3:86773d65ed58 789 }
dxyang 3:86773d65ed58 790
dxyang 3:86773d65ed58 791 // go to wait for selection input and reset button flags
dxyang 3:86773d65ed58 792 currentScreenH = batterySelectNumberForPickup;
dxyang 3:86773d65ed58 793 clearAllUserInitiatedFlagsH();
dxyang 3:86773d65ed58 794 return;
dxyang 3:86773d65ed58 795 }
dxyang 3:86773d65ed58 796
dxyang 3:86773d65ed58 797 /**
dxyang 3:86773d65ed58 798 * Do if user selects to dropoff a battery. Determines how many batteries
dxyang 3:86773d65ed58 799 * a user can pickup based off user info and displays corresponding text
dxyang 3:86773d65ed58 800 */
dxyang 3:86773d65ed58 801 void batteryDropOffH() {
dxyang 3:86773d65ed58 802 TFT_H.cls();
dxyang 3:86773d65ed58 803 TFT_H.locate(0,0);
dxyang 3:86773d65ed58 804 TFT_H.printf("UserID: %u\n\r\n\r", allUsersH[currentUserH].rfid);
dxyang 3:86773d65ed58 805
dxyang 3:86773d65ed58 806 TFT_H.printf("Action: DROP OFF\n\r");
dxyang 3:86773d65ed58 807 TFT_H.locate(0,160);
dxyang 3:86773d65ed58 808 TFT_H.printf("How many batteries?\n\r");
dxyang 3:86773d65ed58 809 TFT_H.locate(0,200);
dxyang 3:86773d65ed58 810 switch (allUsersH[currentUserH].batteriesOut) {
dxyang 3:86773d65ed58 811 case 1: {
dxyang 3:86773d65ed58 812 TFT_H.printf(" 1 exit");
dxyang 3:86773d65ed58 813 break;
dxyang 3:86773d65ed58 814 }
dxyang 3:86773d65ed58 815 case 2: {
dxyang 3:86773d65ed58 816 TFT_H.printf(" 1 2 exit");
dxyang 3:86773d65ed58 817 break;
dxyang 3:86773d65ed58 818 }
dxyang 3:86773d65ed58 819 case 3: {
dxyang 3:86773d65ed58 820 TFT_H.printf(" 1 2 3 exit");
dxyang 3:86773d65ed58 821 break;
dxyang 3:86773d65ed58 822 }
dxyang 3:86773d65ed58 823 }
dxyang 3:86773d65ed58 824
dxyang 3:86773d65ed58 825 // go to wait for selection input and reset button flags
dxyang 3:86773d65ed58 826 currentScreenH = batterySelectNumberForDropoff;
dxyang 3:86773d65ed58 827 clearAllUserInitiatedFlagsH();
dxyang 3:86773d65ed58 828 return;
dxyang 3:86773d65ed58 829 }
dxyang 3:86773d65ed58 830
dxyang 3:86773d65ed58 831 /**
dxyang 3:86773d65ed58 832 * Do after use selects number of batteries to drop off.
dxyang 3:86773d65ed58 833 * Logs the action, changes user info, transmits instructions to other systems
dxyang 3:86773d65ed58 834 * @param numBatteries - int for number of batteries selected to drop off
dxyang 3:86773d65ed58 835 */
dxyang 3:86773d65ed58 836 void batteryDropOffH(int numBatteries) {
dxyang 3:86773d65ed58 837 switch(numBatteries) {
dxyang 3:86773d65ed58 838 case 1:
dxyang 3:86773d65ed58 839 logActionWithUserInfoH(hubAction_OneBatteryDropped);
dxyang 6:00a132a076d5 840 txBatteryDropOff(1);
dxyang 3:86773d65ed58 841 allUsersH[currentUserH].batteriesOut--;
dxyang 3:86773d65ed58 842 break;
dxyang 3:86773d65ed58 843 case 2:
dxyang 3:86773d65ed58 844 logActionWithUserInfoH(hubAction_TwoBatteryDropped);
dxyang 6:00a132a076d5 845 txBatteryDropOff(2);
dxyang 3:86773d65ed58 846 allUsersH[currentUserH].batteriesOut -= 2;
dxyang 3:86773d65ed58 847 break;
dxyang 3:86773d65ed58 848 case 3:
dxyang 3:86773d65ed58 849 logActionWithUserInfoH(hubAction_ThreeBatteryDropped);
dxyang 6:00a132a076d5 850 txBatteryDropOff(3);
dxyang 3:86773d65ed58 851 allUsersH[currentUserH].batteriesOut -= 3;
dxyang 3:86773d65ed58 852 break;
dxyang 3:86773d65ed58 853 }
dxyang 3:86773d65ed58 854
dxyang 3:86773d65ed58 855 currentScreenH = initialScanRfid;
dxyang 3:86773d65ed58 856 return;
dxyang 3:86773d65ed58 857 }
dxyang 3:86773d65ed58 858
dxyang 3:86773d65ed58 859 /**
dxyang 3:86773d65ed58 860 * Do after use selects number of batteries to pick up.
dxyang 3:86773d65ed58 861 * Logs the action, changes user info, transmits instructions to other systems
dxyang 3:86773d65ed58 862 * @param numBatteries - int for number of batteries selected to pick up
dxyang 3:86773d65ed58 863 */
dxyang 3:86773d65ed58 864 void batteryPickUpH(int numBatteries) {
dxyang 3:86773d65ed58 865 switch(numBatteries) {
dxyang 3:86773d65ed58 866 case 1:
dxyang 3:86773d65ed58 867 logActionWithUserInfoH(hubAction_OneBatteryPicked);
dxyang 6:00a132a076d5 868 txBatteryPickUp(1);
dxyang 3:86773d65ed58 869 allUsersH[currentUserH].batteriesOut++;
dxyang 3:86773d65ed58 870 break;
dxyang 3:86773d65ed58 871 case 2:
dxyang 3:86773d65ed58 872 logActionWithUserInfoH(hubAction_TwoBatteryPicked);
dxyang 6:00a132a076d5 873 txBatteryPickUp(2);
dxyang 3:86773d65ed58 874 allUsersH[currentUserH].batteriesOut += 2;
dxyang 3:86773d65ed58 875 break;
dxyang 3:86773d65ed58 876 case 3:
dxyang 3:86773d65ed58 877 logActionWithUserInfoH(hubAction_ThreeBatteryPicked);
dxyang 6:00a132a076d5 878 txBatteryPickUp(3);
dxyang 3:86773d65ed58 879 allUsersH[currentUserH].batteriesOut += 3;
dxyang 3:86773d65ed58 880 break;
dxyang 3:86773d65ed58 881 }
dxyang 3:86773d65ed58 882
dxyang 3:86773d65ed58 883 currentScreenH = initialScanRfid;
dxyang 3:86773d65ed58 884 return;
dxyang 3:86773d65ed58 885 }
dxyang 3:86773d65ed58 886
dxyang 5:88c516cf34e6 887 /*************************************************************************************************/
dxyang 5:88c516cf34e6 888 /* Misc Services */
dxyang 5:88c516cf34e6 889 /*************************************************************************************************/
dxyang 3:86773d65ed58 890 /**
dxyang 3:86773d65ed58 891 * Do if Posho RFID flag is set. Add posho functionality later.
dxyang 3:86773d65ed58 892 */
dxyang 3:86773d65ed58 893 void doPoshoRfidH()
dxyang 3:86773d65ed58 894 {
dxyang 3:86773d65ed58 895 flagPoshoRfidH = 0;
dxyang 3:86773d65ed58 896 }
dxyang 3:86773d65ed58 897
dxyang 3:86773d65ed58 898 /**
dxyang 3:86773d65ed58 899 * Do if Incubator RFID flag is set. Add incubator functionality later.
dxyang 3:86773d65ed58 900 */
dxyang 3:86773d65ed58 901 void doIncubatorRfidH()
dxyang 3:86773d65ed58 902 {
dxyang 3:86773d65ed58 903 flagIncubatorRfidH = 0;
dxyang 3:86773d65ed58 904 }
dxyang 3:86773d65ed58 905
dxyang 3:86773d65ed58 906 /*************************************************************************************************/
dxyang 3:86773d65ed58 907 /* Public Methods */
dxyang 3:86773d65ed58 908 /*************************************************************************************************/
dxyang 3:86773d65ed58 909 /**
dxyang 3:86773d65ed58 910 * Initialise for a hub
epgmdm 1:c2232b1eaf31 911 * fp is the config file if additonal information is needed.
epgmdm 1:c2232b1eaf31 912 */
epgmdm 1:c2232b1eaf31 913 void initialiseHub(FILE *fp){
epgmdm 1:c2232b1eaf31 914 #ifdef debug
dxyang 3:86773d65ed58 915 printf("Initializing Hub\n\r");
epgmdm 1:c2232b1eaf31 916 #endif
epgmdm 1:c2232b1eaf31 917
epgmdm 1:c2232b1eaf31 918 // Read in hub address and channel
epgmdm 1:c2232b1eaf31 919 if (fscanf (fp,"%x %*c %*s",&channel )!=1) writeError("Hub config: cannot read channel");
epgmdm 1:c2232b1eaf31 920 if (fscanf (fp,"%llx %*c %*s",&addrLcker )!=1) writeError("Hub config: cannot read hub address");
epgmdm 1:c2232b1eaf31 921
epgmdm 1:c2232b1eaf31 922 #ifdef debug
epgmdm 1:c2232b1eaf31 923 printf(" Channel:%x, Hub Address %llx \n\r",channel, addrLcker);
epgmdm 1:c2232b1eaf31 924 #endif
epgmdm 2:d1eae91343a9 925
epgmdm 2:d1eae91343a9 926 // Setup nrf
epgmdm 2:d1eae91343a9 927 #ifdef debug
epgmdm 2:d1eae91343a9 928 printf("Steup doNrf \n\r");
epgmdm 2:d1eae91343a9 929 #endif
epgmdm 2:d1eae91343a9 930 spiNrf();
epgmdm 2:d1eae91343a9 931 nrf1.quickTxSetup(channel, addrLcker);
epgmdm 2:d1eae91343a9 932 #ifdef debug
epgmdm 2:d1eae91343a9 933 nrf1.printDetails();
epgmdm 2:d1eae91343a9 934 nrf1.checkStatus();
epgmdm 2:d1eae91343a9 935 printf("Setup doNrf complete [nrf:%s]\n\r",nrf1.statusString());
epgmdm 2:d1eae91343a9 936 #endif
epgmdm 2:d1eae91343a9 937
dxyang 3:86773d65ed58 938 // Other initialization routines
dxyang 3:86773d65ed58 939 initializeTimeH();
dxyang 3:86773d65ed58 940 initializeInterruptsH();
dxyang 3:86773d65ed58 941 initializeRfidReadersH();
dxyang 3:86773d65ed58 942 initializeLCD_H();
dxyang 3:86773d65ed58 943 initializeUsersFromSD_H();
epgmdm 1:c2232b1eaf31 944 }
epgmdm 2:d1eae91343a9 945
dxyang 3:86773d65ed58 946 void loopHub(){
dxyang 3:86773d65ed58 947 while (true) {
dxyang 3:86773d65ed58 948 // put interrupts here that should supercede anything else
dxyang 3:86773d65ed58 949 if (flag1sH) { do1sH(); }
epgmdm 1:c2232b1eaf31 950
dxyang 3:86773d65ed58 951 // put interrupts here that may be active depending on screen stage
dxyang 3:86773d65ed58 952 switch(currentScreenH) {
dxyang 3:86773d65ed58 953 case initialScanRfid: {
dxyang 3:86773d65ed58 954 TFT_H.cls();
dxyang 3:86773d65ed58 955 TFT_H.locate(0,0);
dxyang 3:86773d65ed58 956 TFT_H.printf("Please scan your ID");
dxyang 3:86773d65ed58 957 currentScreenH = waitForRfid;
dxyang 3:86773d65ed58 958 clearAllUserInitiatedFlagsH();
dxyang 3:86773d65ed58 959 }
dxyang 3:86773d65ed58 960 case waitForRfid: {
dxyang 3:86773d65ed58 961 if (flagTimeCheckH) doTimeCheckH();
dxyang 3:86773d65ed58 962 if (flagBatteryRfidH) doBatteryRfidH();
dxyang 3:86773d65ed58 963 if (flagPoshoRfidH) doPoshoRfidH();
dxyang 3:86773d65ed58 964 if (flagIncubatorRfidH) doIncubatorRfidH();
dxyang 3:86773d65ed58 965 if (flagUpdateUserTableH) doUpdateUserTableH();
dxyang 3:86773d65ed58 966 break;
dxyang 3:86773d65ed58 967 }
dxyang 3:86773d65ed58 968 case batterySelectAction: {
dxyang 3:86773d65ed58 969 uint8_t maxBatteries = allUsersH[currentUserH].batterySubscription;
dxyang 3:86773d65ed58 970 uint8_t outBatteries = allUsersH[currentUserH].batteriesOut;
dxyang 3:86773d65ed58 971
dxyang 3:86773d65ed58 972 if ((maxBatteries - outBatteries) == 0) {
dxyang 3:86773d65ed58 973 if (flagButtonOneH) batteryDropOffH();
dxyang 3:86773d65ed58 974 if (flagButtonFourH) cancelPressedH();
dxyang 3:86773d65ed58 975 } else if (outBatteries == 0) {
dxyang 3:86773d65ed58 976 if (flagButtonOneH) batteryPickUpH();
dxyang 3:86773d65ed58 977 if (flagButtonFourH) cancelPressedH();
dxyang 3:86773d65ed58 978 } else {
dxyang 3:86773d65ed58 979 if (flagButtonOneH) batteryPickUpH();
dxyang 3:86773d65ed58 980 if (flagButtonThreeH) batteryDropOffH();
dxyang 3:86773d65ed58 981 if (flagButtonFourH) cancelPressedH();
dxyang 3:86773d65ed58 982 }
epgmdm 1:c2232b1eaf31 983
dxyang 3:86773d65ed58 984 break;
dxyang 3:86773d65ed58 985 }
dxyang 3:86773d65ed58 986 case batterySelectNumberForDropoff: {
dxyang 3:86773d65ed58 987 switch (allUsersH[currentUserH].batteriesOut) {
dxyang 3:86773d65ed58 988 case 1: {
dxyang 3:86773d65ed58 989 if (flagButtonOneH) batteryDropOffH(1);
dxyang 3:86773d65ed58 990 if (flagButtonFourH) cancelPressedH();
dxyang 3:86773d65ed58 991 break;
dxyang 3:86773d65ed58 992 }
dxyang 3:86773d65ed58 993 case 2: {
dxyang 3:86773d65ed58 994 if (flagButtonOneH) batteryDropOffH(1);
dxyang 3:86773d65ed58 995 if (flagButtonTwoH) batteryDropOffH(2);
dxyang 3:86773d65ed58 996 if (flagButtonFourH) cancelPressedH();
dxyang 3:86773d65ed58 997 break;
dxyang 3:86773d65ed58 998 }
dxyang 3:86773d65ed58 999 case 3: {
dxyang 3:86773d65ed58 1000 if (flagButtonOneH) batteryDropOffH(1);
dxyang 3:86773d65ed58 1001 if (flagButtonTwoH) batteryDropOffH(2);
dxyang 3:86773d65ed58 1002 if (flagButtonThreeH) batteryDropOffH(3);
dxyang 3:86773d65ed58 1003 if (flagButtonFourH) cancelPressedH();
dxyang 3:86773d65ed58 1004 break;
dxyang 3:86773d65ed58 1005 }
dxyang 3:86773d65ed58 1006 }
dxyang 3:86773d65ed58 1007 break;
dxyang 3:86773d65ed58 1008 }
dxyang 3:86773d65ed58 1009 case batterySelectNumberForPickup: {
dxyang 3:86773d65ed58 1010 switch (allUsersH[currentUserH].batterySubscription - allUsersH[currentUserH].batteriesOut) {
dxyang 3:86773d65ed58 1011 case 1: {
dxyang 3:86773d65ed58 1012 if (flagButtonOneH) batteryPickUpH(1);
dxyang 3:86773d65ed58 1013 if (flagButtonFourH) cancelPressedH();
dxyang 3:86773d65ed58 1014 break;
dxyang 3:86773d65ed58 1015 }
dxyang 3:86773d65ed58 1016 case 2: {
dxyang 3:86773d65ed58 1017 if (flagButtonOneH) batteryPickUpH(1);
dxyang 3:86773d65ed58 1018 if (flagButtonTwoH) batteryPickUpH(2);
dxyang 3:86773d65ed58 1019 if (flagButtonFourH) cancelPressedH();
dxyang 3:86773d65ed58 1020 break;
dxyang 3:86773d65ed58 1021 }
dxyang 3:86773d65ed58 1022 case 3: {
dxyang 3:86773d65ed58 1023 if (flagButtonOneH) batteryPickUpH(1);
dxyang 3:86773d65ed58 1024 if (flagButtonTwoH) batteryPickUpH(2);
dxyang 3:86773d65ed58 1025 if (flagButtonThreeH) batteryPickUpH(3);
dxyang 3:86773d65ed58 1026 if (flagButtonFourH) cancelPressedH();
dxyang 3:86773d65ed58 1027 break;
dxyang 3:86773d65ed58 1028 }
dxyang 3:86773d65ed58 1029 }
dxyang 3:86773d65ed58 1030 break;
dxyang 3:86773d65ed58 1031 }
dxyang 3:86773d65ed58 1032 }
epgmdm 2:d1eae91343a9 1033 }
epgmdm 1:c2232b1eaf31 1034 }