Communication with LDC1101. Working version, ready for extensive calibration tests for resolution, linearity, etc.

Dependencies:   Bob DS1825 LDC1101 SDFileSystem mbed

Fork of Inductive_Sensor by Bob Giesberts

main.cpp

Committer:
bobgiesberts
Date:
2016-03-30
Revision:
11:599ca9982e45
Parent:
10:3cab80866536
Child:
12:cceece4f3afb

File content as of revision 11:599ca9982e45:

/**
* @file main.cpp
* @brief This file programs the processor for the inductive force sensor
* using the library LDC1101.h and LDC1101.cpp.
* - Red Led: processing communication with LDC1101
* - Green Led: processing SD card
*
* Log protocol:
* -  1 minute  at 20 Hz
* - 29 minutes rest
*
* @author Bob Giesberts
*
* @date 2015-12-17
*/
#include "mbed.h"
#include "LDC1101.h"        // inductive force sensor
#include "SDFileSystem.h"   // control the SD card
#include "Bob.h"            // processorboard
#include "DS1825.h"         // thermometer

#include <iostream>
#include <vector>
#include <string>
using namespace std;

// SETTINGS
bool DEBUG = false;
float C = 120E-12;      // pF
uint16_t INTERVAL_FIRST = 600; // 5 sec
uint16_t INTERVAL_OFF   = 870; // 1770 = 29*60+30 sec
uint16_t INTERVAL_ON    = 30; //   30 =       30 sec

// load libraries
Bob bob(PTB0, PTB1, PTC3, PTE0, PTC2, PTE30); // red led, green led, sd_enable, sd_present, batt, 3V3_DET
Serial pc(USBTX, USBRX);

// timer variables
uint32_t now = 0, next = 0, prev = 0;
uint8_t t_high = 0;
uint32_t t_lost = 0, lost_prev = 0;
uint8_t lost_high = 0;
uint32_t t_sleep = 0;

// file variables
FILE *fp;
string filename = "/sd/data00.txt";
const char *fn;

// temperature variables
PinName _Tpin = PTB1;      // Thermometer is connected to the original pin for the RED / GREEN LED
uint8_t Tdata[9];
int16_t T_bin;
float T;

// temporal storage for data samples
const uint8_t package_size = 16;     // Write is per 512 bits: 16 * 32 = 512
uint32_t tarray[package_size];
uint32_t t;
uint32_t Larray[package_size];
float batt;

