Los Putacos / Mbed OS WearableDevice_Nucleo_New

Dependencies:   MPU9250_SPI

Fork of WearableDevice_Nucleo by Los Putacos

main.cpp

Committer:
Muglug
Date:
2017-11-12
Revision:
27:c4b2ce6fa5b8
Parent:
26:4bc56ce08d15
Child:
28:c7e977a19564

File content as of revision 27:c4b2ce6fa5b8:

/*
* Los Putacos
* Copyright (C) 2017, All rights reserved.
* ________________________________________
*
* Created by: Gustavo Campana, Michael Schmidt, Miguel Lopez
*       Date: 11-Oct-2017
*    Version: V0.1
*/
//-----------------------------------------------------------------

//-----------------------------------------------------------------
//     Board: NUCLEO - F401RE
//   Version: MR1136 rev C
//-----------------------------------------------------------------

//-----------------------------------------------------------------
// Includes
#include "mbed.h"
#include "configuration.h"

#include "XBeeLib.h"
#include "SDFileSystem.h"
#include "MPU9250.h"

#include "event.h"
//-----------------------------------------------------------------

//-----------------------------------------------------------------
// Declarations
FILE *fp;                                   // FILE Type for SD-Card
Timer TimeStamp;                            // Timer µS time-stamp
Serial PC(USBTX, USBRX);                    // Create an Serial PC Object - USBTX, USBRX
SPI spi(MPU_MOSI, MPU_MISO, MPU_SCK);       // Create an SPI Object for MPU9250 - MOSI, MISO, SCK
mpu9250_spi imu(spi, MPU_CS);               // Create an MPU9250 Object - SPI Object, CS
SDFileSystem sd(SD_MOSI, SD_MISO, SD_CLK, SD_CS, "sd", SD_CD, SDFileSystem::SWITCH_NEG_NO, 25000000);   // Create an SDFileSystem Object - MOSI, MISO, CLK, CS
XBeeLib::XBeeZB XBee = XBeeLib::XBeeZB(RADIO_TX, RADIO_RX, RADIO_RESET, NC, NC, 230400);                // Create an XBee Object - TX, RX, RESET, NC, NC, BaudRate
XBeeLib::TxStatus txStatus;                 // XBee Status Variable

// Events
EventQueue queue(32 * EVENTS_EVENT_SIZE);   // Event Setup

// Tickers
Ticker Ticker_IMU;
Ticker Ticker_ReceiveXBee;

// Threads
Thread Thread_IMU(osPriorityRealtime);
Thread Thread_ReceiveXBee(osPriorityNormal);

// Global Variables
uint16_t Time_Data = 0;
uint32_t Data_Size = 0;
uint16_t LineCount = 0;
volatile uint16_t readPointer = 0;
volatile uint16_t readPointer_MIC = 0;
volatile uint16_t writePointer = 0;
volatile uint16_t writePointer_MIC = 0;

uint8_t ReadIMUDone_Flag = 0;
uint8_t WriteSDDone_Flag = 0;
uint8_t SendXBeeDone_Flag = 0;

uint8_t Requested_Time = 0;
uint8_t Current_Position = 0;

char Time_Buffer[2];
char Data_Buffer[255];
const char DeviceNr[6] = "DEV01";
int16_t Data_Storage[BufferSize];               // BufferSize defined in "event.h"
uint16_t Data_Storage_MIC[BufferSize_MIC];      // BufferSize_MIC defined in "event.h"

//-----------------------------------------------------------------

