Modify the previous example to use NVStore for keeping track of how many times every different LED turned on This information must persist across system reboots! Print this information on STDout at every boot before running the application

Dependencies:   BSP_B-L475E-IOT01

main.cpp

Committer:
vicara
Date:
2018-12-06
Revision:
1:288cdb94027a
Parent:
0:063b251c6aed
Child:
2:4cfbd0da7242

File content as of revision 1:288cdb94027a:

#include "mbed.h"

#include "stm32l475e_iot01_accelero.h"

#include <stdio.h>
#include <errno.h>

// Block devices
#if COMPONENT_SPIF
#include "SPIFBlockDevice.h"
#endif

#if COMPONENT_DATAFLASH
#include "DataFlashBlockDevice.h"
#endif 

#if COMPONENT_SD
#include "SDBlockDevice.h"
#endif 

#include "HeapBlockDevice.h"

// File systems
#include "LittleFileSystem.h"
#include "FATFileSystem.h"
#include "nvstore.h"


// Physical block device, can be any device that supports the BlockDevice API
/*SPIFBlockDevice bd(
        MBED_CONF_SPIF_DRIVER_SPI_MOSI,
        MBED_CONF_SPIF_DRIVER_SPI_MISO,
        MBED_CONF_SPIF_DRIVER_SPI_CLK,
        MBED_CONF_SPIF_DRIVER_SPI_CS);*/

#define BLOCK_SIZE 512
HeapBlockDevice bd(16384, BLOCK_SIZE);

// File system declaration
LittleFileSystem fs("fs");

DigitalOut led1(LED1);
DigitalOut led2(LED2);
DigitalOut led3(LED3);

Ticker timeout_ticker;
Thread t;

static FILE *f;
volatile int seconds_passed = 0;
uint16_t key_1 = 1; 
uint32_t value_1;
uint16_t key_2 = 2; 
uint32_t value_2;
uint16_t key_3 = 3;
uint32_t value_3;

EventQueue queue(32 * EVENTS_EVENT_SIZE);

InterruptIn button(USER_BUTTON);
int16_t pDataXYZ[3] = {0};

void toggle_led(int led1_status, int led2_status, int led3_status){
    led1 = led1_status;
    led2 = led2_status;
    led3 = led3_status;
}

void write_positions_on_file() {
    int16_t pDataXYZ[3] = {0};
    BSP_ACCELERO_AccGetXYZ(pDataXYZ);
    if ((pDataXYZ[0] < -950  && pDataXYZ[0] > -1030) || (pDataXYZ[0] < 1030 && pDataXYZ[0] > 950)) {
            fprintf(f, "%d\n", 0);
        } else if ((pDataXYZ[1] < 1030 && pDataXYZ[1] > 950) || (pDataXYZ[1] < -950 && pDataXYZ[1] > -1030)) {
            fprintf(f, "%d\n", 1);
        } else if ((pDataXYZ[2] < 1030 && pDataXYZ[2] > 950) || (pDataXYZ[2] < -950 && pDataXYZ[2] > -1030)) {
             fprintf(f, "%d\n", 2);
        } else {
             fprintf(f, "%d\n", -1);
        }
    fflush(f);
    fflush(stdout);
}

void toggle_led_based_on_position() {
      int horizontal_occurrencies = 0;
      int long_vertical_occurrencies = 0;
      int short_vertical_occurrencies = 0;
      fflush(stdout);
      fflush(f);
      
      fseek(f, 0, SEEK_SET);
      int position;
      while (!feof(f)) {
        fscanf(f, "%d", &position); 
        if (position == 0) {
            short_vertical_occurrencies +=1;
        } else if(position == 1) {
            long_vertical_occurrencies +=1;
        } else if(position == 2) {
            horizontal_occurrencies +=1;
        }
      }
      printf("horizontal occ: %d \n",horizontal_occurrencies);
      printf("long vert occ: %d \n",long_vertical_occurrencies);
      printf("short vert occ: %d \n",short_vertical_occurrencies);
      NVStore &nvstore = NVStore::get_instance();
      if (horizontal_occurrencies >= long_vertical_occurrencies && horizontal_occurrencies >= short_vertical_occurrencies) {
            toggle_led(1,0,0);
            value_1+=1;
            nvstore.set(key_1, sizeof(value_1), &value_1);
        } else if (long_vertical_occurrencies >= horizontal_occurrencies && long_vertical_occurrencies >= short_vertical_occurrencies ) {
            toggle_led(0,1,0);
            value_2+=1;
            nvstore.set(key_2, sizeof(value_2), &value_2);
        } else if (short_vertical_occurrencies >= horizontal_occurrencies && short_vertical_occurrencies >= long_vertical_occurrencies) {
            toggle_led(0,0,1);
            value_3+=1;
            nvstore.set(key_3, sizeof(value_3), &value_3);
        }
      printf("Press the restart button to sample again.\n");
      
      fflush(stdout);
      int err = fclose(f);
      printf("%s\n", (err < 0 ? "Fail :(" : "OK"));
      if (err < 0) {
        error("error: %s (%d)\n", strerror(err), -err);
      }
      err = fs.unmount();
      printf("%s\n", (err < 0 ? "Fail :(" : "OK"));
      if (err < 0) {
          error("error: %s (%d)\n", strerror(-err), err);
      }    
      
}

