Raspberry Pi
라즈베리파이 시작하기
터미널 명령어
`cd` : 상위로 폴더로 이동
`cd home/pi/파일폴더이름` : 폴더 이동
`ls` : 현재 폴더의 파일 보기
sd카드 포맷
[RASP | SD카드 포맷, 복제 및 용량 확장](https://velog.io/@sz3728/RASP-SD카드-복제-및-용량-확장)
sd카드에 RASP OS 넣어주기.
라즈베리파이 사이트에서 OS 다운 및 설치
sd카드 연결
라즈베리파이 끄는 법
메뉴에서 로그아웃 선택해서 끄고 전부 해체한다.
초기 세팅
- 패키지 업데이트
- 항상 터미널에서 패키지 파일을 받기 전, 패키지 업데이트
$ sudo apt-get update
$ sudo apt-get upgrade
한글설정
[RASP | Fcitx 설치, 한글 설정 및 키보드 한영 전환](https://velog.io/@sz3728/RASP-Fcitx-설치-한글-설정-및-키보드-한영-전환)
기본 정보
라즈베리파이 5 나옴.
라즈베리 파이 쇼트 조심
라즈베리 파이 보드에 전원을 넣기 전 마우스, 키보드, 모니터 등을 꼽고 전원을 꽂아야 쇼트가 나지 않는다.
전원은 무조건 마지막에 연결.
- [GPIO 고장나는 경우](https://velog.io/@amos42/%EB% 9D% BC% EC% A6%88% EB% B2% A0% EB% A6% AC% ED% 8C% 8C% EC% 9D% B4-GPIO-%EB% B3% B4% ED%98% B8-%EB% B0% A9% EB% B2%95)
- INPUT 모드인 상태에서 VCC와 직결
- OUTPUT 모드인 상태에서 GND와 직결
- GPIO에 3.3V를 초과한 과전압이 흐를 때
- 각 GPIO 핀의 허용 전류 이상이 흐를 때
- 전체 GPIO로 흐르는 전류의 총합이 허용 전류 이상일 때
전원 5 볼트
40 Pin 정보
GPIO를 사용할 땐 전원과 연결 필요 없이 GPIO 핀에 바로 꼽기만 하면 됨. GPIO, GND만 연결되면 됨.
참고. [Raspberry Pi4 GPIO Pinout 완벽 정리](https://fishpoint.tistory.com/7687)
BCM과 Physical pin 넘버
라즈베리파이 터미널에서 GPIO 번호 확인하기 $ gpio readall
출처 : ChatGPT
내가 이해한 내용 : Physical은 라즈베리파이에 핀이 40개가 있고 그걸 순서대로 1,2,3... 번호를 매겨둔 것이다.
BCM : 각 피지컬 번호를 GPIO에 할당시켜 직접 코드에서 사용하는 번호이다. 따라서 BCM의 번호를 코드에 사용하면 된다. BCM은 개발자가 임의로 바꿀 수 없다.
MODE : IN, OUT 입, 출력 상태를 나타냄.
V : 전원의 On(1), Off(0)를 나타냄.
pi@yahboom4wd:~ $ gpio readall
+-----+-----+---------+------+---+---Pi 4B--+---+------+---------+-----+-----+
| BCM | wPi | Name | Mode | V | Physical | V | Mode | Name | wPi | BCM |
+-----+-----+---------+------+---+----++----+---+------+---------+-----+-----+
| | | 3.3v | | | 1 || 2 | | | 5v | | |
| 2 | 8 | SDA.1 | OUT | 1 | 3 || 4 | | | 5v | | |
| 3 | 9 | SCL.1 | IN | 1 | 5 || 6 | | | 0v | | |
| 4 | 7 | GPIO. 7 | IN | 1 | 7 || 8 | 1 | ALT0 | TxD | 15 | 14 |
| | | 0v | | | 9 || 10 | 1 | ALT0 | RxD | 16 | 15 |
| 17 | 0 | GPIO. 0 | IN | 1 | 11 || 12 | 1 | IN | GPIO. 1 | 1 | 18 |
| 27 | 2 | GPIO. 2 | OUT | 0 | 13 || 14 | | | 0v | | |
| 22 | 3 | GPIO. 3 | OUT | 0 | 15 || 16 | 0 | OUT | GPIO. 4 | 4 | 23 |
| | | 3.3v | | | 17 || 18 | 1 | OUT | GPIO. 5 | 5 | 24 |
| 10 | 12 | MOSI | ALT0 | 0 | 19 || 20 | | | 0v | | |
| 9 | 13 | MISO | OUT | 0 | 21 || 22 | 0 | IN | GPIO. 6 | 6 | 25 |
| 11 | 14 | SCLK | OUT | 0 | 23 || 24 | 1 | OUT | CE0 | 10 | 8 |
| | | 0v | | | 25 || 26 | 0 | IN | CE1 | 11 | 7 |
| 0 | 30 | SDA.0 | IN | 1 | 27 || 28 | 0 | OUT | SCL.0 | 31 | 1 |
| 5 | 21 | GPIO.21 | IN | 1 | 29 || 30 | | | 0v | | |
| 6 | 22 | GPIO.22 | IN | 0 | 31 || 32 | 1 | IN | GPIO.26 | 26 | 12 |
| 13 | 23 | GPIO.23 | OUT | 0 | 33 || 34 | | | 0v | | |
| 19 | 24 | GPIO.24 | OUT | 0 | 35 || 36 | 0 | OUT | GPIO.27 | 27 | 16 |
| 26 | 25 | GPIO.25 | OUT | 0 | 37 || 38 | 0 | OUT | GPIO.28 | 28 | 20 |
| | | 0v | | | 39 || 40 | 0 | OUT | GPIO.29 | 29 | 21 |
+-----+-----+---------+------+---+----++----+---+------+---------+-----+-----+
| BCM | wPi | Name | Mode | V | Physical | V | Mode | Name | wPi | BCM |
+-----+-----+---------+------+---+---Pi 4B--+---+------+---------+-----+-----+
RPi.GPIO 입,출력
GPIO 핀의 설정을 입력 또는 출력 하나로만 지정이 가능.
setup(), 핀의 Mode, 즉 입, 출력 상태 설정하기.
initial : 초기상태 0 또는 1
GPIO.setup(pin_no, GPIO.IN(또는 OUT), initial=GPIO.LOW(또는 HIGH))
저항
저항(R) 구하기.
R = V/I(A)
참고. [[아두이노 기초 강좌] 6. 저항 색상표로 저항 크기 읽는 법 (저항 색띠 읽는 법)](https://blog.naver.com/roboholic84/220304850807)
GPIO
LED 켜기
import RPi.GPIO as GPIO
led_pin = 17
GPIO.setmode(GPIO.BCM)
GPIO.setup(led_pin, GPIO.OUT)
GPIO.output(led_pin, True)
try:
while True:
pass
except KeyboardInterrupt :
pass
GPIO.cleanup()
LED 2초 뒤에 끄기
import RPi.GPIO as GPIO
Import time
led_pin = 17
GPIO.setmode(GPIO.BCM)
GPIO.setup(led_pin, GPIO.OUT)
GPIO.output(led_pin, True)
time.sleep(2.0)
GPIO.output(led_pin, False)
GPIO.cleanup()
LED 깜빡이기
import RPi.GPIO as GPIO
Import time
led_pin = 17
GPIO.setmode(GPIO.BCM)
GPIO.setup(led_pin, GPIO.OUT)
try :
while True :
GPIO.output(led_pin, True)
time.sleep(2.0)
GPIO.output(led_pin, False)
time.sleep(2.0)
except KeyboardInterrupt :
pass
GPIO.cleanup()
참고. [라즈베리 파이 40 PIN 정리](https://fishpoint.tistory.com/7687)
PWM
40핀 레이아웃 참고, 펄스폭 변조라고 하며 0V와 5V를 적절히 사용하여 평균값으로 아날로그 신호를 대체한다.
주파수가 높을수록 빠르게 변화한다.
참고. [PWM LED 제어하기](https://minimax95.tistory.com/entry/PWM-LED-%EC%A0%9C%EC%96%B4%ED%95%98%EA%B8%B0)
import RPi.GPIO as GPIO
led_pin = 18
GPIO.setmode(GPIO.BCM)
GPIO.setup(led_pin, GPIO.OUT)
pwm = GPIO.PWM(led_pin, 1.0) #1.0Hz, 1초동안
pwm.start(50.0) # 0.0~100.0, High 구간은 50프로로 시작.
try :
while True :
pass
except KeyboardInterrupt :
pass
pwm.stop()
GPIO.cleanup()
밝기 및 속도 조절, 천천히 밝아짐.
import RPi.GPIO as GPIO
import time
led_pin = 17
GPIO.setmode(GPIO.BCM)
GPIO.setup(led_pin, GPIO.OUT)
try :
while True:
for t_high in range(0,11) :
cnt = 0
while True :
GPIO.output(led_pin, True)
time.sleep(t_high * 0.001)
GPIO.output(led_pin, False)
time.sleep((10 - t_high) * 0.001)
cnt += 1
if cnt == 10 : break
except KeyboardInterrupt :
pass
GPIO.cleanup()
ChangeDuttyCycle
import RPi.GPIO as GPIO
import time
led_pin = 18
GPIO.setmode(GPIO.BCM)
GPIO.setup(led_pin, GPIO.OUT)
pwm = GPIO.PWM(led_pin, 1000.0)
pwm.start(0.0)
try :
while True :
for t_high in range(0, 101) :
pwm.ChangeDuttyCycle(t_high)
time.sleep(0.01)
for t_high in range(100, -1, -1) :
pwm.ChangeDuttyCycle(t_high)
time.sleep(0.01)
except KeyboardInterrupt :
pass
pwm.stop()
GPIO.cleanup()
원격 접속 및 데이터 전송
원격 접속(터미널)
1. 기본 설정 -> 라즈베리파이 환경설정 -> 인터페이스 -> SSH, VNC ON -> 확인
Window
- Putty 프로그램으로 접속할 수 있게 환경 만들기 : 터미널을 통해 윈도에서 RASP을 컨트롤 가능
[TheKoguryo's 기술 블로그](https://thekoguryo.github.io/oci/chapter03/5/2/)
Macbook
- 터미널에서 `$ SSH@RASP의 IP주소`만 치면 진입 가능
데이터 송수신
Window는 winSCP 사이트에서 프로그램 다운로드하기
해당 프로그램을 통해 RASP와 window에 있는 파일을 서로 공유 가능하다.
[winSCP](https://winscp.net/eng/download.php)
디폴트 ID : pi, PW : raspberry
맥북은 CyberDuck 프로그램 사용
- 프로그램을 열어 새 연결을 클릭
- 프로토콜을 SFTP(SSH File Transfer Protocol)로 변경
- 서버에 IP 주소 입력, 사용자 이름 pi, 비밀번호 yahboom 입력
- IP주소는 연결된 와이파이마다 다름.
버튼연결
GPIO08, 07번 사용.
08번 스위치 연결법
- 3V 사용(1번) - 저항 10k - GPIO 8번으로 연결 - 버튼 - GND
07번 스위치 연결법
위와 같지만 저항은 GPIO 7번으로 연결
부저 사용
LED 위치에 대신 적용, 저항 필요 없음.
부저 `+` 부분이 전원과 연결
모터 돌리기
빨간색 - 전원 5v
오렌지 - signal(pin18번과 연결)
갈색 - GND
코드에 작성되는 점퍼 선 번호는 GPIO에 있는 번호를 작성해야 함.
GND 같은 애들은 코드에 따로 작성을 안 하니 상관없음.
Thread, 스레드
뜻은 실을 의미하지만 프로그래밍에서 멀티태스킹이 가능하도록 해준다.
각 스레드에 작업을 걸어 두기에 많은 양의 작업을 동시에 진행할 경우 버벅거린다.
라즈베리 파이로 예를 들면 LED가 깜빡거리는 동시에 컴퓨터 화면상에 print가 된다.
반드시 `import threading`을 하여 사용해야 여러 기능 사용이 가능하다.
메인 프로그램을 주로 하고 시간이 날 때 스레드에 있는 요청을 불러와 기능하기에 반응이 느리다.
thread 예제. Python Idle에서 사용.
import threading
import time
flag_exit = False
def t1_main():
while True:
print("\tt1")
time.sleep(0.5)
if flag_exit: break
t1 = threading.Thread(target=t1_main)
t1.start()
try:
while True:
print("main")
time.sleep(1.0);
except KeyboardInterrupt:
pass
flag_exit = True
t1.join()
Window와 Raspberry Pi 서버 연결하기
윈도에서 `JK_Comm.exe` 해당 프로그램 실행
RASP에서 `Server.py` 파일 실행 후 서버단의 IP주소를 코드에 변경한다. (서버단은 RASP이니까 RASP IP주소 입력)
RASP은 서버단이라 윈도(클라이언트)에서 먼저 메시지를 보내야 응답이 가능.
RASP이 클라이언트인 경우 `Client.py` 파일 사용 (서버단은 Win이니까 Win IP주소 입력)
Window 명령 프롬프트에서 ipconfig를 입력하여 IP주소를 알 수 있다.
chattering
소프트웨어적으로는 문제없음. 하드웨어적 문제.
신호가 끊겨 스위치를 누를 때 값이 제멋대로 변경되는 사항을 의미.
신호가 끊기는 시간을 랜덤임. 따라서 실험을 해보고 타임 딜레이를 줘야 함. (너무 길면 반응이 없으니 적당히 조절할 것.)
time.sleep 적용 전
import RPi.GPIO as IoPort
def DisplayState(St): #.....................(1)
if St == 1:
IoPort.output(Led1,False)
IoPort.output(Led2,False)
elif St == 2:
IoPort.output(Led1,True)
IoPort.output(Led2,False)
elif St == 3:
IoPort.output(Led1,False)
IoPort.output(Led2,True)
else:
IoPort.output(Led1,True)
IoPort.output(Led2,True)
Key1 = 8
Led1 = 18
Led2 = 23
IoPort.setmode(IoPort.BCM)
IoPort.setup(Led1, IoPort.OUT)
IoPort.setup(Led2, IoPort.OUT)
IoPort.setup(Key1, IoPort.IN)
State = 1
while State <= 4: #.....................(2)
DisplayState(State) #.....................(3)
while True: #.....................(4)
if IoPort.input(Key1)== False:
break
while True: #.....................(5)
if IoPort.input(Key1)== True:
break
State += 1 #.....................(6)
DisplayState(1) #.....................(7)
time.sleep 적용 후
import RPi.GPIO as IoPort
import time
def DisplayState(St):
global State #....................(1)
if St == 1:
IoPort.output(Led1,False)
IoPort.output(Led2,False)
elif St == 2:
IoPort.output(Led1,True)
IoPort.output(Led2,False)
elif St == 3:
IoPort.output(Led1,False)
IoPort.output(Led2,True)
else:
IoPort.output(Led1,True)
IoPort.output(Led2,True)
State = 0 #....................(2)
Key1 = 8
Led1 = 18
Led2 = 23
IoPort.setmode(IoPort.BCM)
IoPort.setup(Led1, IoPort.OUT)
IoPort.setup(Led2, IoPort.OUT)
IoPort.setup(Key1, IoPort.IN)
State = 1
while State <= 4:
DisplayState(State)
while True:
if IoPort.input(Key1)== False:
break
time.sleep(0.1) #....................(3)
while True:
if IoPort.input(Key1)== True:
break
time.sleep(0.1) #....................(4)
State += 1
초음파 센서
TRIG : GPIO23, 송신 모듈
ECHO : GPIO24, 수신 모듈
TRIG에서 초음파 근접 신호를 잡으면 ECHO까지 걸리는 시간을 계산하여 알 수 있다.
참고. https://rasino.tistory.com/349
openCV 활용 웹캠 사용하기
참고. https://supersfel.tistory.com/305
라즈비안 GUI에서 카메라 설정이 안 보이는 문제 발생.
- 카메라 연결 후 `$ lsusb`로 정상 연결 확인.
- 카메라 설정이 라즈베리파이 환경설정 > 인터페이스에 떠야 하는데 안 뜸.
- [찾다 보니 gpu가 문제인걸 앎. 최소 128mb가 되어야 카메라 사용가능](https://raspberrypi.stackexchange.com/questions/68927/why-raspberry-pi-camera-wont-appear-on-rasp-config)
- 하지만 gpu 설정하는 창인 환경설정 > 퍼포먼스에 gpu설정이 안 보임.
- `$ sudo raspi-config`에서도 없음.
- 터미널에 `$ vcgencmd get_mem arm;vcgencmd get_mem gpu` 입력 후 확인하니 gpu값이 뜸.
- `$ sudo nano /boot/config.txt` 입력 후 arm_64bit=1 밑에다 `gpu_mem=128`이라고 작성함.
- `$ vcgencmd get_mem gpu` 확인 결과 gpu 메모리 128mb로 변경되어 있음.
- 하지만 세팅에 카메라가 뜨지 않음.
[카메라 세팅법](https://youtu.be/OEGR19aE0dg?si=qRJJf9rqz100zp-S)
# 카메라 프로그램 설치
$ sudo apt install fswebcam
# 캡쳐 명령어 테스트
$ fswebcam -r 1280x270 --no-banner /home/pi/image1.jpg
# openCV 설치
$ pip3 install opencv-python
openCV 모듈 찾기 에러 발생.
[xternally-managed 삭제](https://www.jeffgeerling.com/blog/2023/how-solve-error-externally-managed-environment-when-installing-pip3)
error: externally-managed-enviroment
$ sudo rm -rf /usr/lib/python3.11/EXTERNALLY-MANAGED
# opencv 재설치 OK
$ pip3 install opencv-python
비디오카메라 테스트
참고. https://raspberrypi-guide.github.io/electronics/using-usb-webcams
아래 카메라 실행코드 `.py` 파일로 작성 후 노트북 저장. > RASP 다운로드 폴더로 옮김.
import cv2
cam = cv2.VideoCapture(0)
while True:
ret, image = cam.read()
cv2.imshow('Imagetest',image)
k = cv2.waitKey(1)
if k != -1:
break
cv2.imwrite('/home/pi/testimage.jpg', image)
cam.release()
cv2.destroyAllWindows()
RASP 터미널에서 카메라 실행
$ python3
>>> import sys
>>> sys.path.append('/home/pi/Downloads')
>>> import camera.py
라즈베리파이 화면 사이즈 수정하기
옵션 들어가기
$ sudo raspi-config
> Display Options
> Resolution
> 원하는 해상도 선택 후 재부팅