Hi,
So I couldn't get my head around SPI flash, so I give up and went back to the microsd card.
Implementing a few sleep techniques I managed to get it to run on the coin battery, but it only ran for half an hour. The coin battery had the capacity, but couldn't absorb the sudden writes to sd.
it sleeps at around 2ma and jumps to I think 15ma while writing to sd. I have a basic multimeter so I'm not sure if I'm catching the peak ma at write.
Anyhow I decided to add a small 3.3v regulator to the circuit and used a 100ma lipo battery, and hey presto, it worked. 24 hours of continuous accelerometer readings. Around 2 million data points. I'm over the moon with this because the lipo is only 20x20x3mm, which is about the same as the coin battery.
Now to see how much more I can get out of this. I have added my sketch below. Sorry its not commented, and I'm using two sleep libraries, so that needs tidied up a bit.
#include <LowPower.h>
#include <SD.h>
#include <Time.h>
#include <DSRTCLib.h>// RTC library
#include <Wire.h> // Must include Wire library for I2C
#include <SFE_MMA8452Q.h> // Includes the SFE_MMA8452Q library
#include <avr/power.h>
#include <avr/sleep.h>
int INT_PIN = 1;
int int_number = 0;
const int chipSelect = 10;
MMA8452Q accel;
DS1339 RTC = DS1339(INT_PIN, int_number);
File file;
void setup()
{
pinMode(INT_PIN, INPUT);
digitalWrite(INT_PIN, HIGH);
// enable deep sleeping
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
sleep_enable();
RTC.start();
RTC.snooze(86400);
Serial.begin(9600);
pinMode(10, OUTPUT);
accel.init();
SD.begin(chipSelect);
file = SD.open("datalog.txt", O_CREAT | O_WRITE);
}
void nap()
{
// Dummy function. We don't actually want to do anything here, just use an interrupt to wake up.
//RTC.clear_interrupt();
// For some reason, sending commands to clear the interrupt on the RTC here does not work. Maybe Wire uses interrupts itself?
Serial.print(".");
}
void loop()
{
tmElements_t tm;
if (file)
{
for (uint8_t i = 0; i < 100; i++) {
RTC.readTime();
accel.read();
print2digits(RTC.getHours());
file.write(':');
print2digits(RTC.getMinutes());
file.write(':');
print2digits(RTC.getSeconds());
file.print('\t');
printCalculatedAccels();
printOrientation();
file.println(); // Print new line every time.
LowPower.powerDown(SLEEP_30MS, ADC_OFF, BOD_OFF);
}
file.flush();
}
}
void printCalculatedAccels()
{
file.print(accel.cx, 3);
file.print("\t");
file.print(accel.cy, 3);
file.print("\t");
file.print(accel.cz, 3);
file.print("\t");
}
void printOrientation()
{
byte pl = accel.readPL();
switch (pl)
{
case PORTRAIT_U:
file.print("PU");
break;
case PORTRAIT_D:
file.print("PD");
break;
case LANDSCAPE_R:
file.print("LR");
break;
case LANDSCAPE_L:
file.print("LL");
break;
case LOCKOUT:
file.print("Fl");
break;
}
}
void print2digits(int number) {
if (number >= 0 && number < 10) {
file.write('0');
}
file.print(number);
}
It only writes to sd every 3 or 4 seconds and I believe it is this FOR loop that handles that
void loop()
{
tmElements_t tm;
if (file)
{
for (uint8_t i = 0; i < 100; i++) {
RTC.readTime();
accel.read();
print2digits(RTC.getHours());
file.write(':');
print2digits(RTC.getMinutes());
file.write(':');
print2digits(RTC.getSeconds());
file.print('\t');
printCalculatedAccels();
printOrientation();
file.println(); // Print new line every time.
LowPower.powerDown(SLEEP_30MS, ADC_OFF, BOD_OFF);
}
file.flush();
}
}
Does that mean take 100 readings before flushing to sd? Whats the max readings it could take before flushing to sd? Where is the accelerometer data stored during this time considering the atmega is sleeping between reads?
I may in the future try and get interrupts from the accelerometer working.
For now, how far can I push that FOR loop? and how do I get the sd card to fully power down during sleep? At the min it uses 2ma with sd.h and sdfat.h.
Thanks for any advice you can give, and hope this helps someone else.
Cheers,
Damien