Полицейская мигалка

guardauto
Offline
Зарегистрирован: 23.04.2015

Добрый день.

На просторах интернета нашел код для полицейской мигалки

  digitalWrite(ledPin, HIGH); // Зажигаем светодиод 1
  delay(40);                  // Держим его гореть 40 мс.
  digitalWrite(ledPin, LOW);  // Гасим светодиод 1
  delay(40);                  // Держим его погасшим 40 мс.
  //==========Повторяем цикл====================
  digitalWrite(ledPin, HIGH); // Зажигаем светодиод 1
  delay(40);                  // Держим его гореть 40 мс.
  digitalWrite(ledPin, LOW);  // Гасим светодиод 1
  delay(40);                  // Держим его погасшим 40 мс.
  //==========Повторяем цикл====================
  digitalWrite(ledPin, HIGH); // Зажигаем светодиод 1
  delay(40);                  // Держим его гореть 40 мс.
  digitalWrite(ledPin, LOW);  // Гасим светодиод 1
  delay(500);                 // Держим его погасшим пол секунды.
  //==========Переходим к светодиоду 2====================
  digitalWrite(ledPina, HIGH); //Зажигаем светодиод 2
  delay(40);                   // Держим его гореть 40 мс.
  digitalWrite(ledPina, LOW);  // Гасим светодиод 2
  delay(40);                   // Держим его погасшим 40 мс.
  digitalWrite(ledPina, HIGH); //Зажигаем светодиод 2
  delay(40);                   // Держим его гореть 40 мс.
  digitalWrite(ledPina, LOW);  // Гасим светодиод 2
  delay(40);                   // Держим его погасшим 40 мс.
  digitalWrite(ledPina, HIGH); //Зажигаем светодиод 2
  delay(40);                   // Держим его гореть 40 мс.
  digitalWrite(ledPina, LOW);  // Гасим светодиод 2
  delay(500);    // Держим его гореть пол секунды.
  }
 
Работа мигалкис такими интервалами вполне устраивает. поскольку хочу вставить в код управления сервомашинкой с блютузом delay() вешает программу и команды с блютуза не проходят.
Если использовать milllis(), то блютуз отрабатывает как положено, но эффекта мигалки получитьне могу.
 
Помогите переработать код с использованием millis().
maksim
Offline
Зарегистрирован: 12.02.2012
images?q=tbn:ANd9GcSwz5LjU51sefhN9-52IZj
22 апр 2011 ... Мы уже рассматривали пример того, как можно мигать светодиодом, в том примере мы использовали функцию delay(). Главный ...
arduino.ru/tutorials/BlinkWithoutDelay
 
16 ноя 2012 ... Все мы знаем чудесный пример "моргаем светодиодом без delay()" - приведу его еще разок:
arduino.ru/forum/programmirovanie/otkaz-ot-delay
 
7 сен 2013 ... Я уж и не припомню сколько раз тут на форуме отсылал новичков к примеру Мигаем светодиодом без delay() Но... не нравится мне он.
arduino.ru/.../eshche-raz-migaem-svetodiodom-bez-delay
 
11 фев 2012 ... Помогите убрать delay из библиотеки DallasTemperature Для работы с датчиком необходимо выдерживать временные паузы , в ...
arduino.ru/forum/.../ubrat-delay-iz-biblioteki-ds18b20
 
12 ноя 2013 ... как сделать задержку без delay (чтобы избежать дребезга кнопки) использовать переменную? других вариантов нету? int ...
arduino.ru/forum/.../zaderzhka-bez-delay
 
27 мар 2015 ... Просто сам пытаюсь,с малого,поэтому не все написал.насчет без delay- предыдущий скетч не работал,вернее кнопка,так как delayее ...
arduino.ru/forum/.../sketch-svetofora-bez-delay
 
3 апр 2013 ... Как видно в этой конструкции есть delay который на несколько микро секунд останавливает работу всего Arduino. Как-то можно ...
arduino.ru/forum/.../zaderzhka-delay-i-buzzer
 
6 апр 2014 ... Добрый день. Пытаюсь реализовать задержку в программе не через delay, а через millis. Чтобы нажатие на кнопки (в конце скетча) не ...
arduino.ru/.../millis-vmesto-delay-pomogite-razobratsya

 

