- 
	
	
	
		
Прерывания в Arduino.
	
	
		типа как у х86 прерывания по таймеру? а то хочу навесить ардуино для решения пары простых, но длительных по времени задач, было бы сделать проще как обработчик прерывания. или просто на какой-нить вход подать тактовые импульсы и на этом сделать что-то вроде обработчика? опять же, мож есть внутренний таймер для этой цели, чтоб не городить ниче вокруг?
ну и примеры программки, если есть...
	 
 - 
	
	
		
Вложений: 1
	
	
		Re: а есть ли у ардуино прерывания?
	
	
		Привожу два примера прерываний.
Ниже пример кода для Arduino, прерывание по таймеру
В этом примере процедура flash_led будет выполнятся каждый раз по истечению 0,5 сек.
	PHP код:
	
//Выполнение процедуры по прерыванию таймеру.
#include <MsTimer2.h>
  static boolean output = HIGH;
  
void flash_led() //обработчик прерывания
{
  digitalWrite(13, (output==HIGH) ? output=LOW : output=HIGH);
}
void setup() {
  pinMode(13, HIGH);
  MsTimer2::set(500, flash_led); // 500ms период
  MsTimer2::start();  //включить таймер
}
void loop() 
{
//.....
} 
 Еще один пример работы аппаратного прерывания.
В данном примере  при изменении  напряжения на ножке D2
каждый раз будет выполнятся процедура int_on
Таких входов в Arduino всего 2 (D2,D3)
И несколько вариантов настройки событий
LOW - to trigger the interrupt whenever the pin is low, 
CHANGE - to trigger the interrupt whenever the pin changes value 
RISING - to trigger when the pin goes from low to high, 
FALLING - for when the pin goes from high to low.
	PHP код:
	
#define PinA  2
static boolean output = HIGH;
void setup() 
{   
  pinMode(PinA, INPUT); 
  digitalWrite(PinA, HIGH);     // подключить подтягивающий резистор
  attachInterrupt(0, int_on, CHANGE);  // настроить прерывание interrupt 0 на pin 2
} 
void loop()
{
//........
}
// обработка прерывания
void  int_on()
{
digitalWrite(13, (output==HIGH) ? output=LOW : output=HIGH);
} 
 
	 
 - 
	
	
	
		
Re: Прерывания в Arduino.
	
	
		а не в курсе, случаем, есть возможности дернуть сигнал откуда-нибудь о достижении скорости километров в 20? или все же придется импульсы с датчика скорости считать? приятнее было бы че-нить с уровнем 0 и 1. двиг 2AZ-FE, на камри в частности ставится. понимаю, что управление меняется и от модели и от года, но вдруг есть наколки какие
	 
 - 
	
	
	
		
Re: Прерывания в Arduino.
	
	
		Акселерометр использовать.
	 
 - 
	
	
	
		
Re: Прерывания в Arduino.
	
	
		я бы рекомендовал либо GPS либо с датчика скорости. С датчика скорости просто импульсы идут. Напрягает больше всего то, что надо провода тащить, а обработать импульсы совсем просто.
	 
 - 
	
	
	
		
Re: Прерывания в Arduino.
	
	
		да там проводов-то... метр в салоне. буду щщитать
	 
 - 
	
	
	
		
Re: Прерывания в Arduino.
	
	
		кстати, о птичках. а сколько примерно длиться цикл с инкрементом и парой проверок? на атмеге 16-20Мгц. чтоб поменьше гадать
	 
 - 
	
	
	
		
Re: Прерывания в Arduino.
	
	
		Дергай ногой в начале цикла, и на осциллографе посмотри.
Все зависит от числа выполняемых инструкций и  количества  тактов на конкретную инструкцию.
	 
 - 
	
	
	
		
Быстродействие Arduino
	
	
		можно поставить AVR studio (она бесплатная), GCC и посмотреть буквально по тактам. 
Но, я не знаю как Arduino проект открыть в AVR Studio, хотя Arduino использует при компиляции тот же самый GCC, что и AVR Studio.
Большинство команд AVR выполняется за 1 такт, но команды очень простые+восьмибитность. Поэтому чтение 8-битной переменной состоит из задания регистровой пары (2 операции)+чтение(эта команда исполняется 2 два такта).
Очень долго выполняются некоторые Arduino куски кода, поскольку заточены под максимальную универсальность. Точно знаю про очень долгое дергание ногами посредством команд arduino.
UPD: Скомпилил под AVR Studio простейший проект Arduino.
Для примера смотри, вот этот код 
	uint8_t volatile w,k;
	k=0;
	for (w=10;w<250;w++)
	{
		k++;
		if (k==5 && ((PIND & (1<<PIN5)) != 0))
			k--;
	}	
