пятница, 15 марта 2013 г.

Прерывания


Использование прерываний

Прерывания обычно используют для задач, которые должны быть выполнены автоматически при наступление какого либо внешнего воздействия. Например, считывание значения энкодера (датчика угла) или реакция на действия пользователя.
Так, если вы хотите считывать значения энкодера без использования прерываний, то написать программу, которая бы не пропускала ни одного импульса, практически невозможно, такая программа должна будет практически все время считывать значения с датчика, чтобы не пропусть импульс. На другие операции просто не останется процессорного времени. Это же относится и к другим датчикам, выдающим короткий импульс. В таких задачах использования внешних прерываний позволяет разгрузить процессор для других операций и не пропустить ожидаемый сигнал. (С) Оф сайт ардуино

Большинство контроллеров Arduino умеют обрабатывать до двух внешних прерываний. Но есть и контроллеры с более развитыми возможностями:
Boardint.0int.1int.2int.3int.4int.5
Uno, Ethernet23
Mega25602321201918
Leonardo3201
Due(see below)
The Arduino Due board has powerful interrupt capabilities that allows you to attach an interrupt function on all available pins. You can directly specify the pin number in attachInterrupt(). 

Для того, чтобы воспользоваться прерыванием, нужно в разделе setup выполнить команду вида
attachInterrupt(0, blink, CHANGE);
0 - 0е прерывание(см. таблицу выше), в моем случае подключаюсь на 3ю DIGITAL ногу
blink - имя процедуры, где будет выполняться код прерывания
CHANGE - режим обработки прерывания.

Допустимо использование следующих констант:
LOW вызывает прерывание, когда на порту LOW
CHANGE прерывание вызывается при смене значения на порту, с LOW на HIGH и наоборот
RISING прерывание вызывается только при смене значения на порту с LOW на HIGH
FALLING прерывание вызывается только при смене значения на порту с HIGH на LOW

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

Код:

int btnPin = 3;
int ledPin = 13;
// Ключевое слово volatile было разработано для отключения компиляторной оптимизации,
// которая могла бы привести к неверной работе кода в мультипоточном окружении.
// К примеру: если переменная базового типа объявлена как volatile, то компилятору не разрешается кэшировать ее в регистре -
// распостраненная оптимизация, которая может привести к непредсказуемым результатам,
// если данная переменная используется в нескольких потоках.
volatile boolean signal = false;

void setup()
{
  // INPUT_PULLUP - Притягивает вывод к +5V, чтобы зафиксировать стабильный сигнал на выводе
  // В разомкнутом состоянии кнопки фиксируем 1
  pinMode(btnPin, INPUT_PULLUP);
  // Цепляем прерывание на ногу 3(int.0), в моем случае(плата - Leonardo)
  // Режим прерывания - по фронту на спад (когда 1 переходит в 0),
  // используем этот режим, т.к. при замыкании кнопки вывод притягивается к земле
  attachInterrupt(0, led, FALLING);
}

void loop()
{
    // Мигаем встроенным диодом
    digitalWrite(ledPin, HIGH);
    delay(500);
    digitalWrite(ledPin, LOW);
    delay(500);
}

void led()
{
  // Читаем сигнал с кнопки. Вывод притянут к +5
  // Таким образом в разомкнутом состоянии фиксируем 1, в замкнутом - 0
  // Инвертируем сигнал с 0 в 1 и наоборот
  signal = !digitalRead(btnPin);
  // Пока кнопка нажата, зажигаем диод,
  // отпускаем кнопку - возвращаемся в цикл loop
  while (signal == HIGH)
  {
    digitalWrite(ledPin, signal);
    signal = !digitalRead(btnPin);
  }
}

Rover 5


Собрал потихоньку вот такой комплект: Arduino Leonardo + Rover 5(4 мотора 4 энкодера) + 2A Motor Shield.

[IMG]

[IMG]
Подключил, все заработало, не с первого раза, конечно =) Моторы крутятся кто в лес, кто по дрова... один назад, другие вперед. Сняв гусеницы и изменив полярность на одном из моторов удалось синхронизировать. 

