정보나눔

오픈소스하드웨어 프로젝트에 대한 다양한 정보를 나누는 공간입니다.

자이로 센서-모터-초음파 센서 연결에 관해 질문 드립니다.
이전구 | 2018-10-09

 

 

1. 프로젝트 사용한 보드 종류

  (EX : 오렌지보드, 오렌지 BLE보드, 아두이노 UNO 등)

 

  아두이노 UNO

  

2. 사용한 개발 프로그램명

  (EX : 아두이노 IDE, 스크래치, mBlock 등)

 

  아두이노 IDE

 

3. 사용한 센서 모델명

  (센서 모델명을 자세하게 적어 주실 경우 더 정확하게 확인할 수 있습니다.)

 

  mpu6050, sr04

 

4. 연결한 회로 설명 (또는 이미지)

 

 

5. 소스코드 (주석 필수)

  (원하는 기능의 코드를 전부 작성해 드리긴 어렵습니다. 기초부터 차근차근 공부해보면서 코드를 만들어 보세요.)

 

#include "Wire.h"
#include "I2Cdev.h"
#include "SPI.h"
#include "MPU6050_6Axis_MotionApps20.h"

 

#define I2C_SLAVE_ADDR 7            // >>>>> I2C 슬레이브 주소(초음파 센서모듈 주소)
#define ULTRASONIC_NUM 3          // >>>>> 초음파 센서를 하나 더 추가할 경우 4로 변경('알칸도 초음파 센서모듈-2') 

 

uint8_t distance[ULTRASONIC_NUM];

 

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

 

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() {
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(7, OUTPUT);
  pinMode(8, OUTPUT);
  
  Serial.begin(115200);
  dmpsetup();
}

 

void dmploop() {
  motor_run();  
  
  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 각속도값

    Serial.print(ypr[1]);
    Serial.print("\t");
    Serial.print(ypr[2]);
    Serial.print("\t");
    Serial.print(ypr[0]);
    Serial.println("\t");

 

    Wire.requestFrom(I2C_SLAVE_ADDR, ULTRASONIC_NUM);    // 슬레이브로 부터 ULTRASONIC_NUM 바이트 데이터 요청
    
    for (int i = 0; i < ULTRASONIC_NUM; i++) {
      distance[i] = Wire.read();  //초음파 센서 값 받아오는 부분
      Serial.print(distance[i]);
      Serial.print("  ");
      
      if(ypr[1] > 45 | distance[0] < 20 | distance[1] < 20 | distance[2] < 20)  //자이로 센서, 초음파 센서를 이용해 모터를 제어하는 부분
      {
        Serial.println("aaaaaaaaaa");
        motor_stop();  
      }
      else
      {
        Serial.println("---------");
        motor_run();
      }

    }
  }
}

 

void loop() {
  dmploop(); //refresh new angle datas from MPU6050
}

 

void motor_run()
{
  //motorA
  digitalWrite(5, HIGH);     // Motor A 방향설정1
  digitalWrite(4, LOW);      // Motor A 방향설정2
  analogWrite(3, 200);       // Motor A 속도조절 (0~255)

  //motorB
  digitalWrite(8, HIGH);      // Motor B 방향설정1
  digitalWrite(7, LOW);     // Motor B 방향설정2
  analogWrite(6, 200);        // Motor B 속도조절 (0~255)
}

void motor_stop()
{
  //motorA
  digitalWrite(5, LOW);     // Motor A 방향설정1
  digitalWrite(4, LOW);      // Motor A 방향설정2
  analogWrite(3, 50);       // Motor A 속도조절 (0~255)

  //motorB
  digitalWrite(8, LOW);      // Motor B 방향설정1
  digitalWrite(7, LOW);     // Motor B 방향설정2
  analogWrite(6, 50);        // Motor B 속도조절 (0~255)
}

 

6. 문제점 및 에러 내용

  (소스코드 문제일 경우 에러 내용도 같이 올려주세요.)

 

  자이로 센서와 초음파 센서 값을 이용해 모터를 제어하는 것을 목적으로 짠 소스입니다.

 

  위 빨간색으로 표시된 if문 조건에 따라 print 값이 'aaaa' 혹은 '------' 로 바뀌긴 하나, 모터 제어가 되지 않습니다.

  혹시 왜 그런지 알 수 있을까요?

이전글   |    안드로이드 블루투스 연결 실패 문제입니다..... 2018-10-09
다음글   |    아두이노 네오픽셀 연결이 제대로 된건지 궁금합니다!... 2018-10-11