MPU6050 и Arduino, управление светодиодами
- Войдите на сайт для отправки комментариев
Вс, 25/08/2019 - 17:49
Всем привет!
Прошу помощи с кодом.
Нашёл на сайте код для управления светодиодами при помощи GY-521.
Вычленил из полного кода кусок для управления только четырьмя диодами (у автора реализована возможность переключения на управление большей группой диодов).
Получилось так:
const int frontLed = 3; const int bottomLed = 5; const int rightLed = 6; const int leftLed = 9; long int lastPrintTime; #include "I2Cdev.h" #include "MPU6050_6Axis_MotionApps20.h" #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE #include "Wire.h" #endif MPU6050 mpu; 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 // orientation/motion vars Quaternion q; // [w, x, y, z] quaternion container VectorInt16 aa; // [x, y, z] accel 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 volatile bool mpuInterrupt = false; // indicates whether MPU interrupt pin has gone high void setup() { #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE Wire.begin(); TWBR = 24; // 400kHz I2C clock (200kHz if CPU is 8MHz) #elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE Fastwire::setup(400, true); #endif Serial.begin(9600); while (!Serial); // wait for Leonardo enumeration, others continue immediately Serial.println(F("Initializing I2C devices...")); mpu.initialize(); Serial.println(F("Testing device connections...")); Serial.println(mpu.testConnection() ? F("MPU6050 connection successful") : F("MPU6050 connection failed")); Serial.println(F("Initializing DMP...")); devStatus = mpu.dmpInitialize(); mpu.setXGyroOffset(220); mpu.setYGyroOffset(76); mpu.setZGyroOffset(-85); mpu.setZAccelOffset(1788); // 1688 factory default for my test chip if (devStatus == 0) { // turn on the DMP, now that it's ready Serial.println(F("Enabling DMP...")); mpu.setDMPEnabled(true); Serial.println(F("Enabling interrupt detection (Arduino external interrupt 0)...")); attachInterrupt(0, dmpDataReady, RISING); mpuIntStatus = mpu.getIntStatus(); Serial.println(F("DMP ready! Waiting for first interrupt...")); dmpReady = true; packetSize = mpu.dmpGetFIFOPacketSize(); } else { Serial.print(F("DMP Initialization failed (code ")); Serial.print(devStatus); Serial.println(F(")")); } initializeLEDsSimple(); lastPrintTime = millis(); } void loop() { if (!dmpReady) return; mpuInterrupt = false; mpuIntStatus = mpu.getIntStatus(); fifoCount = mpu.getFIFOCount(); if ((mpuIntStatus & 0x10) || fifoCount == 1024) { mpu.resetFIFO(); Serial.println(F("FIFO overflow!")); } else if (mpuIntStatus & 0x02) { while (fifoCount < packetSize) { fifoCount = mpu.getFIFOCount(); } mpu.getFIFOBytes(fifoBuffer, packetSize); fifoCount -= packetSize; mpu.dmpGetQuaternion(&q, fifoBuffer); mpu.dmpGetGravity(&gravity, &q); mpu.dmpGetYawPitchRoll(ypr, &q, &gravity); int x = ypr[0] * 180/M_PI; int y = ypr[1] * 180/M_PI; int z = ypr[2] * 180/M_PI; Serial.print(y);Serial.print("\t");Serial.println(z); flashLEDsSimple(x, y, z); } } void initializeLEDsSimple() { pinMode(frontLed, OUTPUT); pinMode(bottomLed, OUTPUT); pinMode(rightLed, OUTPUT); pinMode(leftLed, OUTPUT); } void flashLEDsSimple(int x, int y, int z) { if (y > 0) { analogWrite(rightLed, y*4); analogWrite(leftLed, 0); } else { analogWrite(leftLed, y*4*-1); analogWrite(rightLed, 0); } if (z > 0) { analogWrite(bottomLed, z*4); analogWrite(frontLed, 0); } else { analogWrite(frontLed, z*4*-1); analogWrite(bottomLed, 0); } } void dmpDataReady() { mpuInterrupt = true; }
Всё работает (но если осталось ещё что-то лишнее, подскажите - вырежу).
Моя же задача сводится к тому, чтобы датчик управлял диодами относительно положения, в котором он находился при включении, а не относительно горизонта. Ну и направлять на светодиоды не аналоговый сигнал, а цифровой.
Попробовал собрать такой вариант:
const int frontLed = 3; const int bottomLed = 5; const int rightLed = 6; const int leftLed = 9; int x1; int y1; int z1; long int lastPrintTime; #include "I2Cdev.h" #include "MPU6050_6Axis_MotionApps20.h" #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE #include "Wire.h" #endif MPU6050 mpu; bool dmpReady = false; uint8_t mpuIntStatus; uint8_t devStatus; uint16_t packetSize; uint16_t fifoCount; uint8_t fifoBuffer[64]; // orientation/motion vars Quaternion q; VectorInt16 aa; VectorInt16 aaReal; VectorInt16 aaWorld; VectorFloat gravity; float euler[3]; float ypr[3]; volatile bool mpuInterrupt = false; void setup() { #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE Wire.begin(); TWBR = 24; // 400kHz I2C clock (200kHz if CPU is 8MHz) #elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE Fastwire::setup(400, true); #endif Serial.begin(9600); while (!Serial); Serial.println(F("Initializing I2C devices...")); mpu.initialize(); Serial.println(F("Testing device connections...")); Serial.println(mpu.testConnection() ? F("MPU6050 connection successful") : F("MPU6050 connection failed")); Serial.println(F("Initializing DMP...")); devStatus = mpu.dmpInitialize(); mpu.setXGyroOffset(220); mpu.setYGyroOffset(76); mpu.setZGyroOffset(-85); mpu.setZAccelOffset(1788); if (devStatus == 0) { // turn on the DMP, now that it's ready Serial.println(F("Enabling DMP...")); mpu.setDMPEnabled(true); Serial.println(F("Enabling interrupt detection (Arduino external interrupt 0)...")); attachInterrupt(0, dmpDataReady, RISING); mpuIntStatus = mpu.getIntStatus(); Serial.println(F("DMP ready! Waiting for first interrupt...")); dmpReady = true; packetSize = mpu.dmpGetFIFOPacketSize(); } else { Serial.print(F("DMP Initialization failed (code ")); Serial.print(devStatus); Serial.println(F(")")); } initializeLEDsSimple(); lastPrintTime = millis(); if (!dmpReady) return; mpuInterrupt = false; mpuIntStatus = mpu.getIntStatus(); fifoCount = mpu.getFIFOCount(); if ((mpuIntStatus & 0x10) || fifoCount == 1024) { mpu.resetFIFO(); Serial.println(F("FIFO overflow!")); } else if (mpuIntStatus & 0x02) { while (fifoCount < packetSize) { fifoCount = mpu.getFIFOCount(); } mpu.getFIFOBytes(fifoBuffer, packetSize); fifoCount -= packetSize; mpu.dmpGetQuaternion(&q, fifoBuffer); mpu.dmpGetGravity(&gravity, &q); mpu.dmpGetYawPitchRoll(ypr, &q, &gravity); x1 = ypr[0] * 180/M_PI; y1 = ypr[1] * 180/M_PI; z1 = ypr[2] * 180/M_PI; Serial.print(y1);Serial.print("\t");Serial.println(z1); } } void loop() { if (!dmpReady) return; mpuInterrupt = false; mpuIntStatus = mpu.getIntStatus(); fifoCount = mpu.getFIFOCount(); if ((mpuIntStatus & 0x10) || fifoCount == 1024) { mpu.resetFIFO(); Serial.println(F("FIFO overflow!")); } else if (mpuIntStatus & 0x02) { while (fifoCount < packetSize) { fifoCount = mpu.getFIFOCount(); } mpu.getFIFOBytes(fifoBuffer, packetSize); fifoCount -= packetSize; mpu.dmpGetQuaternion(&q, fifoBuffer); mpu.dmpGetGravity(&gravity, &q); mpu.dmpGetYawPitchRoll(ypr, &q, &gravity); int x = ypr[0] * 180/M_PI; int y = ypr[1] * 180/M_PI; int z = ypr[2] * 180/M_PI; Serial.print(y);Serial.print("\t");Serial.println(z); flashLEDsSimple(x, y, z, x1, y1, z1); } } void initializeLEDsSimple() { pinMode(frontLed, OUTPUT); pinMode(bottomLed, OUTPUT); pinMode(rightLed, OUTPUT); pinMode(leftLed, OUTPUT); } void flashLEDsSimple(int x, int y, int z, int x1, int y1, int z1) { if (y1 > y) { digitalWrite(rightLed, 1); digitalWrite(leftLed, 0); } else { digitalWrite(leftLed, 1); digitalWrite(rightLed, 0); } if (z1 > z) { digitalWrite(bottomLed, 1); digitalWrite(frontLed, 0); } else { digitalWrite(frontLed, 1); digitalWrite(bottomLed, 0); } } void dmpDataReady() { mpuInterrupt = true; }
Помогите, пожалуйста.
Заранее спасибо!
Ср, 04/09/2019 - 16:35
#1
Моя же задача сводится к тому, чтобы датчик управлял диодами относительно положения, в котором он находился при включении, а не относительно горизонта.