Цикл совершается за 20 тактов если не выполняется k-- и 26 если выполняется. Если убрать volatile и таким образом разрешить не располагать эти регистры в памяти (проц оперирует только регистрами), то цикл без захода в k-- выполняется 12 тактов.
Вот такой цикл (по сути даже проще верхнего)
	uint8_t w,k;
	k=0;
	for (w=10;w<250;w++)
	{
		k++;
		if ((digitalRead(5) != 0))
			k--;
           }
выполняется 78 тактов.
digitalWrite(5,HIGH) выполняется 72 такта
а при этом похожая команда
digitalWrite(13,HIGH) в которой отличается только номер выводв выполняется 57 тактов.
На обыкновенной ардуине стоит 16 МГц резонатор. Это означает, что за секунду выполняется 16 миллионов тактов.
UPD2:
Для сравнения быстродействия:
Ниже приведены команды, которые при понимании логики работы программы в 99% случаев делают одно и то же.
digitalWrite(5,HIGH);  // 72 такта
DDRD |=(1<<PIN5); // 2 такта
Но тут надо заметить, что это крайний случай. Во многих случаях разница незначительная, либо ее вообще нет.
Можно все написать на Arduino и только пару строчек таких, как выше - прямых обращений к портам при необходимости.
	 
 - 
	
	
	
		
Re: Прерывания в Arduino.
	
	
		че-то я тупею, что ли, к старости :mad:
не смог добавить внешние модули в скеч, MsTimer2.h и MsTimer2.с
не, вписать абсолютный путь, типа include "d:\arduino\include\MsTimer2.h" ума, конечно, хватило, только и в MsTimer2.cpp, пришлось тоже путь менять, как-то некрасиво.
бросить просто в папку скеча тоже не получилось
куда положено раскидывать сторонние библиотеки или как добавить путь для них?
в ...hardware\tools\avr\avr\include тоже как-то не очень, там все-таки стандартные хидеры лежат.
самое простое -- держать в папке скеча, а не цепляет. почему?
	 
 - 
	
	
	
		
Re: Прерывания в Arduino.
	
	
		Класть в папку со всеми библиотеками \arduino-0018\libraries\MsTimer2
Можно и без библиотеки сделать прерывание по таймеру
	PHP код:
	
volatile unsigned int tcnt2;
void setup() 
{
       TIMSK2 &= ~(1<<TOIE2); //разрешения прерывания по переполнению таймера/счетчика Т2 
    TCCR2A &= ~((1<<WGM21) | (1<<WGM20));// Режим работы таймера/счетчика
    TCCR2B &= ~(1<<WGM22);// Режим работы таймера/счетчика
    ASSR &= ~(1<<AS2);  //Выбор источника синхронизации таймера если AS2=0 от системного генератора
    tcnt2 = 1; //  16000000/64/f=tcnt2
    TIMSK2 |= (1<<TOIE2);//Разрешение прерывания по переполнению Т2.
}
void loop() 
{
} 
void MyInterupt()
{
//обработчик вашего прерывания
}  
//****************обработчик прерывания********************
ISR(TIMER2_OVF_vect) 
{
    TCNT2 = tcnt2;
    MyInterupt();
} 
 
	 
 - 
	
	
	
		
Re: Прерывания в Arduino.
	
	
		а такие конструкци прокатывают?
....
attachInterrupt(0, MeasureSPD, RISING);  //attaching intterrupt to pin D2
....
while (digitalRead(2)) i++;
я в сысле о том, можно ли привязать прерывание к ноге и потом считывать ее состояние?
	 
 - 
	
	
	
		
Re: Прерывания в Arduino.
	
	
		Не понял смысла? Если назначили прерывание на ногу то зачем состояние проверять? Прерывание и так сработает по изменению состояния
	 
 - 
	
	
	
		
Re: Прерывания в Arduino.
	
	
		да мне ж длительность имульса подсчитать. соответственно от старта и до упора.
или мож какой другой метод использовать, встроенный таймер там или еще что
	 
 - 
	
	
	
		
Re: Прерывания в Arduino.
	
	
		Для подсчета можно использовать следующие функции
