
본격적으로 라즈베리파이를 쓰게 되었다.
가상 머신에서 리눅스를 써도 크게 문제는 없지만,
이전 내용에 있었던 코어 덤프 같은 경우 VM에서는 확인이 안 되기도 하고
아무래도 라즈베리파이에서 GPIO를 직접 써 보는 게 더 좋지 않을까 한다.
ssh로 윈도우와 연결해 두면 VS Code에서도 코드를 쉽게 편집할 수 있어서 좋다.
GPIO (General Purpose Input/Output)
마이크로컨트롤러(MCU)나 임베디드 보드(라즈베리파이)에서 일반적인 신호를 입출력하기 위한 범용 핀
HIGH 또는 LOW 두 가지 상태로 작업을 처리
LED 회로 연결하기
라즈베리파이 GPIO는 3.3V이므로 저항을 사용함
라즈베리파이 GPIO ── 저항 ── LED 양극 ── LED 음극 ── GND
터미널에서 제어하기
GPIO 제어를 위해 관리자 권한이 필요함
# GPIO18 활성화
$ echo "18" > /sys/class/gpio/export
# 출력 모드 설정
$ echo "out" > /sys/class/gpio/gpio18/direction
# LED 켜기
$ echo "1" > /sys/class/gpio/gpio18/value
# LED 끄기
$ echo "0" > /sys/class/gpio/gpio18/value
# 사용한 핀 해제하기
$ echo "18" > /sys/class/gpio/unexport
파일 입출력으로 LED 제어하기
sys/class/gpio 파일을 사용해서 GPIO 제어 가능
파일 시스템에 open/read/write/close 로 직접 접근
예시
// GPIO 활성화
fd = open("/sys/class/gpio/export", O_WRONLY);
sprintf(buf, "%d", gpio);
write(fd, buf, strlen(buf));
close(fd);
// 출력 모드 설정
sprintf(buf, "/sys/class/gpio/gpio%d/direction", gpio);
fd = open(buf, O_WRONLY);
write(fd, "out", 4); // NULL 제외 4바이트
close(fd);
// LED 켜고 끄기
sprintf(buf, "/sys/class/gpio/gpio%d/value", gpio);
fd = open(buf, O_WRONLY);
write(fd, "1", 2); // HIGH
getchar(); // 사용자 입력 대기
write(fd, "0", 2); // LOW
close(fd);
// 사용한 핀 해제
fd = open("/sys/class/gpio/unexport", O_WRONLY);
sprintf(buf, "%d", gpio);
write(fd, buf, strlen(buf));
close(fd);
WiringPi
라즈베리 파이에서 사용할 수 있는 GPIO 제어 라이브러리
C언어로 작성되었고, DMA를 사용하여 레지스터에 직접 액세스하여 빠르고 효율적인 제어
WiringPi 설치와 사용
git clone https://github.com/WiringPi/WiringPi.git
주요 함수
| 함수 | 용도 | 예시 |
|---|---|---|
wiringPiSetup() | wPi 번호 초기화 | 가장 간단 |
wiringPiSetupGpio() | BCM 번호 초기화 | sysfs와 동일 |
pinMode(pin, mode) | 핀 모드 설정 | OUTPUT, INPUT |
digitalWrite(pin, val) | 디지털 출력 | HIGH(1), LOW(0) |
digitalRead(pin) | 디지털 입력 | 0 또는 1 반환 |
delay(ms) | 밀리초 대기 | delay(1000) = 1초 |
핀 번호는 gpio readall 의 wPi 번호를 사용하면 편리함
LED 제어 예시
pinMode(gpio, OUTPUT); // Pin을 출력 모드로 설정
for (int i = 0; i < 5; i++) {
digitalWrite(gpio, HIGH); // HIGH(1) 값을 출력: LED 켜기
delay(1000); // 1초(1000밀리초) 동안 대기
digitalWrite(gpio, LOW); // LOW(0) 값을 출력: LED 끄기
delay(1000);
}
PWM의 사용
라즈베리파이의 디지털 핀은 0V 또는 3.3V의 값만 출력 가능
사람 눈에 보이지 않을 정도로 빠르게 깜빡이면 밝기가 바뀌는 것처럼 보임
softPwmCreate(pin, 초기값, 최대값)
해당 핀에 대해 소프트웨어로 PWM을 만들어 주는 wiringPi 함수
0~255 사이 값으로 밝기를 조절 가능 (0 = 완전 꺼짐, 255 = 최대로 켜짐, 중간 값 = 중간 밝기)
softPwmWrite(pin, value)
앞에서 설정한 범위(0~255) 중 value에 해당하는 듀티 사이클로 출력
값이 커질수록 LED가 더 밝게 보임
예시
softPwmCreate(gpio, 0, 255); // PWM 범위 설정
for(int i = 0; i < 10000; i++) {
softPwmWrite(gpio, i&255); // PWM 값을 출력해 LED 켜기
// 하위 8비트만 사용하므로 0~255 사이의 값을 반복
delay(5);
// 5ms마다 값이 조금씩 바뀌도록 설정
}
softPwmWrite(gpio, 0);
피에조 버저의 기본 개념
내부에 피에조 소자라는 얇은 판이 있고 전기 신호를 받으면 판이 진동하며 소리가 남
+핀은 MCU/GPIO에 연결하고 -핀은 GND로 연결하여 사용
액티브 타입과 패시브 타입 두 가지가 있음
액티브 피에조 버저
내부에 오실레이터가 있어 ON/OFF 두 가지의 상태를 가지는 버저
전압을 HIGH로 주면 일정한 음을 계속 내는 버저
패시브 피에조 버저
MCU가 PWM(주파수)를 만들어 줘야 하는 버저
PWM를 걸면 원하는 주파수로 진동시켜 여러 음을 낼 수 있음
패시브 피에조 버저 사용 예시
// wiringPi.h, softTone.h 가져오기
int i;
softToneCreate(SPKR); // SPKR에 GPIO 핀 번호를 두고 톤 출력 핀으로 설정
for (i = 0; i < TOTAL; ++i) {
softToneWrite(SPKR, notes[i]); // note에 있는 톤 출력
delay(280); // 음의 전체 길이만큼 출력되도록 대기
}
return 0;
여기에 있는 센서를 포함해서 LED, 조도 센서, 버저, DC 모터 등등 다양한 장치를 사용해 보았다.
아직 회로도를 보는 게 아주 익숙하지는 않지만,
큰 실수 없이 잘 작동하는 걸 확인할 수 있었다.
그렇지만 소스 코드를 혼자 처음부터 짜라고 하면 짤 수 있을지는 잘 모르겠다.
남은 내용이 엄청 많은데 천천히 더 정리해 보는 걸로...!