dimax
dimax аватар
Онлайн
Зарегистрирован: 25.12.2013

На таймере совсем компактным решение получается :)

void setup() {
TCCR1A=0;
OCR1A=624;// 40ms 
TCCR1B=(1<<WGM12)|(1<<CS12)|(1<<CS10); //div 1024 CTC mode
TIMSK1=1<<OCIE1A;
pinMode(13,OUTPUT);// светодиод на 13 ноге
pinMode(12,OUTPUT); // светодиод на 12 ноге
}

void loop() {  }

ISR (TIMER1_COMPA_vect) { 
static byte n=1;
if (n<=6) PORTB^=(1<<5);//6 тиков моргать светодиодом на 13 ноге
if (n>=13&&n<=18) PORTB^=(1<<4);//6 тиков моргать светодиодом на 12 ноге
n==18? n=1:n++;  
}

 

guardauto
Offline
Зарегистрирован: 23.04.2015

Спасибо за подборку. Буду изучать.

guardauto
Offline
Зарегистрирован: 23.04.2015

dimax пишет:

На таймере совсем компактным решение получается :)

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

art100
Offline
Зарегистрирован: 09.03.2014

Компилятор то ведь на С писан. Компилятору то все равно какой стиль написания. Упрощенный С-и или прародитель читсый С или прародитель ассемблер, не важно. Главное чтобы вы сами понимали и помнили, что написали. Смогли это обьяснить почему так, а не другие стили.  Если знаешь сколько и каких таймеров есть внутри можно напрямую коды в настроечные регистры кидать. Можно напрямую делить, отсчитывать, ножки внешние дергать.

// dimax migalka 2 leds 20150424 http://arduino.ru/forum/programmirovanie/politseiskaya-migalka
//--------я много забыл но кое что еще помню---------------------------------------------
// однократная инициализация памяти кучки таймеров и кучки настроечных регистров
void setup(){
  TCCR1A=0; // таймеру вроде 1-первому загнать 000000000000000000000
  OCR1A=624;// 40ms 
  TCCR1B=(1<<WGM12)|(1<<CS12)|(1<<CS10); //div 1024 CTC mode таймеру второму через его настроечные регистры накидать целую готовую логику
  TIMSK1= 1<<OCIE1A;// тоже с та
  pinMode(13,OUTPUT);// светодиод на 13 ноге ногу подключить как выходную максимум 5 вольт 40 милиАмпер
  pinMode(12,OUTPUT);// светодиод на 12 ноге ногу подключить как выходную
}
//===============
void loop(){
// много кратно вызывать не надо потому как однократная настройка оказывается достаточна все равно трястись ножки будут
}
//===============
//-----------------------------------------------------
ISR (TIMER1_COMPA_vect){ //подпрограмка логику таймеру менять по ходу отсчетов
  static byte n=1;// кусочек памяти отрезать для переменной
  if (n<=6)         PORTB^=(1<<5);//6 тиков моргать светодиодом на 13 ноге счетчик 1 трясет выходной ногой
  if (n>=13&&n<=18) PORTB^=(1<<4);//6 тиков моргать светодиодом на 12 ноге сетчки 2-ой трясет выходной ногой
  n==18? n=1:n++;  // какая-то не ясная мне логика счетчика
}
//-------как-то так. автор автор меня поправит----------------------------------------------

Пишите как угодно, что угодно, но комментируйте чтобы самим потом вспомнить и найти лучшее решение. Эх риторика. Я от такого стиля отошел много лет назад. Продуктивность на экспериментах низкая. Такой стиль эфективен если поток и нехватка возможностей. 

Вот Димах даром готовое решение выдал.

Спасибо.

Может в железе проверю. Может даже сегодня вечером. :) Отдам целую плату под такой умный и компактный код с прямыми настройками таймеров. И будет бездельничать остальная часть микроконтроллера. Сегодня у нас выбор красавицы на огромном холдинге. Если не утащю женское тело и с телом не загуляю. Код на станочек с ЧПУ и двумя светодиодиками волью минут 20. Поробую как там таймеры таймерятся. :)

 

