Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: Bob DS1825 LDC1614 LDC1101 SDFileSystem mbed
Fork of Inductive_Sensor by
main.cpp
- Committer:
- bobgiesberts
- Date:
- 2016-08-24
- Revision:
- 16:b53721840a38
- Parent:
- 15:5de8394fdb3c
- Child:
- 17:a4700b1c3c37
File content as of revision 16:b53721840a38:
/**
* @file main.cpp
* @brief This file programs the processor for the inductive force sensor
* using the library LDC1614.h and LDC1614.cpp.
* - Green Led: processing communication with LDC1614
* - Red Led: error
*
* Log protocol:
* - 0:30 minutes at 13 Hz
* - 14:30 minutes rest
*
* @author Bob Giesberts
*
* @date 2016-08-23
*/
#include "mbed.h"
#include "LDC1614.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; // Capacitor in F
int sensors = 2; // number of attached sensors
uint16_t INTERVAL_FIRST = 3600; // First sampling time in seconds. 60:00 minutes = 3600 sec
uint16_t INTERVAL_OFF = 870; // Waiting interval in seconds. 14:30 minutes = 870 sec (14*60+30)
uint16_t INTERVAL_ON = 30; // Sampling interval in seconds. 0:30 minutes = 30 sec
// Leds
PinName _LED_PROCESS = PTB1; // Green led (PTB0 for the first sensor) // old = new: PTB1
PinName _LED_ERROR = PTB0; // Red led // new: PTB0;
// Thermometer
PinName _Tpin = PTC1; // OneWire system (PTB1 for the first sensor) // old = PTB0, new: PTC1
// LDC1614
PinName _LDC_SDA = PTC5; // I2C: SDA
PinName _LDC_SCL = PTC4; // I2C: SCL
PinName _LDC_SD = PTC6; // Shutdown
// SD File system
PinName _SD_ENABLE = PTC3;
PinName _SD_PRESENT = PTE0; // card detect // old = new: PTE0
PinName _SD_MOSI = PTD6; // mosi // old = new: PTD6
PinName _SD_MISO = PTD7; // miso // old = new: PTD7
PinName _SD_SCLK = PTD5; // sclk // old = new: PTD5
PinName _SD_CS = PTD4; // cs // old = new: PTD4
// Other components
PinName _OSCILLATOR = PTC3;
PinName _BATTERY = PTC2; // voltage // old = new: PTC2
PinName _BUTTON = PTA4;
// load libraries
Bob bob( _LED_PROCESS, _LED_ERROR, _BUTTON, _SD_PRESENT, _BATTERY );
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;
uint32_t t;
// file variables
FILE *fp;
string filename = "/sd/data00.txt";
const char *fn;
// temperature variables
uint8_t Tdata[9];
int16_t T_bin;
float T;
// temporal storage for data samples
const uint8_t package_size = 60; // ±12-13 Hz, so 60 would take about 5 sec.
struct mydata {
uint32_t t[package_size]; // time (s)
uint32_t L[package_size]; // LHR_DATA
} collected;
uint8_t counter = 0;
uint8_t status;
// function to write all data to the SD card
void storeit( float T )
{
// TODO: writing to SD card more efficient!
// t 32-bit | 0.00 2000000.00 3-10x8-bit | FFFFFFFF 8x8
// L 24-bit | 0 1677216 6- 7x8-bit | FFFFFF 6x8
// V 8-bit | 3.10 4.20 4x8-bit | FF 2x8
// T 16-bit | -20.0000 85.0000 7x8-bit | FFFF 4x8
// construct data
/*
bob.ledon();
// fp = fopen( fn, "a" ); // open file (append)
char buffer[16]; memset(buffer, 0, sizeof(buffer));
char towrite[64]; memset(towrite, 0, sizeof(towrite));
int n = 0, m = 0;
for( int i = 0; i < counter; i++ )
{
for( int j = 0; j < 4; j++ )
{
// build up next 'word'
switch(j)
{
case 0: n = sprintf(buffer, "%.2f;", (float) collected.t[i]/100.0); break;
case 1: n = sprintf(buffer, "%d;", collected.L[i]); break;
case 2: n = sprintf(buffer, "%.2f;", bob.battery()); break;
case 3: n = sprintf(buffer, "%.4f\r\n", T); break;
}
// calculate if there is still room left for that word
if( strlen(towrite) + n > 64 )
{
// pc.printf( "%s", towrite);
fp = fopen( fn, "a" ); // open file (append)
fprintf( fp, "%s", towrite);
fclose( fp ); // close file
memset(towrite, 0, sizeof(towrite));
}
// build up letter with the next word
m = sprintf(towrite, "%s%s", towrite, buffer);
}
}
if(m > 0)
{
fp = fopen( fn, "a" ); // open file (append)
fprintf( fp, "%s", towrite);
fclose( fp ); // close file
//pc.printf( "%s", towrite);
}
//fclose( fp ); // close file
bob.ledoff();
*/
// write data to SD card
bob.ledon();
fp = fopen( fn, "a" ); // open file (append)
for( int i = 0; i < counter; i++ )
fprintf( fp, "%.2f;%d;%.2f;%.4f\r\n", (float) collected.t[i]/100.0, collected.L[i], bob.battery(), T ); // write to file
fclose( fp ); // close file
// write to screen
//pc.printf( "%.2f;%d;%.2f;%.4f\r\n", (float) collected.t[counter-1]/100.0, collected.L[counter-1], bob.battery(), T ); // write to screen
bob.ledoff();
// Reset data
memset(collected.t, 0, counter);
memset(collected.L, 0, counter);
counter = 0;
}
int main(void)
{
if( DEBUG )
{
Serial pc( USBTX, USBRX );
LDC1614 ldc( _LDC_SDA, _LDC_SCL, _LDC_SD, _OSCILLATOR, 16E6, sensors, C );
uint8_t status;
while( 1 ) {
// check the sensor
status = ldc.get_status();
// if there is an error turn on the red led
if( ldc.is_error( status ) )
{
// error
// bob.error();
}else{
if( ldc.is_ready( status ) )
{
//bob.no_error();
pc.printf( "sensor 1: %d | sensor 2: %d\r\n", ldc.get_Data( 0 ), ldc.get_Data( 1 ) );
}
}
}
}
// TODO:
// - implement this data conversion in writing to SD!!
// - use T as uint16_t, not float!
// - use V as uint16_t, not float!
// - write blocks of 512 bit (4x 32 + 32 + 16 + 16)
//
// float temp_a = 127.9375;
// pc.printf( "A: %.4f (%08x); \r\n", temp_a, * (uint32_t *) &temp_a);
// Load SD File system
// - the Raspberry Pie SD cards give a warning here that might just be ignored:
// "Not in idle state after sending CMD8 (not an SD card?)
// Didn't get a response from the disk
// Set 512-byte block timed out"
// TODO: buy 'better' SD cards from IAPC / the Stores (Kingston ...)
bob.wakeup();
SDFileSystem *sd = new SDFileSystem( _SD_MOSI, _SD_MISO, _SD_SCLK, _SD_CS, "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.ledon(); // error: unable to create new file
}
} else { // file already exists
fclose( fp );
}
}
if( fp == NULL )
{
bob.ledon(); // error: file 00 - 99 already exists
// 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
LDC1614 *ldc = new LDC1614(_LDC_SDA, _LDC_SCL, _LDC_SD, _OSCILLATOR, 16E6, sensors, C);
DS1825 *thermometer = new DS1825( _Tpin ); // load thermometer (DS1825) library
SDFileSystem *sd = new SDFileSystem(_SD_MOSI, _SD_MISO, _SD_SCLK, _SD_CS, "sd"); // load SD system
mkdir("/sd", 0777); // select folder
// How long should we takes samples?
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 )
{
// 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;
status = ldc->get_status();
// Is there any error?
if( ldc->is_error(status) )
{
// red led on
// bob.error();
}else{
// red led off
// bob.no_error();
if( ldc->is_ready(status) ) // data from all sensors is ready
{
// Store data in temporal memory
collected.t[counter] = t;
collected.L[counter] = ldc->get_Data( 0 );
counter++;
// Write a full package of data points to the SD card
if( counter >= package_size-1 )
storeit( thermometer->getTemperature() );
}
}
}
// Write remaining data to the SD card
if( counter > 0 )
storeit( thermometer->getTemperature() );
// prepare for sleep, power down the SD and the LDC1101
delete sd; sd = NULL; // unload library to be able to power down completely
delete ldc; ldc = NULL; // unload library to be able to power down completely
delete thermometer; thermometer = NULL; // unload library to be able to power down completely
bob.beforesleep();
// if the battery is almost empty (Vbatt < 3.10 V), the thermometer stops
// working well and L can not be corrected. So just shut down...
if( bob.battery() < 3.10f )
{
bob.ledon(); // error: battery empty
// pc.printf( "Battery empty (%.1f V), shutting down.\n", bob.battery() );
exit(0);
}
// 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)
// t has passed the limit of next. Those few ms are substracted from INTERVAL_OFF.
t_sleep = INTERVAL_OFF*100 - (t - next);
// Calculate time that will be lost during sleep
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 );
}
}
