Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Platform-io-source/platformio.ini
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ lib_deps =
Wire
bodmer/TFT_eSPI
adafruit/Adafruit MMC56x3
sparkfun/SparkFun BMI270 Arduino Library
https://github.com/disq/SparkFun_BMI270_Arduino_Library.git#94fe8d0f0a871630f4a5c7327b1a894314ff5819
sparkfun/SparkFun MAX1704x Fuel Gauge Arduino Library@^1.0.4
me-no-dev/ESP Async WebServer@^1.2.3
knolleary/PubSubClient@^2.8
Expand Down
131 changes: 87 additions & 44 deletions Platform-io-source/src/peripherals/imu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,27 @@
extern Activity activity;
extern RTC rtc;

void IMU::init()
void IMU::preinit(bool woke_from_sleep)
{
imu_ready = true;
mag_ready = true;

if (imu.beginI2C(i2cAddress) != BMI2_OK)
imu_preinit_ok = true;
if (imu.beginI2C(i2cAddress, Wire, woke_from_sleep) != BMI2_OK)
{
// Not connected, inform user
info_println("Error: BMI270 not connected, check wiring and I2C address!");
imu_ready = false;
imu_preinit_ok = false;
return;
}
else
info_println(F("Found BMI270"));
}

void IMU::init()
{
imu_ready = imu_preinit_ok;
mag_ready = true;

if (imu_ready)
{
info_println(F("Found BMI270"));
info_println(F("Setting up BMI270"));

imu.setAccelPowerMode(BMI2_POWER_OPT_MODE);
imu.setGyroPowerMode(BMI2_POWER_OPT_MODE, BMI2_POWER_OPT_MODE);
Expand Down Expand Up @@ -144,59 +151,81 @@ void IMU::set_hibernate(bool state)

void IMU::process_steps()
{
if (!imu_ready)
process_steps(false);
}

void IMU::process_steps(bool force)
{
if (!imu_preinit_ok)
{
info_println("IMU not ready");
info_println("process_steps: IMU not ready");
return;
}

// Wait for interrupt to occur
if (!interrupt_happened && !force)
{
return;
}

uint16_t interrupt_status = 0;

// Serial.println("interrupt caught!"); Serial.flush();
// Reset flag for next interrupt
if (interrupt_happened)
{
// Reset flag for next interrupt
interrupt_happened = false;

// Get the interrupt status to know which condition triggered
uint16_t interrupt_status = 0;
imu.getInterruptStatus(&interrupt_status);
if (force)
interrupt_status |= BMI270_STEP_CNT_STATUS_MASK; // force in effect
}
else
{
// no interrupt but we're forced to process
interrupt_status = BMI270_STEP_CNT_STATUS_MASK;
}

// Check if this is the correct interrupt condition
if (interrupt_status & BMI270_STEP_CNT_STATUS_MASK)
{
// Get the step count
uint32_t _step_count = 0;
imu.getStepCount(&_step_count);
bool processed = false;

if (_step_count > 0)
step_count = _step_count;
// Check if this is the correct interrupt condition
if (interrupt_status & BMI270_STEP_CNT_STATUS_MASK)
{
// Get the step count
uint32_t _step_count = 0;
imu.getStepCount(&_step_count);

info_println("Step count: " + step_count);
}
if (interrupt_status & BMI270_STEP_ACT_STATUS_MASK)
if (_step_count > 0)
{
// Get the step activity
movement_activity = 0;
imu.getStepActivity(&movement_activity);

if (movement_activity == BMI2_STEP_ACTIVITY_STILL)
{
// Track steps for day, month, year in settings with date rollover
if (step_count > 0)
{
uint16_t day, month, year;
rtc.get_step_date(day, month, year);
activity.track_steps(step_count, day, month, year);
activity.save(true);
step_count = 0;
}
imu.resetStepCount();
}
step_count = _step_count;
imu.resetStepCount();
}
if (!(interrupt_status & (BMI270_STEP_CNT_STATUS_MASK | BMI270_STEP_ACT_STATUS_MASK)))

processed = true;
info_println("Step count: " + String(step_count));
}

if (interrupt_status & BMI270_STEP_ACT_STATUS_MASK)
{
// Get the step activity
movement_activity = 0;
imu.getStepActivity(&movement_activity);

if (movement_activity == BMI2_STEP_ACTIVITY_STILL && !processed)
{
// info_println("Unkown IInterrupt condition!");
process_steps(true);
return;
}
}
if (!(interrupt_status & (BMI270_STEP_CNT_STATUS_MASK | BMI270_STEP_ACT_STATUS_MASK)))
{
// info_println("Unknown Interrupt condition! " + String(interrupt_status));
}

if (force)
{
persist_step_count();
}
}

uint32_t IMU::get_steps(uint8_t day, uint8_t month, uint16_t year)
Expand Down Expand Up @@ -392,4 +421,18 @@ bool IMU::is_looking_at_face()
return (p >= 30 && p <= 50 && r > -10 && r < 10);
}

IMU imu;
bool IMU::persist_step_count()
{
if (step_count == 0)
return false;

// Track steps for day, month, year in settings with date rollover
uint16_t day, month, year;
rtc.get_step_date(day, month, year);
activity.track_steps(step_count, day, month, year);
auto saved = activity.save(false);
step_count = 0;
return saved;
}

IMU imu;
7 changes: 6 additions & 1 deletion Platform-io-source/src/peripherals/imu.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
class IMU
{
public:
void preinit(bool woke_from_sleep);
void init();
void update();
float get_accel_x();
Expand All @@ -27,6 +28,7 @@ class IMU
// BMI270 Step Counter
void setup_step_counter();
void process_steps();
void process_steps(bool force);
uint32_t get_steps(uint8_t day, uint8_t month, uint16_t year);
uint8_t get_movement_activity_id();
String get_movement_activity();
Expand All @@ -38,7 +40,8 @@ class IMU
void process_wrist_gestures();

// Ready states
bool imu_ready = true;
bool imu_preinit_ok = false;
bool imu_ready = false;
bool mag_ready = true;

private:
Expand All @@ -62,6 +65,8 @@ class IMU
const float soft_iron[3][3] = {{1.003, 0.008, -0.001}, {0.008, 1.004, 0.000}, {-0.001, -0.000, 0.994}};

const float mag_decl = -1.233;

bool persist_step_count();
};

extern IMU imu;
8 changes: 3 additions & 5 deletions Platform-io-source/src/peripherals/rtc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,6 @@ bool RTC::init()

requiresNTP = rtc.getCurrentDateTimeComponent(DATETIME_YEAR) < 23;

next_rtc_read = millis();

return true;
}