Tomasina
Tomasina аватар
Offline
Зарегистрирован: 09.03.2013

арт, это Ваш первый пост, который мне удалось прочесть с первого раза. Браво!

art100
Offline
Зарегистрирован: 09.03.2014

https://yadi.sk/i/wVJKQNy8gDoAy

 

Спасибо димах

Мигает

dimax
dimax аватар
Онлайн
Зарегистрирован: 25.12.2013

art100, на здоровье) Я тайминги правда не такие как у Т.С. поставил, паузу между переключениями светодиодов сделал не 500, а раза в два меньше.  А последнюю паузу совсем убрал. Что б было как в Т.З. нужно немного поменять:

if (n<=6) PORTB^=(1<<5);//6 тиков моргать светодиодом на 13 ноге
//пропустить 12 тиков по 40мс (12*40=480мс)
if (n>=18&&n<=23) PORTB^=(1<<4);//6 тиков моргать светодиодом на 12 ноге
//пропустить ещё 12 тиков по 40мс
n==35? n=1:n++; // сброс счётчика если досчитали до 35

 

guardauto
Offline
Зарегистрирован: 23.04.2015

dimax пишет:

art100, на здоровье) Я тайминги правда не такие как у Т.С. поставил, паузу между переключениями светодиодов сделал не 500, а раза в два меньше.  А последнюю паузу совсем убрал. Что б было как в Т.З. нужно немного поменять:

if (n<=6) PORTB^=(1<<5);//6 тиков моргать светодиодом на 13 ноге
//пропустить 12 тиков по 40мс (12*40=480мс)
if (n>=18&&n<=23) PORTB^=(1<<4);//6 тиков моргать светодиодом на 12 ноге
//пропустить ещё 12 тиков по 40мс
n==35? n=1:n++; // сброс счётчика если досчитали до 35

Чтобы вместо 12 и 13 ног задействовать аналоговые выходы A1 и A2 исправлять так?

if (n<=6) PORTС.1=(1<<5);//6 тиков моргать светодиодом на ноге A1
//пропустить 12 тиков по 40мс (12*40=480мс)
if (n>=18&&n<=23) PORTC.2=(1<<4);//6 тиков моргать светодиодом на ноге A2
//пропустить ещё 12 тиков по 40мс
n==35? n=1:n++; // сброс счётчика если досчитали до 35

 

dimax
dimax аватар
Онлайн
Зарегистрирован: 25.12.2013

guardauto, нет. Будут PORTC^=(1<<1) и  PORTC^=(1<<2)

guardauto
Offline
Зарегистрирован: 23.04.2015

Спасибо, попробую.

art100
Offline
Зарегистрирован: 09.03.2014

dimax пишет:

art100, на здоровье) Я тайминги правда не такие как у Т.С. поставил, паузу между переключениями светодиодов сделал не 500, а раза в два меньше.  А последнюю паузу совсем убрал. Что б было как в Т.З. нужно немного поменять:

if (n<=6) PORTB^=(1<<5);//6 тиков моргать светодиодом на 13 ноге
//пропустить 12 тиков по 40мс (12*40=480мс)
if (n>=18&&n<=23) PORTB^=(1<<4);//6 тиков моргать светодиодом на 12 ноге
//пропустить ещё 12 тиков по 40мс
n==35? n=1:n++; // сброс счётчика если досчитали до 35

 

кино  https://yadi.sk/i/t4kxu6U9gECaD

Запись камеры подтормаживает и смазывает паузы между 6 вспышками. Все похоже в результате на мигалку.

