아두이노 DIY 캔디 디스펜서: 스마트 간식 머신 만들기
부품 및 소모품
| 부품 |
수량 |
비고 |
| 아두이노 우노 (Arduino UNO) |
1 |
|
| 서보 모터 (180° 회전) |
1 |
캔디 배출구 개폐용 |
| 16x2 LCD (I2C 백팩 포함, 흰색/파란색) |
1 |
Adafruit 표준형 |
| 푸시버튼 스위치 12mm |
2 |
적당량/많이 선택용 |
| PHPoC 실드 (아두이노용) |
1 |
네트워크 기능 확장용 (선택) |
| IR 장애물 감지 센서 |
1 |
컵 감지용 |
| 전원 스위치 (파워 버튼) |
1 |
배터리 온오프용 |
| 브레드보드 |
1 |
회로 구성용 |
필요한 도구
소프트웨어
프로젝트 소개
프로젝트 개요
IR 센서, 서보 모터, 푸시버튼만으로 만드는 간단한 캔디 디스펜서입니다. 제작 과정은 크게 5단계로 나뉩니다:
- 아두이노 우노 R3 준비 및 회로 구성
- 코딩 및 아두이노 설정
- 케이스 및 기계 부품 제작
- 전자 부품 설치 및 배선
- 테스트 및 사용
코딩이 가장 까다로웠지만, 구글링과 주변 도움으로 여러 시행착오 끝에 완성했습니다. 이 프로젝트는 gatoninja236 님의 구글 어시스턴트 연동 캔디 디스펜서에서 영감 받아 단순화한 버전입니다.
케이스 및 기계 부품 제작
하루 꼬박 걸려 완성한 재미있는 파트입니다. 여러 번 수정하며 맞춤형으로 제작했습니다.
1단계: 부품 배치 및 테스트
골판지 위에 모든 부품을 올려놓고 배선 색상별로 정리해 가며 각 부품 동작 테스트를 진행했습니다.
2단계: 박스 설계 및 재단
기술 도면을 그리고 치수를 정했습니다. 주로 골판지, 일부는 아크릴을 사용했습니다.
- 앞/뒤면: 20cm × 16cm (뒤면은 아크릴)
- 옆면: 12cm × 16cm
- 윗/아랫면: 20cm × 12cm
3단계: 조립 및 컴포넌트 컷아웃
마스킹 테이프로 임시 조립 후, 각 부품 장착용 구멍을 뚫었습니다.
- LCD: 7.2cm × 2.5cm
- 버튼: 1.2cm × 1.2cm
- 컵 홀더: 9cm × 12cm (깊이 9cm)
- IR 센서 구멍
캔디가 한꺼번에 쏟아지지 않게 내부 계단 구조를 만들었습니다.
4-5단계: 전자부품 장착 및 배선
브레드보드와 아두이노를 아크릴로 고정해 공간을 절약했습니다. LCD, 버튼, 서보 모터 순으로 장착하고 배선을 정리했습니다. 후면에는 배터리 전원 스위치도 추가했습니다.
작동 원리
- 시작 화면: "Welcome to Candy Land" 표시
- 메뉴: "How much candy? / A Little / A Lot" 선택 대기
- 버튼 1(시계방향) 누름 → "적당량" 선택 → 컵 놓기 안내
- 버튼 2(반시계방향) 누름 → "많이" 선택 → 컵 놓기 안내
- IR 센서가 컵 감지 → 서보 모터 90°→180° 회전하며 캔디 배출
- 배출 완료 후 "Thank You" 표시 → 초기 화면으로 리셋
소스 코드
//------ 라이브러리 ------
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <Servo.h>
//------ 설정 ------
LiquidCrystal_I2C lcd(0x27, 16, 2); // I2C 주소 0x27, 16x2 LCD
Servo myservo;
int pos = 90; // 서보 초기 위치 (90도)
int buttonCLK = 7; // 시계방향 버튼
int buttonAntiCLK = 6; // 반시계방향 버튼
const int avoidPin = 5; // IR 센서 핀
int set = 0; // 선택 상태 (1=적당량, 2=많이)
void setup() {
lcd.begin();
lcd.clear();
myservo.attach(9); // 서보 D9 핀
pinMode(buttonCLK, INPUT);
pinMode(buttonAntiCLK, INPUT);
pinMode(avoidPin, INPUT);
Serial.begin(9600);
lcd.backlight();
// 시작 애니메이션
lcd.setCursor(3,0); lcd.print("Welcome to");
lcd.setCursor(3,1); lcd.print("Candy Land");
delay(2000);
lcd.clear();
lcd.setCursor(0,0); lcd.print("How much candy?");
lcd.setCursor(0,1); lcd.print("A Little A Lot");
delay(5000);
}
void loop() {
// 버튼 1: 적당량
if(digitalRead(buttonCLK) == HIGH) {
lcd.clear(); lcd.print("Please Place Cup");
delay(2000); lcd.clear();
set = set + 1;
}
// 버튼 2: 많이
if(digitalRead(buttonAntiCLK) == HIGH) {
lcd.clear(); lcd.print("Please Place Cup");
delay(2000); lcd.clear();
set = set + 2;
}
// 선택에 따른 동작
if(set == 1) IRCLK(); // 적당량 + 컵 감지 → 시계방향 회전
if(set == 2) IRAntiCLK(); // 많이 + 컵 감지 → 반시계방향 회전
}
void TurnClockwise() {
Serial.println("Candy 1 Being Dispensed");
CandyText1();
for(pos = 90; pos < 180; pos += 1) {
myservo.write(pos);
delay(15);
}
if(pos == 180) {
delay(2000);
ThankYouText();
}
}
void TurnAntiClockwise() {
Serial.println("Candy 2 Being Dispensed");
CandyText2();
for(pos = 90; pos < 180; pos += 1) {
myservo.write(pos);
delay(20);
}
if(pos == 180) {
delay(3000);
ThankYouText();
}
}
void IRCLK() {
delay(1000);
boolean avoidVal = digitalRead(avoidPin);
lcd.setCursor(0,0); lcd.print("Detecting Cup");
lcd.setCursor(0,14); lcd.print("...");
if(avoidVal == LOW) { // 컵 감지됨 (LOW 활성)
lcd.clear(); lcd.print("Cup Placed");
delay(2000);
TurnClockwise();
}
}
void IRAntiCLK() {
delay(1000);
boolean avoidVal = digitalRead(avoidPin);
lcd.setCursor(0,0); lcd.print("Detecting Cup");
lcd.setCursor(0,14); lcd.print("...");
if(avoidVal == LOW) {
lcd.clear(); lcd.print("Cup Placed");
delay(2000);
TurnAntiClockwise();
}
}
void CandyText1() {
lcd.clear(); lcd.setCursor(4,0); lcd.print("Pouring");
lcd.setCursor(1,1); lcd.print("Little Candy");
}
void CandyText2() {
lcd.clear(); lcd.setCursor(4,0); lcd.print("Pouring");
lcd.setCursor(3,1); lcd.print("Lot Candy");
}
void ThankYouText() {
lcd.clear(); lcd.setCursor(5,0); lcd.print("Thank");
lcd.setCursor(6,1); lcd.print("You");
delay(15);
software_Reset();
}
void software_Reset() {
asm volatile ("jmp 0"); // 소프트 리셋
}
회로도
배선 색상대로 따라하면 어렵지 않습니다. (첨부 이미지 참조)
제작 팁
- 서보 모터 토크가 약하면 캔디가 안 나올 수 있으니 금속 기어 서보 권장
- IR 센서는 컵 바닥을 향하게 설치하고, 감지 거리 조절 나사 조정 필요
- 캔디 크기에 따라 배출구 크기와 서보 회전 각도 조절
- 전원은 9V 배터리 + 배럴 잭 또는 USB 파워뱅크 사용 가능