2016-08-18 284 views
0

您好,我正在使用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行

enter image description here

回答

1

PulseIn(pin,HIGH)阻止呼叫,它等待LO-> HI過渡然後HI-> LO對它進行測量。我認爲它與代碼時間混淆。如果你不想做非阻塞,你必須使用引腳變化中斷(AVR的東西,它可能不會在Arduino框架中實現)。但它似乎在PinChangeInt等一些圖書館中得到實施。

+0

感謝您的回覆。 然後我無法解決arduino中的這個問題? 或者是否有另外一種方法可以從發射器接收到值? –

+0

你可以直接做(不帶庫),或者找一些像PinChangeInt(answer eddited)這樣的庫。並使用例如micros()來查明脈衝的持續時間。定時器中的捕捉模式甚至更好,但不是4通道。 – KIIV

+0

我解決了問題。謝謝^^ –