// dimax migalka 2 leds 20150425 http://arduino.ru/forum/programmirovanie/politseiskaya-migalka
//-----------------------------------------------------
void setup(){
  TCCR1A=0;
  OCR1A=624;// 40ms 
  TCCR1B=(1<<WGM12)|(1<<CS12)|(1<<CS10); //div 1024 CTC mode
  TIMSK1= 1<<OCIE1A;
  pinMode(13,OUTPUT);// светодиод на 13 ноге
  pinMode(12,OUTPUT);// светодиод на 12 ноге
}
//===============
void loop(){
}
//===============
//-----------------------------------------------------
//ISR (TIMER1_COMPA_vect){ //паузу между переключениями светодиодов сделал не 500, а раза в два меньше.  А последнюю паузу совсем убрал.
//  static byte n=1;
//  if (n<=6)         PORTB^=(1<<5);//6 тиков моргать светодиодом на 13 ноге
//  if (n>=13&&n<=18) PORTB^=(1<<4);//6 тиков моргать светодиодом на 12 ноге
//  n==18? n=1:n++;  
//}
//-----------------------------------------------------
//-----------------------------------------------------
ISR (TIMER1_COMPA_vect){ 
  static byte n=1;
  if (n<=6)         PORTB^=(1<<5);//6 тиков моргать светодиодом на 13 ноге  //пропустить 12 тиков по 40мс (12*40=480мс)
  if (n>=18&&n<=23) PORTB^=(1<<4);//6 тиков моргать светодиодом на 12 ноге  //пропустить ещё 12 тиков по 40мс
  n==35? n=1:n++; // сброс счётчика если досчитали до 35
}
//-----------------------------------------------------

Димах спасибо.

 

guardauto
Offline
Зарегистрирован: 23.04.2015

Видео с Вашим кодом. Ребенок одобрил!

У меня видео подтормаживает, в реале довольно неплохо смотрится.

https://yadi.sk/i/mBye_B4LgExXJ

Попробую со своим кодом, что получилось. Позже покажу.

Спасибо за помощь, не ожидал такой заинтересованности :).

Ещё бы звук теперь к мигалке сделать, квакалку.

dimax
dimax аватар
Онлайн
Зарегистрирован: 25.12.2013

Можно сирену простенькую прикрутить.. тот-же скетч, добавил таймер2 для генерации звука от 600 Гц до 1500 Гц.  На 11 ногу ардуины повесить динамик через ключевой транзистор, или хотя бы через резистор ом на 100.

void setup() {
//настройка сирены
TCCR2A=(1<<COM2A0)| (1<<WGM21); //CTC mode, OC2A Enable
TCCR2B=(1<<CS22)|(1<<CS20); //div 128
OCR2A=40;
pinMode(11,OUTPUT); // speaker на 11 ноге

//настройка мигалки
TCCR1A=0;
OCR1A=624;// 40ms 
TCCR1B=(1<<WGM12)|(1<<CS12)|(1<<CS10); //div 1024 CTC mode
TIMSK1=1<<OCIE1A;
pinMode(13,OUTPUT);// светодиод на 13 ноге
pinMode(12,OUTPUT); // светодиод на 12 ноге
}

void loop() { }

ISR (TIMER1_COMPA_vect) { 
static byte n=1;
static byte spik=40;
static boolean count_direct=false;
if (n<=6) PORTB^=(1<<5);//6 тиков моргать светодиодом на 13 ноге
if (n>=18&&n<=23) PORTB^=(1<<4);//6 тиков моргать светодиодом на 12 ноге
n==35? n=1:n++;  
if (count_direct==false){ 
    spik==100? count_direct=true : spik++;
    }
if (count_direct==true){
    spik==40? count_direct=false : spik--;
    }
OCR2A=spik;
}

 

std
Offline
Зарегистрирован: 05.01.2012

Tomasina пишет:
арт, это Ваш первый пост, который мне удалось прочесть с первого раза. Браво!

Доступно пишет же :)

мне норм.

guardauto
Offline
Зарегистрирован: 23.04.2015

dimax пишет:

Можно сирену простенькую прикрутить.. 

Собрался я было весь код до кучи собрать, да вот беда. Таймер мигалки не хочет с библиотекой сервы дружить:

Arduino: 1.6.1 (Windows XP), Плата"Arduino Uno"
 
Servo\avr\Servo.cpp.o: In function `__vector_11':
 
C:\Program Files\arduino-1.6.1\libraries\Servo\src\avr/Servo.cpp:81: multiple definition of `__vector_11'
 
sketch_apr29d.cpp.o:C:\Program Files\arduino-1.6.1/sketch_apr29d.ino:31: first defined here
 
collect2.exe: error: ld returned 1 exit status
 
 

 

guardauto
Offline
Зарегистрирован: 23.04.2015
#include <Servo.h>

