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:53:35 2016 +0000
Revision:
9:72e93d9ddc8c
Parent:
8:b40c4553f6d4
added posh logging

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