아두이노 우노 스테퍼 모터로 만드는 틴더/범블 자동 스와이퍼
부품 및 소모품
| 아두이노 우노 (Arduino UNO) | × | 1 |
| BYJ48 스테퍼 모터 | × | 1 |
| 3D 프린팅 파일 | × | 1세트 |
| 터치스크린 스타일러스 펜 | × | 1 |
앱 및 온라인 서비스
프로젝트 소개
배경 이야기
친구들이 틴더 계정을 만들어줬는데, 대부분처럼 저도 곧 단조로움에 실망했습니다. 그러다 문득 '연애보단 엔지니어링이 더 낫지'란 생각에 굴러다니는 저렴한 스테퍼 모터로 이걸 만들었습니다. 이제 여러분도 틴더나 범블에서 시간당 800회 이상 스와이프할 수 있습니다!
빠른 개요
단 3단계: 1) 파트 출력, 2) 스테퍼 모터 배선 및 테스트, 3) 조립.
1단계: 파트 출력
3D 프린팅 파일: https://www.thingiverse.com/thing:2849598
베이스는 50% 인필로 출력해 무게감을 줘 스와이프 시 흔들리지 않게 했습니다.
2단계: 스테퍼 모터
유니폴라 28-BYJ48 스테퍼 모터와 SBT0811 드라이버 사용. BYJ48 호환 드라이버면 상관없으나, 아래 배선대로 연결하거나 코드에서 핀 번호 수정 필요:
- IN1 → D8
- IN2 → D9
- IN3 → D10
- IN4 → D11
- VCC → 5V
- GND → GND
아두이노 코드는 페이지 하단에 있습니다. 업로드하면 시계방향으로 회전하는 스테퍼 모터를 볼 수 있습니다. 반시계방향(오른쪽 스와이프)으로 바꾸려면 Direction 변수를 true로 변경하세요.
3단계: 전체 조립
준비된 파트들을 결합합니다.
- 스테퍼 모터를 스와이퍼 베이스에 장착, 작은 목재 나사 2개로 고정
- 스와이퍼 핸들을 스테퍼 모터 축에 끼움
- 휴대폰 위에 구조물을 올리고 터치스크린 펜을 핸들에 꽂아 화면에 닿을 때까지 높이 조절
- 짧은 M3 나사로 펜 고정(스와이프 중 움직이지 않게)
마지막: 스와이프 시작!
구조물을 폰 옆에 두고, 원하는 데이팅 앱 실행, 아두이노 전원 켜고 가만히 구경하세요!
테스트한 4대 중 1대는 화면 가장자리가 예민해 스와이프가 '뒤로 가기'로 인식되는 문제가 있었습니다. 폰 케이스로 가장자리를 높이면 해결됩니다.
코드
Swiper (아두이노)
Direction = false를 true로 바꾸면 스와이프 방향 변경(오른쪽/왼쪽)!
/* BYJ48 Stepper motor code
Connect: IN1 >> D8, IN2 >> D9, IN3 >> D10, IN4 >> D11, VCC >> 5V, GND >> GND
written By: Mohannad Rawashdeh
https://www.instructables.com/member/Mohannad+Rawashdeh/
28/9/2013 */
#define IN1 8
#define IN2 9
#define IN3 10
#define IN4 11
int Steps = 0;
boolean Direction = false; // change to true for right swipe
unsigned long last_time;
unsigned long currentMillis;
int steps_left = 4095;
long time;
void setup() {
Serial.begin(115200);
pinMode(IN1, OUTPUT);
pinMode(IN2, OUTPUT);
pinMode(IN3, OUTPUT);
pinMode(IN4, OUTPUT);
}
void loop() {
while(steps_left > 0) {
currentMillis = micros();
if(currentMillis - last_time >= 1000) {
stepper(1);
time = time + micros() - last_time;
last_time = micros();
steps_left--;
}
}
steps_left = 4095;
}
void stepper(int xw) {
for (int x = 0; x < xw; x++) {
switch(Steps) {
case 0: digitalWrite(IN1, LOW); digitalWrite(IN2, LOW); digitalWrite(IN3, LOW); digitalWrite(IN4, HIGH); break;
case 1: digitalWrite(IN1, LOW); digitalWrite(IN2, LOW); digitalWrite(IN3, HIGH); digitalWrite(IN4, HIGH); break;
case 2: digitalWrite(IN1, LOW); digitalWrite(IN2, LOW); digitalWrite(IN3, HIGH); digitalWrite(IN4, LOW); break;
case 3: digitalWrite(IN1, LOW); digitalWrite(IN2, HIGH); digitalWrite(IN3, HIGH); digitalWrite(IN4, LOW); break;
case 4: digitalWrite(IN1, LOW); digitalWrite(IN2, HIGH); digitalWrite(IN3, LOW); digitalWrite(IN4, LOW); break;
case 5: digitalWrite(IN1, HIGH); digitalWrite(IN2, HIGH); digitalWrite(IN3, LOW); digitalWrite(IN4, LOW); break;
case 6: digitalWrite(IN1, HIGH); digitalWrite(IN2, LOW); digitalWrite(IN3, LOW); digitalWrite(IN4, LOW); break;
case 7: digitalWrite(IN1, HIGH); digitalWrite(IN2, LOW); digitalWrite(IN3, LOW); digitalWrite(IN4, HIGH); break;
default: digitalWrite(IN1, LOW); digitalWrite(IN2, LOW); digitalWrite(IN3, LOW); digitalWrite(IN4, LOW); break;
}
SetDirection();
}
}
void SetDirection() {
if(Direction == 1) { Steps++; }
if(Direction == 0) { Steps--; }
if(Steps > 7) { Steps = 0; }
if(Steps < 0) { Steps = 7; }
}