일단 지난글 방식대로 해서

AD0로 MPU6050 주소를 2가지만 선택이 가능하지만

여러개로부터 값을 가져올수 있도록 정리했었다.

 

이번엔 아예 3개를 연결해서 가져와지나 테스트

 

 

 

 

가져와지는건 좋지만 여전히 데이터가 몇개 빠져서 들어올때가 있다.

 

 

 

 

데이터 송수신시 다른 조건문으로 들어가서라 생각되는데

 

void SendData(int pinNum)
{
    for (int i = 0; i < 2; i++)
    {
      if (mpuPinNums[i] == pinNum)
        digitalWrite(mpuPinNums[i], LOW);  //set selected mpu6050 addr 0x68
      else
        digitalWrite(mpuPinNums[i], HIGH);  //set other mpu6050 addr 0x69
    }

    // if programming failed, don't try to do anything
    if (!dmpReady) return;

    // wait for MPU interrupt or extra packet(s) available
    while (!mpuInterrupt && fifoCount < packetSize) {
    }

    // 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();

    // 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;

        #ifdef OUTPUT_READABLE_YAWPITCHROLL
            // display Euler angles in degrees
            mpu.dmpGetQuaternion(&q, fifoBuffer);
            mpu.dmpGetGravity(&gravity, &q);
            mpu.dmpGetYawPitchRoll(ypr, &q, &gravity);
            BTSerial.print(pinNum);
            BTSerial.print(":");
            BTSerial.print(int(ypr[0] * 180/M_PI));
            BTSerial.print(",");
            BTSerial.print(int(ypr[1] * 180/M_PI));
            BTSerial.print(",");
            BTSerial.print(int(ypr[2] * 180/M_PI));
            BTSerial.print("/");
        #endif
    }
}

 

 

 

 

 

mpu 상태가져오기전에 사용되는 값들 출력시켜봣는데

    Serial.println("");
    Serial.print(pinNum);
    Serial.print("pin dmpReady : ");
    Serial.print(dmpReady);
    Serial.print(", before mpuInterrupt : ");
    Serial.print(mpuInterrupt);
    Serial.print(", fifocount : ");
    Serial.println(fifoCount);

    // if programming failed, don't try to do anything
    if (!dmpReady) return;

    // wait for MPU interrupt or extra packet(s) available
    while (!mpuInterrupt && fifoCount < packetSize) {
    }

 

이것만으로 어쩔때 나오고 어쩔때 안나오는지 판단할수가 없엇음.

 

 

 

 

 

이번에는

상태랑 피포카운트 출력하도록 수정

 

    // reset interrupt flag and get INT_STATUS byte
    mpuInterrupt = false;
    mpuIntStatus = mpu.getIntStatus();

    // get current FIFO count
    fifoCount = mpu.getFIFOCount();
    Serial.print(", after mpuIntStatus : ");
    Serial.print(mpuIntStatus);
    Serial.print(", fifocount : ");
    Serial.println(fifoCount);

    // 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();

    // 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;

        #ifdef OUTPUT_READABLE_YAWPITCHROLL
            // display Euler angles in degrees
            mpu.dmpGetQuaternion(&q, fifoBuffer);
            mpu.dmpGetGravity(&gravity, &q);
            mpu.dmpGetYawPitchRoll(ypr, &q, &gravity);
            Serial.print(pinNum);
            Serial.print(":");

 

 

위 코드 대로 mpuIntStatus 가 2일때만 진입해서 출력하는걸 확인

2 외에

1, 3, 4, 19가 자주 발생한다.

 

 

 

 

 

잠깐 지금 보니 6, 7때 같은값을 가져오고있었네

 

mpu3개 연결했는데

루프문을 몇군대 잘못하기도하고

세번째 mpu를 반대로 놓거나

핀아웃을 안해놔서 안떳다.

거기다가 블루투스때문에 보드레이트를 9600 해놨었는데

 

115200으로 했을때 더 잘나온다.

 

 

//RXD3, TXD4
SoftwareSerial BTSerial(4, 3);
int mpuPinNums[] = {5, 6, 7};
int mpuNum = sizeof(mpuPinNums) / sizeof(int);


void InitMPU(int pinNum);
void SendData(int pinNum);

void setup() {
  for (int i = 0; i < mpuNum;i++)
    pinMode(mpuPinNums[i], OUTPUT);

  Serial.begin(115200);

  #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

  while (!Serial); // wait for Leonardo enumeration, others continue immediately

  for (int i = 0; i < mpuNum;i++)
    InitMPU(mpuPinNums[i]);
}


void loop() {

  for (int i = 0; i < mpuNum;i++)
    SendData(mpuPinNums[i]);

  Serial.println("");
}


void InitMPU(int pinNum)
{
  for (int i = 0; i < mpuNum; i++)
  {
    if (mpuPinNums[i] == pinNum)
      digitalWrite(pinNum, LOW);  //set selected mpu6050 addr 0x68
    else
      digitalWrite(mpuPinNums[i], HIGH);  //set other mpu6050 addr 0x69
  }
  Serial.print("start init pin ");
  Serial.println(pinNum);


  // initialize device
  mpu.initialize();

  // verify connection
  Serial.println(F("Testing device connections..."));
  Serial.println(mpu.testConnection() ? F("MPU6050 connection successful") : F("MPU6050 connection failed"));

  // load and configure the DMP
  Serial.println(F("Initializing DMP..."));
  devStatus = mpu.dmpInitialize();

  // supply your own gyro offsets here, scaled for min sensitivity
  mpu.setXGyroOffset(220);
  mpu.setYGyroOffset(76);
  mpu.setZGyroOffset(-85);
  mpu.setZAccelOffset(1788); // 1688 factory default for my test chip

  // make sure it worked (returns 0 if so)
  if (devStatus == 0) {
      // turn on the DMP, now that it's ready
      Serial.println(F("Enabling DMP..."));
      mpu.setDMPEnabled(true);

      // enable Arduino interrupt detection
      Serial.println(F("Enabling interrupt detection (Arduino external interrupt 0)..."));
      attachInterrupt(0, dmpDataReady, RISING);
      //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
      Serial.println(F("DMP ready! Waiting for first interrupt..."));
      dmpReady = true;

      // get expected DMP packet size for later comparison
      packetSize = mpu.dmpGetFIFOPacketSize();
  } else {
      Serial.print(F("DMP Initialization failed (code "));
      Serial.print(devStatus);
      Serial.println(F(")"));
  }
}