//-----------------------------------------------------------------
/* Callback function, invoked at packet reception */
static void receive_cb(const XBeeLib::RemoteXBeeZB& remote, bool broadcast, const uint8_t *const data, uint16_t len)
{
    PC.printf("Package Length: %i \r\n", len);      // Display Package Length
    for (int i = 0; i < len; i++) {
        Data_Buffer[i] = char(data[i]);
        PC.printf("%c", Data_Buffer[i]);            // Display Received Package
    }

    if (len == 9) {         // Check Package Length (correct: len = 9)
        if ((char(Data_Buffer[0]) == '#') && (char(Data_Buffer[6]) == ',')) {       // Check for "#" and "," at specific Positions
            PC.printf(" - Command Detected!\r\n");

            if (strstr(Data_Buffer, DeviceNr) != NULL) {        // Check for valid DeviceNr in Package
                PC.printf("Correct Package ID!");

                Current_Position = (uint8_t)(strchr(Data_Buffer, ',') - Data_Buffer);
                Time_Buffer[0] = Data_Buffer[Current_Position + 1];
                Time_Buffer[1] = Data_Buffer[Current_Position + 2];
                Requested_Time = atoi(Time_Buffer);                 // Requested Time by received Package
                memset(Data_Buffer, 0, sizeof(Data_Buffer));        // Clear Data_Buffer

                PC.printf(" - Time: %d\n", Requested_Time);         // Display Requested Time
                PC.printf("------------------------------------\r\n");
                Ticker_ReceiveXBee.detach();

                PC.printf("Measuring ...");
                TimeStamp.reset();          // Reset TimeStamp
                TimeStamp.start();          // Start TimeStamp
                Thread_IMU.start(callback(&queue, &EventQueue::dispatch_forever));      // Start Measurement Thread
                Ticker_IMU.attach_us(queue.event(&ReadIMU), 1000);                      // Attach 1 ms Ticker to Measurement "ReadIMU"
            } else
                PC.printf("Wrong Package ID!\r\n");
        } else
            PC.printf(" - Non-valid Command Delimiter!\r\n");
    } else
        PC.printf(" - Non-valid Package Length!\r\n");
}
//-----------------------------------------------------------------

//-----------------------------------------------------------------
void Setup()
{
    PC.baud(230400);            // Initialize PC Serial Connection
    PC.printf("\r\n------------- Booting! -------------\r\n");
    PC.printf("CPU SystemCoreClock is %d Hz", SystemCoreClock);
    wait(0.5);

    XBee.init();                                // Initialize XBee Serial Connection
    XBee.register_receive_cb(&receive_cb);      // Register Callbacks
    wait(0.5);

    // Initialize IMU SPI Connection
    if(imu.init(1, BITS_DLPF_CFG_188HZ))        // Initialize the MPU9250
        PC.printf("\nCouldn't initialize MPU9250 via SPI!");
    PC.printf("\nWHOAMI = 0x%2x", imu.whoami());                        // Output I2C Address to check SPI (correct: 104 - 0x68)
    PC.printf("\nAcc_Scale = %u\n", imu.set_acc_scale(BITS_FS_16G));    // Set Full Range for Acc.
    imu.calib_acc();        // Calibrate Acceleration Sensor
    wait(0.5);

    // Initialize SD-Card SPI Connection
    mkdir("/sd/Log", 0777);                     // Create 'Log' Directory
    fp = fopen("/sd/Log/Data_Log.txt", "w");    // Create & Open "Data_Log.txt" File

    if(fp == NULL)
        error("File Writing Failed!\n");
    else {
        PC.printf("\nSD-Card Initialized!\n");
    }
    fclose(fp);

    // Display Card Type
    printf("Card type: ");
    SDFileSystem::CardType cardType = sd.card_type();
    if (cardType == SDFileSystem::CARD_NONE)
        printf("None\n");
    else if (cardType == SDFileSystem::CARD_MMC)
        printf("MMC\n");
    else if (cardType == SDFileSystem::CARD_SD)
        printf("SD\n");
    else if (cardType == SDFileSystem::CARD_SDHC)
        printf("SDHC\n");
    else
        printf("Unknown\n");

    // Display Card Capacity
    printf("Sectors: %u\n", sd.disk_sectors());
    printf("Capacity: %.1fMB\n", sd.disk_sectors() / 2048.0);

    TimeStamp.reset();  // Reset Timer TimeStamp
    led1 = 1;           // Turn ON LED to display 'Ready!'
    PC.printf("\r\n------------- Ready! ---------------\r\n");

    Thread_ReceiveXBee.start(callback(&queue, &EventQueue::dispatch_forever));      // Start XBee-Receiving Thread
    Ticker_ReceiveXBee.attach(queue.event(&ReceiveXBee), 0.5);                      // Attach 500 ms Ticker to "ReceiveXBee"
}
//-----------------------------------------------------------------

