Помогите с сервой

1SANTER1
1SANTER1 аватар
Offline
Зарегистрирован: 07.03.2015

 

Привет народ, помогите со скетчем, сам не бум-бум :( Компоненты: серво мотор 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);
    }
 
 }
jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

используй millis

1SANTER1
1SANTER1 аватар
Offline
Зарегистрирован: 07.03.2015

Я догадываюсь что надо использовать millis, читаю, пытаюсь вникнуть, но пока некак  :(  я с ардуино начал работать меньше 5 дней назад, можно поподробней или пример, если не сложно конечно.

bwn
Offline
Зарегистрирован: 25.08.2014

Подробнее здесь

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

http://arduino.ru/forum/obshchii/vstavka-programmnogo-koda-v-temukommentarii

http://arduino.ru/forum/obshchii/sokhranenie-kartinok-na-forume

Pochemushka
Offline
Зарегистрирован: 12.12.2014
01#include<Servo.h>
02Servo myservo;
03int led = 9;
04int button_array[4] = {2,3,4,5};  //массив пинво кнопок
05int servo_position[4]={0,90,135,180};// какие позиции у нас есть
06int time_pause= 300000; //в пяти минутах 300 сек, соотвтственно 300 000 мс
07unsigned long time_next=0; //флаг времени и меряем прошло пять минут или нет
08int prev_position=1000; //предыдущая позиция  используем как флаг круить не крутить ставим значение от балды но такое которого у вас никогда в жизни не будет
09int current_position=0; //предполагаем что стартовое значение сервы ноль - можно поменять
10  void setup()
11  {
12    pinMode(led, OUTPUT);   
13    for(int i=0;i<4;i++)pinMode(button_array[i], INPUT); //указали тип пинов кнопок
14    myservo.attach(8); //указали где обитает серва
15    myservo.write(current_position); //ставим серву на старовую позицию
16    delay(1000);
17 
18 
19  void loop()
20 {
21    
22   for (int i=0;i<4;i++){ // крутим массив с кнопками и палим какая кнопка нажмется
23       if(digitalRead(button_array[i]) && current_position!=prev_position ){ //если кнопка нажата и  положения разные  то работаем зачем гонять серву если она уже и так стоит согласно "купленного билета"
24            myservo.write(servo_position[i]); //поворачиваем серву согласно индекса сработавшей кнопки
25            prev_position=current_position; ////запоминаем прошлое состоние сервы
26            current_position=servo_position[i]; //запоминаем текущее состоние сервы
27            time_next=millis()+time_pause; //увеличиваем флаг на пять минут
28            digitalWrite(led, HIGH); //поджигаем фонарь
29            delay(1000);     
30                                                                      }
31                          }
32  if(millis() >time_next & prev_position!=current_position){ //если время вышло и позиця прошлая  и текущая различаются то возвращаем серву в прошлую позицю
33           myservo.write(prev_position);
34           prev_position=1000; //запираем таймер 
35           digitalWrite(led, LOW); //тушим лампу
36           delay(1000);
37                                                          }
38 }

Нарыл в cвоей кладовой немного подправил и сделал коменарии,  нужно конечно еще дребезг кнопки побороть - пошукайте на амперке есть там есть пример.

 

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

1SANTER1, 

ваша задача какая ?

5 возможных положений сервы ( 90 - это постоянное состояние ) , 4 кнопки для установки сервы на заданные углы , 4 СД для индикации текущего положения сервы ? так ?

по нажатию любой кнопки серва отрабатывает заданный угол и через 5 мин неактивности кнопок занимает угол 90 ?

после крайнего нажатия кнопок - снова ждём 5 мин и уводим серву на 90 ?

Pochemushka
Offline
Зарегистрирован: 12.12.2014

SU-27-16 пишет:

1SANTER1, 

ваша задача какая ?

5 возможных положений сервы ( 90 - это постоянное состояние ) , 4 кнопки для установки сервы на заданные углы , 4 СД для индикации текущего положения сервы ? так ?

по нажатию любой кнопки серва отрабатывает заданный угол и через 5 мин неактивности кнопок занимает угол 90 ?

после крайнего нажатия кнопок - снова ждём 5 мин и уводим серву на 90 ?

А ну да если всегда вертать на 90гр то я промахнулся.. У меня задача была немного другая, тут попроще..

Ща поправим...

Pochemushka
Offline
Зарегистрирован: 12.12.2014
01#include<Servo.h>
02Servo myservo;
03int led = 9;
04int button_array[4] = {2,3,4,5};  //массив пинво кнопок
05int servo_position[4]={0,90,135,180};// какие позиции у нас есть
06int time_pause= 300000; //в пяти минутах 300 сек, соотвтственно 300 000 мс
07unsigned long time_next=0; //флаг времени и меряем прошло пять минут или нет
08int current_position=0; //предполагаем что старовое значение сервы ноль - можно поменять
09int back_position=90; //куда всегда возвращаемся
10  void setup()
11  {
12    pinMode(led, OUTPUT);   
13    for(int i=0;i<4;i++)pinMode(button_array[i], INPUT); //указали тип пинов кнопок
14    myservo.attach(8); //указали где обитает серва
15    myservo.write(current_position); //ставим серву на старовую позицию
16    delay(1000);
17 
18  void loop()
19 {
20    
21   for (int i=0;i<4;i++){ // крутим массив с кнопками и палим какая кнопка нажмется
22       if(digitalRead(button_array[i]) & current_position!=servo_position[i]){ //если кнопка нажата и мотор не в том положении в котором сработала кнопка 
23            myservo.write(servo_position[i]); //поворачиваем серву согласно индекса сработавшей кнопки
24            current_position=servo_position[i]; //запоминаем текущее состоние сервы
25            time_next=millis()+time_pause; //увеличиваем флаг на пять минут
26            digitalWrite(led, HIGH); //поджигаем фонарь
27                  
28                                                                      }
29                          }
30  if(millis() >time_next & current_position!=back_position){ //если время вышло и не 90гр
31           myservo.write(back_position);  //крутим на 90
32           current_position=back_position;  //ставим текущей 90 тем самым запираем таймер
33           digitalWrite(led, LOW); //тушим лампу
34                                                          }
35 }

Теперь всегда возвращаемся на 90гр

 

 

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

переделанный код ТС ( чёбы меньше вникать )

 

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

не скомпилится :( - 1SANTER1 , сам подправь где надо..... направление мыслей указано :)-

.....и прописано для 5 сек , а не мин :) ( ни умею пириводить меллесекунды ф менуты )   :)

Pochemushka
Offline
Зарегистрирован: 12.12.2014

SU-27-16 пишет:

не скомпилится :( - 1SANTER1 , сам подправь где надо..... направление мыслей указано :)-

.....и прописано для 5 сек , а не мин :) ( ни умею пириводить меллесекунды ф менуты )   :)

 

