이것은 주소 지정 가능한 RGB LED를 사용하여 차량 운전자가 접근하고 최종 주차(정지) 위치에 도달할 때 피드백을 제공하는 차고 주차 센서입니다. 동작 영상 참조.
아크릴 1/2인치 지름 반원형 재료(길이 20-7/16인치로 절단)를 렌즈로 사용했는데, 이는 도브테일 섹션을 결합해 주는 역할도 합니다. 인터넷에서 피트당 약 $0.66에 구매 가능하며, 투명 필라멘트로 출력 가능한 렌즈 모델도 포함되어 있습니다.
제작 단계
STEP 1: LED 스트립 준비
WS2812B 개별 주소 지정 RGB 스마트 픽셀 30개, 1미터 스트립을 두 개의 15개 세그먼트로 자르고, 각 세그먼트 시작 부분에 리드선 납땜. 스트립의 화살표 방향이 리드가 필요한 방향에서 '멀리' 향하도록 주의.
STEP 2: 레일 섹션 조립
아웃사이드 레일 1개, 인사이드 레일 세그먼트 2개(양쪽 각각), 중앙 케이스로 조립.
STEP 3: LED 스트립 리드선 연결 및 부착
양쪽 케이스로 리드선 통과시켜 부착 테이프로 고정. LED 스트립은 각 아웃사이드 레일 끝에서 약 1/2인치 앞에서 멈춤.
STEP 4: 렌즈 장착
렌즈를 양쪽 끝까지 밀어 넣어 모든 도브테일을 고정. 출력된 렌즈 사용 시 양쪽에 4개씩 필요하며, 도브테일 영역을 연결하도록 설계됨.
STEP 5: 백커 보드에 장착
엔드 캡이 있는 어셈블리를 백커 보드(1/2인치 MDF, 2인치 폭 x 45-1/8인치 길이)에 장착. 작은 팬헤드 또는 플랫헤드 나사 사용(라운드 헤드 사용 시 USB 케이블이 나중에 재프로그래밍용 슬롯에 들어가지 않을 수 있음).
STEP 6: 전자 회로 배선
커패시터 위치 주의. 전원 공급에서 전압 스파이크 방지용. 신호선(핀 7)에는 저항, Arduino(V+)에는 다이오드를 직렬 연결해 열수축 튜브로 절연. 전원 공급 없이 USB 연결 시 Arduino가 LED에 전압 공급하려 들어 온보드 전압 레귤레이터에 과전류 흐르는 것 방지. 케이스 외부 아래쪽 근처에 구멍 뚫어 전원선 통과. 18/2 전선 권장(도어벨 와이어 사용, 케이스 바로 밖에 커넥터 설치).
STEP 7: Arduino 고정 및 배선 완료
2.5mm 나사로 Arduino 고정. 홀드다운 끝이 케이스의 사각 구멍으로 돌출. Arduino 최외곽 미사용 핀 제거해 설치 용이하게 함.
STEP 8: 초음파 센서(HC-SR04) 장착
2.5mm 나사로 커버에 홀드다운으로 고정. 센서 배선 납땜 완료. 주의: 와이어가 센서 중앙 쪽을 향하도록 해 측면 조립 시 간섭 방지.
STEP 9: 커버 장착
3mm 나사로 커버를 케이스에 고정.
STEP 10: Arduino 프로그래밍
아래 코드 사용. 컴파일 전 IDE 라이브러리에 'FastLED'와 'QuickStats' 추가 필요. 매개변수 조정: 'startdistance'(차량 접근 최초 감지 거리), 'stopdistance'(최종 주차 위치). 센서 범위 3cm~400cm이므로 이 범위 내 설정.
STEP 11: 전원 연결
차고 문 개폐기 램프 소켓에 아울렛 내장 어댑터 설치. 5VDC 파워 서플라이 연결해 라이트 바 유닛으로 배선. 문이 열려 있는 동안만 라이트 바 작동(문 조명 타임아웃까지), 상시 켜짐 방지.
코드
/* Garage Parking Sensor - Published By Bob Torrence */
#include <FastLED.h>
#include <QuickStats.h>
QuickStats stats;
#define LED_PIN 7
#define NUM_LEDS 15
const int trigPin = 9;
const int echoPin = 10;
CRGB leds[NUM_LEDS];
float duration;
float durationarray[15];
int distance;
int stopdistance = 115; // 주차 위치 (cm)
int startdistance = 400; // 스캔 시작 거리 (cm)
int increment = ((startdistance - stopdistance) / 15);
void setup() {
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
FastLED.addLeds<WS2812, LED_PIN, GRB>(leds, NUM_LEDS);
Serial.begin(9600);
}
void loop() {
// 15회 측정 후 중앙값 사용으로 노이즈 제거
for (int i = 0; i <= 14; i++) {
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
durationarray[i] = pulseIn(echoPin, HIGH);
distance = durationarray[i] * 0.034 / 2;
Serial.print(distance);
Serial.print(" ");
}
duration = stats.median(durationarray, 15);
distance = duration * 0.034 / 2;
Serial.print("Distance: ");
Serial.println(distance);
// 거리에 따른 LED 색상/개수 표시
if (distance < stopdistance) {
// 정지 위치 도달: 전체 빨강
for (int i = 0; i <= 14; i++) leds[i] = CRGB(255, 0, 0);
FastLED.show();
}
else if (distance < stopdistance + increment) {
// 1단계: 노랑 1개
for (int i = 1; i <= 14; i++) leds[i] = CRGB(0, 0, 0);
leds[0] = CRGB(255, 255, 0);
FastLED.show(); delay(50);
}
else if (distance < stopdistance + increment * 2) {
// 2단계: 노랑 2개
for (int i = 2; i <= 14; i++) leds[i] = CRGB(0, 0, 0);
for (int i = 0; i <= 1; i++) leds[i] = CRGB(255, 255, 0);
FastLED.show(); delay(50);
}
// ... (increment * 3 ~ * 13까지 유사하게 노랑/초록 단계별 증가)
else if (distance < stopdistance + increment * 3) { /* 노랑 3개 */ }
else if (distance < stopdistance + increment * 4) { /* 초록 4개 */ }
else if (distance < stopdistance + increment * 5) { /* 초록 5개 */ }
else if (distance < stopdistance + increment * 6) { /* 초록 6개 */ }
else if (distance < stopdistance + increment * 7) { /* 초록 7개 */ }
else if (distance < stopdistance + increment * 8) { /* 초록 8개 */ }
else if (distance < stopdistance + increment * 9) { /* 초록 9개 */ }
else if (distance < stopdistance + increment * 10) { /* 초록 10개 */ }
else if (distance < stopdistance + increment * 11) { /* 초록 11개 */ }
else if (distance < stopdistance + increment * 12) { /* 초록 12개 */ }
else if (distance < stopdistance + increment * 13) { /* 초록 13개 */ }
else if (distance < stopdistance + increment * 14) { /* 초록 14개 */ }
else {
// 시작 거리 이상: 전체 초록
for (int i = 0; i <= 14; i++) leds[i] = CRGB(0, 255, 0);
FastLED.show(); delay(50);
}
}