void SendData(int pinNum)
{
  for (int i = 0; i < mpuNum; i++)
  {
    if (mpuPinNums[i] == pinNum)
      digitalWrite(mpuPinNums[i], LOW);  //set selected mpu6050 addr 0x68
    else
      digitalWrite(mpuPinNums[i], HIGH);  //set other mpu6050 addr 0x69
  }


  Serial.println("");

  Serial.print(pinNum);
  Serial.print("pin dmpReady : ");

  // if programming failed, don't try to do anything
  if (!dmpReady) return;

  // wait for MPU interrupt or extra packet(s) available
  while (!mpuInterrupt && fifoCount < packetSize) {
  }

  // reset interrupt flag and get INT_STATUS byte
  mpuInterrupt = false;
  mpuIntStatus = mpu.getIntStatus();

  // get current FIFO count
  fifoCount = mpu.getFIFOCount();
  Serial.print(", after mpuIntStatus : ");
  Serial.print(mpuIntStatus);
  Serial.print(", fifocount : ");
  Serial.println(fifoCount);

  // 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();

  // 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;

      #ifdef OUTPUT_READABLE_YAWPITCHROLL
          // display Euler angles in degrees
          mpu.dmpGetQuaternion(&q, fifoBuffer);
          mpu.dmpGetGravity(&gravity, &q);
          mpu.dmpGetYawPitchRoll(ypr, &q, &gravity);
          Serial.print(pinNum);
          Serial.print(":");
          Serial.print(int(ypr[0] * 180/M_PI));
          Serial.print(",");
          Serial.print(int(ypr[1] * 180/M_PI));
          Serial.print(",");
          Serial.print(int(ypr[2] * 180/M_PI));
          Serial.print("/");
      #endif
  }
}

 

 

 

 

 

블루투스로 확인하기전에

잠깐 mpu intstatus의미부터 확인해보면

 

 

깃헙에서 찾은걸보면

이게 인터럽트 레지스터 값 가져오는거같다

각 값별 의미는 없어서 데이터시트 봐야할듯

 

https://github.com/jrowberg/i2cdevlib/blob/master/Arduino/MPU6050/MPU6050.cpp

 

 

 

데이터시트에서 말하길

레지스터맵 레지스터 설명 다큐먼트보랜다.

 

 

 

 

레지스터 다큐먼트에서 인터럽트 상태 레지스터 족 찾긴했는데

좀이해는 안간다.

 

비트1이 없으면 왜 2, 3같은 값이 나오는걸까?

내가 잘못 찾거나 잘못이해한거라 생각되는데

 

 

 

 

 

뭔가 이상하다 싶어서

구글링하다가

우리나라에서도 이것때문에 해맨 분글을 찾았다.

 

https://blog.naver.com/heennavi1004/10183570269

 

 

 

 

진짜 눈물난다.

해외에서도 이렇게 잘 설명해준게 흔치않는데

우리나라 분이 10년전이 정리해서 올려놨다니 ㅜㅜ

 

정리하면 데이터시트에서 제대로 작성안한 히든레지스터가 있어서 그렇다고한다.

 

https://blog.naver.com/heennavi1004/10183570269

 

 

 

 

다시돌아와 지금은 115200 보드레이트를 쓰면서 잘 출력이 됬었지만

블루투스에서 9600 보드레이트를 쓰다보니

9600보드레이트로 낮출때

인터럽트스테이트가 19가 나왔따.

 

다시 보면

인터럽트 스테이터스가 19일때는 피포 오버플로우로 출력이 안됬꼬

나머지 출력이 안된 상황인 1, 4의 경우 피포 오버플로가 안됬지만

1번비트가 하이가 아니여서 조건문에거 걸린것으로 보인다.

  } else if (mpuIntStatus & 0x02) {
 

 

어쨋거나 mpu동작속도 생각하면

115200쓰는게 좋아보이긴한데

배터리 블루투스로하면 왜 못받아오는지 찾질못했었지만

 

이제 상태값도 조금 찾아봣겟다

블루투스 설정을 115200으로해서 다시봐도 될듯하다.

 

이전에 보드레이트변경 코드를 가져와서 사용

 

 

AT로 동작확인

AT+BUAD8로 115200로 변경

 

 

 

 

 

노트북 USB전원으로 동작시킬때는

블루투스 115200으로도 잘 동작한다.

시리얼 115200때보다 인터럽트 상태가 19되는경우가 잦은느낌이긴한데

베터리 전원을 줄때 인터럽트 코드확인

 

 

 

 

 

 

역시나 115200 hc-05를 보조베터리 전원을줄때 안된다.

내가 갖고있는 보조베터리 출력이 5V승압없이 3.7V 2A 라 그런것같기도하고 

그냥 원래 생각했던데로 esp32나 쓸까부다--

 

+ Recent posts