Dirty little program to grab analog sensor data, apply a 3-tap median filter, and log it to a local flash file.

Dependencies:   mbed

main.cpp

Committer:
leimgrub
Date:
2010-01-04
Revision:
0:b7581833f14a

File content as of revision 0:b7581833f14a:

#include "mbed.h"

/***************************
* John W. Leimgruber III
* Test Application
* 1. Read analog value from LM34 temperature sensor and convert to deg Fahrenheit
* 2. Filter using 3-tap median sampling every 1/3 second
* 3. Append to local flash filesystem log file every 512 seconds
* 4. Externally, use a python program I wrote based on matplotlib to grab and parse updated log file then display graphical plot
*****************************/

DigitalOut myled(LED1); // sanity test light
Serial pc(USBTX, USBRX); // beautiful debugging tx, rx to Linux and Minicom @ /dev/ttyACM0 9600 8N1
AnalogIn temp(p15);    // analog temperature sensor, LM34, reads +5 to +300 degF @ 10mv per deg and takes 5-30v Vin...

LocalFileSystem local("local"); // setup local filesystem on the ~2mb internal flash
Timer timer; // timer to generate delays, as I'm newbish and don't know about wait

int main() 
{
    printf("Starting to read and log temperature data to local flash disk.\r\n"); 
    char *tempData, filter[3];
    unsigned int dataCount, filterCount;
    FILE *fp = 0;
    dataCount = 0;
    filterCount = 0;
    memset(filter, 3, 0x00);

    // allocate 512 bytes of memory to store 512 seconds worth of temperature values at one per second stored in deg F [0,255]      
    tempData=(char *) malloc(512);
    if (!tempData)
    {
      fprintf(stderr, "Not enough memory to allocate 512 bytes for temperature data\n");
      exit(1);
    }

    timer.reset();
    timer.start();
    while(1)
    {    
      //grab a temp reading ever second and convert to 0-255 in deg F
      if(timer.read() > 0.333)
      { // implement 3 tap median filter and oversample by 3x
        filter[0] = filter[1];
        filter[1] = filter[2];
        filter[2] = (char) (temp.read() * 330.0 - 5.0);
        filterCount++;

        if(filterCount >= 3)
        {
          filterCount = 0;
          if(filter[0] >= filter[1] && filter[0] <= filter[2] ||
             filter[0] <= filter[1] && filter[0] >= filter[2])
          {
            tempData[dataCount] = filter[0];
          }
          else if(filter[1] >= filter[0] && filter[1] <= filter[2] ||
                  filter[1] <= filter[0] && filter[1] >= filter[2])
          {
            tempData[dataCount] = filter[1];
          }
          else
          {
            tempData[dataCount] = filter[2];
          }
          // in case you want to grab some 'real-time' temp data and debugging...                 
          printf("Temperature [%d] = %d deg F\r\n",dataCount, tempData[dataCount]);
          dataCount++;
        }
        timer.reset();
      }

      // now that we've grabbed a full page of data, dump it do disk then start over...
      if(dataCount >= 512)
      {
        myled = 1;
        fp = fopen("/local/templog.dat", "ab");
        if(!fp)
        {
          printf("File /local/templog.dat could not be opened for append binary writing!\r\n");
          exit(1);
        }
        printf("Writing %d bytes to internal flash!\r\n", dataCount); // should always be 512 bytes? (maybe should keep writing until 512 hit... meh)
        printf("Actually wrote %d bytes...\r\n", fwrite(tempData,1,dataCount,fp)); //memory array, sizeof(char), 512 bytes, file pointer
        fclose(fp);
        dataCount = 0;
        myled = 0;
      }
    }
}