스마트 버스 정류장 건축 모형: 자동 차양막 탑재
구성품 및 부품
| 부품 |
수량 |
비고 |
| Arduino Nano R3 |
1 |
건축 모형용으로 작고 숨기기 쉬운 보드 선택 |
| 서보 MG995 |
1 |
고토크 서보 (차양막 무게 견딤) |
| 포토레지스터 (조도 센서) |
2 |
하나는 동쪽, 하나는 서쪽 방향 |
| 빗물 센서 |
1 |
|
| 고휘도 백색 LED |
6 |
|
| 저항 220Ω |
3 |
|
| 브레드보드 |
1 |
|
| 수-수 점퍼 와이어 |
27 |
|
| 스크류 터미널 |
2 |
|
| 9V 배터리 클립 |
2 |
|
| 9V 배터리 |
1 |
|
| 4xAA 배터리 홀더 |
1 |
MG995 서보용 외부 전원 |
프로젝트 소개
이전 프로젝트(V1.0)의 업그레이드 버전입니다.
V1.0 대비 주요 변경사항
- 모형 크기: 1.5m × 1m로 확대
- 차양막 무게 증가로 SG99 마이크로 서보 → MG995 고토크 서보 교체
- MG995 구동용 외부 전원 추가
- 차양막 전개/수납 메커니즘 2가지 시도 (영상 2: 실패작, 영상 3: 최종 채택)
VarSpeedServo 라이브러리 사용으로 속도 제어
- 차양막 상태 로직 오류 수정 (Gurneet1928 님 제보 감사)
V1.0: Model Version 1.0
코드
The Code (C/C++)
#include <VarSpeedServo.h>
VarSpeedServo servo;
int easternLight = 0;
int westernLight = 0;
int rainSensed = 0;
int sunshadePosition = 0;
int rainThreshold = 512;
int sunshadeExpanded = 120; // 전개 각도
int sunshadeContracted = 60; // 수납 각도
int ambientLighting = 0;
int turnOnLightsOn = 150; // 조명 켜기 임계값
int ledIntensity = 0;
int ledPower = 0;
int servoSpeed = 20;
bool debugging = false; // true로 설정 시 시리얼 디버깅 출력
void setup() {
pinMode(A4, OUTPUT); // 실내 조명
pinMode(A5, OUTPUT); // 가로등
pinMode(A1, INPUT); // 서쪽 조도
pinMode(A2, INPUT); // 동쪽 조도
pinMode(A3, INPUT); // 빗물 센서 아날로그
pinMode(2, INPUT); // 빗물 센서 디지털
servo.attach(A0);
servo.write(sunshadeContracted, servoSpeed, true);
if (debugging) {
Serial.begin(9600);
Serial.println("*** DEBUGGING STARTED ***");
Serial.println("-------------------------");
}
}
void oya_mydebug(String text, int value = NULL) {
if (debugging) {
Serial.print(text);
if (value) { Serial.print(" = "); Serial.println(value); }
else { Serial.println(" "); }
}
}
void expand_collapse(int easternLight, int westernLight) {
if (easternLight <= westernLight) { // 해 뜰 녘 (동쪽이 밝음)
oya_mydebug("It's sunrise");
if (sunshadePosition != sunshadeExpanded) {
servo.write(sunshadeExpanded, servoSpeed, true);
oya_mydebug("Sunshade expanded");
}
}
if (easternLight > westernLight) { // 해 질 녘 (서쪽이 밝음)
oya_mydebug("Sun is going down");
if (sunshadePosition != sunshadeContracted) {
servo.write(sunshadeContracted, servoSpeed, true);
oya_mydebug("Sunshade contracted");
}
}
}
void loop() {
easternLight = analogRead(A2);
westernLight = analogRead(A1);
rainSensed = analogRead(A3);
sunshadePosition = servo.read();
ambientLighting = (easternLight + westernLight) / 2; // 평균 조도
oya_mydebug("easternLight", easternLight);
oya_mydebug("westernLight", westernLight);
oya_mydebug("rainSensed", rainSensed);
oya_mydebug("sunshadePosition", sunshadePosition);
oya_mydebug("ambientLighting", ambientLighting);
// 비 감지 시
if (rainSensed < rainThreshold) {
oya_mydebug("It's raining...");
if (sunshadePosition != sunshadeExpanded) {
servo.write(sunshadeExpanded, servoSpeed, true);
oya_mydebug("Sunshade expanded");
}
} else { // 비 안 올 때
oya_mydebug("It is not raining...");
if (ambientLighting <= turnOnLightsOn) { // 어두워지면 조명 켬
oya_mydebug("It's getting dark, turning on the lights");
ledPower = ((turnOnLightsOn - ambientLighting) * 4);
oya_mydebug("ledPower", ledPower);
analogWrite(A5, ledPower);
analogWrite(A4, ledPower);
expand_collapse(easternLight, westernLight);
} else { // 밝으면 조명 끔
oya_mydebug("A lot of sunshine, turn off lights");
analogWrite(A5, 0);
analogWrite(A4, 0);
expand_collapse(easternLight, westernLight);
}
}
if (debugging) {
Serial.println("********************");
Serial.println(" ");
delay(5000);
} else {
delay(100);
}
}
회로도
(회로도 이미지 참조)