В последнем условии можно еще добавить oldMillis=millis(); а то поледнее условие будет всегда выполняться, в принципе по фигу, но... 

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

да, не подумал.... незачем лишний раз командовать сервой :) спасибо :)

 

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

1SANTER1, 

переходите к схеме подключения кнопок по схеме "кнопка на землю, кнопка на пин, пин через внутренний подтягивающий резистор к VCC" - схема проще, но код надо поменять ( обратная логика ) 

Pochemushka
Offline
Зарегистрирован: 12.12.2014

Да но нужно будет не забыть в setup() включить эти подтягивающие резисторы на самой плате подав на пин с кнопкой HIGH иначе получим шиш при нажатии, а не 0.

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

воооооот ! ШИШ это вовсе не LOW и не HIGH - ШИШ ближе к Z-состоянию :) ( образно )

перейдёт на другую схему - не поймёт - спросит :) 

....всё не объяснить сразу же, а может оно и не нано ему ? :(

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

Pochemushka пишет:

Да но нужно будет не забыть в setup() включить эти подтягивающие резисторы на самой плате подав на пин с кнопкой HIGH иначе получим шиш при нажатии, а не 0.

при нажатии - 0 получим качественный ! а при отжатой кнопке - на пине будет розовый шум - почти что ШИШ.....

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

замена ШИШу - вовсе не ..й - а лексема русского языка - "ДА..., НЕТ....., НАВЕРНОЕ...."

:)

