임베디드 시스템 4주차 - changook123/Embedded GitHub Wiki
Raspberry Pi의 I2C, SPI, UART 통신 프로토콜
GPIO(General Purpose Input/Output)
- 어떠한 신호를 원하는 형태로 제어하고 처리하는 시스템
- 전기 신호를 처리하거나 전자 장치의 동작을 제어하는 데 사용
- 전압: 전기를 공급하기 위해 사용되는 전기적인 차이를 의미함 [단위: 볼트(V)]
- 전류: 흐르는 전기의 양을 나타냄. 전압에 의해 유도 [단위: 암페어(A)]
- 옴의 법칙은 전압(V), 전류(I), 저항(R) 간의 관계를 설명하는 법칙
- 전압(V): 전류(I)와 저항(R)의 곱한 값이다.(전류가 증가하면 전압도 증가)
- 전류(I): 저항(R)과 반비례한다.(저항이 증가하면 전류가 감소)
- 저항(R): 전압(V)과 비례한다.(저항이 증가하면 전압도 증가)
- 아날로그 신호: 연속적인 값으로 표현되는 신호. 시간에 따라 연속적으로 변화하며 소리나 음악, 온도계 등 실제 환경에서 얻은 데이터를 처리하는데 주로 사용
- 디지털 신호: 이산적인 값으로 표현되는 신호. 시간에 따라 일정한 간격으로 값이 변화, 0과 1로 구성된 비트(bit) 형태로 정보를 전달하며 디지털 신호는 컴퓨터, 휴대폰 데이터 처리하는데 사용
- 직류(Direct Current): 전압의 크기와 방향이 일정하게 유지되는 전류의 형태. 평상시 사용하던 건전지(배터리)가 직류 전류이며 라즈베리파이 또한 직류를 사용
- 교류(Alternating Current): 시간에 따라 전압의 크기와 방향이 주기적으로 변하는 전류의 형태. 가정에서 사용하는 전기가 교류 전류이며 단상 220V 60Hz 이다.
- 직렬로 연결된 저항들에 걸리는 전압을 계산할 때 사용하는 법칙
- 이 법칙은 회로 내의 각 저항에 걸리는 전압이 해당 저항값에 비례한다는 원리를 기반함
- 펄스 폭 변조(Pulse Width Modulation) 이하 PWM은 펄스의 폭을 조절하는 제어 방법으로, 주로 LED의 밝기를 조절하거나 모터의 출력을 조절할 때 사용됨
- 수동소자: 전기적 에너지를 소모, 축적 혹은 통과 할 뿐 다른 역할을 하지 않는 소자. 수동적으로 작용하기 때문에 외부전원 없이 단독으로도 동작할 수 있음
- 능동소자: 작은 신호를 큰 출력 신호로 변화시킬 수 있는 전자부품 소자. 에너지 보존 법칙이 성립해야 하므로 다른 전원 장치로부터 에너지를 얻어야만 작동
- 저항(R): 전기적인 저항을 가지는 소자. 전류의 흐름을 방해하거나 전압을 나누는 역할을 함
- 인덕터(L): 전기적인 에너지를 저장하고 방출하는 소자. 전류의 변화를 막거나 필터링하는 역할
- 커패시터(C): 두 개의 도체판 사이 공간에 전하를 모으는 소자. 전기를 일시적으로 저장함
- 4색 띠 저항 읽는법: 첫번째 띠는 10의 자리수의 숫자, 두번째 띠는 1의 자리수, 세번째 띠는 10의 배수를 의미. 마지막 네번째 띠는 오차를 나타냄
- 5색 띠 저항 읽는법: 첫번째 띠는 100의 자리수의 숫자, 두번째 띠는 10의 자리수, 세번째 때는 1의 자리 수. 5색의 경우 네번째 띠는 10의 배수, 마지막 다섯번째 띠는 오차를 나타냄
색상 | 값 |
---|---|
검정색 | 0 |
갈색 | 1 |
빨간색 | 2 |
주황색 | 3 |
노란색 | 4 |
초록색 | 5 |
색상 | 값 |
---|---|
파란색 | 6 |
보라색 | 7 |
회색 | 8 |
흰색 | 9 |
은색 | ±10% |
금색 | ±5% |
- 정류 다이오드: 전류를 일정한 방향으로 흐를 수 있도록 도와주는 소자로 역전류를 방지하여 회로를 보호하는 역할
- 트랜지스터: 전기 신호를 증폭하거나 스위칭하는 기능을 가진 소자. 주로 작은 소리를 증폭하여 출력하는 스피커, 전원을 키고 끄는 스위치로 사용
명령어 | 설명 |
---|---|
ls |
현재 디렉토리의 파일과 디렉토리 목록을 출력 |
cd |
디렉토리 변경 |
pwd |
현재 디렉토리 경로 출력 |
mkdir |
새 디렉토리 생성 |
rm |
파일 또는 디렉토리 삭제 |
touch |
빈 파일 생성 또는 파일 수정 시간 업데이트 |
cp |
파일 또는 디렉토리 복사 |
mv |
파일 또는 디렉토리 이동 또는 이름 변경 |
cat |
파일 내용을 출력 |
nano |
텍스트 편집기 실행 |
echo |
문자열 출력 또는 파일에 내용 추가 |
df |
파일 시스템의 디스크 공간 사용량 확인 |
du |
디렉토리와 파일의 크기 확인 |
ps |
실행 중인 프로세스 목록 확인 |
top |
실시간 시스템 성능 및 프로세스 모니터링 |
chmod |
파일 또는 디렉토리의 권한 변경 |
chown |
파일 또는 디렉토리의 소유자 변경 |
grep |
파일에서 특정 문자열 검색 |
find |
특정 조건에 맞는 파일이나 디렉토리 검색 |
exit |
현재 세션 종료 |
- 고속 데이터 전송을 위한 직렬 통신 인터페이스
- 컴퓨터와 외부 하드웨어 장치 간의 연결을 가능하게 함
- Raspberry Pi 4 및 그 이상의 모델에서 PCIe 레인을 제공
- 기본적으로 USB 포트로 활용되지만 특정 보드에서는 PCIe 슬롯으로 전환 가능
- Raspberry Pi Compute Module 4(CM4)
- 풀 사이즈 라즈베리파이에서 직접 PCIe 슬롯 제공은 없지만 CM4에서 PCIe 지원
- PCIe 2.0 x1 레인 사용 가능(단일 레인, 최대 5Gbps)
- 특징
- 마스터-슬레이브 방식의 양방향 통신
- 핀이 적음
- 속도: 기본속도는 100kHz, 최대 3.4MHz
- 주소: 각 슬레이브 장치는 고유한 주소를 가짐
- 활용
- 온도 센서, RTC(Real Time Clock), LCD 디스플레이 등
- I2C 통신 구조
- 마스터: 클럭을 제공하고 데이터를 요청하거나 전송
- 슬레이브: 요청에 따라 데이터를 제공하거나 수신
- 특징
- 마스터-슬레이브 방식의 동기식 통신
- 빠른 속도: MHz 단위의 빠른 데이터 전송(최대 10MHz 이상)
- 다중 장치 연결: 각각의 슬레이브는 CS(Chip Select)
- 4개의 주요 핀
- MOSI(Master Out Slave In): 마스터에서 슬레이브로 데이터 전송
- MISO(Master In Slave Out): 슬레이브에서 마스터로 데이터 전송
- SCK(Serial Clock): 마스터가 제공하는 클럭 신호
- CS(Chip Select): 슬레이브 장치를 선택
- SPI 활용 예시
- 고해상도 디스플레이, SD 카드, DAC(디지털-아날로그 변환기)
- 특징
- 비동기식 직렬 통신
- 단일 장치 간 통신
- 두 장치 간의 직렬 통신, 마스터-슬레이브 개념 없음
- 핀이 적음
- TX(Transmit): 데이터를 전송하는 핀
- RX(Receive): 데이터를 수신하는 핀
- 속도: SPI > I2C > UART
- 복잡성: SPI가 가장 복잡, I2C는 간단한 주소 체계, UART는 점대점 간 통신
- 핀이 필요: SPI(4개 이상) > I2C(2개) > UART(2개)
- 장치 수: I2C는 여러 슬레이브 가능, SPI는 여러 슬레이브 가능, UART는 1:1 통신
-
I2C, SPI, UART 사용 설정: raspi-config에서 통신 프로토콜을 활성화 가능
sudo raspi-config
- Python 라이브러리: smbus, spidev, pySerial 라이브러리로 통신 구현 가능
- I2C 예제(온도 센서 읽기)
import smbus
bus = smbus.SMBus(1)
temp = bus.read_byte_data(0x48, 0)
print("Temperature: ", temp)
- SPI 예제(ADC 값 읽기)
import spidev
spi = spidev.SpiDev()
spi.open(0, 0)
adc = spi.xfer2([1, (8 + 0) << 4, 0])
print("ADC value: ", adc)
- UART 예제(GPS 모듈 데이터 읽기)
import serial
ser = serial.Serial('/dev/ttyAMA0', 9600, timeout=1)
while True:
gps_data = ser.readline()
print(gps_data.decode('utf-8'))
- 전자 회로와의 상호작용을 위한 범용 핀
- 디지털 신호를 입력받거나 출력할 수 있음
- Physical Pin Numbering: 실제 보드에서의 핀 번호
- BCM Numbering: BCM Numbering: Broadcom SoC에서 정의된 핀 번호
- 3.3V 핀과 5V 핀: 전원 공급
- GND 핀: 접지
- GPIO 핀: 데이터 입력 / 출력 제어
- 입력: 스위치 등 외부 장치로부터 신호 수신
- 출력: LED 같은 장치 제어
- PWM: 서브 모터와 같은 장치의 속도 및 위치 제어
- I2C, SPI, UART: 통신 프로토콜을 사용한 외부 장치와의 데이터 교환
- Python 사용: RPi.GPIO 라이브러리로 핀 제어 가능
- C/C++, Scratch, Node.js 등도 사용 가능
- LED를 켜고 끄는 간단한 Python 코드:
import RPi.GPIO as GPIO
import time
# 핀 설정
GPIO.setmode(GPIO.BCM)
GPIO.setup(18, GPIO.OUT)
# LED 켜기/끄기
GPIO.output(18, GPIO.HIGH) # LED 켜기
time.sleep(1)
GPIO.output(18, GPIO.LOW) # LED 끄기
GPIO.cleanup()
- 코드
from gpiozero import LED
led = LED(12) # LED 핀 OUTPUT 지정: GPIO 12
# 무한반복
while True:
number_input=int(input("Enter 0 or 1: ")) # 코드 실행 시 Enter 0 or 1: 출력
if number_input == 1: # 1 입력 시 LED ON
led.on()
print('P1 on -> led1 on')
if number_input == 0: # 0 입력 시 LED OFF
led.off()
print('P1 off -> led1 off')
- 실습 사진
-
실습 동영상
GPIO.4.mp4
- 코드
from gpiozero import LED
from gpiozero import Button
from time import sleep
led = LED(21) # LED 핀 OUTPUT 지정: GPIO 21
switch = Button(20) # 스위치 핀 INPUT 지정: GPIO 20
pullup = LED(16) # 풀업 핀 OUTPUT 지정: GPIO 16
# 무한반복
while True:
pullup.on() # 풀업 '1' 상태 유지
sleep(0.5) # 0.5초 딜레이
if switch.is_pressed: # 스위치를 누르고 있으면 LED ON
led.on()
print("switch: on")
else: # 스위치에서 손을 떼면 LED OFF
led.off()
print("switch: off")
-
실습 사진
-
실습 동영상
GPIO.5.mp4
- 코드
from gpiozero import LED
from gpiozero import Button
from time import sleep
led = LED(21) # LED 핀 OUTPUT 지정: GPIO 21
switch = Button(20) # 스위치 핀 INPUT 지정: GPIO 20
pulldown = LED(16) # 풀다운 핀 OUTPUT 지정: GPIO 16
# 무한반복
while True:
pulldown.off() # 풀다운 '0' 유지
sleep(0.5) # 0.5초 딜레이
if switch.is_pressed: # 버튼을 누르지 않을 시 LED OFF
led.off()
print("switch: off")
else: # 버튼을 누르고 있을 때 LED ON
led.on()
print("switch: on")
-
실습 사진
-
실습 동영상
GPIO.6.mp4
- 기초전기전자에 대해 다시한번 복습하는 시간을 가졌고 라즈베리파이로 실습을 해보며 파이썬으로 어떻게 적용하는지 제대로 알 수 있는 시간이였습니다. GPIO와 I2C, SPI, UART들에 대해서도 다시 확인할 수 있었고 리눅스 명령어들을 처음 봤었는데 어떻게 사용하는지 알 수 있는 시간이였습니다.