void toggle() {
    int16_t pDataXYZ[3] = {0};
    BSP_ACCELERO_AccGetXYZ(pDataXYZ);
    printf("ACCELERO_X = %d\n", pDataXYZ[0]);
    printf("ACCELERO_Y = %d\n", pDataXYZ[1]);
    printf("ACCELERO_Z = %d\n\n", pDataXYZ[2]);
}

bool is_board_horizontal() {
    return (pDataXYZ[2] < 1030 && pDataXYZ[2] > 950) || (pDataXYZ[2] < -950 && pDataXYZ[2] > -1030);
}

bool is_board_vertical_short() {
    return (pDataXYZ[0] < -950  && pDataXYZ[0] > -1030) || (pDataXYZ[0] < 1030 && pDataXYZ[0] > 950);
}

bool is_board_vertical_long() {
    return (pDataXYZ[1] < 1030 && pDataXYZ[1] > 950) || (pDataXYZ[1] < -950 && pDataXYZ[1] > -1030);
}

void ticker_attach() {    
    queue.call(write_positions_on_file);
    seconds_passed++;
//    Blink correct led after 10 seconds
    if (seconds_passed == 1000) {
      timeout_ticker.detach();
      queue.call(toggle_led_based_on_position);
      seconds_passed = 0;
    }
}

int main(){
    t.start(callback(&queue, &EventQueue::dispatch_forever));
    BSP_ACCELERO_Init();
    
    NVStore &nvstore = NVStore::get_instance();
   
    uint16_t actual_len_bytes = 0;
    int rc;
    
    rc = nvstore.init();
    printf("Init NVStore. \n");
    
    rc = nvstore.get(key_1, sizeof(value_1), &value_1, actual_len_bytes);
    if (rc == NVSTORE_NOT_FOUND) {
        value_1 = 0;
        value_2 = 0;
        value_3 = 0;
        nvstore.set(key_1, sizeof(value_1), &value_1);
        nvstore.set(key_2, sizeof(value_2), &value_2);
        nvstore.set(key_3, sizeof(value_3), &value_3);
    } else {
        nvstore.get(key_2, sizeof(value_2), &value_2, actual_len_bytes);
        nvstore.get(key_3, sizeof(value_3), &value_3, actual_len_bytes);    
    }
    
    printf("LED_1: %d\nLED_2: %d\nLED_3: %d\n", value_1, value_2, value_3);
    
    // Try to mount the filesystem
    printf("Mounting the filesystem... ");
    fflush(stdout);
    int err = fs.mount(&bd);
    printf("%s\n", (err ? "Fail :(" : "OK"));
    if (err) {
        // Reformat if we can't mount the filesystem
        // this should only happen on the first boot
        printf("No filesystem found, formatting... ");
        fflush(stdout);
        err = fs.reformat(&bd);
        printf("%s\n", (err ? "Fail :(" : "OK"));
        if (err) {
            error("error: %s (%d)\n", strerror(-err), err);
        }
    }
    
    // Open the numbers file
    printf("Opening \"/fs/numbers.txt\"... ");
    fflush(stdout);
    f = fopen("/fs/numbers.txt", "r+");
    printf("%s\n", (!f ? "Fail :(" : "OK"));
    if (!f) {
        // Create the numbers file if it doesn't exist
        printf("No file found, creating a new file... ");
        fflush(stdout);
        f = fopen("/fs/numbers.txt", "w+");
        printf("%s\n", (!f ? "Fail :(" : "OK"));
        if (!f) {
            error("error: %s (%d)\n", strerror(errno), -errno);
        }
    }

    timeout_ticker.attach(&ticker_attach, 0.01);
}