Вот что получилось собрать за вечер наспех(прохлопал, что у телеги нет крышки для крепления электроники, придется где то дозаказывать):
[IMG]

[IMG]

Ссылки:
Тележка: http://www.dfrobot.com/index.php?route=product/product&filter_name=rover 5&product_id=470#.UUDv9qWYXjA

UPD 6 апреля:
Приехали аккумуляторы, сенсоры, и проч.








Arduino Shield List

Список плат расширения для Arduino, какие пины они использут и проч инфа. Удобно смотреть совместимость плат расширения друг с другом

Смотрим тут

INPUT_PULLUP



Наткнулся тут на механизм неявного управления подтягивающими резисторами. Нужно указать в функции pinMode режим INPUT_PULLUP. 

Подтягивающий резистор — резистор, включенный между проводником, по которому распространяется электрический сигнал, и питанием, либо между проводником и землей.
Подтягивающий резистор нужен, чтобы гарантировать на логическом входе, с которым соединен проводник, высокий (в первом случае) либо низкий (во втором случае) уровень в случаях:
  • проводник не соединен с логическим выходом
  • присоединённый логический выход находится в высокоимпедансном состоянии.
  • когда разомкнут ключевой элемент на присоединённом логическом выходе, который устроен, как открытый вывод ключевого элемента. Ключевым элементом может быть полевой или биполярный транзистор, а открытым выводом — коллектор, эммитер, сток или исток.

Подтягивающий резистор образует цепь, обеспечивающую подтяжку сигнала к питанию либо к земле. В первом случае подтяжка называется подтяжкой к питанию, во втором — подтяжкой к земле.
(C) Wiki

На arduino.ru на текущий момент информации об этом режиме нет, зато есть на оф сайте arduino.cc

Pins Configured as INPUT_PULLUP

The Atmega chip on the Arduino has internal pull-up resistors (resistors that connect to power internally) that you can access. If you prefer to use these instead of external pull-down resistors, you can use the INPUT_PULLUP argument in pinMode(). This effectively inverts the behavior, where HIGH means the sensor is off, and LOW means the sensor is on. See the Input Pullup Serial tutorial for an example of this in use.
Подтягивающие (нагрузочные) резисторы
Если на порт ввода не поступает сигнал, то в данном случае рекомендуется задать порту известное состояние. Это делается добавлением подтягивающих резисторов 10 кОм, подключающих вход либо к +5 В (подтягивающие к питанию резисторы), либо к земле (подтягивающие к земле резисторы).
Микроконтроллер Atmega имеет программируемые встроенные подтягивающие к питанию резисторы 20 кОм. 
Пример кода(При нажатии кнопки включаем встроенный светодиод на выводе 13):


int btnPin = 7;
int ledPin = 13;
boolean signal = false;

void setup()
{
  pinMode(btnPin, INPUT_PULLUP);
}

void loop()
{
  signal = digitalRead(btnPin);
  signal = !signal;
  delay(31);
  digitalWrite(ledPin, signal);
}

Что нужно для офисного айтишника, который паяльник видел только на картинке? (C) Xakep


Наткнулся на хабре на инфу об Arduino, решил сам попробовать что нибудь собрать и написать для этого программу

Что такое Arduino можно почитать тут или тут

Миниметеостанция




Использовались детали:
Сам леонардо
http://amperka.ru/collection/boards/product/arduino-leonardo
Тройка шилд, для удобного подключения датчиков. Всегда доступны питание, земля и сигнал
http://amperka.ru/collection/arduino-shield/product/arduino-troyka-shield
Мини доска для прототипирования
http://amperka.ru/collection/proto/product/breadboard-mini
Провода папа-мама
http://amperka.ru/collection/cables-wires/product/wire-fm
Провода папа-папа
http://amperka.ru/collection/cables-wires/product/wire-mm
Датчик температуры и влажности DHT11
http://amperka.ru/collection/sensors/product/temperature-humidity-sensor-dht11
Экран 20x4
http://amperka.ru/collection/display/product/text-lcd-20x4