unsigned long millis() 
unsigned long micros()
	 
 - 
	
	
	
		
Re: Прерывания в Arduino.
	
	
		millis и micros не совсем то что надо. хотя мож и пойдет
надо прерывание делать на CHANGE и измерять типа micros(t2)-micros(t1). 
я опасался ситуации, когда импульс начнется, а потом машина остановится и длина импульса уйдет в бесконечность. да черт с ней, вообще-то
	 
 - 
	
	
	
		
Re: Прерывания в Arduino.
	
	
		По-моему у всех машин несколько (от 5) импульсов на 1 метр пути. 1 метр в секунду - это 3.6 км/ч. Так что если тебе не надо отслеживать очень низкие скорости, достаточно считать импульсы. По любому прерыванию изменения состояния ноги увеличиваешь счетчик, а 1-3 раз в секунду считываешь этот счетчик и сразу обнуляешь.
И все, будет у тебя скорость, которую только надо на константу умножить.
Если надо точнее, чем 1 кмч, и/или низкие скорости, то напиши, у меня в голове вертится алгоритм, но он посложнее.
	 
 - 
	
	
	
		
Re: Прерывания в Arduino.
	
	
		не, мне 20кмч плюс-минус отловить. двери хочу закрывать. привык, а на альфарде нету закрывалки. наверное с микрос() сделаю
	 
 - 
	
	
	
		
Re: Прерывания в Arduino.
	
	
		static boolean output = HIGH; 
Подскажите, а для чего используется эта строка ?
	 
 - 
	
	
	
		
Re: Прерывания в Arduino.
	
	
		для того чтобы на пине output включить логическую еденицу
	 
 - 
	
	
	
		
Re: а есть ли у ардуино прерывания?
	
	
		
	Цитата:
	
		
		
			
				Сообщение от 
Chip
				
			 
			Привожу два примера прерываний.
Ниже пример кода для Arduino, прерывание по таймеру
В этом примере процедура 
flash_led будет выполнятся каждый раз по истечению 0,5 сек.
	PHP код:
	
//Выполнение процедуры по прерыванию таймеру.
#include <MsTimer2.h>
  static boolean output = HIGH;
  
void flash_led() //обработчик прерывания
{
  digitalWrite(13, (output==HIGH) ? output=LOW : output=HIGH);
}
void setup() {
  pinMode(13, HIGH);
  MsTimer2::set(500, flash_led); // 500ms период
  MsTimer2::start();  //включить таймер
}
void loop() 
{
//.....
} 
 Еще один пример работы аппаратного прерывания.
В данном примере  при изменении  напряжения на ножке D2
каждый раз будет выполнятся процедура 
int_on
Таких входов в Arduino всего 2 (D2,D3)
И несколько вариантов настройки событий
LOW - to trigger the interrupt whenever the pin is low, 
CHANGE - to trigger the interrupt whenever the pin changes value 
RISING - to trigger when the pin goes from low to high, 
FALLING - for when the pin goes from high to low.
	PHP код:
	
#define PinA  2
static boolean output = HIGH;
void setup() 
{   
  pinMode(PinA, INPUT); 
  digitalWrite(PinA, HIGH);     // подключить подтягивающий резистор
  attachInterrupt(0, int_on, CHANGE);  // настроить прерывание interrupt 0 на pin 2
} 
void loop()
{
//........
}
// обработка прерывания
void  int_on()
{
digitalWrite(13, (output==HIGH) ? output=LOW : output=HIGH);
} 
  
			
		
	 
 Подскажите 
1) где взять библиотеку MsTimer2.h, которой вы пользуетесь.
2) где взять описание комманд типа PortA, DDRD
3) в языке для Ардуино я не нашел описания оператора "?". Вы его применяете в такой связке -  digitalWrite(13, (output==HIGH) ? output=LOW : output=HIGH);. Это очень удобный оператор, но где можно увидетьполный список операторов и комманд Ардуины?
	 
 - 
	
	
	
		
Re: Прерывания в Arduino.
	
	
		1 - Библиотека
2 - Это не команды для ардуино , это Си для AVR  . Вот пример 
3 - Я сам где то подсмотрел
	 
 - 
	
	
	
		
Re: а есть ли у ардуино прерывания?
	
	
		
	Цитата:
	
		
		
			
				Сообщение от 
RainMan
				
			 
			...
