demonstrates: - interrupts - sd card storage - file write/ read - RTC get time - timer vs delay
Dependencies: USBMSD_BD MAX7219 ds3231 max32630fthr USBDevice
Diff: main.cpp
- Revision:
- 0:0df734b49f24
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Wed Aug 11 09:57:08 2021 +0000 @@ -0,0 +1,309 @@ +// Includes and Definitions +#include "mbed.h" +#include "max32630fthr.h" +#include "ds3231.h" +#include "SDBlockDevice.h" +#include "HeapBlockDevice.h" +#include "FATFileSystem.h" +#include "max7219.h" +#include <string> + +#define BLOCK_SIZE 512 + +// Objects +MAX32630FTHR pegasus(MAX32630FTHR::VIO_3V3); + +Timer overCrowdBlinker; +Timer missingMicroSDBlinker; +Timer pollDelay; +Timer sameCardRejectDelay; + +SDBlockDevice bd(P0_5, P0_6, P0_4, P0_7); +FATFileSystem fs("fs"); + +// Variables +bool logSuccessFlag = false; +int entryCountSincePowerOn = 0; +int entryCountSinceBegin = 0; +int err = 0; +char c; + +int headCount = 0; +int oldHeadCount = 0; +bool overCrowdBlink = true; +bool goingIn = true; + +// GPIOs +DigitalOut rLED(LED1); +DigitalOut gLED(LED2); +DigitalOut bLED(LED3); +DigitalOut overcrowd_alarm(P4_0); + +InterruptIn outsideSensor(P5_7); +InterruptIn insideSensor(P6_0); + +DigitalIn uSDetect(P2_2,PullUp); + +DigitalIn dum1(P4_4, OpenDrain); +DigitalIn dum3(P4_5, OpenDrain); +DigitalIn dum2(P4_6, OpenDrain); +DigitalIn dum4(P4_7, OpenDrain); + +void killTheLights(); +void blinkLed(bool, bool, bool); + +void enterISR(); +void egressISR(); + +void mountFileSystem(); +void checkFile(); +void logEntry(int, string); + +int main(){ + killTheLights(); + blinkLed(1,0,0); + blinkLed(0,1,0); + blinkLed(0,0,1); + + Ds3231 rtc(I2C1_SDA, I2C1_SCL); // SDA, SCL + + Max7219 segDriver(P5_1, P5_2, P5_0, P4_7); + + max7219_configuration_t segConfig = { + .device_number = 1, + .decode_mode = 0x01, + .intensity = Max7219::MAX7219_INTENSITY_F, + .scan_limit = Max7219::MAX7219_SCAN_4 + }; + + segDriver.set_display_test(); + wait(0.5); + segDriver.clear_display_test(); + segDriver.init_device(segConfig); + segDriver.enable_device(1); + segDriver.clear_digit(1, Max7219::MAX7219_D0_P0); + wait(0.5); + + outsideSensor.mode(PullDown); + insideSensor.mode(PullDown); + outsideSensor.fall(&enterISR); + insideSensor.fall(&egressISR); + + overCrowdBlinker.start(); + missingMicroSDBlinker.start(); + pollDelay.start(); + sameCardRejectDelay.start(); + + char timeBuffer[32]; + + time_t epoch_time; + + printf("%c[2J", 0x1B); //clear screen + printf("%c[H", 0x1B); //move cursor to Home + printf("\r\n\n\n--- Passage Counter ---\r\n\n"); + + while(1){ + // phase 1 routine + gLED = LED_OFF; + bLED = LED_OFF; + segDriver.write_digit(1, Max7219::MAX7219_D0_P0, headCount); + if(headCount != oldHeadCount){ + segDriver.write_digit(1, Max7219::MAX7219_D0_P0, headCount); + oldHeadCount = headCount; + for(int ii = 0; ii<3; ii++){ + if(goingIn) bLED = LED_ON; else gLED = LED_ON; + wait(0.1); + if(goingIn) bLED = LED_OFF; else gLED = LED_OFF; + wait(0.1); + } + + mountFileSystem(); + if(err == 0){ + checkFile(); + epoch_time = rtc.get_epoch(); + strftime(timeBuffer, 32, "%a %b%e %G %X", localtime(&epoch_time)); + + logEntry(headCount, timeBuffer); + printf("Unmounting..."); + fflush(stdout); + err = fs.unmount(); + printf("%s\r\n", (err < 0 ? "Fail :(" : "OK")); + } + else blinkLed(1,0,0); + + wait_ms(10); + printf("...RFID Reset. after succeeded\r\n"); + } + if(headCount>4){ + if(overCrowdBlinker.read_ms()>300){ + overcrowd_alarm =! overcrowd_alarm; + overCrowdBlinker.reset(); + } + } else overcrowd_alarm = false; + + + // phase 2 routine + if(uSDetect == 1){ + if(missingMicroSDBlinker.read_ms()>300){ + rLED =! rLED; + missingMicroSDBlinker.reset(); + } + } + //end of idle loop + } + //end of main +} + + +void killTheLights(){ + rLED = 1; gLED = 1; bLED = 1; +} + +void blinkLed(bool red, bool green, bool blue){ + for(int xx = 0; xx<10; xx++){ + if(red)rLED =! rLED; + if(green)gLED =! gLED; + if(blue)bLED =! bLED; + wait(0.05); + } + killTheLights(); +} + +void enterISR(){ + bLED = LED_ON; + while(outsideSensor.read() == 0){ + if(insideSensor.read() == 0){ + while(insideSensor.read() == 0 && outsideSensor.read() == 0){ + // stall until further event + } + if(outsideSensor.read() == 1){ + while(outsideSensor.read() == 1 && insideSensor.read() == 0){ + // stall until further event + } + if(insideSensor.read() == 1){ + headCount++; + //if(headCount>9) headCount = 9; + goingIn = true; + return; + // last of if inside high + } + // last of if outside high + } + // last of if inside low + } + // last of while outside low + } + // last of enterISR +} + +void egressISR(){ + gLED = LED_ON; + while(insideSensor.read() == 0){ + if(outsideSensor.read() == 0){ + while(outsideSensor.read() == 0 && insideSensor.read() == 0){ + // stall until further event + } + if(insideSensor.read() == 1){ + while(insideSensor.read() == 1 && outsideSensor.read() == 0){ + // stall until further event + } + if(outsideSensor.read() == 1){ + headCount--; + if(headCount<0) headCount = 0; + goingIn = false; + return; + // last of if outside high + } + // last of if inside high + } + // last of if outside low + } + // last of while inside low + } + // last of egressISR +} + +void mountFileSystem(){ + printf("Mounting the filesystem..."); + fflush(stdout); + + err = fs.mount(&bd); + printf("%s\r\n", (err ? "Fail :(" : "OK")); + if(err){ + printf("No filesystem found, formatting..."); + fflush(stdout); + err = fs.reformat(&bd); + printf("%s\r\n", (err ? "Fail :(" : "OK")); + rLED = LED_ON; + } + else blinkLed(0,0,1); +} + +void checkFile(){ + printf("Checking if file exists \"/fs/log.txt\"..."); + fflush(stdout); + + FILE *f = fopen("/fs/log.txt", "r"); + printf("%s\r\n", (!f ? "Fail :(" : "OK")); + + if(!f){ + //--if fail, create file + printf("info: No file found, creating a new file..."); + fflush(stdout); + + f = fopen("/fs/log.txt", "w+"); // RW mode. erase all contents. create new file if non-existent + printf("%s\r\n", (!f ? "Fail :(" : "OK")); + printf("Writing header..."); + err = fprintf(f, "ID Date Time since POR since Begin 0000000000\r\n"); + printf("%s\r\n", (err < 0 ? "Fail :(" : "OK")); + } + + //--close file + printf("Closing \"/fs/log.txt\"..."); + fflush(stdout); + err = fclose(f); + printf("%s\r\n", (err < 0 ? "Fail :(" : "OK")); + blinkLed(0,0,1); +} + +void logEntry(int idStamp, string timeStamp){ + printf("Opening file \"/fs/log.txt\"..."); // takes formatted const char to stdout + fflush(stdout); // flushes buffered data to the target device/ stream + + FILE *f = fopen("/fs/log.txt", "r+"); // RW mode. read from start. error if non-existent + printf("%s\r\n", (!f ? "Fail :(" : "OK")); + printf("Logging entry..."); + fflush(stdout); + + fseek(f,-10,SEEK_END); + fscanf(f,"%d",&entryCountSinceBegin); + //printf("the last rowCount was: %010d\r\n",entryCountSinceBegin); + fseek(f,0,SEEK_END); + entryCountSinceBegin++; + entryCountSincePowerOn++; + err = fprintf(f, "%d %s %d %10d\r\n", idStamp, timeStamp, entryCountSincePowerOn, entryCountSinceBegin); // 0; // + printf("%s\r\n", (err < 0 ? "Fail :(" : "OK")); + if(err < 0){ + blinkLed(1,0,0); + } + else{ + sameCardRejectDelay.reset(); + logSuccessFlag = true; + blinkLed(0,1,0); // final success. greenlight. + } + + // DUMP + rewind(f); + printf("==Dump==\r\n"); + while (!feof(f)) { + int c = fgetc(f); + printf("%c", c); + } + printf("==EndofDump==\r\n"); + + //--close file + printf("Closing \"/fs/log.txt\"..."); + fflush(stdout); + err = fclose(f); + printf("%s\r\n", (err < 0 ? "Fail :(" : "OK")); +}