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:
|
private:
|
||||||
MPU6050 mpu;
|
MPU6050 mpu;
|
||||||
bool enabled = true;
|
bool enabled = true;
|
||||||
|
bool initDone = false;
|
||||||
unsigned long lastUMRun = millis();
|
unsigned long lastUMRun = millis();
|
||||||
|
|
||||||
// MPU control/status vars
|
// 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 mpuIntStatus; // holds actual interrupt status byte from MPU
|
||||||
uint8_t devStatus; // return status after each device operation (0 = success, !0 = error)
|
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 packetSize; // expected DMP packet size (default is 42 bytes)
|
||||||
uint16_t fifoCount; // count of all bytes currently in FIFO
|
uint16_t fifoCount; // count of all bytes currently in FIFO
|
||||||
uint8_t fifoBuffer[64]; // FIFO storage buffer
|
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:
|
public:
|
||||||
|
bool dmpReady = false; // set true if DMP init was successful // WLEDMM expose this info in public interface
|
||||||
// orientation/motion vars
|
// orientation/motion vars
|
||||||
Quaternion qat; // [w, x, y, z] quaternion container
|
Quaternion qat; // [w, x, y, z] quaternion container
|
||||||
VectorInt16 aa; // [x, y, z] accel sensor measurements
|
VectorInt16 aa; // [x, y, z] accel sensor measurements
|
||||||
@@ -123,6 +129,10 @@ class MPU6050Driver : public Usermod {
|
|||||||
|
|
||||||
void setup() {
|
void setup() {
|
||||||
// WLEDMM begin
|
// WLEDMM begin
|
||||||
|
if (!enabled) {
|
||||||
|
dmpReady = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
USER_PRINTLN(F("mpu setup"));
|
USER_PRINTLN(F("mpu setup"));
|
||||||
PinManagerPinType pins[2] = { { i2c_scl, true }, { i2c_sda, true } };
|
PinManagerPinType pins[2] = { { i2c_scl, true }, { i2c_sda, true } };
|
||||||
if ((i2c_scl < 0) || (i2c_sda < 0)) {
|
if ((i2c_scl < 0) || (i2c_sda < 0)) {
|
||||||
@@ -171,16 +181,26 @@ class MPU6050Driver : public Usermod {
|
|||||||
// initialize device
|
// initialize device
|
||||||
DEBUG_PRINT_IMULN(F("Initializing I2C devices..."));
|
DEBUG_PRINT_IMULN(F("Initializing I2C devices..."));
|
||||||
// WLEDMM begin
|
// 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;
|
//enabled = false;
|
||||||
USER_PRINTF("mpu6050: warning - failed to allocate interrupt GPIO %d\n", INTERRUPT_PIN);
|
USER_PRINTF("mpu6050: warning - failed to allocate interrupt GPIO %d\n", INTERRUPT_PIN);
|
||||||
|
//INTERRUPT_PIN = -1;
|
||||||
//return;
|
//return;
|
||||||
}
|
}
|
||||||
// WLEDMM end
|
// WLEDMM end
|
||||||
|
|
||||||
mpu.initialize();
|
mpu.initialize();
|
||||||
pinMode(INTERRUPT_PIN, INPUT);
|
if (INTERRUPT_PIN >= 0) { // WLEDMM only if pin is valid
|
||||||
|
pinMode(INTERRUPT_PIN, INPUT);
|
||||||
|
}
|
||||||
|
|
||||||
// verify connection
|
// verify connection
|
||||||
DEBUG_PRINT_IMULN(F("Testing device connections..."));
|
DEBUG_PRINT_IMULN(F("Testing device connections..."));
|
||||||
@@ -214,11 +234,13 @@ class MPU6050Driver : public Usermod {
|
|||||||
DEBUG_PRINT_IMULN(F("Enabling DMP..."));
|
DEBUG_PRINT_IMULN(F("Enabling DMP..."));
|
||||||
mpu.setDMPEnabled(true);
|
mpu.setDMPEnabled(true);
|
||||||
|
|
||||||
// enable Arduino interrupt detection
|
if (INTERRUPT_PIN >= 0) {
|
||||||
DEBUG_PRINT_IMU(F("Enabling interrupt detection (Arduino external interrupt "));
|
// enable Arduino interrupt detection
|
||||||
DEBUG_PRINT_IMU(digitalPinToInterrupt(INTERRUPT_PIN));
|
DEBUG_PRINT_IMU(F("Enabling interrupt detection (Arduino external interrupt "));
|
||||||
DEBUG_PRINT_IMULN(F(")..."));
|
DEBUG_PRINT_IMU(digitalPinToInterrupt(INTERRUPT_PIN));
|
||||||
attachInterrupt(digitalPinToInterrupt(INTERRUPT_PIN), dmpDataReady, RISING);
|
DEBUG_PRINT_IMULN(F(")..."));
|
||||||
|
attachInterrupt(digitalPinToInterrupt(INTERRUPT_PIN), dmpDataReady, RISING);
|
||||||
|
}
|
||||||
mpuIntStatus = mpu.getIntStatus();
|
mpuIntStatus = mpu.getIntStatus();
|
||||||
|
|
||||||
// set our DMP Ready flag so the main loop() function knows it's okay to use it
|
// 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(F("DMP Initialization failed (code "));
|
||||||
DEBUG_PRINT(devStatus);
|
DEBUG_PRINT(devStatus);
|
||||||
DEBUG_PRINTLN(")");
|
DEBUG_PRINTLN(")");
|
||||||
|
dmpReady = false;
|
||||||
}
|
}
|
||||||
|
initDone = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void connected() {
|
void connected() {
|
||||||
@@ -244,6 +268,7 @@ class MPU6050Driver : public Usermod {
|
|||||||
|
|
||||||
void loop() {
|
void loop() {
|
||||||
// if programming failed, don't try to do anything
|
// 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
|
if (!enabled || (strip.isUpdating() && (millis() - lastUMRun < 2))) return; // be nice, but not too nice
|
||||||
lastUMRun = millis(); // update time keeping
|
lastUMRun = millis(); // update time keeping
|
||||||
|
|
||||||
@@ -265,6 +290,8 @@ class MPU6050Driver : public Usermod {
|
|||||||
|
|
||||||
void addToJsonInfo(JsonObject& root)
|
void addToJsonInfo(JsonObject& root)
|
||||||
{
|
{
|
||||||
|
if (!initDone) return;
|
||||||
|
if (!enabled && !dmpReady) return; // WLEDMM no info when usermod disabled
|
||||||
JsonObject user = root["u"];
|
JsonObject user = root["u"];
|
||||||
if (user.isNull()) user = root.createNestedObject("u");
|
if (user.isNull()) user = root.createNestedObject("u");
|
||||||
|
|
||||||
@@ -328,29 +355,67 @@ class MPU6050Driver : public Usermod {
|
|||||||
//{
|
//{
|
||||||
//}
|
//}
|
||||||
|
|
||||||
// void addToConfig(JsonObject& root)
|
void addToConfig(JsonObject& root)
|
||||||
// {
|
{
|
||||||
// JsonObject top = root.createNestedObject("MPU6050");
|
JsonObject top = root.createNestedObject(FPSTR(_name));
|
||||||
// top[FPSTR("enabled")] = enabled;
|
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"));
|
//WLEDMM: add appendConfigData
|
||||||
// interruptPin["pin"] = interruptPin;
|
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)
|
bool readFromConfig(JsonObject& root)
|
||||||
// {
|
{
|
||||||
// JsonObject top = root[FPSTR("MPU6050")];
|
JsonObject top = root[FPSTR(_name)];
|
||||||
// bool configComplete = !top.isNull();
|
|
||||||
|
|
||||||
// configComplete &= getJsonValue(top[FPSTR("enabled")], enabled);
|
if (top.isNull()) {
|
||||||
// configComplete &= getJsonValue(top[FPSTR("interruptPin")]["pin"], interruptPin);
|
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()
|
uint16_t getId()
|
||||||
{
|
{
|
||||||
return USERMOD_ID_IMU;
|
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;
|
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.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.y+INT16_MAX)/(2*INT16_MAX), y+=1, BLUE);
|
||||||
SEGMENT.setPixelColorXY(SEGMENT.virtualWidth() * (IMU->aa.z+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;
|
float roll = 0;
|
||||||
|
|
||||||
#ifdef USERMOD_MPU6050_IMU
|
#ifdef USERMOD_MPU6050_IMU
|
||||||
if (IMU != nullptr) {
|
if ((IMU != nullptr) && (IMU->dmpReady)) {
|
||||||
yaw = -IMU->ypr[0];
|
yaw = -IMU->ypr[0];
|
||||||
pitch = IMU->ypr[1];
|
pitch = IMU->ypr[1];
|
||||||
roll = IMU->ypr[2];
|
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_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_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_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_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_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"
|
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"
|
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
|
// #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"
|
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_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"
|
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
|
// #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)
|
// 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
|
//uncomment this if you have a "my_config.h" file you'd like to use
|
||||||
//#define WLED_USE_MY_CONFIG
|
//#define WLED_USE_MY_CONFIG
|
||||||
|
|||||||
Reference in New Issue
Block a user