윌러드의 첫 비행 (그리고 예기치 않은 분해)
Source: Dev.to
지난 글에서는 라즈베리 Pi 5에서 제 드로이드 프로젝트가 “볼” 수 있고 “생각”할 수 있도록 가르치고 있었습니다. Build Hat을 기다리는 동안 저는 이러한 자동차 키트를 발견했는데, 물리적 움직임을 바로 탐구할 수 있는 즉시 사용 가능한 옵션이었습니다.
이제 Elegoo Smart Robot Car Kit v4.0, 혹은 제 아들이 애정 어린 별명으로 부르는 Willard를 소개합니다.
The Physical Build
조립이 놀라울 정도로 매끄러웠다. Elegoo는 필요한 세 개의 드라이버를 제공하고, 부품 가방은 깔끔하게 라벨이 붙어 있다. 마치 “IKEA 설명서와 전자제품이 만난” 느낌이었다.
하지만 곧 물리적인 “하드웨어 세금”에 부딪혔다. 일부 부품이 너무 작아 제자리에 넣는 것이 도전이었다. 로봇이 움직이기 시작하자, 기본 프로그램의 급격한 움직임 때문에 전체 섀시가 진동했다. 몇 분 안에 볼트와 나사가 로봇에서 날아다니며 계획에 없던 분해가 일어났다! 모든 것을 고정하는 권장 방법이 있는지 확신이 서지 않아, 현재는 Willard의 휠을 분리하고 책상 위에서 논리를 안전하게 디버깅하고 있다.
“숨겨진” 소프트웨어 게이트키퍼
비록 키트이지만 로봇 카를 커스터마이징하는 것이 정확히 “플러그 앤 플레이”는 아닙니다. 두 개의 게이트키퍼는 인쇄된 매뉴얼에 강조되지 않지만 다운로드 가능한 zip 파일에 문서화되어 있습니다.
- 업로드 토글: 확장 햇에 작은 토글 스위치가 있습니다. App 모드로 설정되어 있으면 코드를 업로드할 수 없으며, Upload 로 전환하면 Arduino와 통신할 수 있습니다. 라벨이 작아 놓치기 쉽습니다.
- 누락된 드라이버: 칩 부족으로 인해 다른 시리얼 칩이 설치될 수 있습니다. 튜토리얼 zip 파일에 숨겨진 CH340 드라이버를 설치하기 전까지 내 컴퓨터는 보드를 인식하지 못했습니다.
Pro‑tip: 더 빠른 피드백을 위해 Arduino CLI로 전환했습니다:
arduino-cli compile --fqbn arduino:avr:uno --libraries . smart-robot-car-firmware.ino
흔히 겪는 좌절은 “재시작 루프”입니다. 오류와 함께 충돌하는 PC 앱과 달리 Arduino는 종종 그냥 재시작하기 때문에 실제로는 몇 초마다 재부팅되고 있지만 코드가 무시되는 것처럼 보입니다.
모든 바이트가 중요해요
CLI로 전환했을 때 IDE에서는 나타나지 않았던 “Sketch too big” 오류가 발생했습니다. 원래 펌웨어가 이미 Arduino Uno의 32 KB 한도에 근접해 있었고, Servo 라이브러리를 추가하면서 한도를 초과했습니다.
현재 빌드 크기:
Sketch uses 21166 bytes (65%) of program storage space. Maximum is 32256 bytes.
Global variables use 1208 bytes (58%) of dynamic memory, leaving 840 bytes for local variables. Maximum is 2048 bytes.
크기별로 심볼을 나열하기 위해 작은 Python 스크립트를 작성했습니다:
import subprocess
# Runs avr-nm to sort symbols by size
nm_output = subprocess.check_output(['avr-nm', '-S', '--size-sort', '-C', elf_file])
논블로킹 상태 머신으로 로직을 리팩터링하면서 JsonDocument 크기를 200 바이트에서 128 바이트로 줄였고, sprintf를 Serial.write로 교체함으로써 무거운 문자열 포맷팅 라이브러리의 포함을 방지했습니다.
독립적인 눈
이 키트에 포함된 카메라는 Arduino와 전혀 연결되지 않으며 자체 IP 주소로 동작합니다. 따라서 Arduino “반사” 계층은 카메라가 보는 것을 전혀 알 수 없습니다. 그럼에도 불구하고 모든 센서와 카메라를 하나의 패키지에 넣으면 소비자 수준 로봇에 어떤 것이 들어갈 수 있는지 시각화하기가 쉽습니다.
또한 무게 제한에 대한 현실적인 감각을 얻을 수 있었습니다. Willard가 움직이는 모습을 보면서 모터가 성능 저하 없이 감당할 수 있는 질량의 기준선을 잡을 수 있었습니다. 궁극적인 목표는 반사/인지 격차를 메우는 것으로, Pi가 시각 데이터를 분석하고 고수준 명령을 Arduino “근육”에 전달하도록 하는 것입니다.
Source: …
다음 단계
Willard는 현재 수술대 위에 있습니다. 저는 그의 Guard Duty 동작이 “Ghost States”(유령 상태)를 반환하는 이유를 디버깅하고 있습니다.
시리얼 출력 예시:
Current Distance: 13
Current Distance: 12
Alarm triggered!
Guard Duty State: 3 <-- Ghost State Detected
State 3은 존재하지 않으며, 이는 버퍼 오버플로우의 전형적인 징후—메모리가 넘쳐 실시간으로 상태 변수를 덮어쓰는 현상입니다. 다음 번에는 누수를 찾기 위해 수술을 진행할 예정입니다.
이 차를 직접 만들었거나, 수정한 적이 있거나, 아이디어가 있다면 자유롭게 댓글을 남겨 주세요. 지금까지 저는 “Guard” 모드(근접 변화에 의한 움직임 감지)와 “Dance” 모드(다채로운 조명과 사전 프로그래밍된 동작)를 구현했습니다.
또한 I²C(Qwiic)를 사용해 배선을 깔끔하게 유지하고, Willard가 맞춤 톤과 알림으로 “말할” 수 있게 해줄 Arduino Modulino 부저 모듈을 추가하는 것도 고려 중입니다.