PNI / Mbed 2 deprecated VSG_DataLogger1_VariableSpeed

Dependencies:   SDFileSystemVSG mbed

Fork of VSG_DataLogger1 by PNI

main.cpp

Committer:
jtrojan
Date:
2018-08-16
Revision:
7:f655a9ef12e5
Parent:
6:bd675690d831
Child:
8:9304b2c411e4

File content as of revision 7:f655a9ef12e5:

// VSG Board 18-axes mag Datalogger prototype
// install debug jumper for console output only
// remove debug jumper to log data to SDcard only

// set system parameters -------------------------
#define SAMPLE_RATE     (4)    //Hz
#define SAMPLE_RATE_HIGH (300)    //Hz
#define TMRC_VLOW       (0x99)    // TMRC hex value corresponding to reading/rate
#define TMRC_VHIGH      (0x93)    // TMRC hex value corresponding to reading/rate
#define SAMPLE_PERIOD   (30)      // seconds
#define SAMPLE_DELAY    (5)      // seconds -to allow time to seal unit and place in the field
#define CYCLE_COUNT     (50)
#define PRINT_ALL       (0)     //define whether to print all data at the end or line by line during
#define N_REPEAT_LOW    (1)     //number of times to repeat sample the low speed
#define N_REPEAT_HIGH   (3)     //number of times to repeat sample the high speed
//------------------------------------------------


#include "mbed.h"
#include "SDFileSystem.h"
//          NOTICE: SDFileSystem.cpp was modified. See //JM comments
#include "main.h"
 
#define SAMPLE_INTERVAL (1.0/SAMPLE_RATE)
#define MAX_COUNT       (SAMPLE_PERIOD * SAMPLE_RATE * 4)
#define MCC             ((CYCLE_COUNT >> 8) & 0xff)
#define LCC             (CYCLE_COUNT & 0xff)
#define MAX_MAG_VALUE   (8388608)  // positive 23 bits
#define NEGATIVE_ADJUST (MAX_MAG_VALUE + MAX_MAG_VALUE) //signed 24 bits
#define MAG_SCALE       ((int)(0.3671*(float)(CYCLE_COUNT)+1.5)) //calculation to get out uT

// resource assignments
DigitalIn  rdy1a(DRDY1A);
DigitalIn  rdy1b(DRDY1B);
DigitalIn  rdy1c(DRDY1C);
DigitalIn  rdy2a(DRDY2A);
DigitalIn  rdy2b(DRDY2B);
DigitalIn  rdy2c(DRDY2C);
DigitalIn  debugPin(DEBUG_MODE);

DigitalOut sel1a(SSM1A);
DigitalOut sel1b(SSM1B);
DigitalOut sel1c(SSM1C);
DigitalOut sel2a(SSM2A);
DigitalOut sel2b(SSM2B);
DigitalOut sel2c(SSM2C);

DigitalOut LED(DEBUG_LED);

// sample code from mbed nucleo library
//mbed Declaration left here as example 
AnalogIn analog_value(A0);
DigitalOut selt(LED1);
//ST HAL For ADC since we want to access the internal channels
ADC_HandleTypeDef hadc1;
 
SPI         mag(SPI_MOSI, SPI_MISO, SPI_SCK);
SDFileSystem sd(SD_MOSI, SD_MISO, SD_SCK, SD_CSN, "sd"); // the pinout on the mbed Cool Components workshop board
Serial      console(PA_2, PA_3,115200); // debug port
Ticker      magTimer;
Timer       t;

char takeAsample_F;

void sampletimer() {
    takeAsample_F = 1;
//    printf("*");
}


