Low Power Logger - Adafruit Featherlogger M0 and LSM9DS0


i'm working on datalogger track movements of birds , looking guidance. able sample @ 50hz 18hrs , extend battery beyond 24hrs. using 350mah battery because weight factor, go bigger. there programming standpoint reduce power consumption? using adafruit featherlogger m0 lsm9ds0 sensor.
code: [select]

/*
 connections (uses spi)
 note: m0 9ds0
 connect pin 24 scl
 connect pin 22 sdog , sdoxm (miso)
 connect pin 23 sda (mosi)
 connect pin 10 csxm
 connect pin 09 csg
 connect 3v 3v3 (could go vin)
 connect gnd gnd
*/

#include <rtczero.h>
#include <spi.h>
#include <sdfat.h>
sdfat sd;
#include <wire.h>
#include <adafruit_sensor.h>
#include <adafruit_lsm9ds0.h>

#define lsm9ds0_xm_cs 10
#define lsm9ds0_gyro_cs 9
//hardware spi (creates unique sensor id)
adafruit_lsm9ds0 lsm = adafruit_lsm9ds0(lsm9ds0_xm_cs, lsm9ds0_gyro_cs, 1000);

#define cardselect 4  // set pin usd
#define red 13 // red led pin #13
#define green 8 // green led pin #8
#define vbatpin a7    // bat volt pin a7

// number of samples buffer before flush called.
#define samplespercycle 10000
// number of lines of data per file
#define samplesperfile 60000

byte hours = 1;
byte minutes = 1;
byte seconds = 1;
byte day = 1;
byte month = 1;
byte year = 17;
// variable used keep track of changes in seconds, minutes, hours, days, months
byte timekeeper = 0;
// delay adjust sampling rate
// 20ms = ~30hz
// 11ms = ~50hz
// 0ms = ~100hz
byte samplingratedelay = 11;

rtczero rtc;
file logfile;
file settingsfile;
char filename[16];    // array file name data logged named in setup
char settingsfilename[15];    // array file name of settings file log settings of deployment
float measuredvbat;   // variable battery voltage
unsigned int currentcyclecount;  // num of samples in current cycle, before usd flush call
unsigned int currentfilecount;   // num of samples in current file
unsigned long milli; //used store milliseconds since program started

void setup() {
  //  setup rtc , set time
  rtc.begin();
  rtc.settime(hours, minutes, seconds);
  rtc.setdate(day, month, year);

  strcpy(filename, "analog000.csv");  
  strcpy(settingsfilename, "initval00.txt");  
  /* initialise sensor */
  if(!lsm.begin())
  {
    while(1);
  }
  lsm.setupaccel(lsm.lsm9ds0_accelrange_2g);
  lsm.setupmag(lsm.lsm9ds0_maggain_2gauss);
  lsm.setupgyro(lsm.lsm9ds0_gyroscale_245dps);
  createsettingsfile();
  createfile();
}  

void loop() {
  currentcyclecount += 1; //  increment samples in current usd flush cycle
  currentfilecount += 1; // increment samples in current file
  writetosd(); // output usd card stream

  //  code limit number writes usd
  if( currentcyclecount >= samplespercycle ) {
    logfile.flush(); //is power hungry?
    currentcyclecount = 0;
  }

  // code increment files limiting number of lines in each
  if( currentfilecount >= samplesperfile ) {
    if (logfile.isopen()) {
      logfile.close();
    }
    createfile();
    currentfilecount = 0;
  }
}

//capture sensor settings, sampling rate, associated log files , battery status
void createsettingsfile(void)
{  
  if (!sd.begin(cardselect)) {
    error(2);     // 2 red flashes means no card or init failed.
  }
  //increments value of ## in filename (max 99)
  for (uint8_t = 0; < 100; i++) {
    settingsfilename[7] = '0' + i/10;
    settingsfilename[8] = '0' + i%10;
    if (! sd.exists(settingsfilename)) {
      break;
    }
  }  
  settingsfile = sd.open(settingsfilename, file_write);
  writedeploymentdetails();
  if( ! settingsfile ) {
    error(3);
  }
  settingsfile.close();
}

// create new log file
void createfile()
{
  if (!sd.begin(cardselect)) {
    error(2);     // 2 red flashes means no card or init failed.
  }
  //increments value of ### in filename (max 999)
  for (uint8_t = 0; < 1000; i++) {
    filename[6] = '0' + i/100;
    filename[7] = '0' + (i%100)/10;
    filename[8] = '0' + i%10;
    if (! sd.exists(filename)) {
      break;
    }
  }  
  //log newly created file name settings file
  settingsfile = sd.open(settingsfilename, file_write);
  settingsfile.print(filename);
  // giving 5v bat voltage, not sure why
  settingsfile.print(" battery voltage: "); settingsfile.println(batteryvoltage ());
  settingsfile.close();
  delay(10);
  logfile = sd.open(filename, file_write);
  writeheader();
  if( ! logfile ) {
    error(3);
  }
}