3) в языке для Ардуино я не нашел описания оператора "?". ... Это очень удобный оператор, но где можно увидетьполный список операторов и комманд Ардуины?
			
		
	 
 Вопрос интересный - про источник информации и "недокументированные" функции. А про "удобность"... помоему очень вредный :) оператор, поскольку наверняка это просто "орфографический" вариант оператора IF, обладающий кратким написанием в тексте и огромной неинформативностью при отладке. Соответственно получается "грязный" текст с одинаковым кодом.
	 
 - 
	
	
	
		
Re: а есть ли у ардуино прерывания?
	
	
		Такой вопрос: можно ли сконфигурировать цифровой вход на генерацию прерывания по фронту, затем в обработчике прерывания обнулить таймер по прерыванию затем тут же переконфигурировать ЭТОТ же вход на прерывание по спаду и выйти из обработчика прерывания. Потом по прерыванию по спаду в обработчике прочитать значение таймера и переконфигурировать ЭТОТ же вход снова на прерывание по фронту и т.д. в цикле...
	 
 - 
	
	
	
		
Re: Прерывания в Arduino.
	
	
 - 
	
	
	
		
Re: Прерывания в Arduino.
	
	
		
	Цитата:
	
		
		
			
				Сообщение от 
Chip
				
			 
			Можно.
			
		
	 
 а не очень нахально ( с прерываниями не пробовал ещё работать) будет выглядеть, если я попрошу у Вас пример скетча на такое:
на D3, к примеру, настроено прерывание по фронту. Поступает меандр с переменной частотой, обнуляется  таймер в обработке прерывания по фронту, дальше переконфигурация D3 на прерывание по спаду. (Потом у меня там будет опрос клавиатуры и вывод на 7ми сегментник - с этим я вроде разобрался) По прерыванию по спаду получаем из таймера длительность импульса, снова переконфигурируем D3 на прерывание по фронту. Это будет вроде как спидометр с проекцией на лобовое...:o
	 
 - 
	
	
	
		
Re: Прерывания в Arduino.
	
	
 - 
	
	
	
		
Re: Прерывания в Arduino.
	
	
		
	Цитата:
	
		
		
			
				Сообщение от 
Chip
				
			 
			Класть в папку со всеми библиотеками 
\arduino-0018\libraries\MsTimer2
Можно и без библиотеки сделать прерывание по таймеру
	PHP код:
	
volatile unsigned int tcnt2;
void setup() 
{
       TIMSK2 &= ~(1<<TOIE2); //разрешения прерывания по переполнению таймера/счетчика Т2 
    TCCR2A &= ~((1<<WGM21) | (1<<WGM20));// Режим работы таймера/счетчика
    TCCR2B &= ~(1<<WGM22);// Режим работы таймера/счетчика
    ASSR &= ~(1<<AS2);  //Выбор источника синхронизации таймера если AS2=0 от системного генератора
    tcnt2 = 1; //  16000000/64/f=tcnt2
    TIMSK2 |= (1<<TOIE2);//Разрешение прерывания по переполнению Т2.
}
void loop() 
{
} 
void MyInterupt()
{
//обработчик вашего прерывания
}  
//****************обработчик прерывания********************
ISR(TIMER2_OVF_vect) 
{
    TCNT2 = tcnt2;
    MyInterupt();
} 
  
			
		
	 
 То, что мне нужно. Как в нем изменять частоту? например, мне нужно 500 раз в секунду исполнять мой код?
	 
 - 
	
	
	
		
Re: Прерывания в Arduino.
	
	
		
	PHP код:
	
tcnt2 = 1; //  16000000/64/f=tcnt2 
 По этой формуле 16000000/64/500=500
	 
 - 
	
	
	
		
Re: Прерывания в Arduino.
	
	
 - 
	
	
	
		
Re: Прерывания в Arduino.
	
	
		Только не забудь что регистр 8 битный и максимум может натикать 255.
Как вариант можно добавить еще один регистр и в прерывании после переполнения инкрементировать. Или предделитель увеличить
	 
 - 
	
	
	
		
Re: Прерывания в Arduino.
	
	
		а я то думаю что за...
можете помочь? нужно ну очень быстро заполнять восемь регистров 74hc595.. варианты скоростного shiftOut нашел, latch тоже напрямую в порт пишу, а вот с таймером засада.
	 
 - 
	
	
	
		
Re: Прерывания в Arduino.
	
	
		Ваш пример не хочет работать.. 
	Цитата:
	
		
		
			
