본문 바로가기

라즈베리파이

라즈베리파이 3B에서 gpio 제어 (wiringpi)

gpio 제어
라즈베리 파이의 gpio를 제어하는 방법은 크게 보면 sysfs를 통한 방법과 mmap()함수를 통한 gpio 레지스터를 직접적으로 읽고 쓰는 방식이 있다.
아래 사이트에서 거의 모든 종류의 라즈베리파이 gpio 제어에 대한 설명이 잘 되어 있다.
https://elinux.org/RPi_GPIO_Code_Samples

 

그중에서 sysfs, C, python으로 gpio에 대한 제어 예제를 살펴보도록 한다.

  • sysfs - shell상에서 커맨드라인으로 입력
  • C - wiringPi 사용
  • python - wiringpi-python 사용

 

LED 배선도
그림과 같이 gpio 26번을 통하여 LED가 연결되어 있다.

여기서 저항은 200-300 옴 정도를 사용하면 된다.

 

sysfs를 통한 제어
가장 일반적인 방법으로 다음과 같은 흐름으로 gpio를 설정한다.
pin 번호를 export --> direction 설정 --> 값 설정

echo 26 > /sys/class/gpio/export
echo out > /sys/class/gpio/gpio26/direction
echo 1 > /sys/class/gpio/gpio26/value (on)
echo 0 > /sys/class/gpio/gpio26/value (off)

 

WiringPi (c code)
설치 및 빌드

git clone https://github.com/WiringPi/WiringPi
./build

 

코드 수정
wiringPi는 보드 버전을 /proc/cpuinfo를 통해서 확인한다.
현재 사용하는 4.19 (64bit)의 경우 Revision 항목이 없어서 wiringPi 초기화 루틴에서 에러가 난다.

따라서 다음 두가지 중 하나를 수정하여 동작하도록 한다.

두가지 개념 모두 /proc/cpuinfo에 Reviosn 으로 "2a02082"를 나타내게 한것이다. 이 Revision번호는 "Raspberry 3 B rev 1.2 Embest" 제품을 나타낸다.

 

- Wring Pi 코드 수정

diff --git a/wiringPi/wiringPi.c b/wiringPi/wiringPi.c
index c3b9d8b..1bfc99e 100644
--- a/wiringPi/wiringPi.c
+++ b/wiringPi/wiringPi.c
@@ -820,6 +820,8 @@ int piGpioLayout (void)

   fclose (cpuFd) ;

+  strcpy(line, "Revision        : 2a02082");
+
   if (strncmp (line, "Revision", 8) != 0)
     piGpioLayoutOops ("No \"Revision\" line") ;

- 커널에서 /cpu/info에서 Revioson 출력하기

디바이스 트리에서 "/system" node에 Revision항목을 넣던지 아래와 같이 직접 커널 소스에 넣던지 한다.

--- a/arch/arm64/kernel/cpuinfo.c
+++ b/arch/arm64/kernel/cpuinfo.c
@@ -191,6 +191,8 @@ static int c_show(struct seq_file *m, void *v)
                of_node_put(np);
        }

+       seq_printf(m, "Revision\t: 2a02082\n" );
+
        np = of_find_node_by_path("/");
        if (np) {
                if (!of_property_read_string(np, "serial-number",
 

wringPi 핀 맵

gpio readall 하면 다음과 같이 배선도를 보여준다.

이때 gpio26번은 wiringpi 에서 25번을 사용한다는 것을 보여준다.

 

wiringPi example C code
gcc -o led led.c -lwiringPi

#include <wiringPi.h>

int main (void)
{
  wiringPiSetup () ;
  pinMode (25, OUTPUT) ;
  while (1)
  {
    digitalWrite (25, HIGH) ; delay (1000) ;
    digitalWrite (25,  LOW) ; delay (1000) ;
  }
  return 0 ;
}

 

wiringpi-python
소스다운 및 설치

git clone https://github.com/WiringPi/WiringPi-Python
python3 setup.py install
(이 패키지는 swig 가 설치되어 있어야만 정상적으로 진행된다.)


wiringpi-python example code

import wiringpi
import time

wiringpi.wiringPiSetup()
wiringpi.pinMode(25, 1) # Set pin 25 to 1 ( OUTPUT )

while True:
    wiringpi.digitalWrite(25, 1)
    time.sleep(1)
    wiringpi.digitalWrite(25, 0)
    time.sleep(1)