Прерывания и многозадачность в Arduino
#include <Servo.h>
class Flasher
{
// Переменные-участники класса устанавливаются при запуске
int ledPin; // Номер контакта со светодиодом
long OnTime; // длительность ВКЛ в мс
long OffTime; // длительность ВЫКЛ в мс
// Контроль текущего состояния
int ledState; // устанавливает текущее состояние светодиода
unsigned long previousMillis; // время последнего обновления состояния светодиода
// Конструктор — создает объект Flasher, инициализирует переменные-участники и состояние
public:
Flasher(int pin, long on, long off)
{
ledPin = pin;
pinMode(ledPin, OUTPUT);
OnTime = on;
OffTime = off;
ledState = LOW;
previousMillis = 0;
}
void Update(unsigned long currentMillis)
{
if((ledState == HIGH) && (currentMillis — previousMillis >= OnTime))
{
ledState = LOW; // ВЫКЛ
previousMillis = currentMillis; // Запомнить время
digitalWrite(ledPin, ledState); // Обновить состояние светодиода
}
else if ((ledState == LOW) && (currentMillis — previousMillis >= OffTime))
{
ledState = HIGH; // ВКЛ
previousMillis = currentMillis; // Запомнить время
digitalWrite(ledPin, ledState); // Обновить состояние светодиода
}
}
};
class Sweeper
{
Servo servo; // объект servo
int pos; // текущее положение сервопривода
int increment; // определяем увеличение перемещения на каждом интервале
int updateInterval; // определяем время между обновлениями
unsigned long lastUpdate; // определяем последнее обновление положения
public:
Sweeper(int interval)
{
updateInterval = interval;
increment = 1;
}
void Attach(int pin)
{
servo. attach(pin);
}
void Detach()
{
servo.detach();
}
void reset()
{
pos = 0;
servo.write(pos);
increment = abs(increment);
}
void Update(unsigned long currentMillis)
{
if((currentMillis — lastUpdate) > updateInterval) //время обновиться
{
lastUpdate = millis();
pos += increment;
servo.write(pos);
if ((pos >= 180) || (pos <= 0)) // инициализируем конец вращения
{
// инициализируем обратное направление
increment = -increment;
}
}
}
};
Flasher led1(11, 123, 400);
Flasher led2(12, 350, 350);
Flasher led3(13, 200, 222);
Sweeper sweeper1(25);
Sweeper sweeper2(35);
void setup()
{
sweeper1.Attach(9);
sweeper2.Attach(10);
// Timer0 уже используется millis() — прерываемся примерно посередине и вызываем ниже функцию «Compare A»
OCR0A = 0xAF;
TIMSK0 |= _BV(OCIE0A);
pinMode(2, INPUT_PULLUP);
attachInterrupt(0, Reset, FALLING);
}
void Reset()
{
sweeper1. reset();
sweeper2.reset();
}
// Прерывание вызывается один раз в миллисекунду, ищет любые новые данные, и если нашло, сохраняет их
SIGNAL(TIMER0_COMPA_vect)
{
unsigned long currentMillis = millis();
sweeper1.Update(currentMillis);
// if(digitalRead(2) == HIGH)
{
sweeper2.Update(currentMillis);
led1.Update(currentMillis);
}
led2.Update(currentMillis);
led3.Update(currentMillis);
}
void loop()
{
}
Vanyamba uses Linux — Watchdog Timer Arduino. Прерывание и сброс
Сброс по Watchdog и загрузчик Arduino
Для использования режима сброса системы важно, чтобы было обеспечено следующее условие. Сразу после перезагрузки, прошивка должна проверить и сбросить бит WDRF
в регистре MCUCSR
.
Дело в том, что этот бит определяет состояние бита WDE
, и сразу после сброса системы по срабатыванию сторожевого таймера, бит WDRF
будет установлен. Если его не сбросить, то сторожевой таймер сработает ещё раз. И будет срабатывать в бесконечном цикле, пока не будет отключено питание.
Но если при программировании сторожевого таймера мы можем установить тайм-аут, который нам требуется, то сразу после сброса регистр WDTCSR
будет обнулён, и предделитель таймера примет минимальное значение — 16 мс.
В случае с Arduino, сразу после сброса управление передаётся загрузчику Arduino, который некоторое время ждёт управляющей последовательности по последовательному порту, и это время больше, чем минимальный тайм-аут сторожевого таймера.
Таким образом, если в загрузчике Arduino первым делом не выключить сторожевой таймер сбросом флага WDRF
, то после этого потребуется отключение питания, чтобы смог работать загрузчик Arduino, не говоря уже о пользовательском скетче в основной памяти микроконтроллера.
В загрузчике Arduino отключение сторожевого таймера присутствует, но только в виде дополнительной опции WATCHDOG_MODS
, с которой загрузчик должен быть скомпилирован. Не факт, что загрузчик в используемом Вами микроконтроллере включает в себя эту проверку.
Иначе говоря прежде, чем использовать сторожевой таймер, потребуется проверить, как именно запрограммирован FUSE
-бит WDTON
, а также нужно будет скомпилировать и перепрошить загрузчик, с использованием ключа -DWATCHDOG_MODS
. который прописывается в Makefile
.
Arduino. Внешние прерывания. Подключение энкодера
Обрабатывать нажатие кнопок и другие внешние изменения напряжения можно используя прерывания. Они останавливают выполнение основной программы и запускают обработчик прерываний.
Подготовка к работе
На нашей плате TutorShield установлены две кнопки, которые подключены к цифровым выводам D2 и D3. Подробно подключение кнопок описано в предыдущей статье цикла. Помимо них, для дальнейших экспериментов подключим еще две секции трехцветного светодиода (к выводам D9 и D10). Установите перемычки так, как показано на рисунке:
Установка перемычек
Первый пример
В предыдущем примере для обработки кнопок мы настраивали вывод микроконтроллера на вход и постоянно контролировали его состояние. Это не самый эффективный способ, так как при этом трудно заставить микроконтроллер делать что-то помимо опроса кнопок. Специально для этих целей можно использовать прерывания.
Рассмотрим работу с прерываниями на конкретном примере:
#define LED 11 void setup() { attachInterrupt(0, button1, RISING); attachInterrupt(1, button2, RISING); pinMode(LED, OUTPUT); } void loop() { } void button1() { digitalWrite(LED,HIGH); } void button2() { digitalWrite(LED,LOW); }
Для работы с внешним прерыванием в первую очередь его надо инициализировать. Этим занимается функция attachInterrupt(pin,ISR,mode). У этой функции три параметра:
- pin — номер вывода, на который настроено прерывание. Для платы EduBoard с МК Atmega8 прерывание может быть настроено только на 2ом и 3ем выводе
- ISR — имя функции-обработчика прерывания
- mode — режим работы прерывания, может принимать четыре значения. LOW — вызывает обработчик прерывания, когда на выводе низкое напряжение, CHANGE — при изменении, RISING — при переходе от низкого к высокому уровню, FALLING — от высокому к низкому
В приведенном примере настроено два прерывания. Прерывание «0» вызывает обработчик button1() при изменении напряжения с низкого на высокий уровень на выводе D2. Прерывание «1» вызывает обработчик
В обработчике прерывания button1() зажигается светодиод, а при обработке прерывания button2() он гасится.