// dimax migalka 2 leds 20150425 <a href="http://arduino.ru/forum/programmirovanie/politseiskaya-migalka" rel="nofollow">http://arduino.ru/forum/programmirovanie/politseiskaya-migalka</a>
//-----------------------------------------------------
void setup(){
  TCCR1A=0;
  OCR1A=624;// 40ms 
  TCCR1B=(1<<WGM12)|(1<<CS12)|(1<<CS10); //div 1024 CTC mode
  TIMSK1= 1<<OCIE1A;
  pinMode(A1,OUTPUT);// светодиод на 13 ноге
  pinMode(A2,OUTPUT);// светодиод на 12 ноге
  
  #define servoPin 9
  Servo myServo;
}

//===============
void loop(){
}
//===============
//-----------------------------------------------------
//ISR (TIMER1_COMPA_vect){ //паузу между переключениями светодиодов сделал не 500, а раза в два меньше.  А последнюю паузу совсем убрал.
//  static byte n=1;
//  if (n<=6)         PORTB^=(1<<5);//6 тиков моргать светодиодом на 13 ноге
//  if (n>=13&&n<=18) PORTB^=(1<<4);//6 тиков моргать светодиодом на 12 ноге
//  n==18? n=1:n++;  
//}
//-----------------------------------------------------
//-----------------------------------------------------
ISR (TIMER1_COMPA_vect){ 
  static byte n=1;
  if (n<=6)         PORTC^=(1<<1);//6 тиков моргать светодиодом на 13 ноге  //пропустить 12 тиков по 40мс (12*40=480мс)
  if (n>=18&&n<=23) PORTC^=(1<<2);//6 тиков моргать светодиодом на 12 ноге  //пропустить ещё 12 тиков по 40мс
  n==35? n=1:n++; // сброс счётчика если досчитали до 35
}
//-----------------------------------------------------

 

dimax
dimax аватар
Онлайн
Зарегистрирован: 25.12.2013

guardauto, видимо библа сервы использует таймер1, который занят мигалкой.  Можно на таймере2 сделать, но менее удобно, придётся сильно перепахать всю логику работы, т.к. у него самый длинный интервал 16мс. Если тайминги не принципиальны, можно на вотчдог перекинуть. Его никто не использует, кроме "библиотек сна" . У него либо раз в 32мс будет прерывание, либо раз в 64. 32 маловато, а вот 64 наверно пойдёт..

void setup(){
WDTCSR=B00011000;
WDTCSR=(1<<WDIE)|(1<<WDP1); 
pinMode(A1,OUTPUT);// светодиод на 13 ноге
pinMode(A2,OUTPUT);// светодиод на 12 ноге
}
void loop(){
}

ISR (WDT_vect){ //входит в прерывание каждые 64ms
  static byte n=1;
  if (n<=6)         PORTC^=(1<<1);
  if (n>=13&&n<=18) PORTC^=(1<<2);
   n==25? n=1:n++; 
}

 

guardauto
Offline
Зарегистрирован: 23.04.2015

Спасибо, вроде все получилось. Вот мой кусок кода. Ссервой дружит, мигалка включается и выключается, но иногда при выключении бывает подзависнет один из светодиодов и остается включенным. Но это мелочи, включение-выключение мигалки помогает. Тайминги вполне устраивают.

#include <Servo.h>   // Подключаем библиотеку для сервоприводов  
#include <SoftwareSerial.h> // Подключаем библиотеку для работы с Serial через дискретные порты
#include <AFMotor.h>  //Подключаем заголовочный файл библиотеки

//Создаем объект для двигателя на 1 канале (M1)
AF_DCMotor motor(1);

#define servoPin 9

int pos = 0;    // для хранения позиции 
Servo myServo;

SoftwareSerial BTSerial(0, 1); // RX, TX

// Создаем переменную для команд Bluetooth 
char vcmd; 


void setup() 
{ 
pinMode(A1,OUTPUT);// светодиод на 13 ноге
pinMode(A2,OUTPUT);// светодиод на 12 ноге

     // Устанавливаем скорость передачи данных по Bluetooth 
  BTSerial.begin(9600); 
  // Устанавливаем скорость передачи данных по кабелю 
  Serial.begin(9600); 
  // Выбираем пин к которому подключен сервопривод 
  myServo.attach(9);
// Поворачиваем сервопривод в положение 90 градусов при каждом включении 
  myServo.write(90);  
}

