demonstrates: - interrupts - sd card storage - file write/ read - RTC get time - timer vs delay

Dependencies:   USBMSD_BD MAX7219 ds3231 max32630fthr USBDevice

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"));
+}