이 프로젝트는 라즈베리 파이와 C언어를 사용하여 실시간 양방향 통신이 가능한 RC카 제어 시스템을 구현한 결과물입니다. 외부 라이브러리 의존도를 최소화하고, 리눅스 시스템 프로그래밍(Socket, Thread, File I/O)을 활용하여 하드웨어 제어의 원리를 깊이 있게 이해하고자 했습니다.
- Why C & Sysfs?: 파이썬이나 라이브러리를 쓰면 10줄이면 끝날 코드지만,
open/write시스템 콜을 직접 사용해보며 운영체제가 하드웨어 리소스를 어떻게 파일로 추상화하여 관리하는지 체득하고 싶었습니다. Why Multi-thread?: "RC카는 0.1초의 지연도 사고로 이어질 수 있습니다.read()함수에서 블로킹되어 주행 명령을 못 보내는 상황을 막기 위해 쓰레드를 분리하여 **실시간성(Real-time capability)**을 확보했습니다."
- Language: C
- OS: Linux (Raspberry Pi OS)
- Concurrency: POSIX Threads (
pthread) - Network: TCP/IP Socket Programming
- Hardware I/O: Linux Sysfs GPIO Interface (Direct File I/O)
단일 프로세스 흐름의 Blocking I/O 한계를 극복하기 위해 입력(송신)과 출력(수신)을 담당하는 쓰레드를 분리하였습니다.
- Input Thread: GPIO 센서 값을 0.1초 간격으로 폴링(Polling)하여 상태 변화 감지 시 서버/클라이언트로 즉시 데이터 전송.
- Output Thread: 소켓 버퍼를 지속적으로 모니터링하여 상대방의 제어 명령을 실시간으로 수신 및 처리.
- 이를 통해 주행 명령 전송과 동시에 차량의 상태 정보(센서 값 등)를 지연 없이 수신할 수 있습니다.
편의성을 위한 외부 라이브러리(WiringPi, BCM2835 등)를 사용하지 않고, 리눅스 커널의 **Sysfs 인터페이스(/sys/class/gpio)**를 직접 제어했습니다.
open,read,write등 표준 시스템 콜을 사용하여 하드웨어 포트를 파일처럼 다루는 리눅스의 철학을 구현했습니다.
| File | Description |
|---|---|
rcServer.c |
(RC Car Side) 클라이언트의 연결을 수락하고, 수신된 명령에 따라 하드웨어를 제어하거나 센서 값을 송신합니다. |
rcClient.c |
(Controller Side) 서버(RC카)에 접속하여 사용자 입력(버튼/조이스틱)을 전송하고 차량 상태를 수신합니다. |
- Raspberry Pi (x2 or 1 Pi + 1 PC)
- GCC Compiler
# pthread 라이브러리 링크 필요
gcc -o server rcServer.c -lpthread
gcc -o client rcClient.c -lpthreadUsage
- Server (RC Car)
# Usage: ./server <PORT>
sudo ./server 8080- Client (Controller)
# Usage: ./client <SERVER_IP> <PORT>
sudo ./client 192.168.0.10 8080GPIO Configuration
- PIN 20 (Input): 버튼/센서 입력용 (Pull-down/up 회로 구성 필요)
- PIN 21 (Output): LED 또는 모터 드라이버 제어 신호용
Thread Logic Snippet 메인 함수에서 소켓 연결 후, 읽기와 쓰기를 위한 쓰레드를 각각 생성하여 병렬 처리합니다.
// 입/출력 쓰레드 분리 생성
pthread_create(&input_thread, NULL, thread_input_to_socket, (void*)&sock);
pthread_create(&output_thread, NULL, thread_socket_to_output, (void*)&sock);