IMO support in usermod games, add 3D IMO cube effect
- platformio: add USERMOD_MPU6050_IMU and ElectronicCats/MPU6050 @ 0.6.0 to esp32mdevums - USERMOD_MPU6050_IMU: update readme.md and usermod_mpu650_imu.h - usermod_v2_games: support for USERMOD_MPU6050_IMU, add mode_IMUTest and class Frame3D and mode_3DIMUCube, remove old gyro handling - usermods_list.cpp: add USERMOD_MPU6050_IMU
This commit is contained in:
105
platformio.ini
105
platformio.ini
@@ -12,7 +12,7 @@
|
||||
; default_envs = travis_esp8266, travis_esp32
|
||||
|
||||
# Release binaries
|
||||
default_envs = nodemcuv2, esp8266_2m, esp01_1m_full, esp32dev, esp32_eth, esp32s2_saola, esp32c3
|
||||
; default_envs = nodemcuv2, esp8266_2m, esp01_1m_full, esp32dev, esp32_eth, esp32s2_saola, esp32c3
|
||||
|
||||
# Build everything
|
||||
; default_envs = esp32dev, esp8285_4CH_MagicHome, codm-controller-0.6-rev2, codm-controller-0.6, esp32s2_saola, d1_mini_5CH_Shojo_PCB, d1_mini, sp501e, travis_esp8266, travis_esp32, nodemcuv2, esp32_eth, anavi_miracle_controller, esp07, esp01_1m_full, m5atom, h803wf, d1_mini_ota, heltec_wifi_kit_8, esp8285_H801, d1_mini_debug, wemos_shield_esp32, elekstube_ips
|
||||
@@ -32,6 +32,9 @@ default_envs = nodemcuv2, esp8266_2m, esp01_1m_full, esp32dev, esp32_eth, esp32s
|
||||
; default_envs = esp8285_4CH_MagicHome
|
||||
; default_envs = esp8285_H801
|
||||
; default_envs = d1_mini_5CH_Shojo_PCB
|
||||
; default_envs = esp32mdev
|
||||
default_envs = esp32mdevums
|
||||
; default_envs = esp8266mdev
|
||||
; default_envs = wemos_shield_esp32
|
||||
; default_envs = m5atom
|
||||
; default_envs = esp32_eth
|
||||
@@ -222,7 +225,9 @@ default_partitions = tools/WLED_ESP32_4MB_1MB_FS.csv
|
||||
|
||||
lib_deps =
|
||||
${env.lib_deps}
|
||||
https://github.com/lorol/LITTLEFS.git
|
||||
; https://github.com/lorol/LITTLEFS.git
|
||||
; WLEDSR specific: use patched version of lorol LittleFS
|
||||
https://github.com/softhack007/LITTLEFS-threadsafe.git#master
|
||||
makuna/NeoPixelBus @ 2.6.9
|
||||
https://github.com/pbolduc/AsyncTCP.git @ 1.2.0
|
||||
|
||||
@@ -437,6 +442,82 @@ build_unflags = ${common.build_unflags}
|
||||
build_flags = ${common.build_flags_esp8266} -D LEDPIN=12 -D IRPIN=-1 -D RLYPIN=2
|
||||
lib_deps = ${esp8266.lib_deps}
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# MoonModules configs
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
[env:esp32mdev]
|
||||
board = esp32dev
|
||||
platform = ${esp32.platform}
|
||||
upload_speed = 460800 ; or 921600
|
||||
platform_packages = ${esp32.platform_packages}
|
||||
build_unflags = ${common.build_unflags}
|
||||
|
||||
build_flags = ${common.build_flags_esp32}
|
||||
-D WLED_RELEASE_NAME=ESP32 #-D WLED_DISABLE_BLYNK #-D WLED_DISABLE_BROWNOUT_DET
|
||||
-D ABL_MILLIAMPS_DEFAULT=1500 ; 850 not enough for 1024 leds
|
||||
-D UWLED_USE_MY_CONFIG
|
||||
-D USERMOD_AUDIOREACTIVE
|
||||
-D UM_AUDIOREACTIVE_USE_NEW_FFT
|
||||
-D USERMOD_CUSTOMEFFECTS
|
||||
; -D WLED_DEBUG
|
||||
lib_deps = ${esp32.lib_deps}
|
||||
https://github.com/kosme/arduinoFFT#develop @ 1.9.2
|
||||
; monitor_filters = esp32_exception_decoder
|
||||
board_build.partitions = ${esp32.default_partitions}
|
||||
board_build.f_flash = 80000000L
|
||||
board_build.flash_mode = dio
|
||||
|
||||
[env:esp32mdevums]
|
||||
board = esp32dev
|
||||
platform = ${esp32.platform}
|
||||
upload_speed = 460800 ; or 921600
|
||||
platform_packages = ${esp32.platform_packages}
|
||||
build_unflags = ${common.build_unflags}
|
||||
build_flags = ${common.build_flags_esp32}
|
||||
-D WLED_RELEASE_NAME=ESP32 ; what does this do?
|
||||
#-D WLED_DISABLE_BLYNK #-D WLED_DISABLE_BROWNOUT_DET ; which settings and when?
|
||||
-D ABL_MILLIAMPS_DEFAULT=1500 ; 850 not enough for 1024 leds
|
||||
-D WLED_MAX_USERMODS=9 ; default only 4-6
|
||||
-D UWLED_USE_MY_CONFIG ; what does this do?
|
||||
-D USERMOD_AUDIOREACTIVE
|
||||
-D UM_AUDIOREACTIVE_USE_NEW_FFT ; explain
|
||||
; -D USERMOD_DALLASTEMPERATURE
|
||||
; -D USE_ALT_DISPlAY ; new versions of USERMOD_FOUR_LINE_DISPLAY and USERMOD_ROTARY_ENCODER_UI
|
||||
; -D USERMOD_FOUR_LINE_DISPLAY
|
||||
; -D USERMOD_ROTARY_ENCODER_UI
|
||||
-D USERMOD_AUTO_SAVE
|
||||
-D USERMOD_CUSTOMEFFECTS ; WLEDSR usermod
|
||||
-D USERMOD_WEATHER ; WLEDSR usermod
|
||||
-D USERMOD_MPU6050_IMU ; gyro/accelero for USERMOD_GAMES (ONLY WORKS IF USERMOD_FOUR_LINE_DISPLAY NOT INCLUDED - I2C SHARING BUG)
|
||||
-D USERMOD_GAMES ; WLEDSR usermod
|
||||
; -D WLED_DEBUG
|
||||
lib_deps = ${esp32.lib_deps}
|
||||
; OneWire@~2.3.5 ; used for USERMOD_FOUR_LINE_DISPLAY, USERMOD_DALLASTEMPERATURE
|
||||
; olikraus/U8g2 @ ^2.28.8 ; used for USERMOD_FOUR_LINE_DISPLAY
|
||||
https://github.com/kosme/arduinoFFT#develop @ 1.9.2 ; used for USERMOD_AUDIOREACTIVE
|
||||
ElectronicCats/MPU6050 @ 0.6.0 ; used for USERMOD_MPU6050_IMU
|
||||
monitor_filters = esp32_exception_decoder ; used to show crash details
|
||||
board_build.partitions = ${esp32.default_partitions}
|
||||
; board_build.partitions = tools/WLED_ESP32_16MB.csv
|
||||
; board_build.partitions = tools/WLED_ESP32-wrover_4MB.csv
|
||||
board_build.f_flash = 80000000L ; explain
|
||||
board_build.flash_mode = dio ; explain (dio vs qio?)
|
||||
|
||||
[env:esp8266mdev]
|
||||
extends = env:d1_mini
|
||||
upload_speed = 460800 ;115200
|
||||
build_flags = ${common.build_flags_esp8266}
|
||||
-D WLED_DEBUG
|
||||
-D WLED_DISABLE_ALEXA
|
||||
-D WLED_DISABLE_BLYNK
|
||||
-D WLED_DISABLE_HUESYNC
|
||||
; -D WLED_DISABLE_2D
|
||||
; -D WLED_DISABLE_AUDIO
|
||||
; -D USERMOD_AUDIOREACTIVE
|
||||
-UWLED_USE_MY_CONFIG
|
||||
; monitor_filters = esp8266_exception_decoder
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# custom board configurations
|
||||
# ------------------------------------------------------------------------------
|
||||
@@ -444,21 +525,33 @@ lib_deps = ${esp8266.lib_deps}
|
||||
[env:wemos_shield_esp32]
|
||||
board = esp32dev
|
||||
platform = espressif32@3.2
|
||||
upload_speed = 460800
|
||||
upload_speed = 460800 ; or 921600
|
||||
build_unflags = ${common.build_unflags}
|
||||
build_flags = ${common.build_flags_esp32}
|
||||
-D ABL_MILLIAMPS_DEFAULT=1500 ; 850 not enough for 1024 leds
|
||||
-D WLED_MAX_USERMODS=8
|
||||
-D LEDPIN=16
|
||||
-D RLYPIN=19
|
||||
-D BTNPIN=17
|
||||
-D IRPIN=18
|
||||
-D UWLED_USE_MY_CONFIG
|
||||
-D USERMOD_DALLASTEMPERATURE
|
||||
-D USERMOD_FOUR_LINE_DISPLAY
|
||||
-D TEMPERATURE_PIN=23
|
||||
-D USERMOD_CUSTOMEFFECTS
|
||||
-D USERMOD_AUDIOREACTIVE -D AUDIOPIN=-1 -D DMTYPE=1 -D I2S_SDPIN=32 -D I2S_WSPIN=15 -D I2S_CKPIN=14
|
||||
-D UM_AUDIOREACTIVE_USE_NEW_FFT
|
||||
-D USERMOD_DALLASTEMPERATURE -D TEMPERATURE_PIN=23
|
||||
-D USE_ALT_DISPlAY
|
||||
-D USERMOD_FOUR_LINE_DISPLAY -D FLD_PIN_SCL=22 -D FLD_PIN_SDA=21
|
||||
-D USERMOD_ROTARY_ENCODER_UI ; -D ENCODER_DT_PIN=18 -D ENCODER_CLK_PIN=5 -D ENCODER_SW_PIN=19
|
||||
-D USERMOD_AUTO_SAVE
|
||||
-D USERMOD_WEATHER
|
||||
-D USERMOD_GAMES
|
||||
; -D WLED_DEBUG
|
||||
lib_deps = ${esp32.lib_deps}
|
||||
OneWire@~2.3.5
|
||||
olikraus/U8g2 @ ^2.28.8
|
||||
https://github.com/kosme/arduinoFFT#develop @ 1.9.2
|
||||
board_build.partitions = ${esp32.default_partitions}
|
||||
; board_build.partitions = tools/WLED_ESP32_16MB.csv
|
||||
|
||||
[env:m5atom]
|
||||
board = esp32dev
|
||||
|
||||
@@ -20,9 +20,9 @@ react to the globes orientation. See the blog post on building it <https://www.r
|
||||
|
||||
I2Cdev and MPU6050 must be installed.
|
||||
|
||||
To install them, add I2Cdevlib-MPU6050@fbde122cc5 to lib_deps in the platformio.ini file.
|
||||
To install them, add ElectronicCats/MPU6050 @ 0.6.0 to lib_deps in the platformio.ini file.
|
||||
|
||||
You also need to change lib_compat_mode from strict to soft in platformio.ini (This ignores that I2Cdevlib-MPU6050 doesn't list platform compatibility)
|
||||
<!-- You also need to change lib_compat_mode from strict to soft in platformio.ini (This ignores that I2Cdevlib-MPU6050 doesn't list platform compatibility) -->
|
||||
|
||||
For example:
|
||||
|
||||
@@ -36,7 +36,7 @@ lib_deps =
|
||||
AsyncTCP@1.0.3
|
||||
Esp Async WebServer@1.2.0
|
||||
IRremoteESP8266@2.7.3
|
||||
I2Cdevlib-MPU6050@fbde122cc5
|
||||
ElectronicCats/MPU6050 @ 0.6.0
|
||||
```
|
||||
|
||||
## Wiring
|
||||
@@ -77,18 +77,19 @@ to the info object
|
||||
|
||||
## Usermod installation
|
||||
|
||||
1. Copy the file `usermod_mpu6050_imu.h` to the `wled00` directory.
|
||||
2. Register the usermod by adding `#include "usermod_mpu6050_imu.h.h"` in the top and `registerUsermod(new MPU6050Driver());` in the bottom of `usermods_list.cpp`.
|
||||
<!-- 1. Copy the file `usermod_mpu6050_imu.h` to the `wled00` directory. -->
|
||||
2. Register the usermod by adding `#include "usermod_mpu6050_imu.h"` in the top and `registerUsermod(new MPU6050Driver());` in the bottom of `usermods_list.cpp`.
|
||||
|
||||
Example **usermods_list.cpp**:
|
||||
|
||||
```cpp
|
||||
#include "wled.h"
|
||||
|
||||
#include "usermod_mpu6050_imu.h"
|
||||
#ifdef USERMOD_MPU6050_IMU
|
||||
#include "../usermods/mpu6050_imu/usermod_mpu6050_imu.h"
|
||||
#endif
|
||||
|
||||
void registerUsermods()
|
||||
{
|
||||
#ifdef USERMOD_MPU6050_IMU
|
||||
usermods.add(new MPU6050Driver());
|
||||
}
|
||||
#endif
|
||||
```
|
||||
|
||||
@@ -2,6 +2,17 @@
|
||||
|
||||
#include "wled.h"
|
||||
|
||||
#ifdef WLED_DEBUG
|
||||
#define DEBUG_PRINT_IMU(x) Serial.print(x)
|
||||
#define DEBUG_PRINT_IMULN(x) Serial.println(x)
|
||||
#define DEBUG_PRINT_IMUF(x...) Serial.printf(x)
|
||||
#else
|
||||
#define DEBUG_PRINT_IMU(x)
|
||||
#define DEBUG_PRINT_IMULN(x)
|
||||
#define DEBUG_PRINT_IMUF(x...)
|
||||
#endif
|
||||
|
||||
|
||||
/* This driver reads quaternion data from the MPU6060 and adds it to the JSON
|
||||
This example is adapted from:
|
||||
https://github.com/jrowberg/i2cdevlib/tree/master/Arduino/MPU6050/examples/MPU6050_DMP6_ESPWiFi
|
||||
@@ -26,15 +37,14 @@
|
||||
2. Register the usermod by adding #include "usermod_filename.h" in the top and registerUsermod(new MyUsermodClass()) in the bottom of usermods_list.cpp
|
||||
3. I2Cdev and MPU6050 must be installed as libraries, or else the .cpp/.h file
|
||||
for both classes must be in the include path of your project. To install the
|
||||
libraries add I2Cdevlib-MPU6050@fbde122cc5 to lib_deps in the platformio.ini file.
|
||||
4. You also need to change lib_compat_mode from strict to soft in platformio.ini (This ignores that I2Cdevlib-MPU6050 doesn't list platform compatibility)
|
||||
libraries add ElectronicCats/MPU6050 @ 0.6.0 to lib_deps in the platformio.ini file.
|
||||
// 4. You also need to change lib_compat_mode from strict to soft in platformio.ini (This ignores that I2Cdevlib-MPU6050 doesn't list platform compatibility)
|
||||
5. Wire up the MPU6050 as detailed above.
|
||||
*/
|
||||
|
||||
#include "I2Cdev.h"
|
||||
|
||||
#include "MPU6050_6Axis_MotionApps20.h"
|
||||
//#include "MPU6050.h" // not necessary if using MotionApps include file
|
||||
|
||||
// Arduino Wire library is required if I2Cdev I2CDEV_ARDUINO_WIRE implementation
|
||||
// is used in I2Cdev.h
|
||||
@@ -56,6 +66,7 @@ class MPU6050Driver : public Usermod {
|
||||
private:
|
||||
MPU6050 mpu;
|
||||
bool enabled = true;
|
||||
unsigned long lastUMRun = millis();
|
||||
|
||||
// MPU control/status vars
|
||||
bool dmpReady = false; // set true if DMP init was successful
|
||||
@@ -65,47 +76,61 @@ class MPU6050Driver : public Usermod {
|
||||
uint16_t fifoCount; // count of all bytes currently in FIFO
|
||||
uint8_t fifoBuffer[64]; // FIFO storage buffer
|
||||
|
||||
//NOTE: some of these can be removed to save memory, processing time
|
||||
// if the measurement isn't needed
|
||||
public:
|
||||
// orientation/motion vars
|
||||
Quaternion qat; // [w, x, y, z] quaternion container
|
||||
float euler[3]; // [psi, theta, phi] Euler angle container
|
||||
float ypr[3]; // [yaw, pitch, roll] yaw/pitch/roll container
|
||||
VectorInt16 aa; // [x, y, z] accel sensor measurements
|
||||
VectorInt16 gy; // [x, y, z] gyro sensor measurements
|
||||
VectorInt16 aaReal; // [x, y, z] gravity-free accel sensor measurements
|
||||
VectorInt16 aaWorld; // [x, y, z] world-frame accel sensor measurements
|
||||
VectorFloat gravity; // [x, y, z] gravity vector
|
||||
float euler[3]; // [psi, theta, phi] Euler angle container
|
||||
float ypr[3]; // [yaw, pitch, roll] yaw/pitch/roll container and gravity vector
|
||||
|
||||
static const int INTERRUPT_PIN = 15; // use pin 15 on ESP8266
|
||||
|
||||
public:
|
||||
//Functions called by WLED
|
||||
|
||||
/*
|
||||
* setup() is called once at boot. WiFi is not yet connected at this point.
|
||||
*/
|
||||
void setup() {
|
||||
DEBUG_PRINT_IMULN("mpu setup");
|
||||
PinManagerPinType pins[2] = { { i2c_scl, true }, { i2c_sda, true } };
|
||||
if (!pinManager.allocateMultiplePins(pins, 2, PinOwner::HW_I2C)) { enabled = false; return; }
|
||||
|
||||
// join I2C bus (I2Cdev library doesn't do this automatically)
|
||||
#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
|
||||
Wire.begin();
|
||||
Wire.setClock(400000); // 400kHz I2C clock. Comment this line if having compilation difficulties
|
||||
Wire.begin();
|
||||
Wire.setClock(400000); // 400kHz I2C clock. Comment this line if having compilation difficulties
|
||||
#elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE
|
||||
Fastwire::setup(400, true);
|
||||
Fastwire::setup(400, true);
|
||||
#endif
|
||||
|
||||
// // initialize serial communication
|
||||
// // (115200 chosen because it is required for Teapot Demo output, but it's
|
||||
// // really up to you depending on your project)
|
||||
// Serial.begin(115200);
|
||||
// while (!Serial); // wait for Leonardo enumeration, others continue immediately
|
||||
|
||||
// NOTE: 8MHz or slower host processors, like the Teensy @ 3.3V or Arduino
|
||||
// Pro Mini running at 3.3V, cannot handle this baud rate reliably due to
|
||||
// the baud timing being too misaligned with processor ticks. You must use
|
||||
// 38400 or slower in these cases, or use some kind of external separate
|
||||
// crystal solution for the UART timer.
|
||||
|
||||
// initialize device
|
||||
DEBUG_PRINTLN(F("Initializing I2C devices..."));
|
||||
DEBUG_PRINT_IMULN(F("Initializing I2C devices..."));
|
||||
mpu.initialize();
|
||||
pinMode(INTERRUPT_PIN, INPUT);
|
||||
|
||||
// verify connection
|
||||
DEBUG_PRINTLN(F("Testing device connections..."));
|
||||
DEBUG_PRINTLN(mpu.testConnection() ? F("MPU6050 connection successful") : F("MPU6050 connection failed"));
|
||||
DEBUG_PRINT_IMULN(F("Testing device connections..."));
|
||||
DEBUG_PRINT_IMULN(mpu.testConnection() ? F("MPU6050 connection successful") : F("MPU6050 connection failed"));
|
||||
|
||||
// // wait for ready
|
||||
// DEBUG_PRINT_IMULN(F("\nSend any character to begin DMP programming and demo: "));
|
||||
// while (Serial.available() && Serial.read()); // empty buffer
|
||||
// while (!Serial.available()); // wait for data
|
||||
// while (Serial.available() && Serial.read()); // empty buffer again
|
||||
|
||||
// load and configure the DMP
|
||||
DEBUG_PRINTLN(F("Initializing DMP..."));
|
||||
DEBUG_PRINT_IMULN(F("Initializing DMP..."));
|
||||
devStatus = mpu.dmpInitialize();
|
||||
|
||||
// supply your own gyro offsets here, scaled for min sensitivity
|
||||
@@ -116,77 +141,52 @@ class MPU6050Driver : public Usermod {
|
||||
|
||||
// make sure it worked (returns 0 if so)
|
||||
if (devStatus == 0) {
|
||||
// turn on the DMP, now that it's ready
|
||||
DEBUG_PRINTLN(F("Enabling DMP..."));
|
||||
mpu.setDMPEnabled(true);
|
||||
// Calibration Time: generate offsets and calibrate our MPU6050
|
||||
mpu.CalibrateAccel(6);
|
||||
mpu.CalibrateGyro(6);
|
||||
#ifdef WLED_DEBUG
|
||||
mpu.PrintActiveOffsets();
|
||||
#endif
|
||||
// turn on the DMP, now that it's ready
|
||||
DEBUG_PRINT_IMULN(F("Enabling DMP..."));
|
||||
mpu.setDMPEnabled(true);
|
||||
|
||||
// enable Arduino interrupt detection
|
||||
DEBUG_PRINTLN(F("Enabling interrupt detection (Arduino external interrupt 0)..."));
|
||||
attachInterrupt(digitalPinToInterrupt(INTERRUPT_PIN), dmpDataReady, RISING);
|
||||
mpuIntStatus = mpu.getIntStatus();
|
||||
// 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
|
||||
DEBUG_PRINTLN(F("DMP ready! Waiting for first interrupt..."));
|
||||
dmpReady = true;
|
||||
// set our DMP Ready flag so the main loop() function knows it's okay to use it
|
||||
DEBUG_PRINT_IMULN(F("DMP ready! Waiting for first interrupt..."));
|
||||
dmpReady = true;
|
||||
|
||||
// get expected DMP packet size for later comparison
|
||||
packetSize = mpu.dmpGetFIFOPacketSize();
|
||||
// get expected DMP packet size for later comparison
|
||||
packetSize = mpu.dmpGetFIFOPacketSize();
|
||||
} else {
|
||||
// ERROR!
|
||||
// 1 = initial memory load failed
|
||||
// 2 = DMP configuration updates failed
|
||||
// (if it's going to break, usually the code will be 1)
|
||||
DEBUG_PRINT(F("DMP Initialization failed (code "));
|
||||
DEBUG_PRINT(devStatus);
|
||||
DEBUG_PRINTLN(F(")"));
|
||||
// ERROR!
|
||||
// 1 = initial memory load failed
|
||||
// 2 = DMP configuration updates failed
|
||||
// (if it's going to break, usually the code will be 1)
|
||||
DEBUG_PRINT_IMU(F("DMP Initialization failed (code "));
|
||||
DEBUG_PRINT_IMU(devStatus);
|
||||
DEBUG_PRINT_IMULN(F(")"));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* connected() is called every time the WiFi is (re)connected
|
||||
* Use it to initialize network interfaces
|
||||
*/
|
||||
void connected() {
|
||||
//DEBUG_PRINTLN("Connected to WiFi!");
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* loop() is called continuously. Here you can check for events, read sensors, etc.
|
||||
*/
|
||||
void loop() {
|
||||
// if programming failed, don't try to do anything
|
||||
if (!enabled || !dmpReady || strip.isUpdating()) return;
|
||||
|
||||
// wait for MPU interrupt or extra packet(s) available
|
||||
if (!mpuInterrupt && fifoCount < packetSize) return;
|
||||
|
||||
// reset interrupt flag and get INT_STATUS byte
|
||||
mpuInterrupt = false;
|
||||
mpuIntStatus = mpu.getIntStatus();
|
||||
|
||||
// get current FIFO count
|
||||
fifoCount = mpu.getFIFOCount();
|
||||
|
||||
// check for overflow (this should never happen unless our code is too inefficient)
|
||||
if ((mpuIntStatus & 0x10) || fifoCount == 1024) {
|
||||
// reset so we can continue cleanly
|
||||
mpu.resetFIFO();
|
||||
DEBUG_PRINTLN(F("FIFO overflow!"));
|
||||
|
||||
// otherwise, check for DMP data ready interrupt (this should happen frequently)
|
||||
} else if (mpuIntStatus & 0x02) {
|
||||
// wait for correct available data length, should be a VERY short wait
|
||||
while (fifoCount < packetSize) fifoCount = mpu.getFIFOCount();
|
||||
|
||||
// read a packet from FIFO
|
||||
mpu.getFIFOBytes(fifoBuffer, packetSize);
|
||||
|
||||
// track FIFO count here in case there is > 1 packet available
|
||||
// (this lets us immediately read more without waiting for an interrupt)
|
||||
fifoCount -= packetSize;
|
||||
|
||||
if (!enabled || (strip.isUpdating() && (millis() - lastUMRun < 2))) return; // be nice, but not too nice
|
||||
lastUMRun = millis(); // update time keeping
|
||||
|
||||
if (!dmpReady) return;
|
||||
// read a packet from FIFO
|
||||
if (mpu.dmpGetCurrentFIFOPacket(fifoBuffer)) { // Get the Latest packet
|
||||
//NOTE: some of these can be removed to save memory, processing time
|
||||
// if the measurement isn't needed
|
||||
mpu.dmpGetQuaternion(&qat, fifoBuffer);
|
||||
@@ -200,25 +200,24 @@ class MPU6050Driver : public Usermod {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void addToJsonInfo(JsonObject& root)
|
||||
{
|
||||
int reading = 20;
|
||||
//this code adds "u":{"Light":[20," lux"]} to the info object
|
||||
JsonObject user = root["u"];
|
||||
if (user.isNull()) user = root.createNestedObject("u");
|
||||
|
||||
JsonArray imu_meas = user.createNestedObject("IMU");
|
||||
StaticJsonDocument<600> doc; //measured 528
|
||||
|
||||
JsonObject imu_meas = doc.createNestedObject("IMU");
|
||||
#ifdef WLED_DEBUG
|
||||
JsonArray quat_json = imu_meas.createNestedArray("Quat");
|
||||
quat_json.add(qat.w);
|
||||
quat_json.add(qat.x);
|
||||
quat_json.add(qat.y);
|
||||
quat_json.add(qat.z);
|
||||
JsonArray euler_json = imu_meas.createNestedArray("Euler");
|
||||
euler_json.add(euler[0]);
|
||||
euler_json.add(euler[1]);
|
||||
euler_json.add(euler[2]);
|
||||
euler_json.add(euler[0] * 180/M_PI);
|
||||
euler_json.add(euler[1] * 180/M_PI);
|
||||
euler_json.add(euler[2] * 180/M_PI);
|
||||
JsonArray accel_json = imu_meas.createNestedArray("Accel");
|
||||
accel_json.add(aa.x);
|
||||
accel_json.add(aa.y);
|
||||
@@ -227,10 +226,6 @@ class MPU6050Driver : public Usermod {
|
||||
gyro_json.add(gy.x);
|
||||
gyro_json.add(gy.y);
|
||||
gyro_json.add(gy.z);
|
||||
JsonArray world_json = imu_meas.createNestedArray("WorldAccel");
|
||||
world_json.add(aaWorld.x);
|
||||
world_json.add(aaWorld.y);
|
||||
world_json.add(aaWorld.z);
|
||||
JsonArray real_json = imu_meas.createNestedArray("RealAccel");
|
||||
real_json.add(aaReal.x);
|
||||
real_json.add(aaReal.y);
|
||||
@@ -239,49 +234,54 @@ class MPU6050Driver : public Usermod {
|
||||
grav_json.add(gravity.x);
|
||||
grav_json.add(gravity.y);
|
||||
grav_json.add(gravity.z);
|
||||
JsonArray orient_json = imu_meas.createNestedArray("Orientation");
|
||||
orient_json.add(ypr[0]);
|
||||
orient_json.add(ypr[1]);
|
||||
orient_json.add(ypr[2]);
|
||||
#endif
|
||||
JsonArray world_json = imu_meas.createNestedArray("WorldAccel");
|
||||
world_json.add(aaWorld.x);
|
||||
world_json.add(aaWorld.y);
|
||||
world_json.add(aaWorld.z);
|
||||
JsonArray orient_json = imu_meas.createNestedArray("YPR");
|
||||
orient_json.add(ypr[0] * 180/M_PI);
|
||||
orient_json.add(ypr[1] * 180/M_PI);
|
||||
orient_json.add(ypr[2] * 180/M_PI);
|
||||
|
||||
char stringBuffer[300]; // measured 266
|
||||
serializeJson(imu_meas, stringBuffer);
|
||||
JsonArray mainObject = user.createNestedArray("IMU");
|
||||
mainObject.add(stringBuffer);
|
||||
|
||||
// Serial.printf("imu_meas %u (%u %u) stringBuffer %u\n", (unsigned int)imu_meas.memoryUsage(), (unsigned int)imu_meas.size(), (unsigned int)imu_meas.nesting(), strlen(stringBuffer));
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* addToJsonState() can be used to add custom entries to the /json/state part of the JSON API (state object).
|
||||
* Values in the state object may be modified by connected clients
|
||||
*/
|
||||
//void addToJsonState(JsonObject& root)
|
||||
//{
|
||||
//root["user0"] = userVar0;
|
||||
//}
|
||||
|
||||
|
||||
/*
|
||||
* readFromJsonState() can be used to receive data clients send to the /json/state part of the JSON API (state object).
|
||||
* Values in the state object may be modified by connected clients
|
||||
*/
|
||||
//void readFromJsonState(JsonObject& root)
|
||||
//{
|
||||
//if (root["bri"] == 255) DEBUG_PRINTLN(F("Don't burn down your garage!"));
|
||||
//}
|
||||
|
||||
// void addToConfig(JsonObject& root)
|
||||
// {
|
||||
// JsonObject top = root.createNestedObject("MPU6050");
|
||||
// top[FPSTR("enabled")] = enabled;
|
||||
|
||||
/*
|
||||
* addToConfig() can be used to add custom persistent settings to the cfg.json file in the "um" (usermod) object.
|
||||
* It will be called by WLED when settings are actually saved (for example, LED settings are saved)
|
||||
* I highly recommend checking out the basics of ArduinoJson serialization and deserialization in order to use custom settings!
|
||||
*/
|
||||
// void addToConfig(JsonObject& root)
|
||||
// {
|
||||
// JsonObject top = root.createNestedObject("MPU6050_IMU");
|
||||
// JsonArray pins = top.createNestedArray("pin");
|
||||
// pins.add(HW_PIN_SCL);
|
||||
// pins.add(HW_PIN_SDA);
|
||||
// }
|
||||
// JsonObject interruptPin = top.createNestedObject(FPSTR("interruptPin"));
|
||||
// interruptPin["pin"] = interruptPin;
|
||||
// }
|
||||
|
||||
// bool readFromConfig(JsonObject& root)
|
||||
// {
|
||||
// JsonObject top = root[FPSTR("MPU6050")];
|
||||
// bool configComplete = !top.isNull();
|
||||
|
||||
// configComplete &= getJsonValue(top[FPSTR("enabled")], enabled);
|
||||
// configComplete &= getJsonValue(top[FPSTR("interruptPin")]["pin"], interruptPin);
|
||||
|
||||
// return configComplete;
|
||||
// }
|
||||
|
||||
/*
|
||||
* getId() allows you to optionally give your V2 usermod an unique ID (please define it in const.h!).
|
||||
*/
|
||||
uint16_t getId()
|
||||
{
|
||||
return USERMOD_ID_IMU;
|
||||
|
||||
@@ -1,25 +1,19 @@
|
||||
/*
|
||||
Games usermod by ewowi, september 2022
|
||||
|
||||
Contains:
|
||||
- mode_pongGame
|
||||
- Depending on USERMOD_MPU6050_IMU
|
||||
- mode_IMUTest (shows IMU values only if WLED_DEBUG)
|
||||
- class Frame3D and struct Voxel
|
||||
- mode_3DIMUCube (uses class Frame3D to show a rotating cube, if USERMOD_MPU6050_IMU then IMU used for rotation)
|
||||
- class GamesUsermod (Add the modes/effects and initiates IMU)
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "wled.h"
|
||||
|
||||
/*
|
||||
* Usermods allow you to add own functionality to WLED more easily
|
||||
* See: https://github.com/Aircoookie/WLED/wiki/Add-own-functionality
|
||||
*
|
||||
* This is an example for a v2 usermod.
|
||||
* v2 usermods are class inheritance based and can (but don't have to) implement more functions, each of them is shown in this example.
|
||||
* Multiple v2 usermods can be added to one compilation easily.
|
||||
*
|
||||
* Creating a usermod:
|
||||
* This file serves as an example. If you want to create a usermod, it is recommended to use usermod_v2_empty.h from the usermods folder as a template.
|
||||
* Please remember to rename the class and file to a descriptive name.
|
||||
* You may also use multiple .h and .cpp files.
|
||||
*
|
||||
* Using a usermod:
|
||||
* 1. Copy the usermod into the sketch folder (same folder as wled00.ino)
|
||||
* 2. Register the usermod by adding #include "usermod_filename.h" in the top and registerUsermod(new MyUsermodClass()) in the bottom of usermods_list.cpp
|
||||
*/
|
||||
|
||||
//inspired by https://noobtuts.com/cpp/2d-pong-game
|
||||
typedef struct PongBall {
|
||||
float x;// = SEGMENT.virtualWidth() / 2;
|
||||
@@ -181,94 +175,170 @@ uint16_t mode_pongGame(void) {
|
||||
static const char _data_FX_MODE_PONGGAME[] PROGMEM = "🎮 Pong@!;!;!;2d";
|
||||
|
||||
//https://howtomechatronics.com/tutorials/arduino/arduino-and-mpu6050-accelerometer-and-gyroscope-tutorial/
|
||||
#define MPU_ADDR 0x68 // I2C address of the MPU-6050. If AD0 pin is set to HIGH, the I2C address will be 0x69.
|
||||
int16_t accelerometer_x, accelerometer_y, accelerometer_z; // variables for accelerometer raw data
|
||||
int16_t gyro_x, gyro_y, gyro_z; // variables for gyro raw data
|
||||
int16_t temperature; // variables for temperature data
|
||||
|
||||
uint16_t mode_gyro(void) {
|
||||
#ifdef USERMOD_MPU6050_IMU
|
||||
MPU6050Driver *IMU = nullptr;
|
||||
uint16_t mode_IMUTest(void) {
|
||||
SEGMENT.fill(BLACK);
|
||||
|
||||
uint8_t y = 0;
|
||||
|
||||
SEGMENT.setPixelColorXY(SEGMENT.virtualWidth() * (accelerometer_x+INT16_MAX)/(2*INT16_MAX), y+=2, BLUE);
|
||||
SEGMENT.setPixelColorXY(SEGMENT.virtualWidth() * (accelerometer_y+INT16_MAX)/(2*INT16_MAX), y+=2, BLUE);
|
||||
SEGMENT.setPixelColorXY(SEGMENT.virtualWidth() * (accelerometer_z+INT16_MAX)/(2*INT16_MAX), y+=2, BLUE);
|
||||
SEGMENT.setPixelColorXY(SEGMENT.virtualWidth() * (gyro_x+INT16_MAX)/(2*INT16_MAX), y+=2, BLUE);
|
||||
SEGMENT.setPixelColorXY(SEGMENT.virtualWidth() * (gyro_y+INT16_MAX)/(2*INT16_MAX), y+=2, BLUE);
|
||||
SEGMENT.setPixelColorXY(SEGMENT.virtualWidth() * (gyro_z+INT16_MAX)/(2*INT16_MAX), y+=2, BLUE);
|
||||
if (IMU != nullptr) {
|
||||
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);
|
||||
|
||||
SEGMENT.setPixelColorXY(SEGMENT.virtualWidth() * (IMU->aaReal.x+INT16_MAX)/(2*INT16_MAX), y+=1, BLUE);
|
||||
SEGMENT.setPixelColorXY(SEGMENT.virtualWidth() * (IMU->aaReal.y+INT16_MAX)/(2*INT16_MAX), y+=1, BLUE);
|
||||
SEGMENT.setPixelColorXY(SEGMENT.virtualWidth() * (IMU->aaReal.z+INT16_MAX)/(2*INT16_MAX), y+=1, BLUE);
|
||||
|
||||
SEGMENT.setPixelColorXY(SEGMENT.virtualWidth() * (IMU->gy.x+1024)/(2*1024), y+=1, RED);
|
||||
SEGMENT.setPixelColorXY(SEGMENT.virtualWidth() * (IMU->gy.y+1024)/(2*1024), y+=1, RED);
|
||||
SEGMENT.setPixelColorXY(SEGMENT.virtualWidth() * (IMU->gy.z+1024)/(2*1024), y+=1, RED);
|
||||
|
||||
SEGMENT.setPixelColorXY(SEGMENT.virtualWidth() * (IMU->aaWorld.x+INT16_MAX)/(2*INT16_MAX), y+=1, BLUE);
|
||||
SEGMENT.setPixelColorXY(SEGMENT.virtualWidth() * (IMU->aaWorld.y+INT16_MAX)/(2*INT16_MAX), y+=1, BLUE);
|
||||
SEGMENT.setPixelColorXY(SEGMENT.virtualWidth() * (IMU->aaWorld.z+INT16_MAX)/(2*INT16_MAX), y+=1, BLUE);
|
||||
|
||||
SEGMENT.setPixelColorXY(SEGMENT.virtualWidth() * (IMU->ypr[0]* 180/M_PI+180)/(2*180), y+=1, RED);
|
||||
SEGMENT.setPixelColorXY(SEGMENT.virtualWidth() * (IMU->ypr[1]* 180/M_PI+180)/(2*180), y+=1, RED);
|
||||
SEGMENT.setPixelColorXY(SEGMENT.virtualWidth() * (IMU->ypr[2]* 180/M_PI+180)/(2*180), y+=1, RED);
|
||||
}
|
||||
|
||||
return FRAMETIME;
|
||||
}
|
||||
static const char _data_FX_MODE_GYRO[] PROGMEM = "🎮 Gyro@!;!;!;2d";
|
||||
static const char _data_FX_MODE_IMUTest[] PROGMEM = "🎮 IMUTest@;;;2d";
|
||||
|
||||
#ifndef FLD_PIN_SCL
|
||||
#define FLD_PIN_SCL i2c_scl
|
||||
#endif
|
||||
#ifndef FLD_PIN_SDA
|
||||
#define FLD_PIN_SDA i2c_sda
|
||||
#endif
|
||||
|
||||
//WLEDSR 3D to 2D mapping
|
||||
struct Voxel {
|
||||
float x;
|
||||
float y;
|
||||
float z;
|
||||
uint32_t col;
|
||||
};
|
||||
|
||||
class Frame3D {
|
||||
private:
|
||||
std::vector<Voxel> points;
|
||||
void rotate(float a, float b, float angle, float &x, float &y) {
|
||||
x = cosf(angle) * a - sinf(angle) * b;
|
||||
y = sinf(angle) * a + cosf(angle) * b;
|
||||
}
|
||||
float yaw;
|
||||
float pitch;
|
||||
float roll;
|
||||
public:
|
||||
Frame3D(float yaw1, float pitch1, float roll1) {
|
||||
points.clear();
|
||||
yaw = yaw1;
|
||||
pitch = pitch1;
|
||||
roll = roll1;
|
||||
}
|
||||
~Frame3D() {
|
||||
std::sort(points.begin(), points.end(), [](const Voxel &lhs, const Voxel &rhs) {return lhs.z > rhs.z;});
|
||||
for(size_t i = 0; i < points.size(); ++i) {
|
||||
float w = 0.5;//SEGMENT.virtualWidth()/2;
|
||||
float h = 0.5;//SEGMENT.virtualHeight()/2;
|
||||
float perspective = SEGMENT.intensity / 64.0;
|
||||
if(points[i].z > 0) {
|
||||
float projX, projY;
|
||||
projX = w+points[i].x/points[i].z*perspective;
|
||||
projY = h+points[i].y/points[i].z*perspective;
|
||||
SEGMENT.setPixelColorXY(projX, projY, points[i].col, false); //no aa
|
||||
}
|
||||
}
|
||||
}
|
||||
void setPixelColorXYZ(Voxel voxel) {
|
||||
float camx = 0;
|
||||
float camy = 0;
|
||||
float camz = -6;
|
||||
rotate(voxel.x,voxel.z,yaw, voxel.x, voxel.z); // Camera yaw
|
||||
rotate(voxel.y,voxel.z,pitch, voxel.y, voxel.z); // Camera pitch
|
||||
rotate(voxel.x,voxel.y,roll, voxel.x, voxel.y); // Camera roll
|
||||
voxel.x -= camx;
|
||||
voxel.y -= camy;
|
||||
voxel.z -= camz;
|
||||
points.push_back(voxel);
|
||||
}
|
||||
void drawLineXYZ(Voxel from, Voxel to, uint32_t col) {
|
||||
for (float x=MIN(from.x, to.x); x<=MAX(from.x, to.x); x+=.05)
|
||||
for (float y=MIN(from.y, to.y); y<=MAX(from.y, to.y); y+=.05)
|
||||
for (float z=MIN(from.z, to.z); z<=MAX(from.z, to.z); z+=.05)
|
||||
setPixelColorXYZ({x, y, z, col});
|
||||
}
|
||||
};
|
||||
|
||||
uint16_t mode_3DIMUCube(void) {
|
||||
SEGMENT.fill(BLACK);
|
||||
|
||||
float yaw = 0;
|
||||
float pitch = 0;
|
||||
float roll = 0;
|
||||
|
||||
#ifdef USERMOD_MPU6050_IMU
|
||||
if (IMU != nullptr) {
|
||||
yaw = -IMU->ypr[0];
|
||||
pitch = IMU->ypr[1];
|
||||
roll = IMU->ypr[2];
|
||||
}
|
||||
#else
|
||||
//simulate rotation
|
||||
yaw = (fmod(SEGENV.call, 360)-180) / (180/M_PI); //-180 .. 180
|
||||
pitch = yaw;
|
||||
roll = yaw;
|
||||
#endif
|
||||
|
||||
Frame3D frame3D = Frame3D(yaw, pitch, roll);
|
||||
|
||||
Voxel leftbottomback = {-1,-1,-1};
|
||||
Voxel rightbottomback = {1,-1,-1};
|
||||
Voxel lefttopback = {-1,1,-1};
|
||||
Voxel righttopback = {1,1,-1};
|
||||
Voxel leftbottomfront = {-1,-1,1};
|
||||
Voxel rightbottomfront = {1,-1,1};
|
||||
Voxel lefttopfront = {-1,1,1};
|
||||
Voxel righttopfront = {1,1,1};
|
||||
frame3D.drawLineXYZ(leftbottomback, rightbottomback, SEGMENT.color_from_palette(255/12, false, true, 0));
|
||||
frame3D.drawLineXYZ(leftbottomback, lefttopback, SEGMENT.color_from_palette(255/12*2, false, true, 0));
|
||||
frame3D.drawLineXYZ(rightbottomback, righttopback, SEGMENT.color_from_palette(255/12*3, false, true, 0));
|
||||
frame3D.drawLineXYZ(lefttopback, righttopback, SEGMENT.color_from_palette(255/12*4, false, true, 0));
|
||||
|
||||
frame3D.drawLineXYZ(leftbottomfront, leftbottomback, SEGMENT.color_from_palette(255/12*9, false, true, 0));
|
||||
frame3D.drawLineXYZ(rightbottomfront, rightbottomback, SEGMENT.color_from_palette(255/12*10, false, true, 0));
|
||||
frame3D.drawLineXYZ(lefttopfront, lefttopback, SEGMENT.color_from_palette(255/12*11, false, true, 0));
|
||||
frame3D.drawLineXYZ(righttopfront, righttopback, SEGMENT.color_from_palette(255/12*12, false, true, 0));
|
||||
|
||||
frame3D.drawLineXYZ(leftbottomfront, rightbottomfront, SEGMENT.color_from_palette(255/12*5, false, true, 0));
|
||||
frame3D.drawLineXYZ(leftbottomfront, lefttopfront, SEGMENT.color_from_palette(255/12*6, false, true, 0));
|
||||
frame3D.drawLineXYZ(rightbottomfront, righttopfront, SEGMENT.color_from_palette(255/12*7, false, true, 0));
|
||||
frame3D.drawLineXYZ(lefttopfront, righttopfront, SEGMENT.color_from_palette(255/12*8, false, true, 0));
|
||||
|
||||
return FRAMETIME;
|
||||
}
|
||||
static const char _data_FX_MODE_3DIMUCube[] PROGMEM = "🎮 3DIMUCube@,Perspective;!;!;,pal=1,2d"; //random cycle
|
||||
|
||||
class GamesUsermod : public Usermod {
|
||||
private:
|
||||
bool enabled = true;
|
||||
int8_t ioPin[5] = {FLD_PIN_SCL, FLD_PIN_SDA, -1, -1, -1}; // I2C pins: SCL, SDA
|
||||
unsigned long lastUMRun = millis();
|
||||
|
||||
public:
|
||||
//Functions called by WLED
|
||||
|
||||
void setup() {
|
||||
bool isHW;
|
||||
PinOwner po = PinOwner::UM_Unspecified;
|
||||
uint8_t hw_scl = i2c_scl<0 ? HW_PIN_SCL : i2c_scl;
|
||||
uint8_t hw_sda = i2c_sda<0 ? HW_PIN_SDA : i2c_sda;
|
||||
if (ioPin[0] < 0 || ioPin[1] < 0) {
|
||||
ioPin[0] = hw_scl;
|
||||
ioPin[1] = hw_sda;
|
||||
}
|
||||
isHW = (ioPin[0]==hw_scl && ioPin[1]==hw_sda);
|
||||
if (isHW) po = PinOwner::HW_I2C; // allow multiple allocations of HW I2C bus pins
|
||||
PinManagerPinType pins[2] = { {ioPin[0], true }, { ioPin[1], true } };
|
||||
if (!pinManager.allocateMultiplePins(pins, 2, po)) { enabled = false; return; }
|
||||
// PinManagerPinType pins[2] = { { i2c_scl, true }, { i2c_sda, true } };
|
||||
// if (!pinManager.allocateMultiplePins(pins, 2, PinOwner::HW_I2C)) { enabled = false; return; }
|
||||
Wire.begin();
|
||||
Wire.beginTransmission(MPU_ADDR); // Begins a transmission to the I2C slave (GY-521 board)
|
||||
Wire.write(0x6B); // PWR_MGMT_1 register
|
||||
Wire.write(0); // set to zero (wakes up the MPU-6050)
|
||||
Wire.endTransmission(true);
|
||||
|
||||
strip.addEffect(255, &mode_pongGame, _data_FX_MODE_PONGGAME);
|
||||
strip.addEffect(255, &mode_gyro, _data_FX_MODE_GYRO);
|
||||
#ifdef USERMOD_MPU6050_IMU
|
||||
IMU = (MPU6050Driver *)usermods.lookup(USERMOD_ID_IMU);
|
||||
#ifdef WLED_DEBUG
|
||||
strip.addEffect(255, &mode_IMUTest, _data_FX_MODE_IMUTest);
|
||||
#endif
|
||||
#endif
|
||||
strip.addEffect(255, &mode_3DIMUCube, _data_FX_MODE_3DIMUCube); //works also without IMU
|
||||
}
|
||||
|
||||
/*
|
||||
* connected() is called every time the WiFi is (re)connected
|
||||
* Use it to initialize network interfaces
|
||||
*/
|
||||
void connected() {
|
||||
//Serial.println("Connected to WiFi!");
|
||||
}
|
||||
|
||||
void loop() {
|
||||
if (!enabled || (strip.isUpdating() && (millis() - lastUMRun < 2))) return; // be nice, but not too nice
|
||||
lastUMRun = millis(); // update time keeping
|
||||
|
||||
Wire.beginTransmission(MPU_ADDR);
|
||||
Wire.write(0x3B); // starting with register 0x3B (ACCEL_XOUT_H) [MPU-6000 and MPU-6050 Register Map and Descriptions Revision 4.2, p.40]
|
||||
Wire.endTransmission(false); // the parameter indicates that the Arduino will send a restart. As a result, the connection is kept active.
|
||||
Wire.requestFrom(MPU_ADDR, 7*2); // request a total of 7*2=14 registers
|
||||
|
||||
// "Wire.read()<<8 | Wire.read();" means two registers are read and stored in the same variable
|
||||
accelerometer_x = Wire.read()<<8 | Wire.read(); // reading registers: 0x3B (ACCEL_XOUT_H) and 0x3C (ACCEL_XOUT_L)
|
||||
accelerometer_y = Wire.read()<<8 | Wire.read(); // reading registers: 0x3D (ACCEL_YOUT_H) and 0x3E (ACCEL_YOUT_L)
|
||||
accelerometer_z = Wire.read()<<8 | Wire.read(); // reading registers: 0x3F (ACCEL_ZOUT_H) and 0x40 (ACCEL_ZOUT_L)
|
||||
temperature = Wire.read()<<8 | Wire.read(); // reading registers: 0x41 (TEMP_OUT_H) and 0x42 (TEMP_OUT_L)
|
||||
gyro_x = Wire.read()<<8 | Wire.read(); // reading registers: 0x43 (GYRO_XOUT_H) and 0x44 (GYRO_XOUT_L)
|
||||
gyro_y = Wire.read()<<8 | Wire.read(); // reading registers: 0x45 (GYRO_YOUT_H) and 0x46 (GYRO_YOUT_L)
|
||||
gyro_z = Wire.read()<<8 | Wire.read(); // reading registers: 0x47 (GYRO_ZOUT_H) and 0x48 (GYRO_ZOUT_L)
|
||||
}
|
||||
|
||||
void addToJsonState(JsonObject& root)
|
||||
|
||||
@@ -136,6 +136,9 @@
|
||||
#include "../usermods/audioreactive/audio_reactive.h"
|
||||
#endif
|
||||
|
||||
#ifdef USERMOD_MPU6050_IMU
|
||||
#include "../usermods/mpu6050_imu/usermod_mpu6050_imu.h"
|
||||
#endif
|
||||
#ifdef USERMOD_GAMES
|
||||
#include "../usermods/usermod_v2_games/usermod_v2_games.h"
|
||||
#endif
|
||||
@@ -263,6 +266,11 @@ void registerUsermods()
|
||||
#ifdef USERMOD_AUDIOREACTIVE
|
||||
usermods.add(new AudioReactive());
|
||||
#endif
|
||||
|
||||
#ifdef USERMOD_MPU6050_IMU
|
||||
usermods.add(new MPU6050Driver());
|
||||
#endif
|
||||
|
||||
#ifdef USERMOD_GAMES
|
||||
usermods.add(new GamesUsermod());
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user