Используем Ардуино, чтобы сделать автоматическую систему открывания и закрывания жалюзи с активацией звуком или кнопкой.
Шаг 1. Комплектующие
Этот проект Ардуино жалюзей позволит вам автоматизировать открывание и закрывание шторок, используя только Arduino и шаговый двигатель. Благодаря этому проекту вы сможете сэкономить время на процессе открывания или закрывания жалюзей, а также сможете произвести впечатление на окружающих. Для этого урока нам понадобятся следующие детали:
1x | Ардуино (использовали в уроке Arduino Nano из-за экономии места) |
1x | Звуковой сенсор от Adafruit (по желанию) |
1x | Шаговый двигатель + драйвер (сборка) Дарлингтона |
3x | Кнопки |
1x | Светодиод |
Провода/перемычки | |
1x | Макетная плата |
Дизайн этой системы автоматических жалюзей Ардуино довольно прост и в нём два способа активировать занавески:
- Используя звуковой датчик (микрофон), чтобы управлять им, используя хлопки в ладоши;
- Использование кнопок для открывания/закрывания шторок.
Шаг 2. Как это работает?
Работа этой системы очень проста. Ардуина принимает входные сигналы от звукового датчика (микрофона) или кнопок. Затем он соответственно управляет шаговым двигателем через драйвер Дарлингтона для двигателя. Шаговый двигатель прикреплен к ручке управления шторками и, таким образом, вращает и открывает/закрывает шторы.
Шаг 3. Подключаем и настраиваем шаговый мотор
Сначала всегда должно идти тестирование проекта до его финальной сборки. Начнем с двигателя. Двигатель подключен к 4 проводам драйвера, как показано на рисунках выше. В зависимости от направления вращения необходимо соответствующим образом подключить драйвер.
Первая кнопка справа активирует двигатель для вращения в определенном направлении (вы можете изменить это в коде ниже). Нажмите кнопку 4 раза и она вернется в исходное положение, так как она будет вращаться на 90 градусов во время каждого нажатия. Средняя кнопка блокирует цепь так, чтобы первая кнопка не могла активировать двигатель.
Светодиод включается, когда двигатель заблокирован. Последняя кнопка вернет двигатель в исходное положение независимо от того, где он находится, в момент нажатия.
int pin[8]={2,3,4,5,6,7,8,9}; int steps[][4] = { {HIGH,HIGH,LOW,LOW}, {HIGH,LOW,LOW,HIGH}, {LOW,LOW,HIGH,HIGH}, {LOW,HIGH,HIGH,LOW}, } ; int numofroun=1; //Change accordingly to your needs int current=1; int type=3; int place=0; int lastLockState = LOW; long lastLockTime = 0; int LockState; int Lockreading; bool lock=true; int lastPauseState = LOW; long lastPauseTime = 0; int PauseState; int Pausereading; bool Pauseled=false; bool pause=false; int lastReturnState = LOW; long lastReturnTime = 0; int ReturnState; int Returnreading; void setup() { for (int num=0; num<5; num++) pinMode(pin[num],OUTPUT); for (int num=5; num<8; num++) pinMode(pin[num],INPUT); } void reset(){ for(int num=0;num<4;num++) digitalWrite(pin[num],LOW); } void stepper() { for (int num=0; num<4;num++) { digitalWrite(pin[num],steps[abs(type-current)][num]);} if(type==0) {++place;} if(type==3) {--place;} delay(2); } void button1() { Lockreading = digitalRead(pin[5]); if (Lockreading != lastLockState) { lastLockTime = millis(); } if ((millis() - lastLockTime) > 50) { if (Lockreading != LockState) { LockState = Lockreading; if (LockState == HIGH) { lock=false; if ((place!=1536*numofroun)&&(place!=1024*numofroun)&&(place!=512*numofroun)) {type=abs(type-3);} } } } lastLockState = Lockreading; } void button2() { Pausereading = digitalRead(pin[6]); if (Pausereading != lastPauseState) { lastPauseTime = millis(); } if ((millis() - lastPauseTime) > 50) { if (Pausereading != PauseState) { PauseState = Pausereading; if (PauseState == HIGH) { Pauseled=!Pauseled; pause=!pause; if (Pauseled) {digitalWrite(pin[4],HIGH);} if (!Pauseled) {digitalWrite(pin[4],LOW);} } } } lastPauseState = Pausereading; } void button3() { Returnreading = digitalRead(pin[7]); if (Returnreading != lastReturnState) { lastReturnTime = millis(); } if ((millis() - lastReturnTime) > 50) { if (Returnreading != ReturnState) { ReturnState = Returnreading; if (ReturnState == HIGH) { type=3; while (place>0) { for (int num=0; num<4;num++) { digitalWrite(pin[num],steps[3-current][num]);} --place; if (current==3) {current=0;} else ++current; delay(2); } reset(); } } } lastReturnState = Returnreading; } void loop() { if (lock==true) {button2();button3();} if (!pause) { if (lock==true) {button1();} if (lock==false) {stepper();} if ((place==2048)or(place==0)or(((place==1536*numofroun)or(place==1024*numofroun)or(place==512*numofroun))&&(type==3))) {lock=true;reset();} if (current==3) {current=0;} else ++current; } }
Шаг 4. Настройка схемы жалюзей Ардуино
После тестирования шагового двигателя вы можете использовать приведенную выше схему соединений, чтобы сделать окончательный прототип. После того, как вы закончите вы можете просто сменить вход (кнопку) на звуковой датчик. Код ниже:
int pin[8]={2,3,4,5,6,7,8,9}; int steps[][4] = { {HIGH,HIGH,LOW,LOW}, {HIGH,LOW,LOW,HIGH}, {LOW,LOW,HIGH,HIGH}, {LOW,HIGH,HIGH,LOW}, } ; float numofroun=4.5; //Change accordingly to your needs int current=1; int type=3; int place=0; int claps = 0; long detectionSpanInitial = 0; long detectionSpan = 0; long spancondition; bool spanconditioncheck=false; bool lock=true; int lastPauseState = LOW; long lastPauseTime = 0; int PauseState; int Pausereading; bool Pauseled=false; bool pause=false; int lastReturnState = LOW; long lastReturnTime = 0; int ReturnState; int Returnreading; void setup() { for (int num=0; num<5; num++) pinMode(pin[num],OUTPUT); for (int num=5; num<8; num++) pinMode(pin[num],INPUT); } void reset(){ for(int num=0;num<4;num++) digitalWrite(pin[num],LOW); } void stepper() { for (int num=0; num<4;num++) { digitalWrite(pin[num],steps[abs(type-current)][num]);} if(type==0) {++place;} if(type==3) {--place;} delay(2); } void sound() { int sensorState = digitalRead(pin[5]); if (sensorState == 0){ if (claps == 0){ detectionSpanInitial = detectionSpan = millis(); claps++; } else if (claps > 0 && millis()-detectionSpan >= 50){ detectionSpan = millis(); claps++; } } if (millis()-detectionSpanInitial >= 400) { if (claps == 2) { lock=false; if ((place!=1024*numofroun)&&(place!=512*numofroun)) {type=abs(type-3);} spancondition=millis(); } claps = 0; } } void button1() { Pausereading = digitalRead(pin[6]); if (Pausereading != lastPauseState) { lastPauseTime = millis(); } if ((millis() - lastPauseTime) > 50) { if (Pausereading != PauseState) { PauseState = Pausereading; if (PauseState == HIGH) { Pauseled=!Pauseled; pause=!pause; spancondition=millis(); if (Pauseled) {digitalWrite(pin[4],HIGH);} if (!Pauseled) {digitalWrite(pin[4],LOW);} } } } lastPauseState = Pausereading; } void button2() { Returnreading = digitalRead(pin[7]); if (Returnreading != lastReturnState) { lastReturnTime = millis(); } if ((millis() - lastReturnTime) > 50) { if (Returnreading != ReturnState) { ReturnState = Returnreading; if (ReturnState == HIGH) { type=3; while (place>0) { for (int num=0; num<4;num++) { digitalWrite(pin[num],steps[3-current][num]);} --place; if (current==3) {current=0;} else ++current; delay(2); } reset(); spancondition=millis(); } } } lastReturnState = Returnreading; } void loop() { if (lock==true) {button1();button2();} if (!pause) { if ((lock==true)&&(millis()-spancondition>1000)) {sound();} if (lock==false) {stepper();spanconditioncheck=false; } if ((place==2048*numofroun)or(place==0)or(((place==1024*numofroun)or(place==512*numofroun))&&(type==3))){ lock=true; reset(); if (!spanconditioncheck){ spancondition=millis(); spanconditioncheck=true; } } if (current==3) {current=0;} else ++current; } }
Шаг 5. Финальные действия
Лучше использовать пенопласт, чтобы сделать держатель для двигателя (1, 2) и ручки жалюзи (3). Т.к. в некоторых домах многие предпочитают не сверлить стены позже можно использовать двусторонний скотч, чтобы зафиксировать всё на месте.
У нас есть также кнопка паузы на тот случай если в вашей комнате становится слишком громко, - тогда вы сможете заблокировать ее, чтобы шторы не сошли с ума.
Посмотрите ниже демо-видео финального результата проекта, когда управление производится хлопком:
Шаг 6. Альтернативная версия с использованием кнопок
Если вам не нравится управление звуком, вы можете просто использовать кнопки. В таком случае нужно только две кнопки: активация и возврат в исходное положение (поскольку пауза нам теперь не нужна). Активация такая же, как и раньше, а кнопка сброса вернет занавеску назад в исходное положение. Код для этой версии ниже:
int pin[8]={2,3,4,5,6,7,8}; int steps[][4] = { {HIGH,HIGH,LOW,LOW}, {HIGH,LOW,LOW,HIGH}, {LOW,LOW,HIGH,HIGH}, {LOW,HIGH,HIGH,LOW}, } ; int current=1; int type=3; int place=0; int lastLockState = LOW; long lastLockTime = 0; int LockState; int Lockreading; bool lock=true; int lastReturnState = LOW; long lastReturnTime = 0; int ReturnState; int Returnreading; void setup() { for (int num=0; num<5; num++) pinMode(pin[num],OUTPUT); for (int num=5; num<7; num++) pinMode(pin[num],INPUT); } void reset(){ for(int num=0;num<4;num++) digitalWrite(pin[num],LOW); } void stepper() { for (int num=0; num<4;num++) { digitalWrite(pin[num],steps[abs(type-current)][num]);} if(type==0) {++place;} if(type==3) {--place;} delay(2); } void button1() { Lockreading = digitalRead(pin[5]); if (Lockreading != lastLockState) { lastLockTime = millis(); } if ((millis() - lastLockTime) > 50) { if (Lockreading != LockState) { LockState = Lockreading; if (LockState == HIGH) { lock=false; if ((place!=1024*4)&&(place!=512*4)) {type=abs(type-3);} } } } lastLockState = Lockreading; } void button2() { Returnreading = digitalRead(pin[6]); if (Returnreading != lastReturnState) { lastReturnTime = millis(); } if ((millis() - lastReturnTime) > 50) { if (Returnreading != ReturnState) { ReturnState = Returnreading; if (ReturnState == HIGH) { type=3; digitalWrite(pin[4],HIGH); while (place>0) { for (int num=0; num<4;num++) { digitalWrite(pin[num],steps[3-current][num]);} --place; if (current==3) {current=0;} else ++current; delay(2); } digitalWrite(pin[4],LOW); reset(); } } } lastReturnState = Returnreading; } void loop() { if (lock==true) {button1();button2();} if (lock==false) {stepper();} if ((place==2048*4)or(place==0)or(((place==1024*4)or(place==512*4))and(type==3))){lock=true;reset();} if (current==3) {current=0;} else ++current; }
Демо того как это работает ниже:
На этом всё. Вы можете использовать свою фантазию и улучшить проект.