새소식

라즈베리파이

라즈베리파이 mpu6050 가속도 센서 제어하는 방법(파이썬, i2c 설정는하는 방법)

  • -

가속도 센서인 mpu6050을 사용하기 위해서는

우선적으로 라즈베리파이의 i2c를 활성화 해주어야 합니다

 

i2c는 대표적인 동기적 통신입니다

clock 신호에 맞춰서 데이터를 주고 받습니다

mpu6050의 SCL이 그 주기를 주고

SDA을 통해 데이터를 읽어옵니다

 

우선 라즈베리파이에서 커맨드 창을 켜주시고

sudo raspi-config 명령어를 실행해주세요

그러면 위와 같은 화면이 나오게됩니다. 위는 라즈베리파이4b 기준으로 조금 다를 수 있습니다

위에서 Interfacing Options로 이동하여 엔터를 입력합니다

그러면 위와 같은 창으로 넘어가게 됩니다

여기서 5번째의 I2C로 이동하여 Enter를 눌러줍니다

 

그러면 다음과 같은 창이 나오면서 활성화 할거냐고 물어봅니다

Yes를 선택후 엔터!!

그리고 Esc를 눌러서 저 파란창을 종료시켜줍니다

그리고 reboot 명령어를 통해 라즈베리파이를 재부팅 합니다

그러면 이제 i2c 통신을 사용할 수 있습니다

 

i2c 모듈 활성화 확인

lsmod 명령어를 통해 확인할 수 있습니다

이 명령어를 통해 라즈베리파이에 있는 모듈들을 모두 확인할 수 있습니다

이 중에서 i2c만 확인하고 싶으므로 grep을 같이 이용해 확인합시다

$ lsmod | grep i2c

 

위와 같이 하셨을때 i2c 모듈이 나오게 된다면

정상적으로 설정이 되었습니다

i2c관련 디바이스 드라이버도 생성되었는지 확인해봅시다

 

위와 같이 디바이스 드라이버도 정상적으로 있습니다

리눅스에서는 장치도 모두 파일로 다루어지며 그 파일들은 /dev/ 밑에 있습니다

이렇게 mpu6050 가속도 센서를 사용하기 위한 준비를 마쳤습니다

 

가속도센서 연결하기

\위와 같이 연결하시면 됩니다

맨 위의 VCC는 3.3V에 연결

그 밑의 GND는 그라운드에 연결

그 밑의 SCL을 빨간색 부분에 연결하고

제일 4번째 SDA는 노란색 부분에 연결합니다

gpio 핀 정보를 보면 위에서 SDA와 SCL이라고 쓰여있는 핀들이 있습니다

이러한 핀을 이용하셔야 i2C 통신을 할 수 있습니다

 

그리고 연결한 센서의 정보를 확인하기 위해서 i2c-tools를 설치합니다

sudo apt-get install i2c-tools

 

mpu 6000 데이터 주소

I2C address ADD = 0 1101000 ( 0x68 )
  ADD = 1 1101001 ( 0x69 )

i2cdetect -y 1 명령어를 켜보면

정상적으로 연결되어있다면 위와 같이 0x68주소에 연결된것을 볼 수 있습니다

그러면 이제 연결이 끝났으니 가속도 센서와 자이로 센서로부터 값을 읽어와봅시다

 

mpu6000 파이썬 코드

우선 파이썬에서 i2c를 사용하기 위해서 smbus2를 설치해야 합니다

sudo pip install smbus2

smbus는 i2c 통신을 지원하는 파이썬 모듈로 데이터를 읽고 쓸 수 있는 기능을 지원합니다

 

파이썬 코드는 다음과 같습니다

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
from smbus2 import SMBus
from bitstring import Bits
import math
import time
import RPi.GPIO as GPIO
 
bus = SMBus(1)
DEV_ADDR = 0x68
 
register_gyro_xout_h = 0x43
register_gyro_yout_h = 0x45
register_gyro_zout_h = 0x47
sensitive_gyro = 131.0
 
register_accel_xout_h = 0x3B
register_accel_yout_h = 0x3D
register_accel_zout_h = 0x3F
sensitive_accel = 16384.0
 
def read_data(register):
    high = bus.read_byte_data(DEV_ADDR,register)
    low = bus.read_byte_data(DEV_ADDR,register+1)
    val = (high << 8+ low
    return val
 
def twocomplements(val):
    s = Bits(uint=val,length=16)
    return s.int
 
def gyro_dps(val):
    return twocomplements(val)/sensitive_gyro
 
def accel_g(val):
    return twocomplements(val)/sensitive_accel
 
def dist(a,b):
    return math.sqrt((a*a)+(b*b))
 
def get_x_rotation(x,y,z):
    radians = math.atan(x/dist(y,z))
    return radians
 
def get_y_rotation(x,y,z):
    radians = math.atan(y/dist(x,z))
    return radians
 
bus.write_byte_data(DEV_ADDR,0x6B,0b00000000)
 
GPIO.setmode(GPIO.BCM)
 
LED1 = 18
LED2 = 23
 
GPIO.setup(LED1, GPIO.OUT, initial=GPIO.LOW)
GPIO.setup(LED2, GPIO.OUT, initial=GPIO.LOW)
 
try:
    while True:
        x = read_data(register_accel_xout_h)
        y = read_data(register_accel_yout_h)
        z = read_data(register_accel_zout_h)
        aX = get_x_rotation(accel_g(x),accel_g(y),accel_g(z))
        aY = get_y_rotation(accel_g(x),accel_g(y),accel_g(z))
        data = str(aX) + ' , ' + str(aY) + '$'
 
        if aX > 0.7 or aX < -0.5:
            print("on LED1")
            GPIO.output(LED1, GPIO.HIGH)
        else:
            GPIO.output(LED1, GPIO.LOW)
 
        if aY < -0.5 or aY > 0.5:
            print("on LED2")
            GPIO.output(LED2, GPIO.HIGH)
        else:
            GPIO.output(LED2, GPIO.LOW)
 
        print(data)
        time.sleep(0.3)
except KeyboardInterrupt:
    print("\nInterrupted!")
except:
    print("\nClosing socket")
finally:
    bus.close()
GPIO.cleanup()
 
 
cs

위와 같이 x,y축으로의 라디안 각도(aX, aY)를 얻을 수 있습니다.

저는 얻은 정보를 이용해서 led제어를 해봤습니다

x축으로 기울이거나 y축으로 기울일때마다 불이 켜지게 하였습니다

회로는 다음과 같습니다

led를 각각 18번과 23번에 연결해줍니다(BCM 번호)

그러면 x축 방향 가속도와 y축 방향 가속도에 따라서 led를 제어할 수 있습니다

 

 

만약 각속도를 얻고 싶다면 다음과 같이 작성합니다

start = time.time()

gyro_x = read_data(register_gyro_xout_h)
gyro_y = read_data(register_gyro_yout_h)
gyro_z = read_data(register_gyro_zout_h)
stop = time.time()

offset = stop-start

rX = rX + (PI*(gyro_dps(gyro_xx)*offset)/180) # rotation around x-axis
rY = rY + (PI*(gyro_dps(gyro_y)*offset)/180) # rotation around y-axis
rZ = rZ + (PI*(gyro_dps(gyro_z)*offset)/180) # rotation around z-axis
data = str(rX) + ',' + str(rY) + ',' + str(rZ) + '$'
Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.