// write data header file of usd.
void writeheader() {
  logfile.println("yyyy-mm-dd hh:mm:ss,timestamp(ms),accelx,accely,accelz,magx,magy,magz,gyrx,gyry,gyrz,temp");
}

// print data , time followed battery voltage sd card
void writetosd() {

  sensors_event_t accel, mag, gyro, temp;
  lsm.getevent(&accel, &mag, &gyro, &temp);  

  // formatting file output yyyy-mm-dd hh:mm:ss
  timekeeper = rtc.getseconds();
  if(seconds != timekeeper) {
    seconds = timekeeper;
    timekeeper = rtc.getminutes();
    if(minutes != timekeeper){
      minutes = timekeeper;
      blink(red,3);
      timekeeper = rtc.gethours();
      if(hours != timekeeper){
        hours = timekeeper;
        timekeeper = rtc.getday();
        if(day != timekeeper){
          day = timekeeper;
          timekeeper = rtc.getmonth();
          if(month != timekeeper){
            month = timekeeper;
          }
        }
      }
    }
  }
  //how happen in fewer print calls
  //is stringbuffer better option?
  logfile.print("20");
  logfile.print(year);  
  logfile.print("-");
  logfile.print(month);
  logfile.print("-");
  logfile.print(day);
  logfile.print(" ");
  logfile.print(hours);
  logfile.print(":");
  if(minutes < 10)
    logfile.print('0');      
  logfile.print(minutes);
  logfile.print(":");
  if(seconds < 10)
    logfile.print('0');      
  logfile.print(seconds); logfile.print(",");
  // sensor timestamp
  logfile.print(accel.timestamp); logfile.print(",");
  // print accelleration data log file:
  logfile.print(accel.acceleration.x); logfile.print(",");
  logfile.print(accel.acceleration.y); logfile.print(",");
  logfile.print(accel.acceleration.z); logfile.print(",");
  // print magnetometer data log file:
  logfile.print(mag.magnetic.x); logfile.print(",");
  logfile.print(mag.magnetic.y); logfile.print(",");
  logfile.print(mag.magnetic.z); logfile.print(",");
  // print gyroscopic data log file:  
  logfile.print(gyro.gyro.x); logfile.print(",");
  logfile.print(gyro.gyro.y); logfile.print(",");
  logfile.print(gyro.gyro.z); logfile.print(",");
  // print temperature data
  logfile.println(temp.temperature);

  delay(samplingratedelay);

}

// blink out error code
void error(uint8_t errno) {
  while(1) {
    uint8_t i;
    for (i=0; i<errno; i++) {
      digitalwrite(13, high);
      delay(100);
      digitalwrite(13, low);
      delay(100);
    }
    for (i=errno; i<10; i++) {
      delay(200);
    }
  }
}

// blink out error code, red on pin #13 or green on pin #8
void blink(uint8_t led, uint8_t flashes) {
  uint8_t i;
  for (i=0; i<flashes; i++) {
    digitalwrite(led, high);
    delay(100);
    digitalwrite(led, low);
    delay(100);
  }
}

// measure battery voltage using divider on feather m0
float batteryvoltage () {
  measuredvbat = analogread(vbatpin);   //measure battery voltage @ pin a7
  measuredvbat *= 2;    // divided 2, multiply back
  measuredvbat *= 3.3;  // multiply 3.3v, our reference voltage
  measuredvbat /= 1024; // convert voltage
  return measuredvbat;
}

// writes txt file setting
void writedeploymentdetails(void)
{
  settingsfile.print("init. time: ");
  settingsfile.print("20");
  settingsfile.print(year);
  settingsfile.print("/");
    settingsfile.print(month);
  settingsfile.print("/");
    settingsfile.print(day);
  settingsfile.print(" ");
  settingsfile.print(hours);
  settingsfile.print(":");
  if(minutes < 10)
    settingsfile.print('0');
  settingsfile.print(minutes);
  settingsfile.print(":");
  if(seconds < 10)
    settingsfile.print('0');
  settingsfile.println(seconds);  
  settingsfile.print("sampling rate delay: ");
  settingsfile.println(samplingratedelay);
  settingsfile.print("num of samples before flush: ");
  settingsfile.println(samplespercycle);
  settingsfile.print("num of samples per csv: ");
  settingsfile.println(samplesperfile);
  settingsfile.println(f("log files , bat.volt:"));
}


any thoughts or guidance appreciated.  

check out :https://learn.adafruit.com/adafruit-feather-m0-adalogger/power-management

if can avoid flushing save around 25% in case.


Arduino Forum > Using Arduino > Project Guidance > Low Power Logger - Adafruit Featherlogger M0 and LSM9DS0


arduino

Comments

Popular posts from this blog

DHT11 Time out error using v0.4.1library

Sketch upload fails with Java error (___REMOVE___/bin/avrdude)!

Arduino Uno + KTY81/210 temperature sensor