int main() {
    t.start();
    ADC_ChannelConfTypeDef sConfig;  //Declare the ST HAL ADC object
    
    /**Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion) 
    */
    hadc1.Instance = ADC1;
    hadc1.Init.ClockPrescaler = ADC_CLOCKPRESCALER_PCLK_DIV4;
    hadc1.Init.Resolution = ADC_RESOLUTION12b;
    hadc1.Init.ScanConvMode = DISABLE;
    hadc1.Init.ContinuousConvMode = DISABLE;
    hadc1.Init.DiscontinuousConvMode = DISABLE;
    hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
    hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
    hadc1.Init.NbrOfConversion = 1;
    hadc1.Init.DMAContinuousRequests = DISABLE;
    hadc1.Init.EOCSelection = EOC_SINGLE_CONV;
    HAL_ADC_Init(&hadc1);   //Go turn on the ADC
    
    sConfig.Channel = ADC_CHANNEL_TEMPSENSOR; //ADC_CHANNEL_VREFINT, ADC_CHANNEL_VBAT
    sConfig.Rank = 1;
 
    int response;
    unsigned int count = 0;
    char SDOK;
    char disp_buffer[34*6];
    char big_disp_buffer[10000];
    char disp_char[34];
    int dbuf_size = 0;
    int newslow = 0;
    int X,Y,Z;
    int islow = 0;
    int nhigh = 0;
    int slow_data_ok = 0;
    int nextdatahs = 0;
    float tprev = 0;
    float tnow = 0;
    mag.lock();
//    magTimer.attach(&sampletimer,SAMPLE_INTERVAL);
    
    sel1a = sel1b = sel1c = sel2a = sel2b = sel2c = 1;
    

    printf("\r\nVSG Datalogger\r\n");   
    printf("Timer interval = %f (sec)\r\n",SAMPLE_INTERVAL);
    printf("Cycle Counts = %d \r\n", CYCLE_COUNT);
    
    for(char i=0; i<6; i++) {  //wakeup blink 6 times
        LED = !LED;
        wait(0.1F);
    }
    wait(1.0F);
    
    if (debugPin == 0){
        SDOK = 1;       //initialize
    }

    printf("\r\nOpening log file for append write\r\n");   
    // cannot make fopen conditional on debugPin - compiler does not understand
    FILE *sd = fopen("/sd/sdtest.txt", "a");
    if(sd == NULL) {
        printf("\r\nRetry opening log file\r\n");
        wait(2);
        FILE *sd = fopen("/sd/sdtest.txt", "a");
        if(sd == NULL) {
            printf("\r\n....one more retry opening log file\r\n");
            wait(2);
            FILE *sd = fopen("/sd/sdtest.txt", "a"); 
            if(sd == NULL) {
                printf("\r\n>>>>>> Could not open file for write try restarting\r\n");
                SDOK = 0;
                while(!debugPin); // stay here if in log mode               
            }
        }
    }
    
    
 
    if (SDOK) {
        printf("LOGGING MODE\r\n");
        for(char i=0; i<6; i++) {  //blink 6 times to show logging mode has been initiated
            LED = !LED;
            wait(0.1F);
        }
        //fprintf(sd, "count,temp,X1a,Y1a,Z1a,X1b,Y1b,Z1b,X1c,Y1c,Z1c,X2a,Y2a,Z2a,X2b,Y2b,Z2b,X2c,Y2c,Z2c\r\n");
    }
 
 
    // BIST Built-In-Self-Test Mag senosrs and ASIC
        // only in debug mode. Print axis OK bit flags for ZYX in that order 
    if (debugPin == 1) {
        printf("Starting BIST (7 = all axes on this device are OK)\r\n");

        sel1a = 0;
        response = mag.write(BIST_REG);  // BIST register addr
        response = mag.write(0x8F);     // Set Self test enable bit
        sel1a = 1;
        sel1a = 0;
        response = mag.write(MAG_REG);     // Mag single measurement Register
        response = mag.write(ALL_AXES);    // start single measurement - all Axes
        sel1a = 1;
        while (!rdy1a); 
        sel1a = 0;
        response = mag.write(BIST_REG);     // BIST register addr
        response = mag.write(0);            // Read back BIST results
        sel1a = 1;
        printf("1a = %d\r\n",((response>>4) & 0x07));
        sel1a = 0;
        response = mag.write(BIST_REG);  // BIST register addr
        response = mag.write(0);     // Set Self test enable bit
        sel1a = 1;

    }


    // BIST Complete

    // Set Cycle Count on all 6 devices simultaniously   
    sel1a = 0;
    response = mag.write(CC_REG);     // Mag single measurement Register
    for (char i=0; i<3;i++) {
        response = mag.write(MCC);     
        response = mag.write(LCC);     
    }
    sel1a = 1;


    //if (debugPin) printf("count,temp,X1a,Y1a,Z1a,X1b,Y1b,Z1b,X1c,Y1c,Z1c,X2a,Y2a,Z2a,X2b,Y2b,Z2b,X2c,Y2c,Z2c\r\n");

    // log start delay when Flash card datalogging to give to to button up and place unit
    if (SDOK) { 
        LED = 1; // LED to show logging is in wait phase
        wait(SAMPLE_DELAY); 
    }
    
    sel1a = 0;
    response = mag.write(TMRC_REG);     // Mag continuous measurement Register
    response = mag.write(TMRC_VLOW);     // start continuous measurement - all Axes
    sel1a = 1;

    sel1a = 0;
    response = mag.write(CMM_REG);     // Mag continuous measurement Register
    response = mag.write(ALL_AXES+START_BIT);     // start continuous measurement - all Axes
    sel1a = 1;
    //Now go read the STM internal channel selected above
    //HAL_ADC_ConfigChannel(&hadc1, &sConfig);
    //HAL_ADC_Start(&hadc1); // Start conversion
    

    while (count < MAX_COUNT) {
        
        if (islow < N_REPEAT_LOW) {
            /*if (islow < 1) {
                sel1a = 0;
                response = mag.write(CMM_REG);     // Mag continuous measurement Register
                response = mag.write(0);     // start continuous measurement - all Axes
                sel1a = 1;
                sel1a = 0;
                response = mag.write(TMRC_REG);     // Mag continuous measurement Register
                response = mag.write(TMRC_VLOW);     // start continuous measurement - all Axes
                sel1a = 1;
                sel1a = 0;
                response = mag.write(CMM_REG);     // Mag continuous measurement Register
                response = mag.write(ALL_AXES+START_BIT);     // start continuous measurement - all Axes
                sel1a = 1;
            }*/
            islow++;
            if (islow == N_REPEAT_LOW) nhigh = 0;
            nextdatahs = 0;
            //printf("low");
        } else {
            if (nhigh < 1) {
                wait_us(1100);
                sel1a = 0;
                response = mag.write(CMM_REG);     // Mag continuous measurement Register
                response = mag.write(0);     // start continuous measurement - all Axes
                sel1a = 1;
                sel1a = 0;
                response = mag.write(TMRC_REG);     // Mag continuous measurement Register
                response = mag.write(TMRC_VHIGH);     // start continuous measurement - all Axes
                sel1a = 1;
                sel1a = 0;
                response = mag.write(CMM_REG);     // Mag continuous measurement Register
                response = mag.write(ALL_AXES+START_BIT);     // start continuous measurement - all Axes
                sel1a = 1;
            }
            nhigh++;
            if (nhigh == N_REPEAT_HIGH) islow = 0;
            nextdatahs = 1;
            //printf("high");            
        }
        
        tprev = t.read(); //time at start of loop
        while (!(slow_data_ok)) {
            while (!(rdy1a)) {
                wait_us(10); // required
                // spin here until all Data Ready signals go high
            }
            tnow = t.read();            
            if ((nextdatahs) || ((tnow - tprev) > (0.5*SAMPLE_INTERVAL))) {
                slow_data_ok = 1; // check if in hs mode or enough time has passed
            } else { //remove unused data
                sel1a = 0;
                response = mag.write(MX_REG); 
                response = mag.write(0);
                sel1a = 1;
            }
        }
        slow_data_ok = 0; // reset for next data point 
        /*while(!takeAsample_F){
             wait_us(10); // required
        }*/
        takeAsample_F = 0;

        // Wait end of conversion and get value
        //if (HAL_ADC_PollForConversion(&hadc1, 10) == HAL_OK) {
        //uint16_t value = HAL_ADC_GetValue(&hadc1); //}
        uint16_t value = 0;
        //Now go read the STM internal channel selected above
        //HAL_ADC_Start(&hadc1); // Start conversion
        
        sel1a = 0;
        response = mag.write(MX_REG);     // Read back mag data
        response = mag.write(0);
        X = response << 16;
        response = mag.write(0);
        X += (response << 8);
        response = mag.write(0);
        X += response;
        response = mag.write(0);
        Y = response << 16;
        response = mag.write(0);
        Y += (response << 8);
        response = mag.write(0);
        Y += response;
        response = mag.write(0);
        Z = response << 16;
        response = mag.write(0);
        Z += (response << 8);
        response = mag.write(0);
        Z += response;
        sel1a = 1;
        
        newslow = 0;
        if (islow < 1) {
            sel1a = 0;
            response = mag.write(CMM_REG);     // Mag continuous measurement Register
            response = mag.write(0);     // start continuous measurement - all Axes
            sel1a = 1;
            sel1a = 0;
            response = mag.write(TMRC_REG);     // Mag continuous measurement Register
            response = mag.write(TMRC_VLOW);     // start continuous measurement - all Axes
            sel1a = 1;
            sel1a = 0;
            response = mag.write(CMM_REG);     // Mag continuous measurement Register
            response = mag.write(ALL_AXES+START_BIT);     // start continuous measurement - all Axes
            sel1a = 1;
            newslow = 1;
        }

        // send/save data after receiving it
        if (X > (0x07FFFFF)) X -= 0x1000000;
        if (Y > (0x07FFFFF)) Y -= 0x1000000;
        if (Z > (0x07FFFFF)) Z -= 0x1000000;


        if (SDOK) {
            sprintf(disp_char,"%d,%0.4f,%i, %d,%d,%d\r\n",count,t.read(),value,X,Y,Z);
        } else {
            sprintf(disp_char,"%d,%0.4f,%i, %d,%d,%d\r\n",count,t.read(),value,X,Y,Z);
        }
        
        if (PRINT_ALL == 1) {
            if (count == 0) {// print everything at once
                strcpy(big_disp_buffer,disp_char);
            } else {
                strcat(big_disp_buffer,disp_char);
                //printf("%i ",count);
            }
        } else {
            if ((islow == 1) && (nextdatahs == 0)) {// reset at each slow interval
                strcpy(disp_buffer,disp_char);
            } else {
                strcat(disp_buffer,disp_char);
            }
            if (islow == 0) { //print at end of fast intervals
                if (debugPin) { //SDOK
                    printf("%s",disp_buffer);
                } else {
                    fprintf(sd,"%s",disp_buffer);
                    printf("%s",disp_buffer);
                }
            }
        }

        //printf("%s",disp_char);
        count++;
        LED = !LED;

    } // end of while(1)
    
    if (PRINT_ALL) {
        if (debugPin) { //SDOK
            printf("%s",big_disp_buffer);
        } else {
            fprintf(sd,"%s",big_disp_buffer);
            printf("%s",big_disp_buffer);
        }
    }


    if (!debugPin) {
// optional get SDCard  available space      
//            FATFS* fs;
//            DWORD fre_clust;
//            f_getfree("0:",&fre_clust,&fs);
//            const float frs = float(fs->csize)*float(fs->free_clust)
//        #if _MAX_SS != 512
//                *(fs->ssize);
//        #else
//                *512;
//        #endif
//            printf("free space = %g MB, %g KB\r\n", frs/1048576.0, frs/1024.0);

        fclose(sd);
        
    }
    
    LED = 0;
    printf("\r\nDONE\r\n");

    magTimer.detach();
    mag.unlock();
    t.stop();
}