-
Прерывания в 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.
Ты бы лучше описал для чего тебе это нужно, возможно что уже давно все написано