您好,我正在使用arduino uno製作quadcopter(無人機)。當我使用pulseIn()函數時,mpu6050傳感器值變得不穩定
我有關於pulseIn函數的問題。
我找到了dmp過濾器的開源代碼。並且我在循環功能中添加了4行pulseIn函數以便從發送接收器接收值。
當我在循環函數中添加這4行代碼時,ypr [2]的值變得非常不穩定,如圖片。
ypr [2]是由dmp代碼frome mpu6050傳感器產生的角度值。
當我刪除4行(channel1 = pulseIn(7,HIGH); ....)時,不會出現此問題。 ypr [2]的值是穩定的。我試圖改變pulseIn函數(channel1 = pulseIn(7,HIGH,10)或channel1 = pulseIn(7,HIGH,100)或channel1 = pulseIn(7,HIGH,1000))的輸入時間參數,但是這個問題並沒有消失。 (channel1 = pulseIn(7,HIGH,10)),ypr [2]的值是穩定的。但不能接收發射接收器的值.......
我該如何解決這個問題?請幫我T.T
和我確認增加代碼更新時間,當我添加4行脈衝功能。 (0.014s> 0.018s),但我不知道是否存在關係。
#include <Servo.h>
#include <Wire.h>
#include <I2Cdev.h>
#include <SPI.h>
#include <MPU6050_6Axis_MotionApps20.h>
MPU6050 mpu; // mpu interface object
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
double channel1 ;
double channel2 ;
double channel3 ;
double channel4 ;
Quaternion q;
VectorFloat gravity;
float ypr[3];
float yprLast[3];
int16_t gyro[3];
volatile bool mpuInterrupt = false;
void dmpDataReady() {
mpuInterrupt = true;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void dmpsetup() {
#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
Wire.begin();
TWBR = 12; // 400kHz I2C clock (200kHz if CPU is 8MHz)
#elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE
Fastwire::setup(400, true);
#endif
Serial.begin(115200);
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(33);
mpu.setYGyroOffset(-13);
mpu.setZGyroOffset(8);
mpu.setZAccelOffset(1416);
if (devStatus == 0) {
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(")"));
}
}
void setup() {
Serial.begin(115200);
pinMode(7, INPUT);
pinMode(8, INPUT);
pinMode(12, INPUT);
pinMode(13, INPUT);
dmpsetup();
}
void dmploop() {
if (!dmpReady) return;
while (!mpuInterrupt && fifoCount < packetSize) {
}
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.dmpGetGyro(gyro, fifoBuffer);
mpu.dmpGetQuaternion(&q, fifoBuffer);
mpu.dmpGetGravity(&gravity, &q);
mpu.dmpGetYawPitchRoll(ypr, &q, &gravity);
ypr[1] = (ypr[1] * 180/M_PI); //x
ypr[2] = (ypr[2] * 180/M_PI); //y
ypr[0] = (ypr[0] * 180/M_PI); //z
//gyro[0],gyro[1],gyro[2]//x,y,z 각속도값
}
}
void loop() {
dmploop(); //refresh new angle datas from MPU6050
channel1 = pulseIn(7, HIGH);
channel2 = pulseIn(8, HIGH);
channel3 = pulseIn(12, HIGH);
channel4 = pulseIn(13, HIGH);
Serial.print(-30);
Serial.print(" ");
Serial.print(30);
Serial.print(" ");
Serial.print(0);
Serial.print(" ");
Serial.println(ypr[2]);
}
僅有4行
感謝您的回覆。 然後我無法解決arduino中的這個問題? 或者是否有另外一種方法可以從發射器接收到值? –
你可以直接做(不帶庫),或者找一些像PinChangeInt(answer eddited)這樣的庫。並使用例如micros()來查明脈衝的持續時間。定時器中的捕捉模式甚至更好,但不是4通道。 – KIIV
我解決了問題。謝謝^^ –