ISR (WDT_vect){ //входит в прерывание каждые 64ms
  static byte n=1;
  if (n<=6)         PORTC^=(1<<1);
  if (n>=13&&n<=18) PORTC^=(1<<2);
   n==25? n=1:n++; 
}

void loop() { 
 
  // Если есть данные 
  if (BTSerial.available()) 
  { 
    // Читаем команды и заносим их в переменную. char преобразует код символа команды в символ 
    vcmd = (char)BTSerial.read(); 
    // Отправляем команду в порт, чтобы можно было их проверить в "Мониторе порта" 
    Serial.println(vcmd);
  
    //Мигалка вкл
    if (vcmd == 'X')
    {
      strob_on();
    }
    //Мигалка выкл.
    if (vcmd == 'x')
    {
      strob_off();
    }
  } 
}

//Включена мигалка
void strob_on()
{
  WDTCSR=B00011000;
  WDTCSR=(1<<WDIE)|(1<<WDP1); 
}
//Выключена мигалка
void strob_off()
{
  WDTCSR &= ~(1<<WDIE)|(1<<WDP1); 
}

 

dimax
dimax аватар
Онлайн
Зарегистрирован: 25.12.2013

guardauto, ничё так, аккуратно. Но ради одной-двух строк можно в  отдельную функцию не выделять) Что-б наверняка гасло, можно специально послать команду что-б обнулить биты:  PORTC&=B11111001;.

san73
Offline
Зарегистрирован: 02.05.2015

dimax подскажите пожалуйста, как сирену подключить к 10 выходу Arduino. C выходами на светодиоды разобрался, переподключил на 8 и 9 выходы. А вот с сиреной не понял. 

if (n<=6) PORTB^=(1<<1);//6 тиков моргать светодиодом на 9 ноге (1 это PB1 это 9 выход arduino )

if (n>=18&&n<=23) PORTB^=(1<<0);//6 тиков моргать светодиодом на 8 ноге(0 это PB0 это 8 выход arduino )

dimax
dimax аватар
Онлайн
Зарегистрирован: 25.12.2013

san73, без существенного изменения кода можно только на 3 вывод ардуины сирену переделать. Для этого вывод 3 сделать OUTPUT, и в строчке, где упоминается COM2A0 поменять на COM2B0.

san73
Offline
Зарегистрирован: 02.05.2015

Согласен, OC2A к 11 ноге привязан, к 10 OC1B. У меня на 3 и 11 выводах motor shieid висит, 8 и 9 на мигалку отвел, машинка должна получиться. Пытаюсь разобраться с таймерами, портами.., но программист из меня не очень.  

 

dimax
dimax аватар
Онлайн
Зарегистрирован: 25.12.2013

san73, в принципе можно сирену к любой ноге приживить почти без изменения кода, если задействовать функцию tone(),

void setup() {
//настройка сирены
pinMode(10,OUTPUT); // speaker на 10 ноге
tone(10,300); // с какой частоты начинать гудеть
//настройка мигалки
TCCR1A=0;
OCR1A=624;// 40ms 
TCCR1B=(1<<WGM12)|(1<<CS12)|(1<<CS10); //div 1024 CTC mode
TIMSK1=1<<OCIE1A;
pinMode(13,OUTPUT);// светодиод на 13 ноге
pinMode(12,OUTPUT); // светодиод на 12 ноге
}

void loop() { }

ISR (TIMER1_COMPA_vect) { 
static byte n=1;
static byte spik=40;
static boolean count_direct=false;
if (n<=6) PORTB^=(1<<5);//6 тиков моргать светодиодом на 13 ноге
if (n>=18&&n<=23) PORTB^=(1<<4);//6 тиков моргать светодиодом на 12 ноге
n==35? n=1:n++;  
if (count_direct==false){ 
    spik==100? count_direct=true : spik++;
    }
if (count_direct==true){
    spik==40? count_direct=false : spik--;
    }
OCR2A=spik;
}

 

