실습은 개인 학습을 위해 "주) 엘케이 임베디드" 사이트에서 구매한 아두이노 코딩 배우기 고급 키트를 이용한 학습입니다. 동봉된 책을 기반으로 학습하면서 개인적인 궁금증과 추가 필요한 부분을 정리한 블로그임을 미리 알려드립니다. 이번 실습은 움직임을 센서로 확인하는 실습이라 아두이노 나노를 사용했습니다. 아두이노 우노를 사용해도 됩니다.
< 준비물 >
아두이노 나노 : 1개
USB 케이블 : 1개
점퍼 케이블(숫숫) : 4개가량
브레드 보드 : 1개, 830홀 사용
MPU-6050 모듈 : 1개
MPU_6050(3축 자이로 센서)를 이용한 가속도, 자이로, 온도의 정보를 시리얼 모니터로 출력하는 실습입니다. 회로는 간단한 편이지만 코딩에서 새로운 부분들이 많이 나옵니다. 전체를 이해하기보다는 이번 실습에서는 MPU_6050 자이로 센서와 아두이노 간에 I2C 통신을 통해 어떤 데이터들을 주고받는지를 이해하는데 목적이 있다고 생각합니다.
< 참고 지식 >
⦿ I2C(Inter Intergrated Circuit) 통신 : 두 개의 전선(SDA, SCL)으로 다수의 통신을 지원하는 디바이스와 데이터를 송/수신할 수 있는 통신방식입니다. 하나의 마스터와 다수의 슬레이브로 연결이 구성되며, 마스터에서 기준 클럭(SCL)을 생성하고, 이 클럭에 맞춰 시리얼 데이터(SDA)를 전송 및 수신합니다. 또한 각각의 송신과 수신은 구분되는 반이중(Half-Duplex) 통신방식을 사용합니다. 각 슬레이브 디바이스는 개별 어드레스를 가지고 있어 이 어드레스를 통해 서로 식별해 통신이 이루어집니다. 즉 마스터에서 기준 클럭과 시리얼 데이터를 I2C의 모든 디바이스에게 전달되고, 해당 어드레스를 가진 슬레이브 디바이스만 응답하는 방식으로 서로 데이터를 주고받습니다.
일반적으로 많이 사용하는 UART 통신보다는 느리지만 하나의 아두이노에서 여러대의 아두이노 등을 연결하여 통신이 가능하다는 특징이 있습니다. 아두이노 스케치에서 Wire라이브러리를 사용하면 I2C 통신을 편리하게 사용할 수 있습니다.
I2C 통신 시 아두이노 핀연결은 A4 = SDA, A5 = SCL연결은 고정입니다. 공 A4, A5핀에 연결해야 한다고 합니다.
⦿ Wire 라이브러리 주요 함수
- Wire.begin() : 디바이스의 식별 주소 지정 함수, 함수 인자값이 없을 때 마스터 주소 지정이고 있을 때에는 슬레이브 주소로 지정됩니다.
- Wire.beginTransmission(address) : 데이터 전송 함수, 슬레이브 address값을 전송
- Wire.endTransmission() : 버퍼에 테이터가 있을 경우 전송한 후, 슬레이브 장치와의 통신을 종료합니다.
- Wire.write(value) : 문자열 전송 함수
- Wire.read() : 데이터 요청 함수, 수신 버퍼의 한 바이트를 읽어서 반환하는 함수
- Wire.requestFrom(address, byte num) : 마스터가 슬레이브에 지정한 수량의 데이터를 요청하는 함수
- Wire.available() : read 함수로 읽어들일 수 있는 유효한 바이트수를 반환하는 함수
- Wire.onreceive() : 슬레이브가 마스터로 부터 데이터를 수신했을 때 호출되는 핸들러 함수
- Wire.onRequest() : 슬레이브가 마스터로 부터 요청받았을 때 호출되는 함수
< 예제소스 >
#include<Wire.h>
const int MPU_addr = 0x68; // I2C address of the MPU-6050
int16_t AcX, AcY, AcZ, Tmp, GyX,GyY, GyZ;
void setup()
{
Wire.begin();
Wire.beginTransmission(MPU_addr);
Wire.write(0x6b); // PWR_MGMT_1 register
Wire.write(0); // set to zero(wakes up the MPU-6050)
Wire.endTransmission(true);
Serial.begin(9600); // 시리얼 통신 사용, 통신 보레이트 9600 bps 설정
}
/* 자이로 센서 모듈은 3축(X, Y, Z) 자이로(회전)와 3축 가속도를 측정하며,
이를 이용하여 각도를 측정할 수 있다.
측정된 값은 시리얼 통신을 통하여 PC에서 확인할 수 있다. */
void loop()
{
Wire.beginTransmission(MPU_addr);
Wire.write(0x3b); //starting with register 0x3b(ACCEL_XOUT_H)
Wire.endTransmission(false);
Wire.requestFrom(MPU_addr, 14, true); // request a total of 14 registers
AcX = Wire.read() << 8 | Wire.read(); // 0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L)
AcY = Wire.read() << 8 | Wire.read(); // 0x3D (ACCEL_YOUT_H) & 0x3E (ACCEL_YOUT_L)
AcZ = Wire.read() << 8 | Wire.read(); // 0x3F (ACCEL_ZOUT_H) & 0x40 (ACCEL_ZOUT_L)
Tmp = Wire.read() << 8 | Wire.read(); // 0x41 (TEMP_OUT_H) & 0x42 (TEMP_OUT_L)
GyX = Wire.read() << 8 | Wire.read(); // 0x43 (GYRO_XOUT_H) & 0x44 (GYRO_XOUT_L)
GyY = Wire.read() << 8 | Wire.read(); // 0x45 (GYRO_YOUT_H) & 0x46 (GYRO_YOUT_L)
GyZ = Wire.read() << 8 | Wire.read(); // 0x47 (GYRO_ZOUT_H) & 0x48 (GYRO_ZOUT_L)
Serial.println(F("MPU_6050"));
Serial.print(F("accel x,y,z: "));
Serial.print("AcX = "); Serial.print(AcX); // 가속도 X축 값
Serial.print(" | AcY = "); Serial.print(AcY); // 가속도 Y축 값
Serial.print(" | AcZ = "); Serial.print(AcZ); // 가속도 Z축 값
Serial.print(F(" temperature: "));
Serial.print(" | Tmp = "); Serial.print(Tmp / 340.00 + 36.53);
// equation for temperature in degrees C form datasheet
Serial.print(F(" gyro x,y,z: "));
Serial.print("GyX = "); Serial.print(GyX); // 자이로 X축 값
Serial.print(" | GyY = "); Serial.print(GyY); // 자이로 Y축 값
Serial.print(" | GyZ = "); Serial.print(GyZ); // 자이로 Z축 값
delay(333);
}
'Arduino > Arduinio기초 실습' 카테고리의 다른 글
9장. 화재 감지 센서 실습 (0) | 2022.04.08 |
---|---|
8장. 기울기 센서(Ball Switch) & LED 실습 (0) | 2022.04.07 |
6장. 7세그먼트(7 Segment. FND), 스위치 실습 (0) | 2022.04.04 |
5장. 가변저항 10K 실습 (0) | 2022.04.02 |
4장. 시리얼 통신 실습 (0) | 2022.04.02 |