Второй пример
В работе кнопок есть одна проблема, которая связана с дребезгом контактов. При нажимании на кнопку напряжение не изменятся мгновенно, а возникает переходной процесс при котором значение напряжение может измениться с низкое на высокое несколько раз. При этом обработчик прерывания может быть вызван несколько раз.
Для демонстрации этого эффекта добавим в предыдущий пример изменение переменной и вывод ее значения в COM-порт.
#define LED 11 int val = 0; void setup() { attachInterrupt(0, button1, RISING); attachInterrupt(1, button2, RISING); pinMode(LED, OUTPUT); Serial.begin(9600); } void loop() { Serial.println(val); delay(500); } void button1() { digitalWrite(LED,HIGH); val++; } void button2() { digitalWrite(LED,LOW); val--; }
После загрузки кода на плату, откройте монитор COM-порта (Ctrl+Shift+M) и посмотрите на то, как изменяются данные при нажатии на кнопки. Чаще всего все будет работать правильно, но иногда переменная будет меняться не на единицу, а сразу на два за одно нажатие. Это значит, что из-за дребезга контактов прерывание было вызвано несколько раз.
В каких-то ситуациях это не имеет большого значения. Чем лучше мы будем предотвращать дребезг контактов, там выше будет риск пропуска нажатия. Есть много способов борьбы с дребезгом контактов, как программных, так и аппаратных. Пока мы не будем останавливаться на них.
Обработка энкодера
На нашем шилде установлен инкрементальный энкодер. По своему виду он похож на переменный резистор, но работает он совершенно по-другому. Вы могли встречать инкрементальные энкодеры в регуляторах громкости с бесконечным вращением.
Мы не будем подробно описывать принцип работы энкодера. Самое главное для нас то, что при вращении на его двух выводах формируется импульсные последовательности сдвинутые по фазе. Фазовый сдвиг может быть положительным и отрицательным в зависимости от направления вращения. Для обработки энкодера необходимо один его вывод настроить на прерывания и в прерывании проверять состояние второго вывода. Если он в высоком состоянии, то значит энкодер вращали по-часовой стрелке. Если на входе низкое напряжение — то против. Рассмотрим на примере:
#define LED 11 int val = 0; void setup() { attachInterrupt(0, button1, RISING); pinMode(LED, OUTPUT); pinMode(3, INPUT); } void loop() { if(val<0) val = 0; if(val>255) val = 250; analogWrite(LED,val); } void button1() { if( digitalRead(3) == HIGH) val=val+10; else val=val-10; }
В результате работы этой программы при вращении энкодера по-часовой яркость светодиода будет увеличиваться, а при вращении против часовой — уменьшаться. Изменение яркости происходит с шагом в 10 единиц. Чтобы переменная не вышла за пределы нормальных значений в основном цикле она нормируется.
Индивидуальные задания
- Измените код первого примера так, чтобы при нажатии на кнопку светодиод менял свое состояние. То есть при каждом последующем нажатии он должен включаться или выключаться.
- Используя знания о работе с сегментным индикатором подключите его и выведите на дисплей значение переменной, изменяемой энкодером
Остальные статьи цикла можно найти здесь.
Мы будем очень рады, если вы поддержите наш ресурс и посетите магазин наших товаров shop.customelectronics.ru.
attachInterrupt () — Ссылка на Arduino
Описание
Цифровые выводы с прерываниями
Первый параметр в attachInterrupt ()
— это номер прерывания. Обычно вы должны использовать digitalPinToInterrupt (pin)
для преобразования фактического цифрового вывода в конкретный номер прерывания. Например, если вы подключаетесь к контакту 3, используйте
digitalPinToInterrupt (3)
attachInterrupt ()
.Доска | Цифровые выводы, используемые для прерываний |
---|---|
Uno, Nano, Mini, прочие 328 на основе | 2, 3 |
Uno WiFi Rev.2, нано каждые | все цифровые контакты |
Mega, Mega2560, MegaADK | 2, 3, 18, 19, 20, 21 |
Micro, Leonardo, другие на базе 32u4 | 0, 1, 2, 3, 7 |
Ноль | все цифровые контакты, кроме 4 |
Платы семейства MKR | 0, 1, 4, 5, 6, 7, 8, 9, A1, A2 |
Нано 33 IoT | 2, 3, 9, 10, 11, 13, A1, A5, A7 |
Nano 33 BLE, Nano 33 BLE Sense | |
Срок погашения | все цифровые контакты |
101 | все цифровые контакты (только контакты 2, 5, 7, 8, 10, 11, 12, 13 работают с CHANGE ) |
Примечания и предупреждения
Note
Внутри присоединенной функции delay ()
не будет работать, а значение, возвращаемое функцией millis ()
, не будет увеличиваться. Последовательные данные, полученные при использовании функции, могут быть потеряны. Вы должны объявить как
volatile
любые переменные, которые вы изменяете в присоединенной функции. См. Раздел ISR ниже для получения дополнительной информации.
Использование прерываний
Прерыванияполезны для автоматического выполнения задач в программах микроконтроллера и могут помочь решить проблемы синхронизации. Хорошие задачи для использования прерывания могут включать чтение поворотного энкодера или мониторинг пользовательского ввода.
Если вы хотите убедиться, что программа всегда улавливает импульсы от поворотного энкодера, чтобы она никогда не пропускала импульс, было бы очень сложно написать программу, которая бы делала что-то еще, потому что программе нужно было бы постоянно опрашивать сенсорные линии для энкодера, чтобы улавливать импульсы, когда они возникают.Другие датчики также имеют аналогичную динамику интерфейса, например, попытку прочитать звуковой датчик, который пытается поймать щелчок, или инфракрасный щелевой датчик (фотопрерыватель), пытающийся поймать каплю монеты. Во всех этих ситуациях использование прерывания может освободить микроконтроллер для выполнения другой работы, не пропуская при этом ввод.
О процедурах обслуживания прерывания
ISR— это особые виды функций, которые имеют некоторые уникальные ограничения, которых нет у большинства других функций. ISR не может иметь никаких параметров и не должен ничего возвращать.
Как правило, ISR должна быть как можно более короткой и быстрой. Если в вашем скетче используется несколько ISR, одновременно может выполняться только одна, остальные прерывания будут выполняться после завершения текущего в порядке, зависящем от их приоритета. millis ()
полагается на прерывания для подсчета, поэтому он никогда не будет увеличиваться внутри ISR. Поскольку delay ()
требует для работы прерываний, он не будет работать, если вызывается внутри ISR. micros ()
работает изначально, но через 1-2 мс начнет работать нестабильно. delayMicroseconds ()
не использует счетчик, поэтому будет работать как обычно.
Обычно глобальные переменные используются для передачи данных между ISR и основной программой. Чтобы убедиться, что переменные, совместно используемые ISR и основной программой, обновляются правильно, объявите их как volatile
.
Синтаксис
attachInterrupt (digitalPinToInterrupt (контакт), ISR, режим)
(рекомендуется)
attachInterrupt (прерывание, ISR, режим)
(не рекомендуется)
attachInterrupt (контакт, ISR, режим)
(не рекомендуется.Кроме того, этот синтаксис работает только на платах Arduino SAMD, Uno WiFi Rev2, Due и 101.)
Параметры
прерывание
: номер прерывания. Допустимые типы данных: int
.
pin
: номер контакта Arduino.
ISR
: ISR для вызова при возникновении прерывания; эта функция не должна принимать никаких параметров и ничего не возвращать. Эту функцию иногда называют процедурой обслуживания прерывания.
режим
: определяет, когда должно срабатывать прерывание.Четыре константы предопределены как допустимые значения:
LOW для запуска прерывания всякий раз, когда на выводе низкий уровень,
CHANGE для запуска прерывания всякий раз, когда вывод изменяет значение
RISING для срабатывания, когда вывод переходит с низкого на высокий,
ПАДЕНИЕ , когда штифт переходит от высокого к низкому.
Платы Due, Zero и MKR1000 также позволяют:
Возвращает
прерываний Arduino: 5 шагов
прерываний
Это руководство по реализации прерываний для вашего кода Arduino.Существует много полезной информации о прерываниях, но это руководство является частью серии по работе вашего Arduino с крошечным энергопотреблением. И мы имеем в виду крошечные. Мы говорим о годах работы в зависимости от приложения…. На батарейке типа «таблетка». Это то, что вам нужно знать для создания будущих встраиваемых проектов или проектов Интернета вещей. Честно говоря, просто смешно, сколько энергии тратит штатная Arduino. Используя различные приемы из этой серии руководств, вы сможете снизить энергопотребление более чем в 1000 раз! Звучит интересно? Тогда это руководство для вас! Если вам нравится это руководство или вы хотите увидеть, как мы реализовали прерывания в нашем собственном проекте, посетите наш веб-сайт:
http: // doteverything.co /
Зачем нужны прерывания?
Ответ очень прост. Вам нужны прерывания, потому что без прерываний вы не можете перевести Arduino в спящий режим и ожидать, что он снова проснется (в общем. Существуют способы выхода из спящего режима без прерываний в ограниченных ситуациях). И если вы не можете усыпить его, вы будете поглощать энергию, как марафонец, бегущий по Долине Смерти посреди лета, жрет воду. Спящий режим потребляет очень и очень мало энергии… но для его настройки требуются особые усилия.Первое, что вы должны знать, это как написать свой код, чтобы использовать прерывания, тогда вы сможете использовать более мощные методы.
ЧТО такое прерывание?
Прерывание — это несколько вещей. Но по своей сути это фрагмент кода, который вызывается при выполнении особого действия. Какое специальное действие? В основном, когда напряжение на определенном выводе изменилось. На Duemilanove / UNO есть только 2 таких пина, которые могут быть квалифицированы. Но, как видите, это очень широкое требование.Вы можете использовать что угодно, чтобы изменить напряжение на этих контактах. Это может быть пользовательский ввод с помощью кнопки, это может быть периферийное устройство, такое как датчик, это может быть другой микрочип, это может быть даже внутренний таймер. Первое, что вам нужно сделать, чтобы начать использовать прерывания, — это выяснить, как ваше приложение может быть преобразовано, чтобы иметь внешний электрический триггер. Часто другие устройства, которые вы хотите связать с вашим Arduino, будут использовать прерывания, чтобы привлечь ваше внимание. Наше предыдущее руководство «Как добавить Bluetooth в ваш проект Arduino» является прекрасным примером такого взаимодействия с внешним устройством.
Это руководство продемонстрирует, как подключить примерную схему для срабатывания прерываний. Затем мы предоставим пример кода. Надеюсь, увидев, как это делается, вы попадете в нужное настроение, чтобы понять, как применить прерывание к вашему проекту.
Скажем, меня не волнует энергопотребление. Мне все еще нужны прерывания?
Да! Даже если вы не планируете переводить процессор в спящий режим, вам могут понадобиться прерывания! Прерывания необходимы, если у вас есть приложение, зависящее от времени.Это может означать, что вам нужно, чтобы действие происходило каждые x миллисекунд, или вам нужно, чтобы действие происходило сразу после возникновения внешнего события. Если вы знакомы с основами программирования Arduino, вам может быть интересно, почему вы не можете просто использовать цикл while, чтобы проверить, когда пора выполнять свое действие. Типичное решение состоит в том, чтобы ваш цикл while «опрашивал» состояние вывода как можно быстрее. Этот метод часто срабатывает, но он ненадежен. Что произойдет, если вы запрашиваете нажатие кнопки, но кнопка нажимается и отпускается до того, как цикл while снова проверяет состояние кнопки? Вы пропустите нажатие кнопки.Что произойдет, если вы ищете очень быстрое событие, например, сигнал от датчика? Вам придется проводить опросы почти постоянно, и ваша программа не сможет делать ничего другого из-за страха пропустить критическое событие. Но с прерываниями вы на 100% гарантированно поймаете событие. Использование прерывания также избавляет вас от необходимости постоянно проверять состояние, экономя вычислительную мощность и позволяя вашему циклу while быстрее выполнять другие задачи.
Прерывание Arduino: пошаговое руководство с практическим примером
Группа инженеров по обучению
Команда опытных инженеров, делящихся знаниями со всем миром
Группа инженеров по обучению — ведущая команда в индустрии микроконтроллеров, насчитывающая более 13 Годы опыта в обучении и выполнении практических проектов.
Мы стремимся использовать весь наш практический опыт на этих курсах. Вместо поверхностных знаний — мы углубляемся в тему и даем вам точный — пошаговый план того, как приручить простые, а также сложные темы в легких и легко усваиваемых небольших видеороликах.
Эти реальные знания позволяют легко усваивать знания, и вы можете сразу же применять их в своей жизни и проектах.
Группа инженеров по обучению занимается программированием и микроконтроллерами с 2007 года .Мы участвовали во многих проектах. За эти годы мы получили хорошее представление о потребностях студентов и преподавателей. Мы стремимся делиться с вами всеми нашими коллективными знаниями. По состоянию на 2018 год мы уже обучили более 250 тыс. Студентов, из них человек.
В настоящее время у нас более 100 курсов по Удеми
Педагог и автор «Образовательной инженерии».
Ашраф — педагог, инженер мехатроники, любитель электроники и программирования, производитель . Он создает онлайн-видеокурсы на канале EduEng на YouTube (более 4 миллионов просмотров, более 20 тысяч подписчиков) и автор четырех книг о микроконтроллерах.
В качестве главного инженера по вопросам образования с 2007 года в компании Educational Engineering Team, которую он основал, миссия Ашрафа заключается в изучении новых тенденций и технологий, а также в обучении мира и его улучшении.
Педагогическая инженерия предлагает образовательные курсы и учебные курсы, статьи, уроки и онлайн-поддержку для любителей электроники, любителей программирования, любителей микроконтроллеров, студентов STEM и учителей STEM.
Эта команда также работает в качестве инженеров-фрилансеров, помогая многим студентам в их дипломных проектах и предоставляя рекомендации и консультации многим студентам на протяжении многих лет, чтобы помочь им начать свою карьеру.
Основной навык Ашрафа заключается в пошаговом объяснении сложных понятий с помощью видео и текста. Обладая более чем 11-летним опытом преподавания в высших учебных заведениях, Ашраф разработал простой, но всеобъемлющий и информативный стиль обучения, который ценят студенты со всего мира.
Его страсть к микроконтроллерам и программированию и, в частности, к миру Arduino, микроконтроллеров PIC, Rasberry Pi руководил своим личным развитием и своей работой через образовательную инженерию.
Онлайн-курсы Ashraf помогли более 250 000 человек со всего мира стать лучше и сделать отличную карьеру в отрасли.
Группа инженеров по обучению предлагает курс по
Проектирование схем, моделирование и изготовление печатных плат
Arduino, микроконтроллер PIC и Raspberry Pi
Программирование на C, Python и других языках программирования
Промышленное программирование и автоматизация ПЛК
3D-дизайн и моделирование
ESP и мир Интернета вещей
Для получения дополнительной информации воспользуйтесь ссылками на странице профиля, чтобы следить за учебной группой инженеров и последними инновациями Ashraf.
Arduino Программирование HC-SR04 с прерываниями
Как сделать ультразвуковой эхо-дальномер с Arduino и HC-SR04
Чтобы получить полную информацию о статье и проекте , подпишитесь на HDE Magazine бесплатно.
Вы когда-нибудь задумывались, как они делают датчики парковки, которые вы, кажется, найдете на всех новых автомобилях? Вы знаете, те, которые начинают пищать, когда вы приближаетесь к объекту, которого следует избегать.По мере того, как вы приближаетесь, звуковой сигнал становится все быстрее и быстрее, пока все звуковые сигналы не сливаются в один и … слишком поздно вы его ударили!
Если вы хотите иметь возможность исследовать формы сигналов, создаваемые этим и другими проектами, возьмите копию моей книги «Осциллограф звуковой карты » и создайте себе очень способное испытательное оборудование.
Я собираюсь показать вам, как сделать ультразвуковой дальномер или датчик парковки, используя Arduino Uno, модуль ультразвукового дальномера HC-SR04 и какое-то простое программное обеспечение. Чтобы упростить задачу и избежать необходимости покупать дополнительные компоненты, мы будем мигать светодиодом на плате Arduino вместо включения зуммера.
Используйте прерывания, чтобы сделать ваш код лучше и быстрее
В программном скетче, который я вам дам, используются прерывания. Не волнуйтесь, что бы вам ни говорили, ничего страшного в этом нет. Прерывания — это не волшебство, но они могут сделать ваши программы намного лучше, если вы их правильно используете.
Когда я огляделся, я обнаружил, что во всех примерах использования HC-SR04 с Arduino использовались скетчи, которые живут исключительно в основном цикле () скетча. Это нормально, если все, что вы хотите сделать, это доказать, что ультразвуковой модуль работает, но это не очень удобно, если вы ожидаете, что ваше программное обеспечение будет делать что-то умное с информацией с датчика. Помещение всего кода в основной цикл затрудняет планирование ваших измерений и приводит к значительным задержкам в доступном вам времени обработки.Я думал, что буду другим и покажу вам лучший способ использования прерываний.
Если вы хотите узнать больше об использовании прерываний на Arduino, взгляните на этот пример прерывания таймера.
Как работает HC-SR04
Модуль HC-SR04 имеет 4 контакта:
Для работы модуля требуется питание 5 В, поэтому подключите контакт заземления к одному из контактов заземления на Arduino, а VCC — к контакту 5 В на Arduino. Это было просто.
Когда HC-SR04 получает короткий импульс на входе триггера, модуль начинает измерение.Сначала он передает короткий ультразвуковой импульс, а затем прослушивает эхо. Импульс запуска должен быть не менее 10 мкс и доставляться с вывода 2 на Arduino Uno.
Когда HC-SR04 передает ультразвуковой пакет импульсов, напряжение сигнала на выводе Echo становится высоким. Он будет оставаться высоким до 25 мс в зависимости от расстояния от объекта. Если в поле зрения нет объекта, то эхо-сигнал будет оставаться высоким в течение 38 мс. Итак, все, что вам нужно сделать, это измерить время, в течение которого эхо-сигнал является высоким.Исходя из этого, вместе со скоростью звука, вы можете рассчитать расстояние до объекта.
Вот где, на мой взгляд, большинство примеров использования этого датчика терпят неудачу. Все они полагаются на функцию синхронизации pulseIn () для измерения длительности эхо-импульса. Чтобы сделать это точно в основном цикле, он не может ничего делать, пока не завершится импульс, что эффективно тратит до 38 мс на каждое измерение, ожидая изменения состояния вывода. Если вы делаете это 5 раз в секунду, то это 190 мс или 19% времени, потраченного впустую на ожидание изменения сигналов.Вы можете уменьшить эти накладные расходы как минимум в 10 раз, используя прерывания для обработки измерения импульсов.
Вы также можете использовать одно из прерываний таймера на Arduino, чтобы гарантировать, что запланированные измерения выполняются, когда вы хотите, чтобы они выполнялись, независимо от того, что делает код в основном цикле. Этого было бы очень трудно добиться, если бы измерения производились в основном контуре.
ADXL362 + Arduino: Использование прерываний для реализации режима сна, активируемого движением — Документы — Инерционные датчики MEMS
В этом руководстве подробно описано, как использовать ADXL362 для перевода Arduino в состояние низкого энергопотребления, когда цепь не движется, а затем снова включить ее при обнаружении движения.
Прежде чем начать:
Если вы еще этого не сделали, убедитесь, что вы можете успешно пройти обучение ADXL362 Arduino How-To, которое проведет вас через подключение, установку библиотеки ADXL362 Arduino и загрузку / выполнение примера «ADXL362_SimpleRead». Любые нерешенные проблемы, возникающие при работе с первым руководством, вызовут у вас проблемы с этим.
Загрузите библиотеку Arduino малой мощности Rocket Scream:
Я уверен, что есть много хороших примеров / библиотек для перевода вашего Arduino в спящий режим, но мне повезло с библиотекой Low Power Arduino от Rocket Scream — загрузите zip-файл здесь.
В своих примерах я переименовал каталог библиотеки верхнего уровня «Low-Power» в «LowPower». ( Моей среде не нравится дефис … Я не уверен, что это проблема ОС, или, возможно, дефис работал нормально в более старой версии программного обеспечения Arduino? В любом случае … удалите дефис, чтобы заставить библиотеку работать с моим примером кода. )
Помните уроки, извлеченные при установке библиотеки ADXL362 Arduino из предыдущего руководства. Папка библиотеки «LowPower» должна быть помещена в папку
Структура каталогов ваших библиотек должна выглядеть, как показано на рисунке ниже. Перейдите к ADXL362 Arduino How-To для более подробного описания того, как установить библиотеки Arduino.
Если она установлена успешно, библиотека Rocket Scream LowPower появится в Sketch -> Import Library -> LowPower (см. Изображение ниже):
Добавить прерывание соединения между ADXL362 и Arduino:
В этом примере сна используется вывод INT1 ADXL362 и прерывание 0 (цифровой вывод 2) на Arduino.Итак, добавив к соединениям, которые были выполнены в предыдущем руководстве, добавьте провод для соединения вывода INT1 на ADXL362 с выводом DP2 на Arduino. См. Изображение ниже для иллюстрации необходимых соединений:
Дополнительную информацию о прерываниях Arduino можно найти на http://arduino.cc/en/Reference/AttachInterrupt
Загрузите эскиз ADXL362_MotionActivatedSleep в Arduino:
После выполнения описанных выше шагов загрузка примера ADXL362_MotionActivatedSleep в Arduino должна быть простой и понятной. Для примера сна, активированного движением, необходимо правильно установить библиотеку LowPower.
Откройте пример, щелкнув Файл -> Примеры -> ADXL362 -> ADXL362_MotionActivatedSleep, как показано на изображении ниже:
Убедитесь, что у вас выбраны правильная плата и последовательный порт (см. Предыдущее руководство), и нажмите кнопку Загрузить , как показано ниже:
Наблюдать за активностью бодрствования / сна на последовательном мониторе:
Откройте монитор последовательного порта и посмотрите, как ваша схема засыпает и просыпается, в зависимости от того, трясется она или перемещается.
В примере кода схема остается включенной в течение двух секунд после того, как она была неподвижна, а затем отключается. Время включения / выключения, а также порог движения можно изменить, настроив параметры прерывания активности / бездействия, которые я установил с помощью функций setupDCActivityInterrupt и setupDCInactivityInterrupt .
Или, наблюдайте активность бодрствования / сна с помощью мультиметра:
Чтобы измерить общий ток, я отключил Pro Mini Arduino от моего ПК и FTDI Basic, а затем подключил мультиметр последовательно с 4.Питание от аккумулятора 5 В — я подключил аккумулятор к выводу RAW на моем Pro Mini Arduino. Мое быстрое наблюдение заключалось в том, что общая схема потребляет чуть более 4 мА в бодрствующем состоянии и примерно 270 мкА во время сна.
Это руководство не включает подробное исследование того, какие части схемы потребляют какую часть общей рассеиваемой мощности. Но в этом примере ADXL362 потребляет менее 3 мкА во включенном состоянии и 300 нА, когда схема находится в «спящем». (Потребление тока ADXL362 незначительно зависит от скорости передачи данных на выходе, входного напряжения и режима) Таким образом, большая часть общего тока в активном или спящем режиме потребляется Pro Mini Arduino.Я предоставлю читателю возможность провести собственные эксперименты относительно энергопотребления.
Изображения ниже — Потребление тока в то время как схема Pro Mini Arduino + ADXL362 находится в «активном» и «спящем» состоянии.
А для еще более низкого энергопотребления используйте Rocket Scream Ultra Mini Arduino-совместимый
.Итак, насколько я люблю, люблю, люблю Pro Mini, я не был полностью удовлетворен током сна всей моей схемы. И, вероятно, я мог бы взломать свой Pro Mini, чтобы внести несколько улучшений (на ум приходит удаление резистора 10K через VCC), вместо этого я решил приобрести плату, совместимую с Rocket Scream Mini Ultra Arduino, тем более что я использую их удобные Библиотека Arduino для спящих режимов.
Используя Mini Ultra, я смог снизить ток сна примерно до 2uA! Вот это больше нравится!
Изображение ниже — Потребление тока при «спящем» режиме Mini Ultra + ADXL362.
Что мне делать с моей Arduino, активируемой движением?
У меня есть несколько идей … следите за обновлениями!
Hardware University
Прерывание — это сигнал, который сообщает процессору немедленно остановить его текущую задачу и выполнить другую обработку с высоким приоритетом.Эта высокоприоритетная обработка называется обработкой прерывания / процедурой обслуживания прерывания. Почти каждое электронное устройство сталкивается со сценарием, когда прерывание должно «прервать» обычный процесс и заняться важной задачей. Таким образом, технически прерывания — это механизм, с помощью которого ввод-вывод или инструкция могут приостановить нормальное выполнение процессора и получить обслуживание, поскольку оно имеет высокий приоритет. Как только эта задача завершена, она возвращается к выполнению первоначальной задачи.
Как работают прерывания?
Прерывания вызывают внешнюю функцию, которая обычно называется процедурой обслуживания прерывания (ISR), так что при возникновении внешнего прерывания процессор сначала выполняет код, присутствующий в ISR, а затем возвращается в состояние, в котором он оставил нормальное выполнение.
ISR имеет следующий синтаксис в Arduino: attachInterrupt (digitalPinToInterrupt (вывод), ISR, режим)
digitalPinToInterrupt (вывод ): В Arduino Uno для прерывания используются выводы 2 и 3.Здесь вам нужно указать входной контакт, который используется для внешнего прерывания.
ISR : это функция, которая вызывается при выполнении внешнего прерывания.
Mode : Тип перехода для запуска прерывания, например, падение, рост и т. Д.
- Rising — Запуск прерывания, когда вывод переходит с LOW на HIGH.
- Falling — Для запуска прерывания, когда вывод переходит с HIGH в LOW.
- Change — Для запуска прерывания, когда вывод переходит из LOW в HIGH или из HIGH в LOW.
- LOW — Для запуска прерывания, когда вывод находится в состоянии LOW.
Типы прерываний
Существует два типа прерываний:
- Аппаратные прерывания — они возникают в ответ на внешнее событие, такое как высокий или низкий уровень вывода внешнего прерывания.
- Программные прерывания — они возникают в ответ на инструкцию, отправленную из программного обеспечения. Прерывания от таймера — это программные прерывания.
Теперь давайте посмотрим, как использовать прерывания Arduino, используя функции, доступные в Arduino IDE.Мы будем использовать функцию подключения прерывания, чтобы инициализировать прерывание и указать контакт Arudino, который будет использоваться для этого. Функция принимает на вход два аргумента: один — это вывод, который используется для запуска внешнего прерывания, а второй аргумент — это имя функции, которую вы хотите вызывать при каждом прерывании. Последний аргумент — это режим прерывания, который вы используете.
Мы будем использовать пример мигания светодиода, чтобы понять, как работает функция прерывания.Выполните подключения в соответствии со следующей схемой:
Необходимые компоненты:
- Arduino Uno
- Макетная плата
- Перемычки
- 2 светодиода
- Кнопка
- Резистор 1K
После завершения соединений вы можете использовать следующий эскиз и загрузить его на Arduino.
Светодиод подключен к контакту 13, а кнопка — к контакту прерывания 2.Итак, когда кнопка нажата, срабатывает прерывание и происходит изменение состояния. Но если он не поднимается, изменений не происходит, и цикл продолжается. Функция ISR называется «мигание», а режим установлен на «изменение», так что всякий раз, когда есть подъем или спад, срабатывает прерывание. ISR используется для изменения состояния светодиода, поэтому всякий раз, когда нажимается кнопка или вызывается прерывание, светодиод светится.
В этом блоге мы узнали о прерываниях, их различных режимах, типах и функциях, которые требуются для их запуска.Мы также видели пример, чтобы понять, как запускается прерывание и как именно оно работает.
Проблема (и решения) с прерываниями Arduino
Если вы когда-либо пытались перенести проект Arduino, который использует прерывания с одного типа платы на другой, вы, вероятно, испытывали разочарование, это включает пример кода во всем RCArduino.В следующем посте исследуются различия в прерываниях между популярными платами Arduino UNO, Micro, Mega, Mini и Leonardo.Основываясь на этой информации, мы можем модифицировать скетчи для работы на полном диапазоне 8-битных Arduinos.
8-битные платы Arduino основаны на одном из трех связанных чипов —
ATMega328 — UNO и Mini
ATMega32u4 — Leonardo и Micro
ATMega2560 — Mega
Каждый из этих чипов поддерживает два типа прерываний —
10004 ) Внешние прерыванияЭто гибкие, простые в использовании прерывания, которые могут запускаться при нарастании, падении или изменении сигналов.Недостатком является то, что для каждого типа микросхемы доступно ограниченное количество.
Если мы хотим получить доступ к большему количеству прерываний, нам нужно взглянуть на следующий тип —
2) Прерывания смены контактов
Базовый чип в вашем Arduino поддерживает второй тип прерываний, однако эти прерывания напрямую не поддерживаются Arduino и необходимо получить доступ через дополнительную библиотеку.
Различия во внешних прерываниях
Внешние прерывания связаны с определенными цифровыми выводами на каждом типе микросхемы, в следующей таблице, взятой со справочной страницы attachInterrupt, перечислены доступные внешние прерывания и связанный вывод Arduino на каждой микросхеме —