//-----------------------------------------------------------------
void Reset()            // Reset All Variables
{
    Time_Data = 0;
    Data_Size = 0;
    LineCount = 0;

    readPointer = 0;
    readPointer_MIC = 0;
    writePointer = 0;
    writePointer_MIC = 0;

    ReadIMUDone_Flag = 0;
    WriteSDDone_Flag = 0;
    SendXBeeDone_Flag = 0;

    Requested_Time = 0;
    Current_Position = 0;

    memset(Time_Buffer, 0, sizeof(Time_Buffer));
    memset(Data_Buffer, 0, sizeof(Data_Buffer));
    memset(Data_Storage, 0, sizeof(Data_Storage));
    memset(Data_Storage_MIC, 0, sizeof(Data_Storage_MIC));
}
//-----------------------------------------------------------------

//-----------------------------------------------------------------
int main()
{
    Setup();    // Initial Setups

    while (true) {
        while ((writePointer != readPointer) && (writePointer_MIC != readPointer_MIC) && (ReadIMUDone_Flag == 1)) {
            if (((Requested_Time * 1000) - LineCount) >= 8) {
                for (int i = 0; i < 8; i++) {
                    Data_Size += sprintf(&Data_Buffer[Data_Size], "%d;%d;%d;%d;%d#\n", Data_Storage[readPointer++], Data_Storage_MIC[readPointer_MIC++], Data_Storage[readPointer++], Data_Storage[readPointer++], Data_Storage[readPointer++]);
                    LineCount++;
                }

                txStatus = XBee.send_data_to_coordinator((const uint8_t *) Data_Buffer, Data_Size);
                if (txStatus != XBeeLib::TxStatusSuccess)
                    PC.printf("send_data_to_coordinator() failed with error %d\n", (int) txStatus);
            } else {
                for (int i = 0; i < ((Requested_Time * 1000) - LineCount); i++) {
                    Data_Size += sprintf(&Data_Buffer[Data_Size], "%d;%d;%d;%d;%d#\n", Data_Storage[readPointer++], Data_Storage_MIC[readPointer_MIC++], Data_Storage[readPointer++], Data_Storage[readPointer++], Data_Storage[readPointer++]);
                    LineCount++;
                }

                txStatus = XBee.send_data_to_coordinator((const uint8_t *) Data_Buffer, Data_Size);
                if (txStatus != XBeeLib::TxStatusSuccess)
                    PC.printf("send_data_to_coordinator() failed with error %d\n", (int) txStatus);
            }

            Data_Size = 0;
            memset(Data_Buffer, 0, sizeof(Data_Buffer));    // Clear Data_Buffer
        }

        if ((LineCount >= (Requested_Time * 1000)) && (ReadIMUDone_Flag == 1)) {
            PC.printf(" Done! - Time taken: %d ms\n", TimeStamp.read_ms());
            TimeStamp.stop();

            readPointer = 0;
            readPointer_MIC = 0;
            SendXBeeDone_Flag = 1;

            PC.printf("Writing SD-Card ...");
            fp = fopen("/sd/Log/Data_Log.txt", "w");            // Create & Open "Data_Log.txt" File
            setvbuf(fp, NULL, _IONBF, 0);                       // Set SD-Buffer to "0"
            fprintf(fp, "Time; Mic; AccX; AccY; AccZ#\n");      // Write Header into File
            TimeStamp.reset();
            TimeStamp.start();
        }

        while ((writePointer != readPointer) && (writePointer_MIC != readPointer_MIC) && (SendXBeeDone_Flag == 1)) {
            fprintf(fp, "%d;%d;%d;%d;%d#\n", Data_Storage[readPointer++], Data_Storage_MIC[readPointer_MIC++], Data_Storage[readPointer++], Data_Storage[readPointer++], Data_Storage[readPointer++]);
            WriteSDDone_Flag = 1;
        }

        if ((readPointer == writePointer) && (writePointer_MIC == readPointer_MIC) && (WriteSDDone_Flag == 1)) {
            fclose(fp);
            PC.printf(" Done! - Time taken: %d ms\n", TimeStamp.read_ms());
            PC.printf("------------------------------------\r\n");
            TimeStamp.stop();

            Reset();        // Reset All Variables
            Ticker_ReceiveXBee.attach(queue.event(&ReceiveXBee), 0.5);
        }
    }
}
//-----------------------------------------------------------------