#include <avr/interrupt.h>
#include <avr/io.h>
//таймер
//#define FQ 5000 //установка частоты обновления в Гц
volatile unsigned int tcnt2; //timer freq
//74hc595 wiring
//Pin connected to ST_CP of 74HC595
int _latch = 8;
//Pin connected to SH_CP of 74HC595
int _clock = 12;
////Pin connected to DS of 74HC595
int _data = 11;
byte registers[8] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
//настройки при запуске
void setup() { 
  //timer setup
  TIMSK2 &= ~(1<<TOIE2); //разрешения прерывания по переполнению таймера/счетчика Т2  
  TCCR2A &= ~((1<<WGM21) | (1<<WGM20));// Режим работы таймера/счетчика 
  TCCR2B &= ~(1<<WGM22);// Режим работы таймера/счетчика 
  ASSR &= ~(1<<AS2);  //Выбор источника синхронизации таймера если AS2=0 от системного генератора 
  tcnt2 = 1; //  16000000/64/f=tcnt2 
  TIMSK2 |= (1<<TOIE2);//Разрешение прерывания по переполнению Т2. 
  //установка портов
  pinMode(_latch, OUTPUT);
  digitalWrite(_latch, LOW);
  pinMode(_clock, OUTPUT);
  digitalWrite(_clock, LOW);
  pinMode(_data, OUTPUT);
  digitalWrite(_data, LOW);
}
//цикл главной программы
void loop() {   
}
//процедура динамической индикации
void timer2() {
  
  
        if (registers[0]==0x01) registers[0]=0x00;
        else registers[0]=0x01;
        digitalWrite(_latch, LOW);
        shiftOut(_data, _clock, MSBFIRST, registers[7]);
        shiftOut(_data, _clock, MSBFIRST, registers[6]);
        shiftOut(_data, _clock, MSBFIRST, registers[5]);
        shiftOut(_data, _clock, MSBFIRST, registers[4]);
        shiftOut(_data, _clock, MSBFIRST, registers[3]);
        shiftOut(_data, _clock, MSBFIRST, registers[2]);
        shiftOut(_data, _clock, MSBFIRST, registers[1]);
        shiftOut(_data, _clock, MSBFIRST, registers[0]);
        digitalWrite(_latch, HIGH);
  }
//обработчик прерывания
ISR(TIMER2_OVF_vect) {
  TCNT2 = tcnt2;
  timer2();
}
Включается но не выключается, либо скорость настолько высока что пц (при установке в 1).
Как установить частоту 1 гц? просто 1?
			
		
	
 
	 
 - 
	
	
	
		
Re: Прерывания в Arduino.
	
	
		Вот так можно
	PHP код:
	
//Выполнение процедуры по прерыванию таймеру. 
#include <MsTimer2.h> 
  static boolean output = HIGH; 
   
void flash_led() //обработчик прерывания 
{ 
  digitalWrite(13, (output==HIGH) ? output=LOW : output=HIGH); 
} 
void setup() { 
  pinMode(13, HIGH); 
  MsTimer2::set(1000, flash_led); // 1000ms период 
  MsTimer2::start();  //включить таймер 
} 
void loop()  
{ 
//..... 
} 
 
	 
 - 
	
	
	
		
Re: Прерывания в Arduino.
	
	
		Спасибо, наверно так и сделаю. Просто хотелось разобраться именно на уровне МК и его регистров и прочей мутотени.
Читал-читал, далеко не все отложилось в голове. Надо на практике попробовать.
	 
 - 
	
	
	
		
Re: Прерывания в Arduino.
	
	
		Я шифты поключал к SPI , работает очень быстро и в коде все просто реализуется
	 
 - 
	
	
	
		
Re: Прерывания в Arduino.
	
	
		А можно ли сделать вот такое: есть прерывание по фронту на спад, когда оно срабатывает, то надо включить таймер на определенный интервал и по его истечению подать коротко временный импульс (логическая 1) на какой-не будь выход?
	 
 - 
	
	
	
		
Re: Прерывания в Arduino.
	
	
 - 
	
	
	
		
Re: Прерывания в Arduino.
	
	
		да, забыл добавить: после срабатывания таймер должен останавливаться и ждать новой инициализации
	 
 - 
	
	
	
		
Re: Прерывания в Arduino.
	
	
		Ты бы лучше описал для чего тебе это нужно, возможно что уже давно все написано