Две задачи для 1 Ардуино

bloomer
Offline
Зарегистрирован: 21.02.2015

Подскажите новичку, как мне заставить Ардуино делать 2 задачи в цикле, одну быструю, вторую медленную.
1 задача - поворачивать серву с интервалом в 50 секунд.
2 задача - быстро щёлкать фотоаппаратом.

По отдельности всё работает прекрасно, при попытке запихнуть 2 скетча в один портятся обе программы - серва начинает лихорадочно вибрировать, фотоаппарат щёлкает с интервалом в 15 секунд, что меня категорически не устраивает.

Подозреваю, что нужен какой-то разделитель двух задач, оператор или функция какая - вот в этом я совсем профан. "Гибридный" нерабочий скетч выглядит так:

#include <Servo.h>
#include "multiCameraIrControl.h"

Nikon D5000(9);

void setup(){
}

void loop(){
  D5000.shutterNow();
  delay(500);

Servo tilt; //Серва для наклона по вертикали

tilt.attach(10); //Сообщаем, что серва для наклона фотоаппарата подключена к 10 контакту Ардуино

//управление сервой для поворота фотоаппарата

tilt.write(127);

//Поворачиваем серву на 27 градусов. Функция принимает параметр от 0 до 180-ти,

//что соответствует крайним левому и правому положения сервы. Серва обычно имеет ход в 180 градусов.

delay(5000);     

// Пауза 5 сек. - держать фотоаппарат в таком положении 5 секунд для съёмки 2 кольца.

tilt.write(160);

//Поворачиваем серву на 60 градусов от исходного положения или ещё на 63 градуса для съёмки 2 кольца. 

delay(2000);     

// Пауза 2 сек. - держать фотоаппарат в таком положении 20 секунд для съёмки надира. 

tilt.write(90); 

// Возвращаем тягу в центральное положение

delay(5000);        

// Пауза 5 сек. Держать серву в исходном положении 5 секунд для съёмки 1 кольца.

}

 

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

Для начала ликвидировать из кода все delay(). Пока идет выполнение этой команды, ардуин тихо курит на пенечке((((.

http://arduino.ru/tutorials/BlinkWithoutDelay

bloomer
Offline
Зарегистрирован: 21.02.2015

Написал ответ, не понял, куда он улетел, пишу второй раз.

Попробовал я избавиться от delay, ничего у меня не получилось. Пример работает, светодиод моргает, фотоаппарат не реагирует. Но стоит в пример воткнуть строку с delay, Никон начинает щёлкать.

vvadim
Offline
Зарегистрирован: 23.05.2012

вам нужно заменить все делеи как в примере 

Мигаем светодиодом без delay()

и всё будет одновременно поворачиваться и фоткать

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

bloomer, для медленных циклических задач удобно настроить отдельный счётчик. Берём таймер 1, программируем его на прерывание каждую секунду. В прерывании инкременируем счётчик. Когда счёт доходит до нужного времени (когда команды нужно вновь отправлять по кругу) -счётчик обнуляем. А в loop можно вставить стандартные If или swith-case. Таким образом можно задать произвольные действия для любых событий на каждую секунду циклической программы.

volatile unsigned int sec=0; 

void setup(){
TCCR1A=0; TIMSK1=(1<<TOIE1); //разрешить прерываение
ICR1=31250; TCCR1B=20; //настройка запуска прерывания 1 раз в секунду
pinMode (13, OUTPUT); //пин светодиода
}

void loop() {   

  switch(sec){
    case 5: 
     digitalWrite (13,HIGH); //зажечь светодиод
     break;
   
     case 10: 
     digitalWrite (13,LOW); //погасить светодиод
    break;
 }// end swith-case
}//end loop

ISR (TIMER1_OVF_vect) { 
  sec++ ;
  if (sec==11) sec=1;
}

В данном скетче включается светодиод на 5 секунде, а выключается на 10. На 11-й секунде счёт секунд сбрасывается вновь на 1-ю секунду. Можете доработать этот шаблон под свои нужды.  В 24 строке задаётся длина полного цикла в секундах, далее по аналогии с 12 строкой вставлять свои команды , case (число:на какой секунде выполнить команду) , команды, break. В отличии от использования миллис всё очень наглядно, и никакой путаницы нет. Можно хоть на час расписать программу команд :)

bloomer
Offline
Зарегистрирован: 21.02.2015

Я же выше написал, что у меня не получилось избавиться от delay, мозгов моих на это не хватает.

bloomer
Offline
Зарегистрирован: 21.02.2015

Спасибо за совет, приступаю к экспериментам!

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

bloomer, только тут есть особенность - если запуск swith-case будет в Loop, то одни и те-же команды будут срабатывать по многу раз в секунду, если это недопустимо, то эту конструкцию (в данном примере с 11 по 19 строчку) нужно поместить в тело прерывания, т.е. перед скобкой в 25 строчке. Тогда все команды будут срабатывать только по одному разу.

Barny
Offline
Зарегистрирован: 23.01.2015

Попробуйте leOS.

Bishkek
Offline
Зарегистрирован: 11.12.2014