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 14:38:13 2016 +0000
Revision:
8:b40c4553f6d4
Parent:
7:0aee09577ad3
Child:
9:72e93d9ddc8c
added posho functionality screens (lockout, one user at a time)

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 8:b40c4553f6d4 82 batterySelectNumberForDropoff,
dxyang 8:b40c4553f6d4 83 poshoSelectKilograms
dxyang 3:86773d65ed58 84 };
dxyang 3:86773d65ed58 85 enum HubScreenStageH currentScreenH = initialScanRfid;
dxyang 3:86773d65ed58 86
dxyang 3:86773d65ed58 87 // hubUser struct containing the users uid, rfid, number of batteries, current account credit,
dxyang 3:86773d65ed58 88 // an enum corresponding to a locker channel address, and pod ID within a locker
dxyang 3:86773d65ed58 89 struct hubUserH {
dxyang 3:86773d65ed58 90 uint32_t uid;
dxyang 3:86773d65ed58 91 uint32_t rfid;
dxyang 3:86773d65ed58 92 int32_t accountCredit;
dxyang 3:86773d65ed58 93 enum LockerAddressH lockerID;
dxyang 3:86773d65ed58 94 int32_t podID;
dxyang 3:86773d65ed58 95 int32_t batteriesOut;
dxyang 3:86773d65ed58 96 int32_t batterySubscription;
dxyang 3:86773d65ed58 97 };
dxyang 3:86773d65ed58 98
dxyang 3:86773d65ed58 99 // community ID should be defined somewhere and accessible globally
dxyang 3:86773d65ed58 100 uint32_t communityID_H = 1;
dxyang 3:86773d65ed58 101
dxyang 3:86773d65ed58 102 // array to store all users and index of end of the current list
dxyang 3:86773d65ed58 103 hubUserH allUsersH[256];
dxyang 3:86773d65ed58 104 uint8_t userCountH = 0;
dxyang 3:86773d65ed58 105 uint8_t currentUserH;
dxyang 3:86773d65ed58 106
dxyang 3:86773d65ed58 107 // Data is being logged and collected
dxyang 3:86773d65ed58 108 // these actions depend on a known user using the system
dxyang 3:86773d65ed58 109 enum HubActionForLoggingH {
dxyang 8:b40c4553f6d4 110 hubAction_BatteryRfidScanned,
dxyang 8:b40c4553f6d4 111 hubAction_PoshoRfidScanned,
dxyang 3:86773d65ed58 112 hubAction_Exit,
dxyang 3:86773d65ed58 113 hubAction_OneBatteryDropped,
dxyang 3:86773d65ed58 114 hubAction_TwoBatteryDropped,
dxyang 3:86773d65ed58 115 hubAction_ThreeBatteryDropped,
dxyang 3:86773d65ed58 116 hubAction_OneBatteryPicked,
dxyang 3:86773d65ed58 117 hubAction_TwoBatteryPicked,
dxyang 3:86773d65ed58 118 hubAction_ThreeBatteryPicked
dxyang 3:86773d65ed58 119 };
dxyang 3:86773d65ed58 120
dxyang 8:b40c4553f6d4 121 // any rfid can log errors regarding an unknown tag being read
dxyang 8:b40c4553f6d4 122 enum HubLoggingRfidSourceH {
dxyang 8:b40c4553f6d4 123 source_battery,
dxyang 8:b40c4553f6d4 124 source_posho,
dxyang 8:b40c4553f6d4 125 source_incubator
dxyang 8:b40c4553f6d4 126 };
dxyang 8:b40c4553f6d4 127
dxyang 8:b40c4553f6d4 128 // price per kilogram of material to be used with the posho
dxyang 8:b40c4553f6d4 129 int poshoPricePerKgH;
dxyang 8:b40c4553f6d4 130
dxyang 8:b40c4553f6d4 131 // flag for if the posho is already in use; multiple people cannot use at once
dxyang 8:b40c4553f6d4 132 char flagPoshoAlreadyInUseH = 0;
dxyang 8:b40c4553f6d4 133 Ticker tickPoshoInUseClearH;
dxyang 8:b40c4553f6d4 134 int timeForOneKgH;
dxyang 8:b40c4553f6d4 135 int timeForTwoKgH;
dxyang 8:b40c4553f6d4 136 int timeForThreeKgH;
dxyang 8:b40c4553f6d4 137
dxyang 3:86773d65ed58 138 /*************************************************************************************************/
dxyang 3:86773d65ed58 139 /* Set a flag when an interrupt is detected */
dxyang 3:86773d65ed58 140 /*************************************************************************************************/
dxyang 3:86773d65ed58 141 /**
dxyang 3:86773d65ed58 142 * Time check interrupt
dxyang 3:86773d65ed58 143 */
dxyang 3:86773d65ed58 144 void interruptTimeCheckH()
dxyang 3:86773d65ed58 145 { flagTimeCheckH = 1; }
dxyang 3:86773d65ed58 146
dxyang 3:86773d65ed58 147 /**
dxyang 3:86773d65ed58 148 * Update user table interrupt
dxyang 3:86773d65ed58 149 */
dxyang 3:86773d65ed58 150 void interruptUpdateUserTableH()
dxyang 3:86773d65ed58 151 { flagUpdateUserTableH = 1; }
dxyang 3:86773d65ed58 152
dxyang 3:86773d65ed58 153 /**
dxyang 3:86773d65ed58 154 * Battery RFID reader interrupt
dxyang 3:86773d65ed58 155 */
dxyang 3:86773d65ed58 156 void interruptBatteryRfidH()
dxyang 3:86773d65ed58 157 { flagBatteryRfidH = 1; }
dxyang 3:86773d65ed58 158
dxyang 3:86773d65ed58 159 /**
dxyang 3:86773d65ed58 160 * Posho RFID reader interrupt
dxyang 3:86773d65ed58 161 */
dxyang 3:86773d65ed58 162 void interruptPoshoRfidH()
dxyang 3:86773d65ed58 163 { flagPoshoRfidH = 1; }
dxyang 3:86773d65ed58 164
dxyang 3:86773d65ed58 165 /**
dxyang 3:86773d65ed58 166 * Incubator RFID reader interrupt
dxyang 3:86773d65ed58 167 */
dxyang 3:86773d65ed58 168 void interruptIncubatorRfidH()
dxyang 3:86773d65ed58 169 { flagIncubatorRfidH = 1; }
dxyang 3:86773d65ed58 170
dxyang 3:86773d65ed58 171 /**
dxyang 3:86773d65ed58 172 * buttone one interrupt
dxyang 3:86773d65ed58 173 */
dxyang 3:86773d65ed58 174 void interruptButtonOneH()
dxyang 3:86773d65ed58 175 { flagButtonOneH = 1; }
dxyang 3:86773d65ed58 176
dxyang 3:86773d65ed58 177 /**
dxyang 3:86773d65ed58 178 * buttone two interrupt
dxyang 3:86773d65ed58 179 */
dxyang 3:86773d65ed58 180 void interruptButtonTwoH()
dxyang 3:86773d65ed58 181 { flagButtonTwoH = 1; }
dxyang 3:86773d65ed58 182
dxyang 3:86773d65ed58 183 /**
dxyang 3:86773d65ed58 184 * buttone three interrupt
dxyang 3:86773d65ed58 185 */
dxyang 3:86773d65ed58 186 void interruptButtonThreeH()
dxyang 3:86773d65ed58 187 { flagButtonThreeH = 1; }
dxyang 3:86773d65ed58 188
dxyang 3:86773d65ed58 189 /**
dxyang 3:86773d65ed58 190 * buttone four interrupt
dxyang 3:86773d65ed58 191 */
dxyang 3:86773d65ed58 192 void interruptButtonFourH()
dxyang 3:86773d65ed58 193 { flagButtonFourH = 1; }
dxyang 3:86773d65ed58 194
epgmdm 2:d1eae91343a9 195 /**
epgmdm 2:d1eae91343a9 196 * Fast interrupt routine for every 1 second
epgmdm 2:d1eae91343a9 197 */
epgmdm 2:d1eae91343a9 198 void int1sH()
dxyang 3:86773d65ed58 199 { flag1sH=1; }
dxyang 3:86773d65ed58 200
dxyang 8:b40c4553f6d4 201 /**
dxyang 8:b40c4553f6d4 202 * interrupt to clear the posho is in use flag after a designated time
dxyang 8:b40c4553f6d4 203 */
dxyang 8:b40c4553f6d4 204 void interruptPoshoInUseClearH()
dxyang 8:b40c4553f6d4 205 {
dxyang 8:b40c4553f6d4 206 flagPoshoAlreadyInUseH = 0;
dxyang 8:b40c4553f6d4 207 tickPoshoInUseClearH.detach();
dxyang 8:b40c4553f6d4 208 }
dxyang 8:b40c4553f6d4 209
dxyang 3:86773d65ed58 210 /*************************************************************************************************/
dxyang 3:86773d65ed58 211 /* Transfer Info */
dxyang 3:86773d65ed58 212 /*************************************************************************************************/
epgmdm 2:d1eae91343a9 213 /**
dxyang 8:b40c4553f6d4 214 * Sends a time stamp
dxyang 8:b40c4553f6d4 215 */
epgmdm 2:d1eae91343a9 216 void txTimeH()
epgmdm 2:d1eae91343a9 217 {
epgmdm 2:d1eae91343a9 218 #ifdef debug
epgmdm 2:d1eae91343a9 219 printf("Send time \n\r");
epgmdm 2:d1eae91343a9 220 #endif
epgmdm 2:d1eae91343a9 221 time_t now= time(NULL);
epgmdm 2:d1eae91343a9 222 sprintf(txBuff,"T %X",now);
epgmdm 2:d1eae91343a9 223 nrf1.transmitData(txBuff,strlen(txBuff));
epgmdm 2:d1eae91343a9 224 #ifdef debug
epgmdm 2:d1eae91343a9 225 printf("Tx %s [nrf:%s] \n\r", txBuff,nrf1.statusString());
epgmdm 2:d1eae91343a9 226 #endif
epgmdm 2:d1eae91343a9 227 }
epgmdm 2:d1eae91343a9 228
epgmdm 2:d1eae91343a9 229 /**
dxyang 8:b40c4553f6d4 230 * Sends max Current
dxyang 8:b40c4553f6d4 231 */
epgmdm 2:d1eae91343a9 232 void txCurrentH()
epgmdm 2:d1eae91343a9 233 {
epgmdm 2:d1eae91343a9 234 #ifdef debug
epgmdm 2:d1eae91343a9 235 printf("Send current \n\r");
epgmdm 2:d1eae91343a9 236 #endif
epgmdm 2:d1eae91343a9 237 sprintf(txBuff,"I %04X", *((int *) &currentMaxH));
epgmdm 2:d1eae91343a9 238 nrf1.transmitData(txBuff,strlen(txBuff));
epgmdm 2:d1eae91343a9 239 #ifdef debug
epgmdm 2:d1eae91343a9 240 printf("Tx %s [nrf:%s] \n\r", txBuff,nrf1.statusString());
epgmdm 2:d1eae91343a9 241 #endif
epgmdm 2:d1eae91343a9 242 }
epgmdm 1:c2232b1eaf31 243
epgmdm 2:d1eae91343a9 244 /**
dxyang 8:b40c4553f6d4 245 * Slow interrupt routine for every 1 second
dxyang 8:b40c4553f6d4 246 */
epgmdm 2:d1eae91343a9 247 void do1sH()
epgmdm 2:d1eae91343a9 248 {
dxyang 3:86773d65ed58 249 flag1sH = 0;
epgmdm 2:d1eae91343a9 250 #ifdef debug
epgmdm 2:d1eae91343a9 251 printf("Hub 1s \n\r");
epgmdm 2:d1eae91343a9 252 #endif
epgmdm 2:d1eae91343a9 253
epgmdm 2:d1eae91343a9 254 time_t now= time(NULL);
epgmdm 2:d1eae91343a9 255 if ((now % 60)==0){
epgmdm 2:d1eae91343a9 256 txTimeH();
epgmdm 2:d1eae91343a9 257 }
epgmdm 2:d1eae91343a9 258 txCurrentH();
epgmdm 2:d1eae91343a9 259 #ifdef debug
epgmdm 2:d1eae91343a9 260 printf("Tx %s [nrf:%s] \n\r", txBuff,nrf1.statusString());
epgmdm 2:d1eae91343a9 261 #endif
epgmdm 2:d1eae91343a9 262 }
dxyang 6:00a132a076d5 263
dxyang 6:00a132a076d5 264 /**
dxyang 8:b40c4553f6d4 265 * Sends a signal to a locker that the current user is picking up numBatteries batteries
dxyang 8:b40c4553f6d4 266 * @param numBatteries - int representing number of batteries user is picking up
dxyang 8:b40c4553f6d4 267 */
dxyang 6:00a132a076d5 268 void txBatteryPickUp(int numBatteries) {
dxyang 6:00a132a076d5 269
dxyang 6:00a132a076d5 270 }
dxyang 6:00a132a076d5 271
dxyang 6:00a132a076d5 272 /**
dxyang 8:b40c4553f6d4 273 * Sends a signal to a locker that the current user is dropping off numBatteries batteries
dxyang 8:b40c4553f6d4 274 * @param numBatteries - int representing number of batteries user is dropping off
dxyang 8:b40c4553f6d4 275 */
dxyang 6:00a132a076d5 276 void txBatteryDropOff(int numBatteries) {
dxyang 6:00a132a076d5 277
dxyang 6:00a132a076d5 278 }
dxyang 6:00a132a076d5 279
dxyang 8:b40c4553f6d4 280 /**
dxyang 8:b40c4553f6d4 281 * Sends a signal to a services mbed to schedule the posho/husker for use for x kilograms
dxyang 8:b40c4553f6d4 282 * @param numKilograms - int representing number of kilograms user is processing
dxyang 8:b40c4553f6d4 283 */
dxyang 8:b40c4553f6d4 284 void txPoshoSerialUse(int numKilograms) {
dxyang 8:b40c4553f6d4 285
dxyang 8:b40c4553f6d4 286 }
dxyang 6:00a132a076d5 287
dxyang 5:88c516cf34e6 288 /*************************************************************************************************/
dxyang 5:88c516cf34e6 289 /* Initialization */
dxyang 5:88c516cf34e6 290 /*************************************************************************************************/
epgmdm 2:d1eae91343a9 291 /**
dxyang 3:86773d65ed58 292 * Initialize system on reset and set the time from the terminal
dxyang 3:86773d65ed58 293 */
dxyang 3:86773d65ed58 294 void initializeTimeH()
dxyang 3:86773d65ed58 295 {
epgmdm 2:d1eae91343a9 296 // get the current time from the terminal
epgmdm 2:d1eae91343a9 297 struct tm t;
epgmdm 2:d1eae91343a9 298 printf("Enter current date :\n\r");
epgmdm 2:d1eae91343a9 299 printf("YYYY MM DD [enter]\n\r");
epgmdm 2:d1eae91343a9 300 scanf("%d %d %d", &t.tm_year, &t.tm_mon, &t.tm_mday);
epgmdm 2:d1eae91343a9 301 printf("Enter current time:\n\r");
epgmdm 2:d1eae91343a9 302 printf("HH MM SS [enter]\n\r");
epgmdm 2:d1eae91343a9 303 scanf("%d %d %d", &t.tm_hour, &t.tm_min, &t.tm_sec);
epgmdm 2:d1eae91343a9 304
epgmdm 2:d1eae91343a9 305 // adjust for tm structure required values
epgmdm 2:d1eae91343a9 306 t.tm_year = t.tm_year - 1900;
epgmdm 2:d1eae91343a9 307 t.tm_mon = t.tm_mon - 1;
epgmdm 2:d1eae91343a9 308
epgmdm 2:d1eae91343a9 309 // set the time
epgmdm 2:d1eae91343a9 310 set_time(mktime(&t));
dxyang 3:86773d65ed58 311 #ifdef debug
dxyang 3:86773d65ed58 312 printf("Time initialized\n\r");
dxyang 3:86773d65ed58 313 #endif
dxyang 3:86773d65ed58 314 }
dxyang 3:86773d65ed58 315
dxyang 3:86773d65ed58 316 /**
dxyang 3:86773d65ed58 317 * Initialize all the interrupts
dxyang 3:86773d65ed58 318 */
dxyang 3:86773d65ed58 319 void initializeInterruptsH()
dxyang 3:86773d65ed58 320 {
dxyang 3:86773d65ed58 321 tickTimeCheckH.attach(&interruptTimeCheckH, 5.0);
dxyang 3:86773d65ed58 322 tickBatteryRfidH.attach(&interruptBatteryRfidH, 1.0);
dxyang 3:86773d65ed58 323 tickPoshoRfidH.attach(&interruptPoshoRfidH, 1.0);
dxyang 3:86773d65ed58 324 tickIncubatorRfidH.attach(&interruptIncubatorRfidH, 1.0);
dxyang 3:86773d65ed58 325 tickerUpdateUserTableH.attach(&interruptUpdateUserTableH, 1800.0);
dxyang 3:86773d65ed58 326 buttonOneH.rise(&interruptButtonOneH);
dxyang 3:86773d65ed58 327 buttonTwoH.rise(&interruptButtonTwoH);
dxyang 3:86773d65ed58 328 buttonThreeH.rise(&interruptButtonThreeH);
dxyang 3:86773d65ed58 329 buttonFourH.rise(&interruptButtonFourH);
dxyang 3:86773d65ed58 330 tick1sHub.attach(&int1sH, 10.0);
dxyang 3:86773d65ed58 331
dxyang 3:86773d65ed58 332 #ifdef debug
dxyang 3:86773d65ed58 333 printf("Interrupts initialized\n\r");
dxyang 3:86773d65ed58 334 #endif
dxyang 3:86773d65ed58 335 }
dxyang 3:86773d65ed58 336
dxyang 3:86773d65ed58 337 /**
dxyang 3:86773d65ed58 338 * Initialize RFID readers
dxyang 3:86773d65ed58 339 */
dxyang 3:86773d65ed58 340 void initializeRfidReadersH()
dxyang 3:86773d65ed58 341 {
dxyang 3:86773d65ed58 342 BatteryRfChipH.PCD_Init();
dxyang 3:86773d65ed58 343 PoshoRfChipH.PCD_Init();
dxyang 3:86773d65ed58 344 IncubatorRfChipH.PCD_Init();
dxyang 3:86773d65ed58 345
dxyang 3:86773d65ed58 346 #ifdef debug
dxyang 3:86773d65ed58 347 uint8_t tempA = BatteryRfChipH.PCD_ReadRegister(MFRC522::VersionReg);
dxyang 3:86773d65ed58 348 printf("Battery MFRC522 version: %d\n\r", tempA & 0x07);
dxyang 3:86773d65ed58 349 printf("\n\r");
dxyang 3:86773d65ed58 350 uint8_t tempB = PoshoRfChipH.PCD_ReadRegister(MFRC522::VersionReg);
dxyang 3:86773d65ed58 351 printf("Posho MFRC522 version: %d\n\r", tempB & 0x07);
dxyang 3:86773d65ed58 352 printf("\n\r");
dxyang 3:86773d65ed58 353 uint8_t tempC = IncubatorRfChipH.PCD_ReadRegister(MFRC522::VersionReg);
dxyang 3:86773d65ed58 354 printf("Incubator MFRC522 version: %d\n\r", tempC & 0x07);
dxyang 3:86773d65ed58 355 printf("\n\r");
dxyang 3:86773d65ed58 356 #endif
dxyang 3:86773d65ed58 357
dxyang 3:86773d65ed58 358 #ifdef debug
dxyang 3:86773d65ed58 359 printf("RFID readers initialized\n\r");
dxyang 3:86773d65ed58 360 #endif
dxyang 3:86773d65ed58 361 }
dxyang 3:86773d65ed58 362
dxyang 3:86773d65ed58 363 /**
dxyang 3:86773d65ed58 364 * Initialize LCD screen
dxyang 3:86773d65ed58 365 */
dxyang 3:86773d65ed58 366 void initializeLCD_H()
dxyang 3:86773d65ed58 367 {
dxyang 3:86773d65ed58 368 TFT_H.background(Black); // set background to black
dxyang 3:86773d65ed58 369 TFT_H.foreground(White); // set chars to white
dxyang 3:86773d65ed58 370 TFT_H.cls(); // clear the screen
dxyang 3:86773d65ed58 371 TFT_H.set_font((unsigned char*) Arial24x23);
dxyang 3:86773d65ed58 372 TFT_H.set_orientation(3); //Portrait, wiring on left
dxyang 3:86773d65ed58 373 #ifdef debug
dxyang 3:86773d65ed58 374 printf("LCD initialized\n\r");
dxyang 3:86773d65ed58 375 #endif
dxyang 3:86773d65ed58 376 }
dxyang 3:86773d65ed58 377
dxyang 3:86773d65ed58 378 /**
dxyang 3:86773d65ed58 379 * Creates a new user by defining user attributes.
dxyang 3:86773d65ed58 380 * @param rfid - uint32_t corresponding to unique id of the RFID tag
dxyang 3:86773d65ed58 381 * @param accountCredit - int32 for user account balance (can be negative)
dxyang 3:86773d65ed58 382 * @param locker - int32_t for which locker (originaly 1-4) user is assigned
dxyang 3:86773d65ed58 383 * @param batterySubscription - max batteries user can get (can be 0)
dxyang 3:86773d65ed58 384 * @param batteriesOut - number of batteries user has out (usually 0 initially)
dxyang 3:86773d65ed58 385 * @param podID - pod associated with the user (originally 0-15) *must be 0 indexed*
dxyang 3:86773d65ed58 386 */
dxyang 3:86773d65ed58 387 void createNewUserH(uint32_t rfid, int32_t accountCredit, int32_t locker,
dxyang 3:86773d65ed58 388 int32_t batterySubscription, int32_t batteriesOut, int32_t podID)
dxyang 3:86773d65ed58 389 {
dxyang 3:86773d65ed58 390 allUsersH[userCountH].rfid = rfid;
dxyang 3:86773d65ed58 391 allUsersH[userCountH].accountCredit = accountCredit;
dxyang 3:86773d65ed58 392 switch(locker) {
dxyang 3:86773d65ed58 393 case 1:
dxyang 3:86773d65ed58 394 allUsersH[userCountH].lockerID = lockerOne;
dxyang 3:86773d65ed58 395 break;
dxyang 3:86773d65ed58 396 case 2:
dxyang 3:86773d65ed58 397 allUsersH[userCountH].lockerID = lockerTwo;
dxyang 3:86773d65ed58 398 break;
dxyang 3:86773d65ed58 399 case 3:
dxyang 3:86773d65ed58 400 allUsersH[userCountH].lockerID = lockerThree;
dxyang 3:86773d65ed58 401 break;
dxyang 3:86773d65ed58 402 case 4:
dxyang 3:86773d65ed58 403 allUsersH[userCountH].lockerID = lockerFour;
dxyang 3:86773d65ed58 404 break;
dxyang 3:86773d65ed58 405 default:
dxyang 3:86773d65ed58 406 allUsersH[userCountH].lockerID = lockerUnassigned;
dxyang 3:86773d65ed58 407 break;
dxyang 3:86773d65ed58 408 }
dxyang 3:86773d65ed58 409 allUsersH[userCountH].batterySubscription = batterySubscription;
dxyang 3:86773d65ed58 410 allUsersH[userCountH].batteriesOut = batteriesOut;
dxyang 3:86773d65ed58 411 allUsersH[userCountH].podID = podID;
dxyang 3:86773d65ed58 412
dxyang 3:86773d65ed58 413 // generate the user id, a 32 byte value
dxyang 3:86773d65ed58 414 // [community byte 1][community byte 2][locker byte 3][podID (1/2 byte) | 0000 (1/2 byte)]
dxyang 3:86773d65ed58 415 uint32_t actualUid = ((((uint32_t)communityID_H << 16) | ((uint32_t)locker << 8)) |
dxyang 3:86773d65ed58 416 ((uint32_t)podID << 4));
dxyang 3:86773d65ed58 417 allUsersH[userCountH].uid = actualUid;
dxyang 3:86773d65ed58 418
dxyang 3:86773d65ed58 419 userCountH++;
dxyang 3:86773d65ed58 420
dxyang 3:86773d65ed58 421 #ifdef debug
dxyang 3:86773d65ed58 422 printf("UserID (decimal):%u\n\r", actualUid);
dxyang 3:86773d65ed58 423 printf("**************************\n\r");
dxyang 3:86773d65ed58 424 #endif
dxyang 3:86773d65ed58 425 }
dxyang 3:86773d65ed58 426
dxyang 3:86773d65ed58 427 /**
dxyang 3:86773d65ed58 428 * Initialize system with users from users.txt on SD card
dxyang 3:86773d65ed58 429 */
dxyang 3:86773d65ed58 430 void initializeUsersFromSD_H()
dxyang 3:86773d65ed58 431 {
dxyang 3:86773d65ed58 432 spiSD();
dxyang 3:86773d65ed58 433 FILE *fp = fopen("/sd/users.txt", "r");
dxyang 3:86773d65ed58 434
dxyang 3:86773d65ed58 435 if (fp == NULL) {
dxyang 3:86773d65ed58 436 #ifdef debug
dxyang 3:86773d65ed58 437 printf("User text file can't be opened");
dxyang 3:86773d65ed58 438 #endif
dxyang 3:86773d65ed58 439 return;
dxyang 3:86773d65ed58 440 }
dxyang 3:86773d65ed58 441
dxyang 3:86773d65ed58 442 // the first line of the user file has the headers for the following roles - get to the next line
dxyang 3:86773d65ed58 443 char line[180];
dxyang 3:86773d65ed58 444 if (fgets(line, 180, fp) != NULL) {
dxyang 3:86773d65ed58 445 #ifdef debug
dxyang 3:86773d65ed58 446 printf("Format of text file:\n\r%s\n\r", line);
dxyang 3:86773d65ed58 447 printf("**************************\n\r");
dxyang 3:86773d65ed58 448 #endif
dxyang 3:86773d65ed58 449 }
dxyang 3:86773d65ed58 450
dxyang 3:86773d65ed58 451 // 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 452 uint32_t rfid;
dxyang 3:86773d65ed58 453 int32_t accountCredit;
dxyang 3:86773d65ed58 454 int32_t locker;
dxyang 3:86773d65ed58 455 int32_t batterySubscription;
dxyang 3:86773d65ed58 456 int32_t batteriesOut;
dxyang 3:86773d65ed58 457 int32_t podID;
dxyang 3:86773d65ed58 458 while (fscanf(fp, "%u %d %d %d %d %d", &rfid, &accountCredit, &locker, &batterySubscription, &batteriesOut, &podID) != EOF) {
dxyang 3:86773d65ed58 459 #ifdef debug
dxyang 3:86773d65ed58 460 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 461 rfid, accountCredit, locker, batterySubscription, batteriesOut, podID);
dxyang 3:86773d65ed58 462 #endif
dxyang 3:86773d65ed58 463 createNewUserH(rfid, accountCredit, locker, batterySubscription, batteriesOut, podID);
dxyang 3:86773d65ed58 464 }
dxyang 8:b40c4553f6d4 465 fclose(fp);
dxyang 8:b40c4553f6d4 466
dxyang 3:86773d65ed58 467 #ifdef debug
dxyang 3:86773d65ed58 468 printf("Users created\n\r");
dxyang 3:86773d65ed58 469 #endif
dxyang 3:86773d65ed58 470 }
dxyang 3:86773d65ed58 471
dxyang 8:b40c4553f6d4 472 /**
dxyang 8:b40c4553f6d4 473 * Initialize posho functionality
dxyang 8:b40c4553f6d4 474 */
dxyang 8:b40c4553f6d4 475 void initializePoshoFunctionality() {
dxyang 8:b40c4553f6d4 476 spiSD();
dxyang 8:b40c4553f6d4 477 FILE *fp = fopen("/sd/poshoInit.txt", "r");
dxyang 8:b40c4553f6d4 478
dxyang 8:b40c4553f6d4 479 if (fp == NULL) {
dxyang 8:b40c4553f6d4 480 #ifdef debug
dxyang 8:b40c4553f6d4 481 printf("User text file can't be opened");
dxyang 8:b40c4553f6d4 482 #endif
dxyang 8:b40c4553f6d4 483 return;
dxyang 8:b40c4553f6d4 484 }
dxyang 8:b40c4553f6d4 485
dxyang 8:b40c4553f6d4 486 // read a price per kg value.
dxyang 8:b40c4553f6d4 487 int32_t poshoPricePerKg;
dxyang 8:b40c4553f6d4 488 int32_t timeForOneKg;
dxyang 8:b40c4553f6d4 489 int32_t timeForTwoKg;
dxyang 8:b40c4553f6d4 490 int32_t timeForThreeKg;
dxyang 8:b40c4553f6d4 491
dxyang 8:b40c4553f6d4 492 if (fscanf(fp,"%d %*c %*s",&poshoPricePerKg)!= 1) writeError("Posho: cannot read price to use");
dxyang 8:b40c4553f6d4 493 if (fscanf(fp,"%d %*c %*s",&timeForOneKg)!= 1) writeError("Posho: cannot read time to use");
dxyang 8:b40c4553f6d4 494 if (fscanf(fp,"%d %*c %*s",&timeForTwoKg)!= 1) writeError("Posho: cannot read time to use");
dxyang 8:b40c4553f6d4 495 if (fscanf(fp,"%d %*c %*s",&timeForThreeKg)!= 1) writeError("Posho: cannot read time to use");
dxyang 8:b40c4553f6d4 496 fclose(fp);
dxyang 8:b40c4553f6d4 497
dxyang 8:b40c4553f6d4 498 poshoPricePerKgH = poshoPricePerKg;
dxyang 8:b40c4553f6d4 499 timeForOneKgH = timeForOneKg;
dxyang 8:b40c4553f6d4 500 timeForTwoKgH = timeForTwoKg;
dxyang 8:b40c4553f6d4 501 timeForThreeKgH = timeForThreeKg;
dxyang 8:b40c4553f6d4 502
dxyang 8:b40c4553f6d4 503 #ifdef debug
dxyang 8:b40c4553f6d4 504 printf("Posho values initialized\n\r");
dxyang 8:b40c4553f6d4 505 printf("Price per kg: %d\n\r", poshoPricePerKgH);
dxyang 8:b40c4553f6d4 506 printf("Time for 1: %d, 2: %d, and 3: %d kilograms\n\r", timeForOneKgH, timeForTwoKgH, timeForThreeKgH);
dxyang 8:b40c4553f6d4 507 #endif
dxyang 8:b40c4553f6d4 508 }
dxyang 8:b40c4553f6d4 509
dxyang 3:86773d65ed58 510 /*************************************************************************************************/
dxyang 3:86773d65ed58 511 /* Logging */
dxyang 3:86773d65ed58 512 /*************************************************************************************************/
dxyang 3:86773d65ed58 513 /**
dxyang 3:86773d65ed58 514 * Log an action from a selection of predefined actions done by the current user
dxyang 3:86773d65ed58 515 * Actions used with this method should require a known user to be using system
dxyang 3:86773d65ed58 516 * @param action - enumerated HubActionForLogging that selects from predefined actions
dxyang 7:0aee09577ad3 517 * @param userIndex - int corresponding to the index of the user in the user table
dxyang 3:86773d65ed58 518 */
dxyang 7:0aee09577ad3 519 void logActionWithUserInfoH(enum HubActionForLoggingH action, int userIndex)
dxyang 3:86773d65ed58 520 {
dxyang 3:86773d65ed58 521 // Append to a log text file
dxyang 3:86773d65ed58 522 spiSD();
dxyang 3:86773d65ed58 523 char * name = "/sd/HubLog.txt";
dxyang 3:86773d65ed58 524 FILE *fp;
dxyang 3:86773d65ed58 525 fp = fopen(name, "a");
dxyang 3:86773d65ed58 526
dxyang 3:86773d65ed58 527 // get the time and append it to an output buffer
dxyang 3:86773d65ed58 528 time_t seconds = time(NULL);
dxyang 3:86773d65ed58 529 char logLine[180];
dxyang 3:86773d65ed58 530 sprintf(logLine, "%x", seconds);
dxyang 3:86773d65ed58 531
dxyang 3:86773d65ed58 532 // append relevant information for action
dxyang 3:86773d65ed58 533 switch (action) {
dxyang 8:b40c4553f6d4 534 case hubAction_BatteryRfidScanned:
dxyang 8:b40c4553f6d4 535 strcat(logLine, " R B ");
dxyang 8:b40c4553f6d4 536 break;
dxyang 8:b40c4553f6d4 537 case hubAction_PoshoRfidScanned:
dxyang 8:b40c4553f6d4 538 strcat(logLine, " R P ");
dxyang 3:86773d65ed58 539 break;
dxyang 3:86773d65ed58 540 case hubAction_Exit:
dxyang 3:86773d65ed58 541 strcat(logLine, " X ");
dxyang 3:86773d65ed58 542 break;
dxyang 3:86773d65ed58 543 case hubAction_OneBatteryDropped:
dxyang 3:86773d65ed58 544 strcat(logLine, " D 1 ");
dxyang 3:86773d65ed58 545 break;
dxyang 3:86773d65ed58 546 case hubAction_TwoBatteryDropped:
dxyang 3:86773d65ed58 547 strcat(logLine, " D 2 ");
dxyang 3:86773d65ed58 548 break;
dxyang 3:86773d65ed58 549 case hubAction_ThreeBatteryDropped:
dxyang 3:86773d65ed58 550 strcat(logLine, " D 3 ");
dxyang 3:86773d65ed58 551 break;
dxyang 3:86773d65ed58 552 case hubAction_OneBatteryPicked:
dxyang 3:86773d65ed58 553 strcat(logLine, " P 1 ");
dxyang 3:86773d65ed58 554 break;
dxyang 3:86773d65ed58 555 case hubAction_TwoBatteryPicked:
dxyang 3:86773d65ed58 556 strcat(logLine, " P 2 ");
dxyang 3:86773d65ed58 557 break;
dxyang 3:86773d65ed58 558 case hubAction_ThreeBatteryPicked:
dxyang 3:86773d65ed58 559 strcat(logLine, " P 3 ");
dxyang 3:86773d65ed58 560 break;
dxyang 3:86773d65ed58 561 }
dxyang 3:86773d65ed58 562
dxyang 3:86773d65ed58 563 // append general user information
dxyang 3:86773d65ed58 564 char rfidBuffer[20];
dxyang 3:86773d65ed58 565 char uidBuffer[20];
dxyang 3:86773d65ed58 566 char acctBalanceBuffer[20];
dxyang 7:0aee09577ad3 567 sprintf(rfidBuffer, "%u ", allUsersH[userIndex].rfid);
dxyang 7:0aee09577ad3 568 sprintf(uidBuffer, "%u ", allUsersH[userIndex].uid);
dxyang 7:0aee09577ad3 569 sprintf(acctBalanceBuffer, "%d\n", allUsersH[userIndex].accountCredit);
dxyang 3:86773d65ed58 570 strcat(logLine, rfidBuffer);
dxyang 3:86773d65ed58 571 strcat(logLine, uidBuffer);
dxyang 3:86773d65ed58 572 strcat(logLine, acctBalanceBuffer);
dxyang 3:86773d65ed58 573
dxyang 3:86773d65ed58 574 // write the line to the log file and close the file
dxyang 3:86773d65ed58 575 fputs(logLine, fp);
dxyang 3:86773d65ed58 576 fclose(fp);
dxyang 3:86773d65ed58 577
dxyang 3:86773d65ed58 578 #ifdef debug
dxyang 3:86773d65ed58 579 printf("%s\n\r", logLine);
dxyang 3:86773d65ed58 580 #endif
dxyang 3:86773d65ed58 581
dxyang 3:86773d65ed58 582 }
dxyang 3:86773d65ed58 583
dxyang 3:86773d65ed58 584 /**
dxyang 3:86773d65ed58 585 * Log an error - RFID not associated with a known user is scanned
dxyang 3:86773d65ed58 586 * @param unknownRfid - uint32 for the unique ID of the unknown rfid tag
dxyang 3:86773d65ed58 587 */
dxyang 8:b40c4553f6d4 588 void logErrorUnknownRfidScannedH(uint32_t unknownRfid, HubLoggingRfidSourceH source)
dxyang 3:86773d65ed58 589 {
dxyang 3:86773d65ed58 590 // Append to a log text file
dxyang 3:86773d65ed58 591 char * name = "/sd/HubLog.txt";
dxyang 3:86773d65ed58 592 spiSD();
dxyang 3:86773d65ed58 593 FILE *fp;
dxyang 3:86773d65ed58 594 fp = fopen(name, "a");
dxyang 3:86773d65ed58 595
dxyang 3:86773d65ed58 596 // get the time and append it to an output buffer
dxyang 3:86773d65ed58 597 time_t seconds = time(NULL);
dxyang 3:86773d65ed58 598 char logLine[180];
dxyang 3:86773d65ed58 599 sprintf(logLine, "%x", seconds);
dxyang 3:86773d65ed58 600
dxyang 3:86773d65ed58 601 // RFID action
dxyang 8:b40c4553f6d4 602 switch (source) {
dxyang 8:b40c4553f6d4 603 case source_battery:
dxyang 8:b40c4553f6d4 604 strcat(logLine, " R X B ");
dxyang 8:b40c4553f6d4 605 break;
dxyang 8:b40c4553f6d4 606 case source_posho:
dxyang 8:b40c4553f6d4 607 strcat(logLine, " R X P");
dxyang 8:b40c4553f6d4 608 break;
dxyang 8:b40c4553f6d4 609 case source_incubator:
dxyang 8:b40c4553f6d4 610 strcat(logLine, " R X I");
dxyang 8:b40c4553f6d4 611 break;
dxyang 8:b40c4553f6d4 612 }
dxyang 3:86773d65ed58 613
dxyang 3:86773d65ed58 614 // include just the RFID (indicates that no known user was found)
dxyang 3:86773d65ed58 615 char rfidBuffer[20];
dxyang 3:86773d65ed58 616 sprintf(rfidBuffer, "%u ", unknownRfid);
dxyang 3:86773d65ed58 617 strcat(logLine, rfidBuffer);
dxyang 3:86773d65ed58 618 strcat(logLine, "\n");
dxyang 3:86773d65ed58 619
dxyang 3:86773d65ed58 620 // write the line to the log file and close the file
dxyang 3:86773d65ed58 621 fputs(logLine, fp);
dxyang 3:86773d65ed58 622 fclose(fp);
dxyang 3:86773d65ed58 623
dxyang 3:86773d65ed58 624 #ifdef debug
dxyang 3:86773d65ed58 625 printf("%s\n\r", logLine);
dxyang 3:86773d65ed58 626 #endif
epgmdm 2:d1eae91343a9 627
epgmdm 2:d1eae91343a9 628 }
epgmdm 2:d1eae91343a9 629
dxyang 3:86773d65ed58 630 /*************************************************************************************************/
dxyang 5:88c516cf34e6 631 /* Housekeeping - flag clearing, cancelling, check time, update user table */
dxyang 3:86773d65ed58 632 /*************************************************************************************************/
dxyang 3:86773d65ed58 633 /*
dxyang 3:86773d65ed58 634 * Reset all user initiated flags. Useful after sequences of events where flags may have
dxyang 3:86773d65ed58 635 * piled up from misc inputs and you don't want the system to act seemingly sporadically.
dxyang 3:86773d65ed58 636 */
dxyang 3:86773d65ed58 637 void clearAllUserInitiatedFlagsH() {
dxyang 3:86773d65ed58 638 flagButtonOneH = 0;
dxyang 3:86773d65ed58 639 flagButtonTwoH = 0;
dxyang 3:86773d65ed58 640 flagButtonThreeH = 0;
dxyang 3:86773d65ed58 641 flagButtonFourH = 0;
dxyang 3:86773d65ed58 642 flagBatteryRfidH = 0;
dxyang 3:86773d65ed58 643 flagPoshoRfidH = 0;
dxyang 3:86773d65ed58 644 flagIncubatorRfidH = 0;
dxyang 3:86773d65ed58 645 }
epgmdm 2:d1eae91343a9 646
dxyang 3:86773d65ed58 647 /*
dxyang 3:86773d65ed58 648 * User presses the button corresponding to an exit. Returns to home screen
dxyang 3:86773d65ed58 649 * after logging the action.
dxyang 7:0aee09577ad3 650 * @param userIndex - int representing index of user in user table
dxyang 3:86773d65ed58 651 */
dxyang 7:0aee09577ad3 652 void cancelPressedH(int userIndex) {
dxyang 3:86773d65ed58 653 clearAllUserInitiatedFlagsH();
dxyang 3:86773d65ed58 654 currentScreenH = initialScanRfid;
dxyang 7:0aee09577ad3 655 logActionWithUserInfoH(hubAction_Exit, userIndex);
dxyang 3:86773d65ed58 656 }
dxyang 3:86773d65ed58 657
dxyang 3:86773d65ed58 658 /**
dxyang 3:86773d65ed58 659 * Do if time check flag is set
dxyang 3:86773d65ed58 660 * reads the unix time, converts into human readable format, and displays on PC
dxyang 3:86773d65ed58 661 */
dxyang 3:86773d65ed58 662 void doTimeCheckH()
dxyang 3:86773d65ed58 663 {
dxyang 3:86773d65ed58 664 flagTimeCheckH = 0;
dxyang 3:86773d65ed58 665 time_t seconds = time(NULL);
dxyang 3:86773d65ed58 666 printf("%s\n\r", ctime(&seconds));
dxyang 3:86773d65ed58 667 }
dxyang 3:86773d65ed58 668
dxyang 3:86773d65ed58 669 /**
dxyang 3:86773d65ed58 670 * Do if update user table flag is set
dxyang 3:86773d65ed58 671 */
dxyang 3:86773d65ed58 672 void doUpdateUserTableH()
dxyang 3:86773d65ed58 673 {
dxyang 3:86773d65ed58 674 flagUpdateUserTableH = 0;
dxyang 3:86773d65ed58 675 // Write to a users.txt file
dxyang 3:86773d65ed58 676 spiSD();
dxyang 3:86773d65ed58 677 char * name = "/sd/users.txt";
dxyang 3:86773d65ed58 678 FILE *fp;
dxyang 3:86773d65ed58 679 fp = fopen(name, "w");
dxyang 3:86773d65ed58 680
dxyang 3:86773d65ed58 681 // output the header for the users.txt file
dxyang 3:86773d65ed58 682 fputs("rfid accountCredit locker batterySubscription batteriesOut podID\n", fp);
dxyang 3:86773d65ed58 683
dxyang 3:86773d65ed58 684 // output buffer
dxyang 3:86773d65ed58 685 char logLine[180];
dxyang 3:86773d65ed58 686
dxyang 3:86773d65ed58 687 for (int i = 0; i < userCountH; i++) {
dxyang 3:86773d65ed58 688 // get all the needed information in strings
dxyang 3:86773d65ed58 689 sprintf(logLine, "%u ", allUsersH[i].rfid);
dxyang 3:86773d65ed58 690 char accountCreditBuffer[20];
dxyang 3:86773d65ed58 691 char* lockerBuffer;
dxyang 3:86773d65ed58 692 char batterySubscriptionBuffer[20];
dxyang 3:86773d65ed58 693 char batteriesOutBuffer[20];
dxyang 3:86773d65ed58 694 char podIdBuffer[20];
dxyang 3:86773d65ed58 695
dxyang 3:86773d65ed58 696 sprintf(accountCreditBuffer, "%d ", allUsersH[i].accountCredit);
dxyang 3:86773d65ed58 697 switch (allUsersH[i].lockerID) {
dxyang 3:86773d65ed58 698 case lockerOne:
dxyang 3:86773d65ed58 699 lockerBuffer = "1 ";
dxyang 3:86773d65ed58 700 break;
dxyang 3:86773d65ed58 701 case lockerTwo:
dxyang 3:86773d65ed58 702 lockerBuffer = "2 ";
dxyang 3:86773d65ed58 703 break;
dxyang 3:86773d65ed58 704 case lockerThree:
dxyang 3:86773d65ed58 705 lockerBuffer = "3 ";
dxyang 3:86773d65ed58 706 break;
dxyang 3:86773d65ed58 707 case lockerFour:
dxyang 3:86773d65ed58 708 lockerBuffer = "4 ";
dxyang 3:86773d65ed58 709 break;
dxyang 3:86773d65ed58 710 case lockerUnassigned:
dxyang 3:86773d65ed58 711 default:
dxyang 3:86773d65ed58 712 lockerBuffer = "0 ";
dxyang 3:86773d65ed58 713 break;
dxyang 3:86773d65ed58 714 }
dxyang 3:86773d65ed58 715 sprintf(batterySubscriptionBuffer, "%d ", allUsersH[i].batterySubscription);
dxyang 3:86773d65ed58 716 sprintf(batteriesOutBuffer, "%d ", allUsersH[i].batteriesOut);
dxyang 3:86773d65ed58 717 sprintf(podIdBuffer, "%d\n", allUsersH[i].podID);
dxyang 3:86773d65ed58 718
dxyang 3:86773d65ed58 719 // concatenate all the strings
dxyang 3:86773d65ed58 720 strcat(logLine, accountCreditBuffer);
dxyang 3:86773d65ed58 721 strcat(logLine, lockerBuffer);
dxyang 3:86773d65ed58 722 strcat(logLine, batterySubscriptionBuffer);
dxyang 3:86773d65ed58 723 strcat(logLine, batteriesOutBuffer);
dxyang 3:86773d65ed58 724 strcat(logLine, podIdBuffer);
dxyang 3:86773d65ed58 725
dxyang 3:86773d65ed58 726 // write the line to the log file
dxyang 3:86773d65ed58 727 fputs(logLine, fp);
dxyang 3:86773d65ed58 728
dxyang 3:86773d65ed58 729 #ifdef debug
dxyang 3:86773d65ed58 730 printf("%s\n\r", logLine);
dxyang 3:86773d65ed58 731 #endif
dxyang 3:86773d65ed58 732 }
dxyang 3:86773d65ed58 733 fclose(fp);
dxyang 3:86773d65ed58 734 }
epgmdm 2:d1eae91343a9 735
dxyang 5:88c516cf34e6 736 /*************************************************************************************************/
dxyang 5:88c516cf34e6 737 /* Battery Services */
dxyang 5:88c516cf34e6 738 /*************************************************************************************************/
epgmdm 1:c2232b1eaf31 739 /**
dxyang 3:86773d65ed58 740 * Do if Battery RFID flag is set. Read RFID tag and check user status.
dxyang 3:86773d65ed58 741 * If there's a valid battery subscription, display drop off and/or pick up.
dxyang 3:86773d65ed58 742 * Otherwise, returns to initial screen.
dxyang 3:86773d65ed58 743 */
dxyang 3:86773d65ed58 744 void doBatteryRfidH()
dxyang 3:86773d65ed58 745 {
dxyang 3:86773d65ed58 746 flagBatteryRfidH = 0;
dxyang 3:86773d65ed58 747
dxyang 3:86773d65ed58 748 // is there a new readable card?
dxyang 3:86773d65ed58 749 if (!BatteryRfChipH.PICC_IsNewCardPresent()) {
dxyang 3:86773d65ed58 750 return;
dxyang 3:86773d65ed58 751 }
dxyang 3:86773d65ed58 752
dxyang 3:86773d65ed58 753 if (!BatteryRfChipH.PICC_ReadCardSerial()) {
dxyang 3:86773d65ed58 754 #ifdef debug
dxyang 3:86773d65ed58 755 printf("Card not readable\n\r");
dxyang 3:86773d65ed58 756 #endif
dxyang 3:86773d65ed58 757 return;
dxyang 3:86773d65ed58 758 }
dxyang 3:86773d65ed58 759
dxyang 3:86773d65ed58 760 // get the id of the scanned tag
dxyang 3:86773d65ed58 761 uint8_t tempReadingRfid[4];
dxyang 3:86773d65ed58 762 for(uint8_t i = 0; i < BatteryRfChipH.uid.size; i++) {
dxyang 3:86773d65ed58 763 tempReadingRfid[i] = BatteryRfChipH.uid.uidByte[i];
dxyang 3:86773d65ed58 764 }
dxyang 3:86773d65ed58 765
dxyang 3:86773d65ed58 766 // concatenate the 4 bytes into a single integer via bit shifting
dxyang 3:86773d65ed58 767 uint32_t actualRfid = ((((uint32_t)tempReadingRfid[0] << 24) |
dxyang 3:86773d65ed58 768 ((uint32_t)tempReadingRfid[1] << 16)) |
dxyang 3:86773d65ed58 769 (((uint32_t)tempReadingRfid[2] << 8) |
dxyang 3:86773d65ed58 770 ((uint32_t)tempReadingRfid[3] << 0)));
dxyang 3:86773d65ed58 771
dxyang 3:86773d65ed58 772 // find the user info
dxyang 3:86773d65ed58 773 char foundUserFlag = 0;
dxyang 7:0aee09577ad3 774 int foundUserIndex;
dxyang 3:86773d65ed58 775 for (int i = 0; i < userCountH; i++) {
dxyang 3:86773d65ed58 776 if (allUsersH[i].rfid == actualRfid) {
dxyang 3:86773d65ed58 777 currentUserH = i;
dxyang 7:0aee09577ad3 778 foundUserIndex = i;
dxyang 3:86773d65ed58 779 foundUserFlag = 1;
dxyang 3:86773d65ed58 780 break;
dxyang 3:86773d65ed58 781 }
dxyang 3:86773d65ed58 782 }
dxyang 3:86773d65ed58 783
dxyang 3:86773d65ed58 784 // if the user is found, set the global variable for current user interacting with the system
dxyang 3:86773d65ed58 785 // if the user isn't found, log that an rfid without a user was used and display
dxyang 3:86773d65ed58 786 if (!foundUserFlag) {
dxyang 3:86773d65ed58 787 #ifdef debug
dxyang 3:86773d65ed58 788 printf("User not found\n\r");
dxyang 3:86773d65ed58 789 printf("ID:%u\n\r", actualRfid);
dxyang 3:86773d65ed58 790 #endif
dxyang 3:86773d65ed58 791 // log the error interaction
dxyang 8:b40c4553f6d4 792 logErrorUnknownRfidScannedH(actualRfid, source_battery);
dxyang 3:86773d65ed58 793
dxyang 3:86773d65ed58 794 // let user know tag wasn't found
dxyang 3:86773d65ed58 795 TFT_H.cls();
dxyang 3:86773d65ed58 796 TFT_H.locate(0,0);
dxyang 3:86773d65ed58 797 TFT_H.printf("User not found\n\r");
dxyang 3:86773d65ed58 798 TFT_H.printf("ID:%u\n\r", actualRfid);
dxyang 3:86773d65ed58 799 wait(1);
dxyang 3:86773d65ed58 800 currentScreenH = initialScanRfid;
dxyang 3:86773d65ed58 801 return;
dxyang 3:86773d65ed58 802 }
dxyang 3:86773d65ed58 803
dxyang 3:86773d65ed58 804 // log user scan
dxyang 8:b40c4553f6d4 805 logActionWithUserInfoH(hubAction_BatteryRfidScanned, foundUserIndex);
dxyang 3:86773d65ed58 806
dxyang 3:86773d65ed58 807 // Display info about the user
dxyang 3:86773d65ed58 808 char authorizationFlag = 0;
dxyang 3:86773d65ed58 809 TFT_H.cls();
dxyang 3:86773d65ed58 810 TFT_H.locate(0,0);
dxyang 3:86773d65ed58 811 TFT_H.printf("UserID: %u\n\r", actualRfid);
dxyang 7:0aee09577ad3 812 TFT_H.printf("Balance:%d\n\r", allUsersH[foundUserIndex].accountCredit);
dxyang 7:0aee09577ad3 813 if (allUsersH[foundUserIndex].batterySubscription > 0) {
dxyang 3:86773d65ed58 814 authorizationFlag = 1;
dxyang 3:86773d65ed58 815 }
dxyang 3:86773d65ed58 816 TFT_H.printf("Authorization:%s\n\r", (authorizationFlag)? "YES":"NO");
dxyang 3:86773d65ed58 817
dxyang 3:86773d65ed58 818 #ifdef debug
dxyang 3:86773d65ed58 819 printf("User:");
dxyang 3:86773d65ed58 820 for(uint8_t i = 0; i < BatteryRfChipH.uid.size; i++)
dxyang 3:86773d65ed58 821 {
dxyang 3:86773d65ed58 822 uint8_t uidByte = BatteryRfChipH.uid.uidByte[i];
dxyang 3:86773d65ed58 823 printf(" %d", uidByte);
dxyang 3:86773d65ed58 824 }
dxyang 3:86773d65ed58 825 printf("\n\rUserID: %u\n\r", actualRfid);
dxyang 3:86773d65ed58 826 #endif
dxyang 3:86773d65ed58 827
dxyang 3:86773d65ed58 828 // if not authorized for batteries, return to main screen
dxyang 3:86773d65ed58 829 wait(1);
dxyang 3:86773d65ed58 830 if (!authorizationFlag) {
dxyang 3:86773d65ed58 831 currentScreenH = initialScanRfid;
dxyang 3:86773d65ed58 832 return;
dxyang 3:86773d65ed58 833 }
dxyang 3:86773d65ed58 834
dxyang 3:86773d65ed58 835 // otherwise, ask user if the user wants to pick up or drop off batteries?
dxyang 3:86773d65ed58 836 TFT_H.locate(0,160);
dxyang 3:86773d65ed58 837 TFT_H.printf("Battery Action?\n\r");
dxyang 3:86773d65ed58 838 TFT_H.locate(0,200);
dxyang 3:86773d65ed58 839
dxyang 7:0aee09577ad3 840 uint8_t maxBatteries = allUsersH[foundUserIndex].batterySubscription;
dxyang 7:0aee09577ad3 841 uint8_t outBatteries = allUsersH[foundUserIndex].batteriesOut;
dxyang 3:86773d65ed58 842
dxyang 3:86773d65ed58 843 if ((maxBatteries - outBatteries) == 0) { // can only drop off
dxyang 3:86773d65ed58 844 TFT_H.printf(" drop exit");
dxyang 3:86773d65ed58 845 } else if (outBatteries == 0) { // can only pick up
dxyang 3:86773d65ed58 846 TFT_H.printf(" pick exit");
dxyang 3:86773d65ed58 847 } else { // can pickup or dropoff
dxyang 3:86773d65ed58 848 TFT_H.printf(" pick drop exit");
dxyang 3:86773d65ed58 849 }
dxyang 3:86773d65ed58 850
dxyang 3:86773d65ed58 851 // go to action selecting screen and clear buttons beforehand
dxyang 3:86773d65ed58 852 currentScreenH = batterySelectAction;
dxyang 3:86773d65ed58 853 clearAllUserInitiatedFlagsH();
dxyang 3:86773d65ed58 854 return;
dxyang 3:86773d65ed58 855 }
dxyang 3:86773d65ed58 856
dxyang 3:86773d65ed58 857 /**
dxyang 3:86773d65ed58 858 * Do if user selects to pickup a battery. Determines how many batteries
dxyang 3:86773d65ed58 859 * a user can pickup based off user info and displays corresponding text
dxyang 7:0aee09577ad3 860 * @param userIndex - int representing index of user in user table
dxyang 3:86773d65ed58 861 */
dxyang 7:0aee09577ad3 862 void batteryPickUpH(int userIndex) {
dxyang 3:86773d65ed58 863 TFT_H.cls();
dxyang 3:86773d65ed58 864 TFT_H.locate(0,0);
dxyang 7:0aee09577ad3 865 TFT_H.printf("UserID: %u\n\r\n\r", allUsersH[userIndex].rfid);
dxyang 3:86773d65ed58 866
dxyang 3:86773d65ed58 867 TFT_H.printf("Action: PICK UP\n\r");
dxyang 3:86773d65ed58 868 TFT_H.locate(0,160);
dxyang 3:86773d65ed58 869 TFT_H.printf("How many batteries?\n\r");
dxyang 3:86773d65ed58 870 TFT_H.locate(0,200);
dxyang 7:0aee09577ad3 871 switch (allUsersH[userIndex].batterySubscription - allUsersH[userIndex].batteriesOut) {
dxyang 3:86773d65ed58 872 case 1: {
dxyang 3:86773d65ed58 873 TFT_H.printf(" 1 exit");
dxyang 3:86773d65ed58 874 break;
dxyang 3:86773d65ed58 875 }
dxyang 3:86773d65ed58 876 case 2: {
dxyang 3:86773d65ed58 877 TFT_H.printf(" 1 2 exit");
dxyang 3:86773d65ed58 878 break;
dxyang 3:86773d65ed58 879 }
dxyang 3:86773d65ed58 880 case 3: {
dxyang 3:86773d65ed58 881 TFT_H.printf(" 1 2 3 exit");
dxyang 3:86773d65ed58 882 break;
dxyang 3:86773d65ed58 883 }
dxyang 3:86773d65ed58 884 }
dxyang 3:86773d65ed58 885
dxyang 3:86773d65ed58 886 // go to wait for selection input and reset button flags
dxyang 3:86773d65ed58 887 currentScreenH = batterySelectNumberForPickup;
dxyang 3:86773d65ed58 888 clearAllUserInitiatedFlagsH();
dxyang 3:86773d65ed58 889 return;
dxyang 3:86773d65ed58 890 }
dxyang 3:86773d65ed58 891
dxyang 3:86773d65ed58 892 /**
dxyang 3:86773d65ed58 893 * Do if user selects to dropoff a battery. Determines how many batteries
dxyang 3:86773d65ed58 894 * a user can pickup based off user info and displays corresponding text
dxyang 7:0aee09577ad3 895 * @param userIndex - int representing index of user in user table
dxyang 3:86773d65ed58 896 */
dxyang 7:0aee09577ad3 897 void batteryDropOffH(int userIndex) {
dxyang 3:86773d65ed58 898 TFT_H.cls();
dxyang 3:86773d65ed58 899 TFT_H.locate(0,0);
dxyang 7:0aee09577ad3 900 TFT_H.printf("UserID: %u\n\r\n\r", allUsersH[userIndex].rfid);
dxyang 3:86773d65ed58 901
dxyang 3:86773d65ed58 902 TFT_H.printf("Action: DROP OFF\n\r");
dxyang 3:86773d65ed58 903 TFT_H.locate(0,160);
dxyang 3:86773d65ed58 904 TFT_H.printf("How many batteries?\n\r");
dxyang 3:86773d65ed58 905 TFT_H.locate(0,200);
dxyang 7:0aee09577ad3 906 switch (allUsersH[userIndex].batteriesOut) {
dxyang 3:86773d65ed58 907 case 1: {
dxyang 3:86773d65ed58 908 TFT_H.printf(" 1 exit");
dxyang 3:86773d65ed58 909 break;
dxyang 3:86773d65ed58 910 }
dxyang 3:86773d65ed58 911 case 2: {
dxyang 3:86773d65ed58 912 TFT_H.printf(" 1 2 exit");
dxyang 3:86773d65ed58 913 break;
dxyang 3:86773d65ed58 914 }
dxyang 3:86773d65ed58 915 case 3: {
dxyang 3:86773d65ed58 916 TFT_H.printf(" 1 2 3 exit");
dxyang 3:86773d65ed58 917 break;
dxyang 3:86773d65ed58 918 }
dxyang 3:86773d65ed58 919 }
dxyang 3:86773d65ed58 920
dxyang 3:86773d65ed58 921 // go to wait for selection input and reset button flags
dxyang 3:86773d65ed58 922 currentScreenH = batterySelectNumberForDropoff;
dxyang 3:86773d65ed58 923 clearAllUserInitiatedFlagsH();
dxyang 3:86773d65ed58 924 return;
dxyang 3:86773d65ed58 925 }
dxyang 3:86773d65ed58 926
dxyang 3:86773d65ed58 927 /**
dxyang 3:86773d65ed58 928 * Do after use selects number of batteries to drop off.
dxyang 3:86773d65ed58 929 * Logs the action, changes user info, transmits instructions to other systems
dxyang 3:86773d65ed58 930 * @param numBatteries - int for number of batteries selected to drop off
dxyang 7:0aee09577ad3 931 * @param userIndex - int representing index of user in user table
dxyang 3:86773d65ed58 932 */
dxyang 7:0aee09577ad3 933 void batteryDropOffH(int numBatteries, int userIndex) {
dxyang 3:86773d65ed58 934 switch(numBatteries) {
dxyang 3:86773d65ed58 935 case 1:
dxyang 7:0aee09577ad3 936 logActionWithUserInfoH(hubAction_OneBatteryDropped, userIndex);
dxyang 6:00a132a076d5 937 txBatteryDropOff(1);
dxyang 7:0aee09577ad3 938 allUsersH[userIndex].batteriesOut--;
dxyang 3:86773d65ed58 939 break;
dxyang 3:86773d65ed58 940 case 2:
dxyang 7:0aee09577ad3 941 logActionWithUserInfoH(hubAction_TwoBatteryDropped, userIndex);
dxyang 6:00a132a076d5 942 txBatteryDropOff(2);
dxyang 7:0aee09577ad3 943 allUsersH[userIndex].batteriesOut -= 2;
dxyang 3:86773d65ed58 944 break;
dxyang 3:86773d65ed58 945 case 3:
dxyang 7:0aee09577ad3 946 logActionWithUserInfoH(hubAction_ThreeBatteryDropped, userIndex);
dxyang 6:00a132a076d5 947 txBatteryDropOff(3);
dxyang 7:0aee09577ad3 948 allUsersH[userIndex].batteriesOut -= 3;
dxyang 3:86773d65ed58 949 break;
dxyang 3:86773d65ed58 950 }
dxyang 3:86773d65ed58 951
dxyang 3:86773d65ed58 952 currentScreenH = initialScanRfid;
dxyang 3:86773d65ed58 953 return;
dxyang 3:86773d65ed58 954 }
dxyang 3:86773d65ed58 955
dxyang 3:86773d65ed58 956 /**
dxyang 3:86773d65ed58 957 * Do after use selects number of batteries to pick up.
dxyang 3:86773d65ed58 958 * Logs the action, changes user info, transmits instructions to other systems
dxyang 3:86773d65ed58 959 * @param numBatteries - int for number of batteries selected to pick up
dxyang 7:0aee09577ad3 960 * @param userIndex - int representing index of user in user table
dxyang 3:86773d65ed58 961 */
dxyang 7:0aee09577ad3 962 void batteryPickUpH(int numBatteries, int userIndex) {
dxyang 3:86773d65ed58 963 switch(numBatteries) {
dxyang 3:86773d65ed58 964 case 1:
dxyang 7:0aee09577ad3 965 logActionWithUserInfoH(hubAction_OneBatteryPicked, userIndex);
dxyang 6:00a132a076d5 966 txBatteryPickUp(1);
dxyang 7:0aee09577ad3 967 allUsersH[userIndex].batteriesOut++;
dxyang 3:86773d65ed58 968 break;
dxyang 3:86773d65ed58 969 case 2:
dxyang 7:0aee09577ad3 970 logActionWithUserInfoH(hubAction_TwoBatteryPicked, userIndex);
dxyang 6:00a132a076d5 971 txBatteryPickUp(2);
dxyang 7:0aee09577ad3 972 allUsersH[userIndex].batteriesOut += 2;
dxyang 3:86773d65ed58 973 break;
dxyang 3:86773d65ed58 974 case 3:
dxyang 7:0aee09577ad3 975 logActionWithUserInfoH(hubAction_ThreeBatteryPicked, userIndex);
dxyang 6:00a132a076d5 976 txBatteryPickUp(3);
dxyang 7:0aee09577ad3 977 allUsersH[userIndex].batteriesOut += 3;
dxyang 3:86773d65ed58 978 break;
dxyang 3:86773d65ed58 979 }
dxyang 3:86773d65ed58 980
dxyang 3:86773d65ed58 981 currentScreenH = initialScanRfid;
dxyang 3:86773d65ed58 982 return;
dxyang 3:86773d65ed58 983 }
dxyang 3:86773d65ed58 984
dxyang 5:88c516cf34e6 985 /*************************************************************************************************/
dxyang 5:88c516cf34e6 986 /* Misc Services */
dxyang 5:88c516cf34e6 987 /*************************************************************************************************/
dxyang 3:86773d65ed58 988 /**
dxyang 8:b40c4553f6d4 989 * Do if Posho RFID flag is set. Reads rfid and checks user table for a positive balance.
dxyang 3:86773d65ed58 990 */
dxyang 3:86773d65ed58 991 void doPoshoRfidH()
dxyang 3:86773d65ed58 992 {
dxyang 3:86773d65ed58 993 flagPoshoRfidH = 0;
dxyang 8:b40c4553f6d4 994
dxyang 8:b40c4553f6d4 995 // is there a new readable card?
dxyang 8:b40c4553f6d4 996 if (!PoshoRfChipH.PICC_IsNewCardPresent()) {
dxyang 8:b40c4553f6d4 997 return;
dxyang 8:b40c4553f6d4 998 }
dxyang 8:b40c4553f6d4 999
dxyang 8:b40c4553f6d4 1000 if (!PoshoRfChipH.PICC_ReadCardSerial()) {
dxyang 8:b40c4553f6d4 1001 #ifdef debug
dxyang 8:b40c4553f6d4 1002 printf("Card not readable\n\r");
dxyang 8:b40c4553f6d4 1003 #endif
dxyang 8:b40c4553f6d4 1004 return;
dxyang 8:b40c4553f6d4 1005 }
dxyang 8:b40c4553f6d4 1006
dxyang 8:b40c4553f6d4 1007 // is the posho already in use?
dxyang 8:b40c4553f6d4 1008 if (flagPoshoAlreadyInUseH) {
dxyang 8:b40c4553f6d4 1009 TFT_H.cls();
dxyang 8:b40c4553f6d4 1010 TFT_H.locate(0,0);
dxyang 8:b40c4553f6d4 1011 TFT_H.printf("Posho in use\n\r");
dxyang 8:b40c4553f6d4 1012 wait(1);
dxyang 8:b40c4553f6d4 1013 currentScreenH = initialScanRfid;
dxyang 8:b40c4553f6d4 1014 return;
dxyang 8:b40c4553f6d4 1015 }
dxyang 8:b40c4553f6d4 1016
dxyang 8:b40c4553f6d4 1017 // get the id of the scanned tag
dxyang 8:b40c4553f6d4 1018 uint8_t tempReadingRfid[4];
dxyang 8:b40c4553f6d4 1019 for(uint8_t i = 0; i < PoshoRfChipH.uid.size; i++) {
dxyang 8:b40c4553f6d4 1020 tempReadingRfid[i] = PoshoRfChipH.uid.uidByte[i];
dxyang 8:b40c4553f6d4 1021 }
dxyang 8:b40c4553f6d4 1022
dxyang 8:b40c4553f6d4 1023 // concatenate the 4 bytes into a single integer via bit shifting
dxyang 8:b40c4553f6d4 1024 uint32_t actualRfid = ((((uint32_t)tempReadingRfid[0] << 24) |
dxyang 8:b40c4553f6d4 1025 ((uint32_t)tempReadingRfid[1] << 16)) |
dxyang 8:b40c4553f6d4 1026 (((uint32_t)tempReadingRfid[2] << 8) |
dxyang 8:b40c4553f6d4 1027 ((uint32_t)tempReadingRfid[3] << 0)));
dxyang 8:b40c4553f6d4 1028
dxyang 8:b40c4553f6d4 1029 // find the user info
dxyang 8:b40c4553f6d4 1030 char foundUserFlag = 0;
dxyang 8:b40c4553f6d4 1031 int foundUserIndex;
dxyang 8:b40c4553f6d4 1032 for (int i = 0; i < userCountH; i++) {
dxyang 8:b40c4553f6d4 1033 if (allUsersH[i].rfid == actualRfid) {
dxyang 8:b40c4553f6d4 1034 currentUserH = i;
dxyang 8:b40c4553f6d4 1035 foundUserIndex = i;
dxyang 8:b40c4553f6d4 1036 foundUserFlag = 1;
dxyang 8:b40c4553f6d4 1037 break;
dxyang 8:b40c4553f6d4 1038 }
dxyang 8:b40c4553f6d4 1039 }
dxyang 8:b40c4553f6d4 1040
dxyang 8:b40c4553f6d4 1041 // if the user is found, set the global variable for current user interacting with the system
dxyang 8:b40c4553f6d4 1042 // if the user isn't found, log that an rfid without a user was used and display
dxyang 8:b40c4553f6d4 1043 if (!foundUserFlag) {
dxyang 8:b40c4553f6d4 1044 #ifdef debug
dxyang 8:b40c4553f6d4 1045 printf("User not found\n\r");
dxyang 8:b40c4553f6d4 1046 printf("ID:%u\n\r", actualRfid);
dxyang 8:b40c4553f6d4 1047 #endif
dxyang 8:b40c4553f6d4 1048 // log the error interaction
dxyang 8:b40c4553f6d4 1049 logErrorUnknownRfidScannedH(actualRfid, source_posho);
dxyang 8:b40c4553f6d4 1050
dxyang 8:b40c4553f6d4 1051 // let user know tag wasn't found
dxyang 8:b40c4553f6d4 1052 TFT_H.cls();
dxyang 8:b40c4553f6d4 1053 TFT_H.locate(0,0);
dxyang 8:b40c4553f6d4 1054 TFT_H.printf("User not found\n\r");
dxyang 8:b40c4553f6d4 1055 TFT_H.printf("ID:%u\n\r", actualRfid);
dxyang 8:b40c4553f6d4 1056 wait(1);
dxyang 8:b40c4553f6d4 1057 currentScreenH = initialScanRfid;
dxyang 8:b40c4553f6d4 1058 return;
dxyang 8:b40c4553f6d4 1059 }
dxyang 8:b40c4553f6d4 1060
dxyang 8:b40c4553f6d4 1061 // log user scan
dxyang 8:b40c4553f6d4 1062 logActionWithUserInfoH(hubAction_PoshoRfidScanned, foundUserIndex);
dxyang 8:b40c4553f6d4 1063
dxyang 8:b40c4553f6d4 1064 // Display info about the user
dxyang 8:b40c4553f6d4 1065 char authorizationFlag = 0;
dxyang 8:b40c4553f6d4 1066 TFT_H.cls();
dxyang 8:b40c4553f6d4 1067 TFT_H.locate(0,0);
dxyang 8:b40c4553f6d4 1068 TFT_H.printf("UserID: %u\n\r", actualRfid);
dxyang 8:b40c4553f6d4 1069 int userAccountBalance = allUsersH[foundUserIndex].accountCredit;
dxyang 8:b40c4553f6d4 1070 TFT_H.printf("Balance:%d\n\r", userAccountBalance);
dxyang 8:b40c4553f6d4 1071 if (userAccountBalance > 1*poshoPricePerKgH) {
dxyang 8:b40c4553f6d4 1072 authorizationFlag = 1;
dxyang 8:b40c4553f6d4 1073 }
dxyang 8:b40c4553f6d4 1074 TFT_H.printf("Authorization:%s\n\r", (authorizationFlag)? "YES":"NO");
dxyang 8:b40c4553f6d4 1075
dxyang 8:b40c4553f6d4 1076
dxyang 8:b40c4553f6d4 1077 // if not authorized for batteries, return to main screen
dxyang 8:b40c4553f6d4 1078 wait(1);
dxyang 8:b40c4553f6d4 1079 if (!authorizationFlag) {
dxyang 8:b40c4553f6d4 1080 currentScreenH = initialScanRfid;
dxyang 8:b40c4553f6d4 1081 return;
dxyang 8:b40c4553f6d4 1082 }
dxyang 8:b40c4553f6d4 1083
dxyang 8:b40c4553f6d4 1084 // otherwise, ask user how may kg of material to process?
dxyang 8:b40c4553f6d4 1085 TFT_H.cls();
dxyang 8:b40c4553f6d4 1086 TFT_H.locate(0,0);
dxyang 8:b40c4553f6d4 1087 TFT_H.printf("UserID: %u\n\r\n\r", actualRfid);
dxyang 8:b40c4553f6d4 1088
dxyang 8:b40c4553f6d4 1089 TFT_H.printf("Action: Posho\n\r");
dxyang 8:b40c4553f6d4 1090 TFT_H.locate(0,160);
dxyang 8:b40c4553f6d4 1091 TFT_H.printf("How many kilos?\n\r");
dxyang 8:b40c4553f6d4 1092 TFT_H.locate(0,200);
dxyang 8:b40c4553f6d4 1093 if (userAccountBalance > 3*poshoPricePerKgH) {
dxyang 8:b40c4553f6d4 1094 TFT_H.printf(" 1 2 3 exit");
dxyang 8:b40c4553f6d4 1095 } else if (userAccountBalance > 2*poshoPricePerKgH) {
dxyang 8:b40c4553f6d4 1096 TFT_H.printf(" 1 2 exit");
dxyang 8:b40c4553f6d4 1097 } else {
dxyang 8:b40c4553f6d4 1098 TFT_H.printf(" 1 exit");
dxyang 8:b40c4553f6d4 1099 }
dxyang 8:b40c4553f6d4 1100
dxyang 8:b40c4553f6d4 1101 // go to wait for selection input and reset button flags
dxyang 8:b40c4553f6d4 1102 currentScreenH = poshoSelectKilograms;
dxyang 8:b40c4553f6d4 1103 clearAllUserInitiatedFlagsH();
dxyang 8:b40c4553f6d4 1104 return;
dxyang 8:b40c4553f6d4 1105 }
dxyang 8:b40c4553f6d4 1106
dxyang 8:b40c4553f6d4 1107 /**
dxyang 8:b40c4553f6d4 1108 * Prepare to active the posho and husker for serial use. Change user balance as necessary
dxyang 8:b40c4553f6d4 1109 * and send corresponding signal.
dxyang 8:b40c4553f6d4 1110 * @param numKilograms - int for number of kilograms to be processed
dxyang 8:b40c4553f6d4 1111 * @param userIndex - int representing index of user in user table
dxyang 8:b40c4553f6d4 1112 */
dxyang 8:b40c4553f6d4 1113 void poshoSerialUse(int numKilograms, int userIndex) {
dxyang 8:b40c4553f6d4 1114 flagPoshoAlreadyInUseH = 1;
dxyang 8:b40c4553f6d4 1115
dxyang 8:b40c4553f6d4 1116 switch (numKilograms) {
dxyang 8:b40c4553f6d4 1117 case 1:
dxyang 8:b40c4553f6d4 1118 tickPoshoInUseClearH.attach(&interruptPoshoInUseClearH, (float)timeForOneKgH);
dxyang 8:b40c4553f6d4 1119 break;
dxyang 8:b40c4553f6d4 1120 case 2:
dxyang 8:b40c4553f6d4 1121 tickPoshoInUseClearH.attach(&interruptPoshoInUseClearH, (float)timeForTwoKgH);
dxyang 8:b40c4553f6d4 1122 break;
dxyang 8:b40c4553f6d4 1123 case 3:
dxyang 8:b40c4553f6d4 1124 tickPoshoInUseClearH.attach(&interruptPoshoInUseClearH, (float)timeForThreeKgH);
dxyang 8:b40c4553f6d4 1125 break;
dxyang 8:b40c4553f6d4 1126 }
dxyang 8:b40c4553f6d4 1127 allUsersH[userIndex].accountCredit -= numKilograms*poshoPricePerKgH;
dxyang 8:b40c4553f6d4 1128 TFT_H.cls();
dxyang 8:b40c4553f6d4 1129 TFT_H.locate(0,0);
dxyang 8:b40c4553f6d4 1130 TFT_H.printf("UserID: %u\n\r\n\r", allUsersH[userIndex].rfid);
dxyang 8:b40c4553f6d4 1131 TFT_H.printf("New balance: %d\n\r", allUsersH[userIndex].accountCredit);
dxyang 8:b40c4553f6d4 1132 txPoshoSerialUse(numKilograms);
dxyang 8:b40c4553f6d4 1133 wait(1);
dxyang 8:b40c4553f6d4 1134 currentScreenH = initialScanRfid;
dxyang 8:b40c4553f6d4 1135 return;
dxyang 3:86773d65ed58 1136 }
dxyang 3:86773d65ed58 1137
dxyang 3:86773d65ed58 1138 /**
dxyang 3:86773d65ed58 1139 * Do if Incubator RFID flag is set. Add incubator functionality later.
dxyang 3:86773d65ed58 1140 */
dxyang 3:86773d65ed58 1141 void doIncubatorRfidH()
dxyang 3:86773d65ed58 1142 {
dxyang 3:86773d65ed58 1143 flagIncubatorRfidH = 0;
dxyang 3:86773d65ed58 1144 }
dxyang 3:86773d65ed58 1145
dxyang 3:86773d65ed58 1146 /*************************************************************************************************/
dxyang 3:86773d65ed58 1147 /* Public Methods */
dxyang 3:86773d65ed58 1148 /*************************************************************************************************/
dxyang 3:86773d65ed58 1149 /**
dxyang 3:86773d65ed58 1150 * Initialise for a hub
epgmdm 1:c2232b1eaf31 1151 * fp is the config file if additonal information is needed.
epgmdm 1:c2232b1eaf31 1152 */
epgmdm 1:c2232b1eaf31 1153 void initialiseHub(FILE *fp){
epgmdm 1:c2232b1eaf31 1154 #ifdef debug
dxyang 3:86773d65ed58 1155 printf("Initializing Hub\n\r");
epgmdm 1:c2232b1eaf31 1156 #endif
epgmdm 1:c2232b1eaf31 1157
epgmdm 1:c2232b1eaf31 1158 // Read in hub address and channel
epgmdm 1:c2232b1eaf31 1159 if (fscanf (fp,"%x %*c %*s",&channel )!=1) writeError("Hub config: cannot read channel");
epgmdm 1:c2232b1eaf31 1160 if (fscanf (fp,"%llx %*c %*s",&addrLcker )!=1) writeError("Hub config: cannot read hub address");
epgmdm 1:c2232b1eaf31 1161
epgmdm 1:c2232b1eaf31 1162 #ifdef debug
epgmdm 1:c2232b1eaf31 1163 printf(" Channel:%x, Hub Address %llx \n\r",channel, addrLcker);
epgmdm 1:c2232b1eaf31 1164 #endif
epgmdm 2:d1eae91343a9 1165
epgmdm 2:d1eae91343a9 1166 // Setup nrf
epgmdm 2:d1eae91343a9 1167 #ifdef debug
epgmdm 2:d1eae91343a9 1168 printf("Steup doNrf \n\r");
epgmdm 2:d1eae91343a9 1169 #endif
epgmdm 2:d1eae91343a9 1170 spiNrf();
epgmdm 2:d1eae91343a9 1171 nrf1.quickTxSetup(channel, addrLcker);
epgmdm 2:d1eae91343a9 1172 #ifdef debug
epgmdm 2:d1eae91343a9 1173 nrf1.printDetails();
epgmdm 2:d1eae91343a9 1174 nrf1.checkStatus();
epgmdm 2:d1eae91343a9 1175 printf("Setup doNrf complete [nrf:%s]\n\r",nrf1.statusString());
epgmdm 2:d1eae91343a9 1176 #endif
epgmdm 2:d1eae91343a9 1177
dxyang 3:86773d65ed58 1178 // Other initialization routines
dxyang 3:86773d65ed58 1179 initializeTimeH();
dxyang 3:86773d65ed58 1180 initializeInterruptsH();
dxyang 3:86773d65ed58 1181 initializeRfidReadersH();
dxyang 3:86773d65ed58 1182 initializeLCD_H();
dxyang 3:86773d65ed58 1183 initializeUsersFromSD_H();
dxyang 8:b40c4553f6d4 1184 initializePoshoFunctionality();
epgmdm 1:c2232b1eaf31 1185 }
epgmdm 2:d1eae91343a9 1186
dxyang 3:86773d65ed58 1187 void loopHub(){
dxyang 3:86773d65ed58 1188 while (true) {
dxyang 3:86773d65ed58 1189 // put interrupts here that should supercede anything else
dxyang 3:86773d65ed58 1190 if (flag1sH) { do1sH(); }
epgmdm 1:c2232b1eaf31 1191
dxyang 3:86773d65ed58 1192 // put interrupts here that may be active depending on screen stage
dxyang 3:86773d65ed58 1193 switch(currentScreenH) {
dxyang 3:86773d65ed58 1194 case initialScanRfid: {
dxyang 3:86773d65ed58 1195 TFT_H.cls();
dxyang 3:86773d65ed58 1196 TFT_H.locate(0,0);
dxyang 3:86773d65ed58 1197 TFT_H.printf("Please scan your ID");
dxyang 3:86773d65ed58 1198 currentScreenH = waitForRfid;
dxyang 3:86773d65ed58 1199 clearAllUserInitiatedFlagsH();
dxyang 3:86773d65ed58 1200 }
dxyang 3:86773d65ed58 1201 case waitForRfid: {
dxyang 3:86773d65ed58 1202 if (flagTimeCheckH) doTimeCheckH();
dxyang 3:86773d65ed58 1203 if (flagBatteryRfidH) doBatteryRfidH();
dxyang 3:86773d65ed58 1204 if (flagPoshoRfidH) doPoshoRfidH();
dxyang 3:86773d65ed58 1205 if (flagIncubatorRfidH) doIncubatorRfidH();
dxyang 3:86773d65ed58 1206 if (flagUpdateUserTableH) doUpdateUserTableH();
dxyang 3:86773d65ed58 1207 break;
dxyang 3:86773d65ed58 1208 }
dxyang 3:86773d65ed58 1209 case batterySelectAction: {
dxyang 3:86773d65ed58 1210 uint8_t maxBatteries = allUsersH[currentUserH].batterySubscription;
dxyang 3:86773d65ed58 1211 uint8_t outBatteries = allUsersH[currentUserH].batteriesOut;
dxyang 3:86773d65ed58 1212
dxyang 3:86773d65ed58 1213 if ((maxBatteries - outBatteries) == 0) {
dxyang 7:0aee09577ad3 1214 if (flagButtonOneH) batteryDropOffH(currentUserH);
dxyang 7:0aee09577ad3 1215 if (flagButtonFourH) cancelPressedH(currentUserH);
dxyang 3:86773d65ed58 1216 } else if (outBatteries == 0) {
dxyang 7:0aee09577ad3 1217 if (flagButtonOneH) batteryPickUpH(currentUserH);
dxyang 7:0aee09577ad3 1218 if (flagButtonFourH) cancelPressedH(currentUserH);
dxyang 3:86773d65ed58 1219 } else {
dxyang 7:0aee09577ad3 1220 if (flagButtonOneH) batteryPickUpH(currentUserH);
dxyang 7:0aee09577ad3 1221 if (flagButtonThreeH) batteryDropOffH(currentUserH);
dxyang 7:0aee09577ad3 1222 if (flagButtonFourH) cancelPressedH(currentUserH);
dxyang 3:86773d65ed58 1223 }
epgmdm 1:c2232b1eaf31 1224
dxyang 3:86773d65ed58 1225 break;
dxyang 3:86773d65ed58 1226 }
dxyang 3:86773d65ed58 1227 case batterySelectNumberForDropoff: {
dxyang 3:86773d65ed58 1228 switch (allUsersH[currentUserH].batteriesOut) {
dxyang 3:86773d65ed58 1229 case 1: {
dxyang 7:0aee09577ad3 1230 if (flagButtonOneH) batteryDropOffH(1, currentUserH);
dxyang 7:0aee09577ad3 1231 if (flagButtonFourH) cancelPressedH(currentUserH);
dxyang 3:86773d65ed58 1232 break;
dxyang 3:86773d65ed58 1233 }
dxyang 3:86773d65ed58 1234 case 2: {
dxyang 7:0aee09577ad3 1235 if (flagButtonOneH) batteryDropOffH(1, currentUserH);
dxyang 7:0aee09577ad3 1236 if (flagButtonTwoH) batteryDropOffH(2, currentUserH);
dxyang 7:0aee09577ad3 1237 if (flagButtonFourH) cancelPressedH(currentUserH);
dxyang 3:86773d65ed58 1238 break;
dxyang 3:86773d65ed58 1239 }
dxyang 3:86773d65ed58 1240 case 3: {
dxyang 7:0aee09577ad3 1241 if (flagButtonOneH) batteryDropOffH(1, currentUserH);
dxyang 7:0aee09577ad3 1242 if (flagButtonTwoH) batteryDropOffH(2, currentUserH);
dxyang 7:0aee09577ad3 1243 if (flagButtonThreeH) batteryDropOffH(3, currentUserH);
dxyang 7:0aee09577ad3 1244 if (flagButtonFourH) cancelPressedH(currentUserH);
dxyang 3:86773d65ed58 1245 break;
dxyang 3:86773d65ed58 1246 }
dxyang 3:86773d65ed58 1247 }
dxyang 3:86773d65ed58 1248 break;
dxyang 3:86773d65ed58 1249 }
dxyang 3:86773d65ed58 1250 case batterySelectNumberForPickup: {
dxyang 3:86773d65ed58 1251 switch (allUsersH[currentUserH].batterySubscription - allUsersH[currentUserH].batteriesOut) {
dxyang 3:86773d65ed58 1252 case 1: {
dxyang 7:0aee09577ad3 1253 if (flagButtonOneH) batteryPickUpH(1, currentUserH);
dxyang 7:0aee09577ad3 1254 if (flagButtonFourH) cancelPressedH(currentUserH);
dxyang 3:86773d65ed58 1255 break;
dxyang 3:86773d65ed58 1256 }
dxyang 3:86773d65ed58 1257 case 2: {
dxyang 7:0aee09577ad3 1258 if (flagButtonOneH) batteryPickUpH(1, currentUserH);
dxyang 7:0aee09577ad3 1259 if (flagButtonTwoH) batteryPickUpH(2, currentUserH);
dxyang 7:0aee09577ad3 1260 if (flagButtonFourH) cancelPressedH(currentUserH);
dxyang 3:86773d65ed58 1261 break;
dxyang 3:86773d65ed58 1262 }
dxyang 3:86773d65ed58 1263 case 3: {
dxyang 7:0aee09577ad3 1264 if (flagButtonOneH) batteryPickUpH(1, currentUserH);
dxyang 7:0aee09577ad3 1265 if (flagButtonTwoH) batteryPickUpH(2, currentUserH);
dxyang 7:0aee09577ad3 1266 if (flagButtonThreeH) batteryPickUpH(3, currentUserH);
dxyang 7:0aee09577ad3 1267 if (flagButtonFourH) cancelPressedH(currentUserH);
dxyang 3:86773d65ed58 1268 break;
dxyang 3:86773d65ed58 1269 }
dxyang 3:86773d65ed58 1270 }
dxyang 3:86773d65ed58 1271 break;
dxyang 3:86773d65ed58 1272 }
dxyang 8:b40c4553f6d4 1273 case poshoSelectKilograms: {
dxyang 8:b40c4553f6d4 1274 if (allUsersH[currentUserH].accountCredit > 3*poshoPricePerKgH) {
dxyang 8:b40c4553f6d4 1275 if (flagButtonOneH) poshoSerialUse(1, currentUserH);
dxyang 8:b40c4553f6d4 1276 if (flagButtonTwoH) poshoSerialUse(2, currentUserH);
dxyang 8:b40c4553f6d4 1277 if (flagButtonThreeH) poshoSerialUse(3, currentUserH);
dxyang 8:b40c4553f6d4 1278 if (flagButtonFourH) cancelPressedH(currentUserH);
dxyang 8:b40c4553f6d4 1279 } else if (allUsersH[currentUserH].accountCredit > 2*poshoPricePerKgH) {
dxyang 8:b40c4553f6d4 1280 if (flagButtonOneH) poshoSerialUse(1, currentUserH);
dxyang 8:b40c4553f6d4 1281 if (flagButtonTwoH) poshoSerialUse(2, currentUserH);
dxyang 8:b40c4553f6d4 1282 if (flagButtonFourH) cancelPressedH(currentUserH);
dxyang 8:b40c4553f6d4 1283 } else {
dxyang 8:b40c4553f6d4 1284 if (flagButtonOneH) poshoSerialUse(1, currentUserH);
dxyang 8:b40c4553f6d4 1285 if (flagButtonFourH) cancelPressedH(currentUserH);
dxyang 8:b40c4553f6d4 1286 }
dxyang 8:b40c4553f6d4 1287 }
dxyang 3:86773d65ed58 1288 }
epgmdm 2:d1eae91343a9 1289 }
epgmdm 1:c2232b1eaf31 1290 }