일단 지난글 방식대로 해서
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의미부터 확인해보면
깃헙에서 찾은걸보면
이게 인터럽트 레지스터 값 가져오는거같다
각 값별 의미는 없어서 데이터시트 봐야할듯
데이터시트에서 말하길
레지스터맵 레지스터 설명 다큐먼트보랜다.
레지스터 다큐먼트에서 인터럽트 상태 레지스터 족 찾긴했는데
좀이해는 안간다.
비트1이 없으면 왜 2, 3같은 값이 나오는걸까?
내가 잘못 찾거나 잘못이해한거라 생각되는데
뭔가 이상하다 싶어서
구글링하다가
우리나라에서도 이것때문에 해맨 분글을 찾았다.
진짜 눈물난다.
해외에서도 이렇게 잘 설명해준게 흔치않는데
우리나라 분이 10년전이 정리해서 올려놨다니 ㅜㅜ
정리하면 데이터시트에서 제대로 작성안한 히든레지스터가 있어서 그렇다고한다.
다시돌아와 지금은 115200 보드레이트를 쓰면서 잘 출력이 됬었지만
블루투스에서 9600 보드레이트를 쓰다보니
9600보드레이트로 낮출때
인터럽트스테이트가 19가 나왔따.
다시 보면
인터럽트 스테이터스가 19일때는 피포 오버플로우로 출력이 안됬꼬
나머지 출력이 안된 상황인 1, 4의 경우 피포 오버플로가 안됬지만
1번비트가 하이가 아니여서 조건문에거 걸린것으로 보인다.
어쨋거나 mpu동작속도 생각하면
115200쓰는게 좋아보이긴한데
배터리 블루투스로하면 왜 못받아오는지 찾질못했었지만
이제 상태값도 조금 찾아봣겟다
블루투스 설정을 115200으로해서 다시봐도 될듯하다.
이전에 보드레이트변경 코드를 가져와서 사용
AT로 동작확인
AT+BUAD8로 115200로 변경
노트북 USB전원으로 동작시킬때는
블루투스 115200으로도 잘 동작한다.
시리얼 115200때보다 인터럽트 상태가 19되는경우가 잦은느낌이긴한데
베터리 전원을 줄때 인터럽트 코드확인
역시나 115200 hc-05를 보조베터리 전원을줄때 안된다.
내가 갖고있는 보조베터리 출력이 5V승압없이 3.7V 2A 라 그런것같기도하고
그냥 원래 생각했던데로 esp32나 쓸까부다--
'컴퓨터과학 > 언리얼' 카테고리의 다른 글
관성모션 - 13. ESP32 블루투스 + MPU6050 YPR + 보조 베터리 (0) | 2024.02.28 |
---|---|
관성모션 - 12. ESP32 블루투스 사용해보기 (0) | 2024.02.28 |
관성모션 - 10. MPU6050 두 개 써보기(I2C 멀티플렉서 없이) (0) | 2024.02.27 |
관성모션 - 9. 관성계 오프셋 조정 x, 다른 모델로 가지고 놀기 (0) | 2024.02.25 |
관성모션 - 8. 보간으로 부드럽게 회전 시키기 (0) | 2024.02.24 |