mpu6050 usermod: allow to disable usermod
* added usermod config information (so it can be disabled) * check that "INTERRUPT_PIN" does support interrupts (MM specific) * expose "dmpReady" in public interface * adjusted games usermod to switch to "simulation" in case mpu6050 is not active Still toDo: 1. add interrupt PIN and errormessages to settings page. 2. de-alloc intPin when disabled (and disable interrupt) 3. usermod is still destroying DEBUG_PRINT macros. 4. temporarily disable MPU interrupt when onUpdateBegin(true)
This commit is contained in:
@@ -94,17 +94,23 @@ class MPU6050Driver : public Usermod {
|
||||
private:
|
||||
MPU6050 mpu;
|
||||
bool enabled = true;
|
||||
bool initDone = false;
|
||||
unsigned long lastUMRun = millis();
|
||||
|
||||
// MPU control/status vars
|
||||
bool dmpReady = false; // set true if DMP init was successful
|
||||
uint8_t mpuIntStatus; // holds actual interrupt status byte from MPU
|
||||
uint8_t devStatus; // return status after each device operation (0 = success, !0 = error)
|
||||
uint16_t packetSize; // expected DMP packet size (default is 42 bytes)
|
||||
uint16_t fifoCount; // count of all bytes currently in FIFO
|
||||
uint8_t fifoBuffer[64]; // FIFO storage buffer
|
||||
|
||||
// strings to reduce flash memory usage (used more than twice)
|
||||
static const char _name[];
|
||||
static const char _enabled[];
|
||||
static const char _INT_pin[];
|
||||
|
||||
public:
|
||||
bool dmpReady = false; // set true if DMP init was successful // WLEDMM expose this info in public interface
|
||||
// orientation/motion vars
|
||||
Quaternion qat; // [w, x, y, z] quaternion container
|
||||
VectorInt16 aa; // [x, y, z] accel sensor measurements
|
||||
@@ -123,6 +129,10 @@ class MPU6050Driver : public Usermod {
|
||||
|
||||
void setup() {
|
||||
// WLEDMM begin
|
||||
if (!enabled) {
|
||||
dmpReady = false;
|
||||
return;
|
||||
}
|
||||
USER_PRINTLN(F("mpu setup"));
|
||||
PinManagerPinType pins[2] = { { i2c_scl, true }, { i2c_sda, true } };
|
||||
if ((i2c_scl < 0) || (i2c_sda < 0)) {
|
||||
@@ -171,16 +181,26 @@ class MPU6050Driver : public Usermod {
|
||||
// initialize device
|
||||
DEBUG_PRINT_IMULN(F("Initializing I2C devices..."));
|
||||
// WLEDMM begin
|
||||
if (!pinManager.allocatePin(INTERRUPT_PIN, false, PinOwner::UM_Unspecified))
|
||||
if ((INTERRUPT_PIN < 0) || (!pinManager.isPinINT(INTERRUPT_PIN))) {
|
||||
//enabled = false;
|
||||
USER_PRINTF("mpu6050: warning - interrupt GPIO %d does not support interrupts.\n", INTERRUPT_PIN);
|
||||
//INTERRUPT_PIN = -1;
|
||||
//return;
|
||||
}
|
||||
if ((INTERRUPT_PIN >= 0) && (pinManager.getPinOwner(INTERRUPT_PIN) != PinOwner::UM_IMU) // only allocate pin if we don't ownn it already
|
||||
&& !pinManager.allocatePin(INTERRUPT_PIN, false, PinOwner::UM_IMU))
|
||||
{
|
||||
//enabled = false;
|
||||
USER_PRINTF("mpu6050: warning - failed to allocate interrupt GPIO %d\n", INTERRUPT_PIN);
|
||||
//INTERRUPT_PIN = -1;
|
||||
//return;
|
||||
}
|
||||
// WLEDMM end
|
||||
|
||||
mpu.initialize();
|
||||
pinMode(INTERRUPT_PIN, INPUT);
|
||||
if (INTERRUPT_PIN >= 0) { // WLEDMM only if pin is valid
|
||||
pinMode(INTERRUPT_PIN, INPUT);
|
||||
}
|
||||
|
||||
// verify connection
|
||||
DEBUG_PRINT_IMULN(F("Testing device connections..."));
|
||||
@@ -214,11 +234,13 @@ class MPU6050Driver : public Usermod {
|
||||
DEBUG_PRINT_IMULN(F("Enabling DMP..."));
|
||||
mpu.setDMPEnabled(true);
|
||||
|
||||
// enable Arduino interrupt detection
|
||||
DEBUG_PRINT_IMU(F("Enabling interrupt detection (Arduino external interrupt "));
|
||||
DEBUG_PRINT_IMU(digitalPinToInterrupt(INTERRUPT_PIN));
|
||||
DEBUG_PRINT_IMULN(F(")..."));
|
||||
attachInterrupt(digitalPinToInterrupt(INTERRUPT_PIN), dmpDataReady, RISING);
|
||||
if (INTERRUPT_PIN >= 0) {
|
||||
// enable Arduino interrupt detection
|
||||
DEBUG_PRINT_IMU(F("Enabling interrupt detection (Arduino external interrupt "));
|
||||
DEBUG_PRINT_IMU(digitalPinToInterrupt(INTERRUPT_PIN));
|
||||
DEBUG_PRINT_IMULN(F(")..."));
|
||||
attachInterrupt(digitalPinToInterrupt(INTERRUPT_PIN), dmpDataReady, RISING);
|
||||
}
|
||||
mpuIntStatus = mpu.getIntStatus();
|
||||
|
||||
// set our DMP Ready flag so the main loop() function knows it's okay to use it
|
||||
@@ -235,7 +257,9 @@ class MPU6050Driver : public Usermod {
|
||||
DEBUG_PRINT(F("DMP Initialization failed (code "));
|
||||
DEBUG_PRINT(devStatus);
|
||||
DEBUG_PRINTLN(")");
|
||||
dmpReady = false;
|
||||
}
|
||||
initDone = true;
|
||||
}
|
||||
|
||||
void connected() {
|
||||
@@ -244,6 +268,7 @@ class MPU6050Driver : public Usermod {
|
||||
|
||||
void loop() {
|
||||
// if programming failed, don't try to do anything
|
||||
if (!initDone) return;
|
||||
if (!enabled || (strip.isUpdating() && (millis() - lastUMRun < 2))) return; // be nice, but not too nice
|
||||
lastUMRun = millis(); // update time keeping
|
||||
|
||||
@@ -265,6 +290,8 @@ class MPU6050Driver : public Usermod {
|
||||
|
||||
void addToJsonInfo(JsonObject& root)
|
||||
{
|
||||
if (!initDone) return;
|
||||
if (!enabled && !dmpReady) return; // WLEDMM no info when usermod disabled
|
||||
JsonObject user = root["u"];
|
||||
if (user.isNull()) user = root.createNestedObject("u");
|
||||
|
||||
@@ -328,29 +355,67 @@ class MPU6050Driver : public Usermod {
|
||||
//{
|
||||
//}
|
||||
|
||||
// void addToConfig(JsonObject& root)
|
||||
// {
|
||||
// JsonObject top = root.createNestedObject("MPU6050");
|
||||
// top[FPSTR("enabled")] = enabled;
|
||||
void addToConfig(JsonObject& root)
|
||||
{
|
||||
JsonObject top = root.createNestedObject(FPSTR(_name));
|
||||
top[FPSTR(_enabled)] = enabled;
|
||||
//JsonObject interruptPin = top.createNestedObject(FPSTR(_INT_pin));
|
||||
//interruptPin["pin"] = INTERRUPT_PIN;
|
||||
DEBUG_PRINTLN(F("MPU6050 IMU config saved."));
|
||||
}
|
||||
|
||||
// JsonObject interruptPin = top.createNestedObject(FPSTR("interruptPin"));
|
||||
// interruptPin["pin"] = interruptPin;
|
||||
// }
|
||||
//WLEDMM: add appendConfigData
|
||||
void appendConfigData()
|
||||
{
|
||||
oappend(SET_F("addHB('MPU6050 Motion Sensor (IMU)');"));
|
||||
/*
|
||||
#ifdef MPU6050_INT_GPIO
|
||||
oappend(SET_F("xOpt('mpu6050-IMU:interrupt_pin',0,' ⎌',")); oappendi(MPU6050_INT_GPIO); oappend(");");
|
||||
#endif
|
||||
//WLEDMM add errorMessage to um settings
|
||||
if (strcmp(errorMessage, "") != 0) {
|
||||
oappend(SET_F("addInfo('errorMessage', 0, '<i>error: ")); oappend(errorMessage); oappend("! Correct and reboot</i>');");
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
// bool readFromConfig(JsonObject& root)
|
||||
// {
|
||||
// JsonObject top = root[FPSTR("MPU6050")];
|
||||
// bool configComplete = !top.isNull();
|
||||
bool readFromConfig(JsonObject& root)
|
||||
{
|
||||
JsonObject top = root[FPSTR(_name)];
|
||||
|
||||
// configComplete &= getJsonValue(top[FPSTR("enabled")], enabled);
|
||||
// configComplete &= getJsonValue(top[FPSTR("interruptPin")]["pin"], interruptPin);
|
||||
if (top.isNull()) {
|
||||
DEBUG_PRINT(FPSTR(_name));
|
||||
DEBUG_PRINTLN(F(": No config found. (Using defaults.)"));
|
||||
return false;
|
||||
}
|
||||
|
||||
// return configComplete;
|
||||
// }
|
||||
bool configComplete = !top.isNull();
|
||||
configComplete &= getJsonValue(top[FPSTR(_enabled)], enabled);
|
||||
//configComplete &= getJsonValue(top[FPSTR(_INT_pin)]["pin"], INTERRUPT_PIN);
|
||||
|
||||
DEBUG_PRINT(FPSTR(_name));
|
||||
if (!initDone) {
|
||||
// first run: reading from cfg.json
|
||||
DEBUG_PRINTLN(F(" config loaded."));
|
||||
} else {
|
||||
DEBUG_PRINTLN(F(" config (re)loaded."));
|
||||
if (enabled || dmpReady) setup(); // re-run setup if user has checked "enabled"
|
||||
if (!enabled) dmpReady = false; // not enabled inplies "no DMP data ready"
|
||||
}
|
||||
|
||||
return configComplete;
|
||||
// use "return !top["newestParameter"].isNull();" when updating Usermod with new features
|
||||
//return !top[FPSTR(_INT_pin)].isNull();
|
||||
}
|
||||
|
||||
uint16_t getId()
|
||||
{
|
||||
return USERMOD_ID_IMU;
|
||||
}
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
// strings to reduce flash memory usage (used more than twice)
|
||||
const char MPU6050Driver::_name[] PROGMEM = "mpu6050-IMU";
|
||||
const char MPU6050Driver::_enabled[] PROGMEM = "enabled";
|
||||
const char MPU6050Driver::_INT_pin[] PROGMEM = "interrupt_pin";
|
||||
|
||||
@@ -183,7 +183,7 @@ uint16_t mode_IMUTest(void) {
|
||||
|
||||
uint8_t y = 0;
|
||||
|
||||
if (IMU != nullptr) {
|
||||
if ((IMU != nullptr) && (IMU->dmpReady)) {
|
||||
SEGMENT.setPixelColorXY(SEGMENT.virtualWidth() * (IMU->aa.x+INT16_MAX)/(2*INT16_MAX), y+=1, BLUE);
|
||||
SEGMENT.setPixelColorXY(SEGMENT.virtualWidth() * (IMU->aa.y+INT16_MAX)/(2*INT16_MAX), y+=1, BLUE);
|
||||
SEGMENT.setPixelColorXY(SEGMENT.virtualWidth() * (IMU->aa.z+INT16_MAX)/(2*INT16_MAX), y+=1, BLUE);
|
||||
@@ -280,7 +280,7 @@ uint16_t mode_3DIMUCube(void) {
|
||||
float roll = 0;
|
||||
|
||||
#ifdef USERMOD_MPU6050_IMU
|
||||
if (IMU != nullptr) {
|
||||
if ((IMU != nullptr) && (IMU->dmpReady)) {
|
||||
yaw = -IMU->ypr[0];
|
||||
pitch = IMU->ypr[1];
|
||||
roll = IMU->ypr[2];
|
||||
|
||||
@@ -49,6 +49,7 @@ String PinManagerClass::getOwnerText(PinOwner tag) {
|
||||
case PinOwner::UM_Audioreactive : return(F("AudioReactive (UM)")); break; // audioreative usermod - analog or digital audio input
|
||||
case PinOwner::UM_Temperature : return(F("Temperature (UM)")); break; // "usermod_temperature.h"
|
||||
case PinOwner::UM_PIR : return(F("PIR (UM)")); break; // "usermod_PIR_sensor_switch.h"
|
||||
case PinOwner::UM_IMU : return(F("IMU mpu6050 (UM)")); break; // "usermod_mpu6050_imu.h"
|
||||
case PinOwner::UM_FourLineDisplay : return(F("4Line Display (UM)")); break; // "usermod_v2_four_line_display.h -- May use "standard" HW_I2C pins
|
||||
case PinOwner::UM_RotaryEncoderUI : return(F("Rotary Enc. (UM)")); break; // "usermod_v2_rotary_encoder_ui.h"
|
||||
case PinOwner::UM_MultiRelay : return(F("Multi Relay (UM)")); break; // "usermod_multi_relay.h"
|
||||
|
||||
@@ -41,7 +41,7 @@ enum struct PinOwner : uint8_t {
|
||||
UM_Temperature = USERMOD_ID_TEMPERATURE, // 0x03 // Usermod "usermod_temperature.h"
|
||||
// #define USERMOD_ID_FIXNETSERVICES // 0x04 // Usermod "usermod_Fix_unreachable_netservices.h" -- Does not allocate pins
|
||||
UM_PIR = USERMOD_ID_PIRSWITCH, // 0x05 // Usermod "usermod_PIR_sensor_switch.h"
|
||||
// #define USERMOD_ID_IMU // 0x06 // Usermod "usermod_mpu6050_imu.h" -- Uses "standard" HW_I2C pins
|
||||
UM_IMU = USERMOD_ID_IMU, // 0x06 // Usermod "usermod_mpu6050_imu.h" -- Uses "standard" HW_I2C pins
|
||||
UM_FourLineDisplay = USERMOD_ID_FOUR_LINE_DISP, // 0x07 // Usermod "usermod_v2_four_line_display.h -- May use "standard" HW_I2C pins
|
||||
UM_RotaryEncoderUI = USERMOD_ID_ROTARY_ENC_UI, // 0x08 // Usermod "usermod_v2_rotary_encoder_ui.h"
|
||||
// #define USERMOD_ID_AUTO_SAVE // 0x09 // Usermod "usermod_v2_auto_save.h" -- Does not allocate pins
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*/
|
||||
|
||||
// version code in format yymmddb (b = daily build)
|
||||
#define VERSION 2303130
|
||||
#define VERSION 2303141
|
||||
|
||||
//uncomment this if you have a "my_config.h" file you'd like to use
|
||||
//#define WLED_USE_MY_CONFIG
|
||||
|
||||
Reference in New Issue
Block a user