Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added ON-OFF button support #318

Draft
wants to merge 9 commits into
base: main
Choose a base branch
from
Draft
6 changes: 6 additions & 0 deletions lib/bmi160/BMI160.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,12 @@ void BMI160::initialize(uint8_t addr,
// I2CdevMod::writeByte(devAddr, BMI160_RA_INT_MAP_2, 0x00);
}

void BMI160::deinitialize() {
/* Issue a soft-reset to bring the device into a clean state */
setRegister(BMI160_RA_CMD, BMI160_CMD_SOFT_RESET);
delay(12);
}

bool BMI160::getErrReg(uint8_t* out) {
bool ok = I2CdevMod::readByte(devAddr, BMI160_RA_ERR, buffer) >= 0;
if (!ok) return false;
Expand Down
1 change: 1 addition & 0 deletions lib/bmi160/BMI160.h
Original file line number Diff line number Diff line change
Expand Up @@ -564,6 +564,7 @@ class BMI160 {
BMI160AccelRange accelRange = BMI160_ACCEL_RANGE_4G,
BMI160DLPFMode accelFilterMode = BMI160_DLPF_MODE_OSR4
);
void deinitialize();
bool testConnection();

uint8_t getGyroRate();
Expand Down
13 changes: 13 additions & 0 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#include "serial/serialcommands.h"
#include "batterymonitor.h"
#include "logging/Logger.h"
#include "onOffButton.h"

Timer<> globalTimer;
SlimeVR::Logging::Logger logger("SlimeVR");
Expand All @@ -40,6 +41,10 @@ SlimeVR::Configuration::Configuration configuration;
SlimeVR::Network::Manager networkManager;
SlimeVR::Network::Connection networkConnection;

#ifdef ON_OFF_BUTTON
SlimeVR::OnOffButton onOffButton;
#endif

int sensorToCalibrate = -1;
bool blinking = false;
unsigned long blinkStart = 0;
Expand Down Expand Up @@ -93,6 +98,10 @@ void setup()
#endif
Wire.setClock(I2C_SPEED);

#ifdef ON_OFF_BUTTON
onOffButton.setup();
#endif

// Wait for IMU to boot
delay(500);

Expand All @@ -118,6 +127,10 @@ void loop()
sensorManager.update();
battery.Loop();
ledManager.update();

#ifdef ON_OFF_BUTTON
onOffButton.update();
#endif
#ifdef TARGET_LOOPTIME_MICROS
long elapsed = (micros() - loopTime);
if (elapsed < TARGET_LOOPTIME_MICROS)
Expand Down
99 changes: 99 additions & 0 deletions src/onOffButton.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
/*
SlimeVR Code is placed under the MIT license
Copyright (c) 2024 Gorbit99 & SlimeVR Contributors

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#include "onOffButton.h"

#include "GlobalVars.h"

void SlimeVR::OnOffButton::setup() {
#ifdef ON_OFF_BUTTON

#ifdef ESP8266
digitalWrite(D0, LOW);
pinMode(D0, OUTPUT);
pinMode(ON_OFF_BUTTON, INPUT);
#endif

#ifdef ESP32
pinMode(
ON_OFF_BUTTON,
ON_OFF_BUTTON_ACTIVE_LEVEL == LOW ? INPUT_PULLUP : INPUT_PULLDOWN
);
esp_deep_sleep_enable_gpio_wakeup(
1 << ON_OFF_BUTTON,
ON_OFF_BUTTON_ACTIVE_LEVEL == LOW ? ESP_GPIO_WAKEUP_GPIO_LOW
: ESP_GPIO_WAKEUP_GPIO_HIGH
);
#endif

#endif
}

void SlimeVR::OnOffButton::update() {
#ifdef ON_OFF_BUTTON

if (digitalRead(ON_OFF_BUTTON) != ON_OFF_BUTTON_ACTIVE_LEVEL) {
return;
}

uint32_t ringBuffer = 0;
long startTime = millis();
while (millis() - startTime < ON_OFF_BUTTON_HOLD_TIME_MS) {
ringBuffer <<= 1;
ringBuffer |= digitalRead(ON_OFF_BUTTON) != ON_OFF_BUTTON_ACTIVE_LEVEL;

int popCount = __builtin_popcount(ringBuffer);
if (popCount > 16) {
return;
}
delay(1);
}

ledManager.off();
for (int i = 0; i < 3; i++) {
ledManager.on();
delay(100);
ledManager.off();
delay(100);
}

ringBuffer = 0;
while (__builtin_popcount(ringBuffer) <= 16) {
ringBuffer <<= 1;
ringBuffer |= digitalRead(ON_OFF_BUTTON) != ON_OFF_BUTTON_ACTIVE_LEVEL;
delay(1);
}

const auto& sensors = sensorManager.getSensors();
for (auto& sensor : sensors) {
// sensor->deinitialize();
}

#ifdef ESP8266
ESP.deepSleep(0);
#endif

#ifdef ESP32
esp_deep_sleep_start();
#endif
#endif
}
49 changes: 49 additions & 0 deletions src/onOffButton.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
SlimeVR Code is placed under the MIT license
Copyright (c) 2024 Gorbit99 & SlimeVR Contributors

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#ifndef SLIMEVR_ONOFFBUTTON_H_
#define SLIMEVR_ONOFFBUTTON_H_

#include "logging/Logger.h"
#include "globals.h"

#ifndef ON_OFF_BUTTON_ACTIVE_LEVEL
#define ON_OFF_BUTTON_ACTIVE_LEVEL LOW
#endif

#ifndef ON_OFF_BUTTON_HOLD_TIME_MS
#define ON_OFF_BUTTON_HOLD_TIME_MS 1000
#endif

namespace SlimeVR {

class OnOffButton {
public:
void setup();
void update();
private:
SlimeVR::Logging::Logger m_Logger = SlimeVR::Logging::Logger("OnOffButton");
};

}

#endif
4 changes: 4 additions & 0 deletions src/sensors/bmi160sensor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1006,3 +1006,7 @@ void BMI160Sensor::getMagnetometerXYZFromBuffer(uint8_t* data, int16_t* x, int16
*z = ((int16_t)data[5] << 8) | data[4];
#endif
}

void BMI160Sensor::deinitialize() {
imu.deinitialize();
}
6 changes: 4 additions & 2 deletions src/sensors/bmi160sensor.h
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ constexpr uint16_t BMI160_FIFO_READ_BUFFER_SIZE_BYTES = min(
// #define BMI160_GYRO_TYPICAL_SENSITIVITY_LSB 16.4f // 2000 deg 0
// #define BMI160_GYRO_TYPICAL_SENSITIVITY_LSB 32.8f // 1000 deg 1
// #define BMI160_GYRO_TYPICAL_SENSITIVITY_LSB 65.6f // 500 deg 2
// #define BMI160_GYRO_TYPICAL_SENSITIVITY_LSB 131.2f // 250 deg 3
// #define BMI160_GYRO_TYPICAL_SENSITIVITY_LSB 131.2f // 250 deg 3
// #define BMI160_GYRO_TYPICAL_SENSITIVITY_LSB 262.4f // 125 deg 4
constexpr double BMI160_GYRO_TYPICAL_SENSITIVITY_LSB = (16.4f * (1 << BMI160_GYRO_RANGE));

Expand Down Expand Up @@ -146,7 +146,7 @@ class BMI160Sensor : public Sensor {
void maybeCalibrateGyro();
void maybeCalibrateAccel();
void maybeCalibrateMag();

void printTemperatureCalibrationState() override final;
void printDebugTemperatureCalibrationState() override final;
void resetTemperatureCalibrationState() override final {
Expand Down Expand Up @@ -176,6 +176,8 @@ class BMI160Sensor : public Sensor {

bool getTemperature(float* out);

void deinitialize() override final;

private:
BMI160 imu {};
int axisRemap;
Expand Down
4 changes: 4 additions & 0 deletions src/sensors/bno055sensor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,3 +70,7 @@ void BNO055Sensor::motionLoop() {
void BNO055Sensor::startCalibration(int calibrationType) {

}

void BNO055Sensor::deinitialize() {
imu.enterSuspendMode();
}
1 change: 1 addition & 0 deletions src/sensors/bno055sensor.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ class BNO055Sensor : public Sensor
void motionSetup() override final;
void motionLoop() override final;
void startCalibration(int calibrationType) override final;
void deinitialize() override final;

private:
Adafruit_BNO055 imu;
Expand Down
5 changes: 5 additions & 0 deletions src/sensors/bno080sensor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -243,3 +243,8 @@ void BNO080Sensor::startCalibration(int calibrationType)
// it's always enabled except accelerometer
// that is disabled 30 seconds after startup
}

void BNO080Sensor::deinitialize()
{
imu.softReset();
}
1 change: 1 addition & 0 deletions src/sensors/bno080sensor.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ class BNO080Sensor : public Sensor
void sendData() override final;
void startCalibration(int calibrationType) override final;
SensorStatus getSensorState() override final;
void deinitialize() override final;

protected:
// forwarding constructor
Expand Down
4 changes: 4 additions & 0 deletions src/sensors/icm20948sensor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -758,3 +758,7 @@ ICM_20948_Status_e ICM_20948::initializeDMP(void)
return worstResult;
}
#endif // OVERRIDEDMPSETUP

void ICM20948Sensor::deinitialize() {
imu.swReset();
}
1 change: 1 addition & 0 deletions src/sensors/icm20948sensor.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ class ICM20948Sensor : public Sensor
void checkSensorTimeout();
void readRotation();
void readFIFOToEnd();
void deinitialize() override final;

#define OVERRIDEDMPSETUP true
// TapDetector tapDetector;
Expand Down
4 changes: 4 additions & 0 deletions src/sensors/mpu6050sensor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -200,3 +200,7 @@ void MPU6050Sensor::startCalibration(int calibrationType) {

ledManager.off();
}

void MPU6050Sensor::deinitialize() {
imu.reset();
}
1 change: 1 addition & 0 deletions src/sensors/mpu6050sensor.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ class MPU6050Sensor : public Sensor
void motionSetup() override final;
void motionLoop() override final;
void startCalibration(int calibrationType) override final;
void deinitialize() override final;

private:
MPU6050 imu{};
Expand Down
4 changes: 4 additions & 0 deletions src/sensors/mpu9250sensor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -442,3 +442,7 @@ bool MPU9250Sensor::getNextSample(union fifo_sample_raw *buffer, uint16_t *remai
swapFifoData(buffer);
return true;
}

void MPU9250Sensor::deinitialize() {
imu.reset();
}
1 change: 1 addition & 0 deletions src/sensors/mpu9250sensor.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ class MPU9250Sensor : public Sensor
void motionLoop() override final;
void startCalibration(int calibrationType) override final;
void getMPUScaled();
void deinitialize() override final;

private:
MPU9250 imu{};
Expand Down
3 changes: 2 additions & 1 deletion src/sensors/sensor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ void Sensor::printTemperatureCalibrationState() { printTemperatureCalibrationUns
void Sensor::printDebugTemperatureCalibrationState() { printTemperatureCalibrationUnsupported(); };
void Sensor::saveTemperatureCalibration() { printTemperatureCalibrationUnsupported(); };
void Sensor::resetTemperatureCalibrationState() { printTemperatureCalibrationUnsupported(); };
void Sensor::deinitialize() {}

const char * getIMUNameByType(ImuID imuType) {
switch(imuType) {
Expand Down Expand Up @@ -106,4 +107,4 @@ const char * getIMUNameByType(ImuID imuType) {
return "UNKNOWN";
}
return "Unknown";
}
}
1 change: 1 addition & 0 deletions src/sensors/sensor.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ class Sensor
bool hasNewDataToSend() {
return newFusedRotation || newAcceleration;
};
virtual void deinitialize();

protected:
uint8_t addr = 0;
Expand Down
Loading