1SANTER1
1SANTER1 аватар
Offline
Зарегистрирован: 07.03.2015

Всем большое спасибо. Пока немогу проверить, на даче пиво пью :) доберусь до дому отпишусь.

 

 

1SANTER1
1SANTER1 аватар
Offline
Зарегистрирован: 07.03.2015
Проверил, оба кода работают на ура, спасибо большое за помощь!
А с подтягивающими резисторами проблемка, я их включаю и серва сходит сума, получается как будто я нажал все 4 кнопки.
Я так понимаю что нужно где-то задать значение что кнопка нажата при LOW уровне ,а не HIGH как сейчас.
 
01#include<Servo.h>
02#define led 9
03#define button1 2
04#define button2 3
05#define button3 4
06#define button4 5
07Servo myServo;
08unsigned long oldMillis;
09//==========================================================
10void setup()
11{
12  pinMode(led,OUTPUT);         //выход на св.диод
13  pinMode(button1,INPUT);      //кнопка на 0гр
14  pinMode(button2,INPUT);      //кнопка на 45гр
15  pinMode(button3,INPUT);      //кнопка на 135гр
16  pinMode(button4,INPUT);      //кнопка на 180гр
17  digitalWrite(2, HIGH);       //включаем подтягивающий резистор
18  digitalWrite(3, HIGH);       //включаем подтягивающий резистор
19  digitalWrite(4, HIGH);       //включаем подтягивающий резистор
20  digitalWrite(5, HIGH);       //включаем подтягивающий резистор
21   
22  myServo.attach(8);
23  oldMillis=millis();
24
25//==========================================================
26void loop()
27{
28  if (digitalRead(button1))
29  {
30    digitalWrite(led,HIGH);         // включаем св.диод
31    myServo.write(0);               // серву на 0гр
32    oldMillis=millis();             // обнуляем секундомер
33  }
34  if (digitalRead(button2))
35  {
36    digitalWrite(led,HIGH);         // включаем св.диод
37    myServo.write(45);              // серву на 45гр
38    oldMillis=millis();             // обнуляем секундомер
39  }
40  if (digitalRead(button3))
41  {
42    digitalWrite(led,HIGH);         // включаем св.диод
43    myServo.write(135);             // серву на 135гр
44    oldMillis=millis();             // обнуляем секундомер
45  }
46  if (digitalRead(button4))
47  {
48    digitalWrite(led,HIGH);         // включаем св.диод
49    myServo.write(180);             // серву на 180гр
50    oldMillis=millis();             // обнуляем секундомер
51  }
52   
53  if((millis()-oldMillis)>300000)   // это сработает после 5 мин после крайнего обнуления секундомера
54  {
55    myServo.write(90);              // серву на 90гр
56    digitalWrite(led, LOW);         // выключаем св.диод
57    oldMillis=millis();             // обнуляем секундомер
58  }
59}

 

 
SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

if (digitalRead(button1))   >>>>>>>>   if (digitalRead(!button1))      ( ! )

второе - при включенной подтяжке и кнопки к пину и земле

digitalWrite(2, HIGH);   >>>>>>>>>   digitalWrite(button1, HIGH);

потому что - #define button1 2

1SANTER1
1SANTER1 аватар
Offline
Зарегистрирован: 07.03.2015
Не знаю чтоб я без вашей помощи делал, всё заработало.
Только у вас была небольшая ошибка.
Заработало так.
 
 if (!digitalRead(button1)).
trembo
trembo аватар
Offline
Зарегистрирован: 08.04.2011

Знаков восклицательных тут наставьте    if (!digitalRead(button1))  
и кнопки на землю перекиньте.

А хотите я вам сделаю красиво? 

 

1SANTER1
1SANTER1 аватар
Offline
Зарегистрирован: 07.03.2015
Уже наставил, всё работает.
Сделайте красивей если не сложно. Будет с чем сравнить и над чем подумать.
jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

да сделай еще красивее. пока не заметил человек))

trembo
trembo аватар
Offline
Зарегистрирован: 08.04.2011

