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.
any thoughts or guidance appreciated.
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.
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
Post a Comment