Expand Down Expand Up @@ -70,11 +68,11 @@ bool RTC::set_time_from_NTP(int16_t utc_offset)
return !time_error;
}

void RTC::set_hourly_alarm(uint minuets)
void RTC::set_hourly_alarm(uint minutes)
{
setup_interrupt();

rtc.setHourlyAlarm(/*minute=*/minuets);
rtc.setHourlyAlarm(/*minute=*/minutes);
rtc.enableInterrupt(INTERRUPT_ALARM);
}

Expand Down Expand Up @@ -129,7 +127,7 @@ uint16_t RTC::get_year() { return ((uint16_t)rtc.getCurrentDateTimeComponent(DAT

void RTC::get_step_date(uint16_t &day, uint16_t &month, uint16_t &year)
{
if (millis() - next_rtc_read > 5000)
if (next_rtc_read == 0 || millis() - next_rtc_read > 5000)
{
next_rtc_read = millis();
cached_day = get_day();
Expand Down
4 changes: 2 additions & 2 deletions Platform-io-source/src/peripherals/rtc.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ class RTC
void setup_interrupt();
bool check_interrupt();
bool set_time_from_NTP(int16_t utc_offset);
void set_hourly_alarm(uint minuets);
void set_hourly_alarm(uint minutes);
// String getTime();
String get_hours_string(bool padded, bool is24hour);
String get_mins_string(bool padded);
Expand Down Expand Up @@ -47,7 +47,7 @@ class RTC
uint8_t interruptPin = 33;
unsigned long next_rtc_read = 0;
uint16_t cached_day = 0;
uint cached_month = 0;
uint16_t cached_month = 0;
uint16_t cached_year = 0;
};

Expand Down
19 changes: 18 additions & 1 deletion Platform-io-source/src/tinywatch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ void setup()
// Start the RTC & Battery early as they are needed for wake fom sleep
battery.init();
rtc.init();
imu.preinit(was_asleep);

if (was_asleep)
{
Expand All @@ -120,7 +121,6 @@ void setup()
if (was_asleep)
{
// Wake up the peripherals because we were sleeping!
imu.set_hibernate(false);

// work out why we were woken up and do something about it
// 0: Touched Screen
Expand Down Expand Up @@ -219,6 +219,16 @@ void setup()
// load the activity data
activity.load();

if (was_asleep)
{
// Do the steps last, after activity is loaded
imu.set_hibernate(false);
if (settings.config.imu_process_steps)
{
imu.process_steps(true);
}
}

// Start the rest of the peripherals
imu.init();
}
Expand Down Expand Up @@ -387,9 +397,16 @@ void TinyWATCH::go_to_sleep()
digitalWrite(TFT_LED, 0);
deinit_buzzer(BUZZER);
battery.set_hibernate(true);

if (settings.config.imu_process_steps)
{
imu.process_steps(true);
}

imu.set_hibernate(false);
settings.save(true);
activity.save(true);
delay(500); // no delay and it sometimes wakes up immediately

LittleFS.end();

Expand Down