Помогите с сервой
- Войдите на сайт для отправки комментариев
Сб, 07/03/2015 - 14:40
Привет народ, помогите со скетчем, сам не бум-бум :( Компоненты: серво мотор 180", 4кнопки, светодиод. 4 кнопки для поворота сервы на 0",45"135",180" градусов. Светодиод включается и горит пока серво находиться в одном из перечисленных положений. Что нужно: (серво на 90:) нажимаю кнопку, серво поворачивается на 0",при этом загорается св.диод и горит. Через 5 минут возвращается в положение 90" и св.диод гаснет . Или так, нажимаю кнопку, серво поворачивается на 0" (5 минут не прошло) нажимаю другую кнопку, серво поворачивается на 180", при этом св.диод горит, через 5 минут возвращается на 90" и св.диод гаснет. Проблема в том, что я незнаю как вернуть его через 5 минут после последнего действия на 90" :( Помогите плиз. Скетч который я нарисовал неподходит.
#include<Servo.h>
Servo myservo;
int led = 9;
int button_1 = 2;
int button_2 = 3;
int button_3 = 4;
int button_4 = 5;
int time = 50000;
int val=0;
void setup()
{
pinMode(led, OUTPUT);
pinMode(button_1, INPUT);
pinMode(button_2, INPUT);
pinMode(button_3, INPUT);
pinMode(button_4, INPUT);
myservo.attach(8);
}
void loop()
{
val = digitalRead(button_1);
if (val == HIGH)
{
digitalWrite(led, HIGH);
myservo.write(0);
delay(time);
myservo.write(90);
digitalWrite(led, LOW);
}
val = digitalRead(button_2);
if (val == HIGH)
{
digitalWrite(led, HIGH);
myservo.write(45);
delay(time);
myservo.write(90);
digitalWrite(led, LOW);
}
val = digitalRead(button_3);
if (val == HIGH)
{
digitalWrite(led, HIGH);
myservo.write(135);
delay(time);
myservo.write(90);
digitalWrite(led, LOW);
}
val = digitalRead(button_4);
if (val == HIGH)
{
digitalWrite(led, HIGH);
myservo.write(180);
delay(time);
myservo.write(90);
digitalWrite(led, LOW);
}
}
используй millis
Я догадываюсь что надо использовать millis, читаю, пытаюсь вникнуть, но пока некак :( я с ардуино начал работать меньше 5 дней назад, можно поподробней или пример, если не сложно конечно.
Подробнее здесь
#include <Servo.h> #define ServoPin_1 9 #define ServoPin_2 10 boolean statusServo_1=0; boolean statusServo_2=0; byte angle_1_0=0; byte angle_1_1=45; byte angle_2_0=0; byte angle_2_1=90; unsigned long oldMillis_1; unsigned long oldMillis_2; Servo myServo1; Servo myServo2; //===================================================== void setup() { myServo1.attach(ServoPin_1); myServo1.write(angle_1_0); myServo2.attach(ServoPin_2); myServo2.write(angle_2_0); delay(500); // чтобы сервы успокоились oldMillis_1=millis(); oldMillis_2=oldMillis_1; } //===================================================== void loop() { if((millis()-oldMillis_1)>2345) // будет выполняться каждые 2,345 секунды { statusServo_1=!statusServo_1; if(statusServo_1) myServo1.write(angle_1_1); else myServo1.write(angle_1_0); oldMillis_1=millis(); // перезапуск первого секундомера ( миллисекундмера ) } if((millis()-oldMillis_2)>5678) // будет выполняться каждые 5,678 секунды { statusServo_2=!statusServo_2; if(statusServo_2) myServo2.write(angle_2_1); else myServo2.write(angle_2_0); oldMillis_2=millis(); // перезапуск второго секундомера ( миллисекундмера ) } } //===================================================== // кодили дети - им захотелось ТАК объяснить :)http://arduino.ru/forum/obshchii/vstavka-programmnogo-koda-v-temukommentarii
http://arduino.ru/forum/obshchii/sokhranenie-kartinok-na-forume
#include<Servo.h> Servo myservo; int led = 9; int button_array[4] = {2,3,4,5}; //массив пинво кнопок int servo_position[4]={0,90,135,180};// какие позиции у нас есть int time_pause= 300000; //в пяти минутах 300 сек, соотвтственно 300 000 мс unsigned long time_next=0; //флаг времени и меряем прошло пять минут или нет int prev_position=1000; //предыдущая позиция используем как флаг круить не крутить ставим значение от балды но такое которого у вас никогда в жизни не будет int current_position=0; //предполагаем что стартовое значение сервы ноль - можно поменять void setup() { pinMode(led, OUTPUT); for(int i=0;i<4;i++)pinMode(button_array[i], INPUT); //указали тип пинов кнопок myservo.attach(8); //указали где обитает серва myservo.write(current_position); //ставим серву на старовую позицию delay(1000); } void loop() { for (int i=0;i<4;i++){ // крутим массив с кнопками и палим какая кнопка нажмется if(digitalRead(button_array[i]) && current_position!=prev_position ){ //если кнопка нажата и положения разные то работаем зачем гонять серву если она уже и так стоит согласно "купленного билета" myservo.write(servo_position[i]); //поворачиваем серву согласно индекса сработавшей кнопки prev_position=current_position; ////запоминаем прошлое состоние сервы current_position=servo_position[i]; //запоминаем текущее состоние сервы time_next=millis()+time_pause; //увеличиваем флаг на пять минут digitalWrite(led, HIGH); //поджигаем фонарь delay(1000); } } if(millis() >time_next & prev_position!=current_position){ //если время вышло и позиця прошлая и текущая различаются то возвращаем серву в прошлую позицю myservo.write(prev_position); prev_position=1000; //запираем таймер digitalWrite(led, LOW); //тушим лампу delay(1000); } }Нарыл в cвоей кладовой немного подправил и сделал коменарии, нужно конечно еще дребезг кнопки побороть - пошукайте на амперке есть там есть пример.
1SANTER1,
ваша задача какая ?
5 возможных положений сервы ( 90 - это постоянное состояние ) , 4 кнопки для установки сервы на заданные углы , 4 СД для индикации текущего положения сервы ? так ?
по нажатию любой кнопки серва отрабатывает заданный угол и через 5 мин неактивности кнопок занимает угол 90 ?
после крайнего нажатия кнопок - снова ждём 5 мин и уводим серву на 90 ?
1SANTER1,
ваша задача какая ?
5 возможных положений сервы ( 90 - это постоянное состояние ) , 4 кнопки для установки сервы на заданные углы , 4 СД для индикации текущего положения сервы ? так ?
по нажатию любой кнопки серва отрабатывает заданный угол и через 5 мин неактивности кнопок занимает угол 90 ?
после крайнего нажатия кнопок - снова ждём 5 мин и уводим серву на 90 ?
А ну да если всегда вертать на 90гр то я промахнулся.. У меня задача была немного другая, тут попроще..
Ща поправим...
#include<Servo.h> Servo myservo; int led = 9; int button_array[4] = {2,3,4,5}; //массив пинво кнопок int servo_position[4]={0,90,135,180};// какие позиции у нас есть int time_pause= 300000; //в пяти минутах 300 сек, соотвтственно 300 000 мс unsigned long time_next=0; //флаг времени и меряем прошло пять минут или нет int current_position=0; //предполагаем что старовое значение сервы ноль - можно поменять int back_position=90; //куда всегда возвращаемся void setup() { pinMode(led, OUTPUT); for(int i=0;i<4;i++)pinMode(button_array[i], INPUT); //указали тип пинов кнопок myservo.attach(8); //указали где обитает серва myservo.write(current_position); //ставим серву на старовую позицию delay(1000); } void loop() { for (int i=0;i<4;i++){ // крутим массив с кнопками и палим какая кнопка нажмется if(digitalRead(button_array[i]) & current_position!=servo_position[i]){ //если кнопка нажата и мотор не в том положении в котором сработала кнопка myservo.write(servo_position[i]); //поворачиваем серву согласно индекса сработавшей кнопки current_position=servo_position[i]; //запоминаем текущее состоние сервы time_next=millis()+time_pause; //увеличиваем флаг на пять минут digitalWrite(led, HIGH); //поджигаем фонарь } } if(millis() >time_next & current_position!=back_position){ //если время вышло и не 90гр myservo.write(back_position); //крутим на 90 current_position=back_position; //ставим текущей 90 тем самым запираем таймер digitalWrite(led, LOW); //тушим лампу } }Теперь всегда возвращаемся на 90гр
переделанный код ТС ( чёбы меньше вникать )
#include<Servo.h> #define led 9 #define button1 2 #define button2 3 #define button3 4 #define button4 5 Servo myServo; unsigned long oldMillis; //========================================================== void setup() { pinMode(led,OUTPUT); pinMode(button1,INPUT); pinMode(button2,INPUT); pinMode(button3,INPUT); pinMode(button4,INPUT); // myServo.attach(8); oldMillis=millis(); } //========================================================== void loop() { if (digitalRead(button1)) { digitalWrite(led,HIGH); myservo.write(0); oldMillis=millis(); // обнуляем секундомер } if (digitalRead(button2)) { digitalWrite(led,HIGH); myservo.write(45); oldMillis=millis(); // обнуляем секундомер } if (digitalRead(button3)) { digitalWrite(led,HIGH); myservo.write(135); oldMillis=millis(); // обнуляем секундомер } if (digitalRead(button4)) { digitalWrite(led,HIGH); myservo.write(180); oldMillis=millis(); // обнуляем секундомер } if((millis()-oldMillis)>5000) // это сработает после 5 мин после крайнего обнуления секундомера { myservo.write(90); digitalWrite(led, LOW); } } //==========================================================не скомпилится :( - 1SANTER1 , сам подправь где надо..... направление мыслей указано :)-
.....и прописано для 5 сек , а не мин :) ( ни умею пириводить меллесекунды ф менуты ) :)
не скомпилится :( - 1SANTER1 , сам подправь где надо..... направление мыслей указано :)-
.....и прописано для 5 сек , а не мин :) ( ни умею пириводить меллесекунды ф менуты ) :)
В последнем условии можно еще добавить oldMillis=millis(); а то поледнее условие будет всегда выполняться, в принципе по фигу, но...
да, не подумал.... незачем лишний раз командовать сервой :) спасибо :)
#include<Servo.h> #define led 9 #define button1 2 #define button2 3 #define button3 4 #define button4 5 Servo myServo; unsigned long oldMillis; //========================================================== void setup() { pinMode(led,OUTPUT); pinMode(button1,INPUT); pinMode(button2,INPUT); pinMode(button3,INPUT); pinMode(button4,INPUT); myServo.attach(8); oldMillis=millis(); } //========================================================== void loop() { if (digitalRead(button1)) { digitalWrite(led,HIGH); myServo.write(0); oldMillis=millis(); // обнуляем секундомер } if (digitalRead(button2)) { digitalWrite(led,HIGH); myServo.write(45); oldMillis=millis(); // обнуляем секундомер } if (digitalRead(button3)) { digitalWrite(led,HIGH); myServo.write(135); oldMillis=millis(); // обнуляем секундомер } if (digitalRead(button4)) { digitalWrite(led,HIGH); myServo.write(180); oldMillis=millis(); // обнуляем секундомер } if((millis()-oldMillis)>300000) // это сработает после 5 мин после крайнего обнуления секундомера { myServo.write(90); digitalWrite(led, LOW); oldMillis=millis(); // обнуляем секундомер } } //==========================================================1SANTER1,
переходите к схеме подключения кнопок по схеме "кнопка на землю, кнопка на пин, пин через внутренний подтягивающий резистор к VCC" - схема проще, но код надо поменять ( обратная логика )
Да но нужно будет не забыть в setup() включить эти подтягивающие резисторы на самой плате подав на пин с кнопкой HIGH иначе получим шиш при нажатии, а не 0.
воооооот ! ШИШ это вовсе не LOW и не HIGH - ШИШ ближе к Z-состоянию :) ( образно )
перейдёт на другую схему - не поймёт - спросит :)
....всё не объяснить сразу же, а может оно и не нано ему ? :(
Да но нужно будет не забыть в setup() включить эти подтягивающие резисторы на самой плате подав на пин с кнопкой HIGH иначе получим шиш при нажатии, а не 0.
при нажатии - 0 получим качественный ! а при отжатой кнопке - на пине будет розовый шум - почти что ШИШ.....
замена ШИШу - вовсе не ..й - а лексема русского языка - "ДА..., НЕТ....., НАВЕРНОЕ...."
:)
Всем большое спасибо. Пока немогу проверить, на даче пиво пью :) доберусь до дому отпишусь.
#include<Servo.h> #define led 9 #define button1 2 #define button2 3 #define button3 4 #define button4 5 Servo myServo; unsigned long oldMillis; //========================================================== void setup() { pinMode(led,OUTPUT); //выход на св.диод pinMode(button1,INPUT); //кнопка на 0гр pinMode(button2,INPUT); //кнопка на 45гр pinMode(button3,INPUT); //кнопка на 135гр pinMode(button4,INPUT); //кнопка на 180гр digitalWrite(2, HIGH); //включаем подтягивающий резистор digitalWrite(3, HIGH); //включаем подтягивающий резистор digitalWrite(4, HIGH); //включаем подтягивающий резистор digitalWrite(5, HIGH); //включаем подтягивающий резистор myServo.attach(8); oldMillis=millis(); } //========================================================== void loop() { if (digitalRead(button1)) { digitalWrite(led,HIGH); // включаем св.диод myServo.write(0); // серву на 0гр oldMillis=millis(); // обнуляем секундомер } if (digitalRead(button2)) { digitalWrite(led,HIGH); // включаем св.диод myServo.write(45); // серву на 45гр oldMillis=millis(); // обнуляем секундомер } if (digitalRead(button3)) { digitalWrite(led,HIGH); // включаем св.диод myServo.write(135); // серву на 135гр oldMillis=millis(); // обнуляем секундомер } if (digitalRead(button4)) { digitalWrite(led,HIGH); // включаем св.диод myServo.write(180); // серву на 180гр oldMillis=millis(); // обнуляем секундомер } if((millis()-oldMillis)>300000) // это сработает после 5 мин после крайнего обнуления секундомера { myServo.write(90); // серву на 90гр digitalWrite(led, LOW); // выключаем св.диод oldMillis=millis(); // обнуляем секундомер } }if(digitalRead(button1)) >>>>>>>>if(digitalRead(!button1)) ( ! )второе - при включенной подтяжке и кнопки к пину и земле
digitalWrite(2, HIGH); >>>>>>>>> digitalWrite(button1, HIGH);
потому что - #define button1 2
Знаков восклицательных тут наставьте
if(!digitalRead(button1))и кнопки на землю перекиньте.
А хотите я вам сделаю красиво?
#include<Servo.h> // buttons pin connecting #define led 9 #define btn0pin 2 #define btn45pin 3 #define btn135pin 4 #define btn180pin 5 // destination angle reading from buttons #define dest0 !digitalRead(btn0pin) #define dest45 !digitalRead(btn45pin) #define dest135 !digitalRead(btn135pin) #define dest180 !digitalRead(btn180pin) // led control #define ledON digitalWrite(led,HIGH) #define ledOFF digitalWrite(led, LOW) // servo positions " presets" #define pos0 myServo.write(0) #define pos45 myServo.write(45) #define pos90 myServo.write(90) #define pos135 myServo.write(135) #define pos180 myServo.write(180) Servo myServo; unsigned long oldMillis; //========================================================== void setup() { pinMode( led , OUTPUT); //выход на св.диод pinMode( btn0pin , INPUT_PULLUP ); //кнопка на 0гр включаем подтягивающий резистор pinMode( btn45pin , INPUT_PULLUP ); //кнопка на 45гр включаем подтягивающий резистор pinMode( btn135pin , INPUT_PULLUP ); //кнопка на 135гр включаем подтягивающий резистор pinMode( btn180pin , INPUT_PULLUP ); //кнопка на 180гр включаем подтягивающий резистор myServo.attach(8); oldMillis=millis(); } //========================================================== void loop(){ if (dest0){ ledON; pos0; oldMillis=millis(); // обнуляем секундомер } if (dest45){ ledON; pos45; oldMillis=millis(); // обнуляем секундомер } if (dest135){ ledON; pos135; oldMillis=millis(); // обнуляем секундомер } if (dest180){ ledON; pos180; oldMillis=millis(); // обнуляем секундомер } if((millis()-oldMillis)>300000){ // это сработает после 5 мин после крайнего обнуления секундомера ledOFF; pos90; oldMillis=millis(); // обнуляем секундомер } }да сделай еще красивее. пока не заметил человек))
Уж подумать точно прийдётся..... Главное чтобы толк был, надеюсь не зря копипастил...
:) торопился в бассейн....
Уж подумать точно прийдётся..... Главное чтобы толк был, надеюсь не зря копипастил...
#define clear oldMillis=millis()
так тоже можно ? :)
myServo.detach();
и при каждом нажатии надо будет её снова подключать, лишние действия ( для вашей задачи )
#define clear oldMillis=millis()
так тоже можно ? :)
А почему нельзя собственно? Можно. Проверил, "clear" подсветилось как чьё-то ключевое слово. От греха подальше:
#define clearTime oldMillis=millis() работает.
И даже #define myDelay millis()-oldMillis
И даже #define myDelay millis()-oldMillis>30000
Главное не запутаться самому. Я бы с миллисом так не поступал. Чтобы видно было , он в глаза бросается, но это глобальная переменная и с ней поосторожней надо!!!
А вот пины-кнопки всякие- сам бог велел в события обратить
спасибо :)
myServo.detach();
и при каждом нажатии надо будет её снова подключать, лишние действия ( для вашей задачи )
Зато когда стоит- дёргаться не будет!
Кстати, открыл новую фичу при написании вот этого всего на форуме:
Если надо сделать перенос строки и нажать "Энтэр"- вставляется пустая стока.
А если нажать с "Шифтом"- не вставляется. !
myServo.detach();
и при каждом нажатии надо будет её снова подключать, лишние действия ( для вашей задачи )
Зато когда стоит- дёргаться не будет!
Кстати, открыл новую фичу при написании вот этого всего на форуме:
Если надо сделать перенос строки и нажать "Энтэр"- вставляется пустая стока.
А если нажать с "Шифтом"- не вставляется. !
Вот меня это и интересует чтоб недёргался и как это прописать ?
во всех ифах - сразу аттач
после команды на серву - задержка на время поворота сервы
потом - детач
энтер работает с шифтом !!!! :) Дадим увеличение плотности сообщений !!!!!!!!
а после аттач перед выставлением угла не будет случайное положение? если каждый раз так делать
Уже проходили. В библиотеке запоминается состояние в момент детача. После аттача оно-же и подаётся.
Даже больше, если после детача серву свернуть с пути истинного силой, то после аттача она поедет в запомненное положение
хорошо. продумали)
Всем огромное спасибо, всё работает как надо! Отдельное спасибо Pochemushka, SU-27-16, trembo. Помогли во многом разобраться! trembo мне очень понравился как вы нарисовали красивый код :) я почти дописал свою новую программку, оказалось не так всё сложно, если включить мозги :) Ещё раз спасибо. Закрываем тему.