0

您好,我正在使用 arduino uno 制作四轴飞行器(无人机)。

我对 pulseIn 函数有疑问。

我发现 dmp 过滤器是开源的。我在循环函数中添加了 4 行 pulseIn 函数,以便从发送器接收器接收值。

当我在循环函数中添加这 4 行代码时,ypr[2] 的值变得非常不稳定,就像图片一样。

ypr[2] 是来自 mpu6050 传感器的 dmp 代码生成的角度值。

当我删除那 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] 的值是稳定的。但无法接收发射器接收器值.......

我该如何解决这个问题?请帮帮我TT

当我添加 4 行 pulsein 函数时,我确认增加了代码更新时间。(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行

在此处输入图像描述

4

1 回答 1

1

PulseIn(pin,HIGH)正在阻塞呼叫,它等待 LO->HI 转换,然后 HI->LO 来测量它。我想它会混淆代码时间。

如果你不想做到非阻塞,你必须使用引脚更改中断(AVR 的东西,它可能没有在 arduino 框架中实现)。但它似乎在PinChangeInt等一些库中实现。

于 2016-08-18T06:53:35.133 回答