Уж подумать точно прийдётся..... Главное чтобы толк был, надеюсь не зря копипастил...

 

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

1SANTER1 пишет:

Не знаю чтоб я без вашей помощи делал, всё заработало.
Только у вас была небольшая ошибка.
Заработало так.
 
 if (!digitalRead(button1)).

:) торопился в бассейн.... 

1SANTER1
1SANTER1 аватар
Offline
Зарегистрирован: 07.03.2015
Быват :) Ещё вопросик, а ненадо в конце прописать команду чтоб серва после того как встала в положение 90гр. отключилась от пина управления ?
Ну чтоб зря не тревожить её до следующего нажатия на кнопку. Где-то читал про это непомну где.
SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

trembo пишет:

Уж подумать точно прийдётся..... Главное чтобы толк был, надеюсь не зря копипастил...

#define clear oldMillis=millis()

так тоже можно ? :)

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

1SANTER1 пишет:

Быват :) Ещё вопросик, а ненадо в конце прописать команду чтоб серва после того как встала в положение 90гр. отключилась от пина управления ?
Ну чтоб зря не тревожить её до следующего нажатия на кнопку. Где-то читал про это непомну где.

myServo.detach();

и при каждом нажатии надо будет её снова подключать, лишние действия ( для вашей задачи )

trembo
trembo аватар
Offline
Зарегистрирован: 08.04.2011

SU-27-16 пишет:

#define clear oldMillis=millis()

так тоже можно ? :)

А почему нельзя собственно? Можно. Проверил, "clear" подсветилось как чьё-то ключевое слово. От греха подальше:  

#define  clearTime    oldMillis=millis() работает.

И даже #define  myDelay     millis()-oldMillis

И даже #define  myDelay     millis()-oldMillis>30000

Главное не запутаться самому. Я бы с миллисом так не поступал. Чтобы видно было , он в глаза бросается, но это глобальная переменная и с ней поосторожней надо!!!

А вот пины-кнопки всякие- сам бог велел в события обратить

 

 

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

спасибо :)

trembo
trembo аватар
Offline
Зарегистрирован: 08.04.2011

SU-27-16 пишет:

myServo.detach();
и при каждом нажатии надо будет её снова подключать, лишние действия ( для вашей задачи )

Зато когда стоит- дёргаться не будет!

Кстати, открыл новую фичу при написании вот этого всего на форуме:
Если надо сделать перенос строки и нажать "Энтэр"- вставляется пустая стока.
А если нажать с "Шифтом"- не вставляется. !

1SANTER1
1SANTER1 аватар
Offline
Зарегистрирован: 07.03.2015

trembo пишет:

SU-27-16 пишет:

myServo.detach();
и при каждом нажатии надо будет её снова подключать, лишние действия ( для вашей задачи )

Зато когда стоит- дёргаться не будет!

Кстати, открыл новую фичу при написании вот этого всего на форуме:
Если надо сделать перенос строки и нажать "Энтэр"- вставляется пустая стока.
А если нажать с "Шифтом"- не вставляется. !

Вот меня это и интересует чтоб недёргался и как это прописать ?

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

во всех ифах - сразу аттач
после команды на серву - задержка на время поворота сервы
потом - детач

энтер работает с шифтом !!!! :) Дадим увеличение плотности сообщений !!!!!!!!

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

а после аттач перед выставлением угла не будет случайное положение? если каждый раз так делать

trembo
trembo аватар
Offline
Зарегистрирован: 08.04.2011

Уже проходили. В библиотеке запоминается состояние в момент детача. После аттача оно-же и подаётся.
Даже больше, если после детача серву свернуть с пути истинного силой, то после аттача она поедет в запомненное положение

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

хорошо.  продумали)

1SANTER1
1SANTER1 аватар
Offline
Зарегистрирован: 07.03.2015

Всем огромное спасибо, всё работает как надо! Отдельное спасибо Pochemushka, SU-27-16, trembo. Помогли во многом разобраться! trembo мне очень понравился как вы нарисовали красивый код :) я почти дописал свою новую программку, оказалось не так всё сложно, если включить мозги :) Ещё раз спасибо. Закрываем тему.