ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Raspberry Pi] 라즈베리파이 library
    임베디드/라즈베리파이 2024. 4. 22. 02:34

     

     

     

     

    raspberry5 pin info

    https://pinout.xyz/

     

    Raspberry Pi GPIO Pinout

    Pinout! The Raspberry Pi GPIO pinout guide. This GPIO Pinout is an interactive reference to the Raspberry Pi GPIO pins, and a guide to the Raspberry Pi's GPIO interfaces. Pinout also includes hundreds of pinouts for Raspberry Pi add-on boards, HATs and pHA

    pinout.xyz

     

     

     

     

    프로그램 멈추기(sleep)
    • lib : from time import sleep
    • 멈추기(초단위) : sleep(second

     

     

    LED (또는 lazer, FND)

     

    • lib : from gpiozero import LED
    • LED 객체 선언 : LED(핀번호)
    • LED 켜기 : led객체.on()
    • LED 끄기 : led객체.off()

    ex)

    from gpiozero import LED
    from time import sleep
    
    red = LED(14) #GPIO pin number
    
    while True:
        red.on()
        sleep(1)
        red.off()
        sleep(1)

    => 1초간견으로 LED가 꺼지고/켜지고 반복됨

     

     

     

    ex) Common Cathode FND

     

    from gpiozero import LED
    from time import sleep
    
    a = LED(5)
    b = LED(6)
    c = LED(13)
    d = LED(19)
    e = LED(26)
    f = LED(16)
    g = LED(20)
    dp = LED(21)
    
    number_list = [ #0~9 숫자. (a <-> b 바뀜..!)
        [a, b, c, d, e, f], 
        [a, c], 
        [a, b, d, e, g],
        [a, b, g, c, d],
        [f, a, g, c],
        [b, f, g, c, d],
        [f, g, e, c, d],
        [f, b, a, c],
        [a, b, c, d, e, f, g],
        [a, b, c, f, g],
    ]
    
    fnd = [a,b,c,d,e,f,g,dp]
    for i in range(8):
        fnd[i].on()
        sleep(0.1)
    
    while True:
        sleep(1)

    => 이를 잘 조합하여 on 시키면, 0~9숫자를 만들 수 있다!

     

     

     

    switch

     

    • lib : from gpiozero import Button
    • Button 객체 선언 : Button(핀번호)
    • Button on/off 확인 : btn객체.is_pressed
      =>눌렸을때 1, 눌리지 않았을 때 0을 반환한다.

    ex)

    from gpiozero import Button
    
    btn = Button(15)
    
    while True:
        if btn.is_pressed:
            print('ON')
        else:
            print('OFF')

    => 누르고 있다면 ON, 누르고 있지 않다면 OFF가 출력된다.

    => callback 함수를 호출하는 것이 아니라, 그냥 while문에서 true, false에 따라 동작하는 것이므로 계~~~~속 출력된다.

     

     

    • Button 동작 정의 : interrupt 방식(내부적으로 Threading 동작)
      • lib : from signal import pause
      • 눌렸을 때 동작 정의 : btn객체.when_pressed = callback함수
        => 버튼이 눌렸을때, 정의한 callback함수가 호출된다.
      • 눌렀다 땠을 때 동작 정의 : btn객체.when_release = callback함수
        => 버튼이 눌렀다 땠을 때, 정의한 callback함수가 호출된다.

    이때, 해당 방식은 interrupt 방식이므로, 버튼에 입력 신호가 들어올 때까지 프로그램이 종료되지 않고 대기해야 한다. 따라서 코드에 맨 끝에 다음을 추가해준다.

    • pause() : 프로세스 종료 or 시그널 종료 신호를 받을 때까지 대기한다.

    ex)

    from gpiozero import Button
    from signal import pause
    
    def press():
        print("Btn Pressed!")
    
    def release():
        print("Btn Released!")
    
    btn = Button(15)
    
    btn.when_pressed = press
    btn.when_released = release
    
    pause()

    => Python Signal 라이브러리를 이용해서 인터럽트 방식으로 구현한 코드.

    => 앞선 코드와 달리, 버튼을 누른/땐 순간에만 callback 함수가 호출된다.

     

     

     

    풀업 회로

     

    • 💡floating 상태란?
      • 스위치를 누르지 않으면, HIGH인지 LOW인지 알 수 없다. 
      • 이러한 상태를 floating 상태라고 한다.
      • (라즈베리파이 뿐 아니라 모든 MCU에서 마찬가지임)

     

     

     

    floating 상태는 S/W or H/W 적으로 해결 가능하다.

    => H/W 적으로 해결하는 것을 풀업/풀다운 회로라고 한다!

    (저항을 사용해 구현)

     

    • 풀업회로 : 스위치를 누르지 않았을 때, HIGH로 정해짐
    • 풀다운회로 : 스위치를 누르지 않았을 때, LOW로 정해짐
      => 노이즈 제거, 회로 보호 등 풀업 저항의 이점이 더 많아 풀업이 주로 쓰인다.

     

    ▶ 풀업 회로

    : 스위치를 누르지 않았을 때, HIGH상태이다.

     

     

    ▶ 풀다운 회로

    : 스위치를 누르지 않았을 때, LOW 상태이다.

     

     

    ex) 풀업회로를 사용하여도, 코드는 동일하다.

    회로 구성에서, 저항을 추가해주면 된다!

    from gpiozero import Button
    from signal import pause
    
    def press():
        print("Btn Pressed!")
    
    def release():
        print("Btn Released!")
    
    btn = Button(18)
    
    btn.when_pressed = press
    btn.when_released = release
    
    pause()

     

     

    💡그런데, 이전 예제에서는 위와 같이 풀업 회로를 구성해주지 않아도 잘 동작했다.
    => 라즈베리파이 GPIO 핀에는 내부 풀업 회로가 동작하는 핀이 있기 때문!

     

     

     

     

    라즈베리 파이 통신 

     

    BMP 280 : 정밀한 대기압, 온도 센서
    • lib : import smbus
    • smbus 객체 생성 : smbus.SMBus(버스번호, rasp는 주로 1)
    • 값 read : sm객체.read_byte_data(장치 주소, 레지스터 주소)
      => 해당 장치의 레지스터 주소로 부터 값 읽어오기

     

    ex)

    • 회로

     

     

    • 이때, 다음의 명령어를 통해 연결된 I2C장치의 주소를 확인한다.

    $ i2cdetect -y 1

     

     

    • 코드 및 동작 : chip_id출력

     

    0xD0에 chip_id가 작성되어 있음 => 해당 값 출력

    💡데이터 시트를 보면, id값은 0x58이라고 적혀있는데,

    실제로 해당 코드 실행결과 나오는 88은 16진수로 0x58임을 알 수 있다!

    import smbus
    from time import sleep
    
    DEVICE_BUS = 1 #I2C 장치에 연결된 버스 번호를 설정
    			#일반적으로 Raspberry Pi에서는 1번 버스가 사용됨
    
    DEVICE_ADDR = 0x76 #통신할  I2C 장치의 주소 (i2cdetect 명령어로 확인)
    
    bus = smbus.SMBus(DEVICE_BUS) #smbus 모듈의 SMBus 클래스를 사용하여 I2C 버스 객체 생성
    
    while True:
    
        # 0x76장치의 0xD0 register 의 값을 1byte 읽어서 출력 
        a = bus.read_byte_data(DEVICE_ADDR, 0xD0)
        print(a) #=> 88
        sleep(0.5)

    0xD0에 chip_id가 작성되어 있는 것을 볼 수 있다.

     

     

    • 코드 및 동작 : 온도와 압력 정보 출력

    온도와 압력 정보가 각각 3개 Byte 에 나뉘어 있다.

    temp : 0xFA ~ 0xFC

    press : 0xF7~0xF9

     

     

    • temp 정보 파싱하기

     

     

    해당 정보를 참고하여 temp 데이터를 알맞게 파싱하여 출력해보자!

    하지만 data sheet에서 말하고 있듯, 해당 값을 그대로 출력하면 값이 잘 나오지 않는다.

    => 라이브러리를 이용해 해결할 수 있다!

    import smbus
    from time import sleep
    
    DEVICE_BUS = 1
    DEVICE_ADDR = 0x76
    
    bus = smbus.SMBus(DEVICE_BUS)
    
    while True:
        a = bus.read_byte_data(DEVICE_ADDR, 0xFA)
        b = bus.read_byte_data(DEVICE_ADDR, 0xFB)
        c = bus.read_byte_data(DEVICE_ADDR, 0xFC)
        print(a,b,c)
    
        result = (a<<12) | (b<<4) | ((c&0xF0) >> 4)
        print(result)
        sleep(0.5)

     

     

     

    • 라이브러리 사용한 temp 출력

    https://github.com/pimoroni/bmp280-python

     

    GitHub - pimoroni/bmp280-python: Python library for the BMP280 temperature, pressure, and altitude sensor.

    Python library for the BMP280 temperature, pressure, and altitude sensor. - pimoroni/bmp280-python

    github.com

    $ git clone https://github.com/pimoroni/bmp280-python
    $ cd bmp280-python
    $ sudo ./install.sh

    => 해당 라이브러리의 get_temperature(), get_pressure() 함수를 사용해 온도, 기압 정보를 얻을 수 있다!

     

    from bmp280 import BMP280
    from smbus import SMBus
    from time import sleep
    
    bus = SMBus(1)
    bmp280 = BMP280(i2c_dev=bus)
    
    while True:
        temp = bmp280.get_temperature()
        pres = bmp280.get_pressure()
        print('{:05.2f}oC {:05.2f}hPa'.format(temp, pres))
        sleep(1)

     

     

     

     

    Sense Hat - j2 (joy stick)

     

     

    • 폴링 방식
    from sense_hat import SenseHat
    
    sense = SenseHat()
    
    while True:
        for event in sense.stick.get_events():
            print("Joystick {} {}".format(event.action, event.direction))

     

     

     

    • 인터럽트 방식
    from sense_hat import SenseHat, ACTION_PRESSED, ACTION_HELD, ACTION_RELEASED
    from signal import pause
    
    x = 3
    y = 3
    sense = SenseHat()
    
    def clamp(value, min_value=0, max_value=7):
        return min(max_value, max(min_value, value))
    
    def pushed_up(event):
        global y
        if event.action != ACTION_RELEASED:
            y = clamp(y - 1)
    
    def pushed_down(event):
        global y
        if event.action != ACTION_RELEASED:
            y = clamp(y + 1)
    
    def pushed_left(event):
        global x
        if event.action != ACTION_RELEASED:
            x = clamp(x - 1)
    
    def pushed_right(event):
        global x
        if event.action != ACTION_RELEASED:
            x = clamp(x + 1)
    
    def refresh():
        sense.clear()
        sense.set_pixel(x, y, 255, 255, 255)
    
    sense.stick.direction_up = pushed_up
    sense.stick.direction_down = pushed_down
    sense.stick.direction_left = pushed_left
    sense.stick.direction_right = pushed_right
    sense.stick.direction_any = refresh
    refresh()
    pause()

     

Designed by Tistory.
-->