int main(void)
{
    if( DEBUG )
    {
        LDC1101 *ldc = new LDC1101(PTC6, PTC7, PTC5, PTC4, C, 16E6);
        DS1825 *thermometer = new DS1825( _Tpin );
        wait(1);
        while(1)
        {
            while( !ldc->is_New_LHR_data() ) { } // wait until data is ready
            
            // T = thermometer->getTemperature();                      
            pc.printf( "%d", ldc->get_LHR_Data() );
            //pc.printf( "%.3f MHz", ldc->get_fsensor()/1000000 );
            pc.printf( "\r\n" );
            wait( 1 ); // 20 Hz
        }
    }

    // Provide some feedback, is it working?
    //bob.flash(2);

    // Load SD File system
    bob.wakeup();
    SDFileSystem *sd = new SDFileSystem(PTD6, PTD7, PTD5, PTD4, "sd");

    // Create a new data file (data00.txt)
    mkdir("/sd", 0777);
    for(uint8_t i = 0; i < 100; i++)
    {
        filename[8] = i/10 + '0';
        filename[9] = i%10 + '0';
        fp = fopen( filename.c_str() , "r" );
        if( fp == NULL ) // read failed so file does not exist
        {
            fp = fopen( filename.c_str(), "w" ); // create it
            if( fp != NULL )
            {
                fn = filename.c_str();
                fclose( fp );
                break;
            } else {
                bob.red();
            }
        } else { // file already exists
            fclose( fp );
        }
    }
    if( fp == NULL )
    {
        pc.printf( "/sd/data00.txt t/m /sd/data99.txt already exist!\n" );
    }

    // Unload SD File system
    delete sd;
    sd = NULL;



    while(1)
    {
        // Wakeup: SD + LDC1101 on
        bob.wakeup();

        // what time is it now?
        prev = now;                                                     // 0 -> 429 496     --> (4 294,96 s)        (71 min)
        now = (uint32_t) clock();                                       // 0 -> 429 496     --> (4 294,96 s)        (71 min)
        if( now < prev )
            t_high++;                                                   // 0 -> 255         --> (255*4 294,96 s)    (12 days)
        t = now + 429496.7296*t_high + t_lost + 429496.7296*lost_high;  // 0 -> 219 901 952 --> (2 199 019,52 s)    (25 days)
        
        // load libraries to take control over the communication        
        LDC1101 *ldc = new LDC1101(PTC6, PTC7, PTC5, PTC4, C, 16E6);        // load sensor (LDC1101) library (this takes 0.81 s)
        DS1825 *thermometer = new DS1825( _Tpin );                          // load thermometer (DS1825) library
        SDFileSystem *sd = new SDFileSystem(PTD6, PTD7, PTD5, PTD4, "sd");  // load SD system on
            mkdir("/sd", 0777); // select folder

        // first time take a comfortably long period
        if( next == 0 )
        {
            next = t + INTERVAL_FIRST*100;
        } else {
            next = t + INTERVAL_ON*100;                                 // 0 -> 219 904 952 --> (2 199 049,52 s)    (25 days)
        }

        // Take samples for INTERVAL_ON seconds
        while( t < next )
        {
                           
            // Collect a package of data points
            int i = 0; 
            while( i < package_size )
            {
                // wait for new data to be ready
                while( !ldc->is_New_LHR_data() ) { }

                // what time is it now?
                prev = now;
                now = (uint32_t) clock();
                if( now < prev ) 
                    t_high++;
                t = now + 429496.7296*t_high + t_lost + 429496.7296*lost_high;

                if( !ldc->is_Oscillation_Error() ) // sensor not overloaded, this happends when the target is too close to the coil
                {
                    // Store data in temporal memory
                    tarray[i] = t;
                    Larray[i] = ldc->get_LHR_Data();
                    i++;
                }
            }
   
            // get battery level
            batt = bob.battery();
           
            // get temperature
            T = thermometer->getTemperature();           

            // Store the package of data points
            // TODO: create a queue with all the data (t, L, Vbatt, T)          --> (Queue<data> queue)
            // TODO: process this data in packages of 16 in a seperate Thread   --> (RTOS?)
            bob.red();
            fp = fopen( fn, "a" );      // open file (append)
            for( int i = 0; i < package_size; i++ )
               fprintf( fp, "%.2f;%d;%.4f;%.4f\r\n", (float) tarray[i]/100.0, Larray[i], batt, T ); // write to file
            fclose( fp );               // close file
            bob.redoff();
            
            
            
            // Print to PC for debugging
            pc.printf( "%.2f;%d;%.4f;%.4f\r\n", (float) tarray[0]/100.0, Larray[0], batt, T ); // write to console
            
            // Reset data
            memset(tarray, 0, package_size);
            memset(Larray, 0, package_size);

            // if the battery is almost empty (Vbatt < 3.10 V), the termometer stops 
            // working well and L can not be corrected. So just shut down
            if( batt < 3.10f )
            {
                bob.red();
                exit(0);
            }
            
        }

        // prepare for sleep, power down the SD and the LDC1101
        delete sd;          sd  = NULL;
        delete ldc;         ldc = NULL;
        delete thermometer; thermometer = NULL;
        bob.greenoff();                             // in current system the thermometer is connected to the old green led. Turning it off might power it down? Well 1,1V remains. So this doesn't work as expected
        bob.beforesleep();

        // what time is it now?
        prev = now;
        now = (uint32_t) clock();
        if( now < prev ) 
            t_high++;
        t = now + 429496.7296*t_high + t_lost + 429496.7296*lost_high;

        // Calculate sleeping time (correction to INTERVAL_OFF)
        // S has passed the limit of next. Those few ms should be substracted from INTERVAL_OFF.
        t_sleep = INTERVAL_OFF*100 - (t - next);

        // Add lost time to the counter
        lost_prev = t_lost;
        t_lost += t_sleep;
        if( t_lost < lost_prev ) 
            lost_high++;

        // Sleep now (ms), enter low power mode
        bob.sleep( t_sleep * 10 );

    }

}