san73
Offline
Зарегистрирован: 02.05.2015

dimax Спасибо большое за идею. Буду разбираться, заодно и про tone почитаю.

san73
Offline
Зарегистрирован: 02.05.2015

К сожалению, на tone тоже не получается. Сирена похрипывает и не работают двигатели. Отключаю сирену, двигатели работают. Собираю программу блоками, прошу сильно не ругать за неграмотность.

 

san73
Offline
Зарегистрирован: 02.05.2015
#include <BTCA2ALite.h>
btca2aLite btca2aLite;
#define D1 12          // Направление вращение двигателя 1
#define M1 3          // ШИМ вывод для управления двигателем 1
#define D2 13          // Направление вращение двигателя 2
#define M2 11          // ШИМ вывод для управления двигателем 2
 
bool direction = 0;   // Текущее направление вращения       
int value;            // Текущее значение ШИМ
int n1;
int n2;
int LED1 = 2; // Пин светодиода 1 
int LED2 = 4; // Пин светодиода 2
void setup() 
{ 
  btca2aLite.SetupHardwareSerial(0, 9600);
    pinMode(D1, OUTPUT);
    pinMode(D2, OUTPUT);      
    pinMode(LED1, OUTPUT); // Инициализируем пин светодиода 1
    pinMode(LED2, OUTPUT); // Инициализируем пин светодиода 2
    digitalWrite(LED1, LOW); // Светодиод 1 выключен
    value = 0;
    n1=1; //n2=1;
  
//настройка сирены
pinMode(10,OUTPUT); // speaker на 10 ноге
tone(10,300); // с какой частоты начинать гудеть

//настройка мигалки
TCCR1A=0;
OCR1A=624;// 40ms 
TCCR1B=(1<<WGM12)|(1<<CS12)|(1<<CS10); //div 1024 CTC mode
TIMSK1=1<<OCIE1A;
pinMode(9,OUTPUT);// светодиод на 9 ноге
pinMode(8,OUTPUT); // светодиод на 8 ноге
} 
  
void loop() 
//мигалка
{ }
 ISR (TIMER1_COMPA_vect) { 
static byte n=1;
static byte spik=40;
static boolean count_direct=false;

if (n<=6) PORTB^=(1<<1);//6 тиков моргать светодиодом на 9 ноге (1 это PB1 это 9 выход arduino )
if (n>=18&&n<=23) PORTB^=(1<<0);//6 тиков моргать светодиодом на 8 ноге(0 это PB0 это 8 выход arduino )
n==35? n=1:n++;  

//сиренка
if (count_direct==false){ 
    spik==100? count_direct=true : spik++;
    }
if (count_direct==true){
  spik==40? count_direct=false : spik--;
   }
OCR2A=spik;
  
  btca2aLite.ReadCommand();
  //управление мигалкой
  if (btca2aLite.Button(KEYCODE_BUTTON_R2))
  {    n1=1;  }
  if (n1==1){   PORTB&=B00000000; }
if (btca2aLite.Button(KEYCODE_BUTTON_R1))
{  n1=0; }
 else (n1==0); {  }
 
  //управление сиреной
  if (btca2aLite.Button(KEYCODE_BUTTON_L2))
    {  noTone(10);}//n2=1;  
   if (btca2aLite.Button(KEYCODE_BUTTON_L1))
    {  tone(10,300);}//n1=0; 
    
  //  управление моторами
  if (btca2aLite.ButtonPressed(KEYCODE_DPAD_UP))
  {
    value = 150;
    digitalWrite(D1, 0);
    digitalWrite(D2, 0);
  }
    
    else if (btca2aLite.ButtonPressed(KEYCODE_DPAD_DOWN))
    {
    value = 100;
    digitalWrite(D1, 1);
    digitalWrite(D2, 1);
    }
    
    else if (btca2aLite.ButtonPressed(KEYCODE_DPAD_RIGHT))
    {
    value = 80;
    digitalWrite(D1, 0);
    digitalWrite(D2, 1);
    }
    
    else if (btca2aLite.ButtonPressed(KEYCODE_DPAD_LEFT))
    {
    value = 80;
    digitalWrite(D1, 1);
    digitalWrite(D2, 0);
    }
    
    else
    {
     value = 0;
     }
        // управление фарами
  if (btca2aLite.Button(KEYCODE_BUTTON_X))
  {
   digitalWrite(LED1, HIGH); //PORTB&=(0<<0);PORTB&=(0<<0);
    
  }
 if (btca2aLite.Button(KEYCODE_BUTTON_Y))
 {
    digitalWrite(LED1, LOW);
  }
  // включение светодиода
  if (btca2aLite.ButtonPressed(KEYCODE_BUTTON_A))
  {
    digitalWrite(LED2, HIGH);
    
    }
  
  else{
    digitalWrite(LED2, LOW); 
  }
  
  { 
    analogWrite(M1, value);       // Задаем скорость вращения
    analogWrite(M2, value);
      } 
 }
 

 

dimax
dimax аватар
Онлайн
Зарегистрирован: 25.12.2013

san73, конечно не получится, вы же используете команду analogwrite, а она использует таймер2, через который так-же работает и tone(). Тут единственный выход мигалку перенести на таймер вотчдога, как в #18, а сирену переделать на таймер 1.

san73
Offline
Зарегистрирован: 02.05.2015

Мигалку на вотчдог перенес, мигает немного медленнее, но в принципе пойдет. С сиреной пока не получается.

san73
Offline
Зарегистрирован: 02.05.2015
void setup(){
WDTCSR=B00011000;
WDTCSR=(1<<WDIE)|(1<<WDP1); 
pinMode(8,OUTPUT);// светодиод на 8 ноге
pinMode(9,OUTPUT);// светодиод на 9 ноге
}
void loop(){
}

ISR (WDT_vect){ //входит в прерывание каждые 64ms
  static byte n=1;
  if (n<=6)         PORTB^=(1<<1);
  if (n>=13&&n<=18) PORTB^=(1<<0);
   n==22? n=1:n++; 
}

 

dimax
dimax аватар
Онлайн
Зарегистрирован: 25.12.2013

san73, как-то так  мне видится:

void setup() {
pinMode(9,OUTPUT); // speaker
pinMode(13,OUTPUT);// светодиод
pinMode(12,OUTPUT); // светодиод
WDTCSR=(1<<WDCE)|(1<<WDE); WDTCSR=(1<<WDIE)|(1<<WDP0); 
TCCR1A=(1<<COM1A0)|(1<<WGM11)|(1<<WGM10); //FastPWM Mode15
TCCR1B=(1<<WGM13)|(1<<WGM12)|(1<<CS12); //div 256 
}

void loop() { }

ISR (WDT_vect){ //входит в прерывание каждые 32ms
static byte n=1;
static byte spik=40;
static boolean count_direct=true;
if (n<=6) PORTB^=(1<<5);//6 тиков моргать светодиодом на 13 ноге
if (n>=18&&n<=23) PORTB^=(1<<4);//6 тиков моргать светодиодом на 12 ноге
n==35? n=1:n++;  
if (count_direct==false) spik==100? count_direct=true:spik++;
if (count_direct==true) spik==40? count_direct=false:spik--;
OCR1A=spik;
}

Мигалка на вотч-доге, в егойных прерываниях мигает и говорит таймеру1 с какой частотой ему пищать. Динамик на 10 ногу малыми силами не перенести, таймер в нужном режиме (mode15) её не поддерживает. Так что динамик на 9 ногу сажать.

san73
Offline
Зарегистрирован: 02.05.2015

dimax, молодец, спасибо, таймеры как орехи щелкаешь. Все работает отлично. Для меня это немного тяжеловато дается. Если не трудно подскажи как сиреной можно управлять, включить – выключить.

dimax
dimax аватар
Онлайн
Зарегистрирован: 25.12.2013

san73, тут масса вариантов. Можно например таймер1 просто остановить командой  TCCR1B^=1<<CS12; ей же можно и снова запустить (это команда инверсии) . Или стандартно включать: TCCR1B|=1<<CS12   и выключать: TCCR1B&=~(1<<CS12)

san73
Offline
Зарегистрирован: 02.05.2015

Спасибо, всё получилось.