Что такое gpio arduino

Распиновка arduino nano

Начнем с пинов, которых больше всего, это GPIO, с англ. General Purpose Input-Output, входы-выходы общего назначения, на плате они подписаны как D0D13 и A0A5. По картинке распиновки они называются PD*, PB* и PC*, (вместо звёздочки – цифра) отмечены тёмно-бежевым цветом. Почему “официально” они называются PD/PB/PC? Потому что пины объединены в пОрты по несколько штук (не более 8), на примере Нано есть три порта: D, B и C, соответственно пины так и подписаны: PD3 – Port D 3 – третий выход порта D. Это цифровые пины, способные выдавать логический сигнал (0 или VCC) и считывать такой же логический сигнал. VCC это напряжение питания микроконтроллера, при обычном использовании обычной платы Ардуино это 5 Вольт, соответственно это 5 вольтовая логика: 0V – сигнал низкого уровня (LOW), 5V – высокого уровня (HIGH). Напряжение питания микроконтроллера играет очень большую роль, об этом мы ещё поговорим. GPIO имеют несколько режимов работы: вход (INPUT), выход (OUTPUT) и вход с подтяжкой к питанию встроенным в МК резистором на 20 кОм (INPUT_PULLUP). Подробнее о режимах поговорим в отдельном уроке.

Все GPIO пины в режиме входа могут принять сигнал с напряжением от 0 до 5 вольт (на самом деле до 5.5 вольт, согласно даташиту на микроконтроллер). Отрицательное напряжение или напряжение, превышающее 5.5 Вольт приведёт к выходу пина или даже самого МК из строя. Напряжение 0-2.5 вольта считается низким уровнем (LOW), 2.5-5.5 – высоким уровнем (HIGH). Если GPIO никуда не подключен, т.е. “висит в воздухе”, он принимает случайное напряжение, возникающее из за наводок от сети (провода 220в в стенах) и электромагнитных волн на разных частотах, которыми пронизан современный мир.

GPIO в режиме выхода (OUTPUT) являются транзисторными выходами микроконтроллера и могут выдать напряжение 0 или VCC (напряжение питания МК). Стоит отметить, что микроконтроллер – логическое, а не силовое устройство, его выходы рассчитаны на подачу сигналов другим железкам, а не на прямое их питание. Максимальный ток, который можно снять с GPIO выхода ардуино – 40 мА. Если попытаться снять больше – пин выйдет из строя (выгорит выходной транзистор и всё). Что такое 40 мА? Обычный 5мм одноцветный светодиод потребляет 20 мА, и это практически единственное, что можно питать напрямую от Ардуино. Также не стоит забывать о максимальном токе со всех пинов, он ограничен 200 мА, то есть не более 10 светодиодов можно запитать от платы на полную яркость…

Интерфейсы

Большинство GPIO имеют дополнительные возможности, так как к ним подключены выводы с других систем микроконтроллера, с ними вы уже знакомы из предыдущего урока:

  • ADC (АЦП, аналогово-цифровой преобразователь) – зелёные подписи ADC* на распиновке
  • UART (интерфейс связи) – голубые TXD и RXD на распиновке
  • Выводы таймеров, они же ШИМ пины – светло-фиолетовые OC*A и OC*B, где * номер таймера
  • SPI (интерфейс связи) – голубые SS, MOSI, MISO, SCK
  • I2C (интерфейс связи) – голубые SDA и SCL
  • INT (аппаратные прерывания) – розовые INT0 и INT1, а также PCINT* – PinChangeInterrupt

Если про интерфейсы мы уже говорили, то АЦП, прерывания и выводы таймеров ещё не затрагивали.

ADC пины (с АЦП) помечены на плате буквой A. Да, пины A6 и A7 на плате Нано имеют только вход на АЦП и не являются GPIO пинами! АЦП – аналогово-цифровой преобразователь, позволяет измерять напряжение от 0 до VCC (напряжения питания МК) или опорного напряжения. На большинстве плат Ардуино разрядность АЦП составляет 10 бит (2^10 = 1024), что означает следующее: напряжение от 0 до опорного преобразуется в цифровую величину от 0 до 1023 (1024-1 так как отсчёт идёт с нуля). Опорное напряжение играет очень большую роль: при опорных 5V один шаг измерения АЦП составит 4.9 милливольта (0.00488 В), а при опорных 1.1В – 1.1 мВ (0.00107 В). Вся суть в точности, я думаю вы поняли. Если опорное напряжение установлено ниже напряжения питания МК, то оцифровывая напряжение выше опорного мы получим 1023. Подавая на АЦП напряжение выше 5.5 Вольт получим выгоревший порт. Подавать отрицательное напряжение также не рекомендуется. На ардуино есть несколько режимов опорного напряжения: оно может быть равно VCC (напряжению питания), 1.1V (от встроенного в МК стабилизатора) или получать значение с внешнего источника в пин Aref, таким образом можно настроить нужный диапазон и получить нужную точность. У других моделей Ардуино (например у Меги) есть и другие встроенные режимы. Опорное напряжение рекомендуется заводить на плату через резистор, например на 1 кОм. Для измерения напряжений выше 5.5 вольт необходимо использовать делитель напряжения на резисторах.

Таймеры (ШИМ)

Выводы таймеров: в микроконтроллере, помимо обычного вычислительного ядра, с которым мы работаем, находятся также “хардварные” счётчики, работающие параллельно со всем остальным железом. Эти счётчики также называют таймерами, хотя к таймерам они не имеют никакого отношения: счётчики буквально считают количество тиков, которые делает кварцевый генератор, задающий частоту работы для всей системы. Зная частоту генератора (обычно 16 МГц) можно с очень высокой точностью определять интервалы времени и делать что-то на этой основе. Какой нам прок от этих счётчиков? “Из коробки” под названием Arduino IDE мы имеем несколько готовых, основанных на таймерах инструментов (функции времени, задержек, измерения длин импульсов и другие).

В этой статье речь идёт о пинах и выходах, о них и поговорим: у каждого счётчика есть два выхода на GPIO. У нано (у МК ATmega328p) три счётчика, соответственно 6 выходов. Одной из возможностей счётчиков является генерация ШИМ сигнала, который и выводится на соответствующие GPIO. Для нано это D пины 5 и 6 (счётчик 0), 9 и 10 (таймер 1) и 3 и 11 (таймер 2). ШИМ сигналу посвящен отдельный урок, сейчас просто запомним, что с его помощью можно управлять яркостью светодиодов, скоростью вращения моторчиков, мощностью нагрева спиралей и многим другим. Но нужно помнить, что ограничение по току в 40 мА никуда не делось и питать от пинов ничего мощнее светодиодов нельзя.

Прерывания

Аппаратные прерывания позволяют процессору мгновенно переключаться на некий блок действий (функция обработчик прерывания) при изменении уровня сигнала на пине. Подробнее об этом, а также о PinChangeInterrupts поговорим в другом уроке.

Другие пины

  • Пин 3.3V может быть использован для питания маломощных датчиков и модулей: максимальный ток, который можно снять с пина 3.3V составляет 150 мА, что с головой хватает для любых датчиков и модулей, кроме пожалуй радиомодулей nrf25L01.
  • Пины GND – земля питания, все GND связаны между собой
  • Пин 5V – питание от источника с напряжением до 5.5V (подробнее о питании смотри в следующем уроке)
  • Пин Vin – питание от источника с напряжением 7-15V (подробнее о питании смотри в следующем уроке)
  • RST – перезагрузка МК. Также этот пин выведен на кнопку

Материалы взяты с сайта: alexgyver.ru/

Аналоговые и цифровые порты

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

Цифровой сигнал передается в виде единиц и нулей, для компьютеров и цифровой техники это проще реализовать (есть сигнал или нет сигнала). Для оперативной памяти в компьютерах используют конденсаторы, один заряженный конденсатор — 1 бит. На флеш-памяти используют транзисторы с плавающим затвором.

С появлением компьютеров аналоговые сигналы стали переводить в цифру, поскольку аналоговый сигнал подвержен искажениям и затуханию при передаче или записи. Наглядно продемонстрировать разницу между аналоговым и цифровым сигналом поможет картинка, где изображен процесс квантования — разбиение непрерывной величины на конечное число интервалов (перевод аналогового сигнала в цифру).

Другими словами

Получается что аналоговым сигналом можно передать и принимать диапозон значений а вот цифровым только да / нет (HIGHT/LOW). Отправляются данные командой DigitalWrite, Принимаются DigitalRead.

Что же касается аналогового то тут можно получить данные от 0 до 1023 и передать данные от 0 до 255. Отправляются данные командой AnalogWrite, Принимаются AnalogRead.

AnalogWrite работает только на пинах 3,5,6,9,10,11, на картинке распиновки в начале статьи они показаны кривой линией которая отходит от платы к пояснению пина.

Источник

Что такое gpio arduino

Всем привет это второй урок об Arduino. В первом уроке мы говорили об азах программирования Arduino. Сегодня мы будем говорить о GPIO у Arduino и PWM сигналах. Мы будем использовать кнопки и управлять яркостью светодиода с помощью PWM сигнала. Также мы будем использовать функции в среде программирования Arduino.

Для начала давайте попробуем управлять светодиодом с помощью кнопки.

Нам понадобятся:

  1. Резистор номиналом около 100-400 ом. Для ограничения тока, который идет через светодиод, чтобы не сжечь его.
  2. Резистор номиналом около 10 ком. Для подтягивания логических уровней на входе Arduino. Если его не ставить то наша кнопка будет работать очень нестабильно, т.к. на входе Arduino вместо полезного сигнала будут помехи.
  3. СветодиодАЛ307 или любой который вам понравиться. Собственно его мы и будем зажигать.
  4. Тактовая кнопка IT-1102 или любая другая. Будет использоваться для управления светодиодом.

Теперь настало время собрать простую схему, можно это сделать используя отладочную плату BreadBoard или при помощи паяльника и проводов.

Схема подключения светодиода и кнопки к Arduino

Светодиод подключен через токоограничительный резистор 200 ом к 10 выходу Arduino, номинал резистора можно поставить 200 ом — 500 ом, от этого будет меняться ток, идущий через светодиод и соответственно его яркость. Если вы подключите светодиод напрямую то это закончится плохо, через светодиод пойдет большой ток, в результате чего либо сам светодиод либо выход Arduino выйдет из строя. Необходимо также учесть что светодиод, это как никак диод, у него есть полярность!

Если вы подключите светодиод неправильно, он не загорится, потому что ток через него не пойдет (он просто будет закрыт). Определить полярность светодиода легко, короткая нога светодиода это минус (т.е. ноль или GND), а длинная это +.

Кнопка подключена таким образом, что в момент нажатия она скоммутирует на вход №10 Arduino +5 вольт что соответствует логической единице цифрового входа Arduino. В момент когда кнопка не нажата наш резистор номиналом 10 ком, притянет вход Arduino к GND (т.е. к нулю) и на входе Arduino стабильно будет логический ноль. Если вы не будете использовать этот подтягивающий резистор, то вполне возможна ситуация, когда будут происходить ложные срабатывания, это связанно с тем что на входе Arduino будет отсутствовать подтягивающий резистор и соответственно напряжение не будет равно нулю, оно будет хаотично меняться, что влечет за собой появление ложной логической единицы на входе Arduino.

Итак, настало время написать программу для Arduino. Для начала давайте будем держать включенным светодиод до тех пор, пока нажата кнопка. Конечно решить такую задачу очень легко без микроконтроллера, но ведь нам нужно с чего-то начать. Открываем среду программирования Arduino (как программировать Arduino подробно изложено в уроке №1) и начинаем писать код:

/*
Урок 2. GPIO, Кнопки и PWM у Arduino
Мигаем светодиодом.
Будем держать включенным светодиод до тех пор, пока нажата кнопка.
Этот демонстрационный код был скачан с сайта www.trunagol.ru
*/

int switchPin = 10; // Для удобства задаем имя «switchPin» для 10 вывода
int ledPin = 13; // Для удобства задаем имя «ledPin» для 13 вывода

void setup() // Блок «Setup» запускается только 1 раз при запуске Arduino, он нужен для инициализации.
<
pinMode(switchPin, INPUT); // Конфигурируем 10 вывод Arduino на вход. Т.к. мы будем считывать состояние кнопки.
pinMode(ledPin, OUTPUT); // Конфигурируем 13 вывод Arduino на выход. С помощью него мы будем включать светодиод.
>

void loop() // Блок «loop» это цикл, т.е. код который работает раз за разом бесконечно
<
if (digitalRead(switchPin) == HIGH) // Если кнопка нажата, наша переменная switchPin будет иметь значение HIGH (логическую 1) и выполниться код на след. строке
<
digitalWrite(ledPin, HIGH); // Зажигаем светодиод, выставив логическую 1 (уровень HIGH) на выходе 13
>
else // Если кнопка не нажата выполниться код идущий ниже.
<
digitalWrite(ledPin, LOW); // Выключаем светодиод
>
>

Ну что работает?! :)

А теперь давайте усложним задачу, сделаем так, чтобы при нажатии кнопки светодиод загорался и горел до тех пор пока не нажмем еще раз и так по кругу.

Наш код для этих целей будет выглядеть так:

/*
Урок 2. GPIO, Кнопки и PWM у Arduino
Включаем/выключаем светодиод.
Будем включать светодиод после нажатия кнопки и выключать после второго нажатия.
Этот демонстрационный код был скачан с сайта www.trunagol.ru
*/

int switchPin = 10; // Для удобства задаем имя «switchPin» для 10 вывода
int ledPin = 13; // Для удобства задаем имя «ledPin» для 13 вывода
boolean lastButton = LOW; // В этой переменной мы будем хранить состояние кнопки во время предыдущей обработки нашего цикла, а также установим его в ноль.
boolean ledOn = false; // В этой переменной мы будем хранить состояние светодиода, чтобы мы могли переключать его
void setup() // Блок «Setup» запускается только 1 раз при запуске Arduino, он нужен для инициализации.
<
pinMode(switchPin, INPUT); // Конфигурируем 10 вывод Arduino на вход. Т.к. мы будем считывать состояние кнопки.
pinMode(ledPin, OUTPUT); // Конфигурируем 13 вывод Arduino на выход. С помощью него мы будем включать светодиод.
>

void loop() // Блок «loop» это цикл, т.е. код который работает раз за разом бесконечно
<
if (digitalRead(switchPin) == HIGH && lastButton == LOW) // Если кнопка нажата, и последнее состояние кнопки было «не нажата», тогда выполняем следующий код
<
ledOn = !ledOn; // Меняем значение ledOn на противоположное
lastButton = HIGH; // Меняем значение lastButton на логическую единицу
>
else
<
lastButton = digitalRead(switchPin); // Устанавливаем в переменную lastButton такое же значение как в переменной switchPin
>
digitalWrite(ledPin, ledOn); // Собственно эта строчка будет зажигать и гасить светодиод
>

Ну как работает?! Хмм… Странно.. Иногда у нас все срабатывает как ожидается, а иногда нет… Почему так могло произойти? Всё дело в эффекте «дребезга контактов»:

Как вы видите на этой осциллограмме на самом деле наша кнопка срабатывает не идеально… И если мы с большой частотой опрашиваем кнопку, то в переходный момент мы можем считать как единицу так и ноль. Лучше было бы использовать аппаратные решения проблемы, но речь сейчас идет о нашем коде. Чтобы избежать этого дребезга нам придется доработать программу и просто ввести задержку по времени:

/*
Урок 2. GPIO, Кнопки и PWM у Arduino
Включаем/выключаем светодиод.
Будем включать светодиод после нажатия кнопки и выключать после второго нажатия и устраняем дребезг кнопок.
Этот демонстрационный код был скачан с сайта www.trunagol.ru

int switchPin = 10; // Для удобства задаем имя «switchPin» для 10 вывода
int ledPin = 13; // Для удобства задаем имя «ledPin» для 13 вывода
boolean lastButton = LOW; // В этой переменной мы будем хранить состояние кнопки во время предыдущей обработки нашего цикла, а также установим его в ноль.
boolean ledOn = false; // В этой переменной мы будем хранить состояние светодиода, чтобы мы могли переключать его
boolean currentButton = LOW; // Переменная для нашей функции debounce

void setup() // Блок «Setup» запускается только 1 раз при запуске Arduino, он нужен для инициализации.
<
pinMode(switchPin, INPUT); // Конфигурируем 10 вывод Arduino на вход. Т.к. мы будем считывать состояние кнопки.
pinMode(ledPin, OUTPUT); // Конфигурируем 13 вывод Arduino на выход. С помощью него мы будем включать светодиод.
>

boolean debounce(boolean last) //функция для устранения дребезга контактов кнопки, будет возвращать предыдущее её состояние
<
boolean current = digitalRead(switchPin); // Пишем в current текущее состояние кнопки
if (last != current) // Проверяем изменилось ли состояние кнопки
<
delay(5); // Если да, делаем задержку 5 миллисекунд, для того чтобы кнопка перестала «дребезжать»
current = digitalRead(switchPin); // Считываем значение кнопки после паузы, сейчас дребезг уже должен пройти
>
return current; // возвращаем стабильное значение кнопки
>

void loop() // Блок «loop» это цикл, т.е. код который работает раз за разом бесконечно

<
currentButton = debounce(lastButton); // передаем в currentButton результат работы функции debounce с переданным в него состоянием кнопки
if (lastButton == LOW && currentButton == HIGH) // Проверяем была ли нажата кнопка
<
ledOn = !ledOn; // Меняем значение ledOn на противоположное
>
lastButton = currentButton; // Устанавливаем в переменную lastButton такое же значение как в переменной currentButton
digitalWrite(ledPin, ledOn); // Собственно эта строчка будет зажигать и гасить светодиод
>

Я думаю теперь у всех все заработало так, как и задумывалось ;)

Теперь настало время изменить нашу программу таким образом, чтобы после каждого нажатия кнопки менялась яркость светодиода, для этого мы будем использовать ШИМ сигнал или как его еще называют PWM. Если вы хотите узнать подробнее про ШИМ, можете почитать об этом в ВИКИ. А для нас на текущий момент достаточно знать лишь то, что меняя логические значения 0 и 1 в определенной последовательности можно заставить светодиод светиться по разному, но сути он просто будет по разному мигать, но так как частота миганий высокая, глазу будет казаться что он просто меняет яркость.

Но к сожалению не все выходы Arduino поддерживают PWM, поддержка PWM обозначена значком

рядом с номером контакта на шелкографии Arduino. Одним из таких контактов является контакт №11, а текущий наш контакт №13 не поддерживает PWM, следовательно нам нужно изменить схему подключения следующим образом:

Схема подключения светодиода и кнопки к Arduino c PWM

А также внести изменения в программный код, а именно нужно изменить номер контакта и добавить использование ШИМ:

/*
Урок 2. GPIO, Кнопки и PWM у Arduino
Меняем яркость светодиода.
Будем менять яркость свечения светодиода после каждого нажатия кнопки.
Этот демонстрационный код был скачан с сайта www.trunagol.ru
*/

int switchPin = 10; // Для удобства задаем имя «switchPin» для 10 вывода
int ledPin = 11; // Для удобства задаем имя «ledPin» для 11 вывода
boolean lastButton = LOW; // В этой переменной мы будем хранить состояние кнопки во время предыдущей обработки нашего цикла, а также установим его в ноль.
int ledLevel = 0; // В этой переменной мы будем хранить яркость свечения светодиода, яркость может иметь значение от 0 до 255, в момент инициализации установим его в 0, чтобы светодиод не светился
boolean currentButton = LOW; // Переменная для нашей функции debounce

void setup() // Блок «Setup» запускается только 1 раз при запуске Arduino, он нужен для инициализации.
<
pinMode(switchPin, INPUT); // Конфигурируем 10 вывод Arduino на вход. Т.к. мы будем считывать состояние кнопки.
pinMode(ledPin, OUTPUT); // Конфигурируем 13 вывод Arduino на выход. С помощью него мы будем включать светодиод.
>

boolean debounce(boolean last) //функция для устранения дребезга контактов кнопки, будет возвращать предыдущее её состояние
<
boolean current = digitalRead(switchPin); // Пишем в current текущее состояние кнопки
if (last != current) // Проверяем изменилось ли состояние кнопки
<
delay(5); // Если да, делаем задержку 5 миллисекунд, для того чтобы кнопка перестала «дребезжать»
current = digitalRead(switchPin); // Считываем значение кнопки после паузы, сейчас дребезг уже должен пройти
>
return current; // возвращаем стабильное значение кнопки
>

void loop() // Блок «loop» это цикл, т.е. код который работает раз за разом бесконечно
<
currentButton = debounce(lastButton); // передаем в currentButton результат работы функции debounce с переданным в него состоянием кнопки
if (lastButton == LOW && currentButton == HIGH) // Проверяем была ли нажата кнопка
<
ledLevel = ledLevel + 51; // Меняем значение яркости на 51
>
lastButton = currentButton; // Устанавливаем в переменную lastButton такое же значение как в переменной currentButton

if (ledLevel > 255) ledLevel = 0; // Ограничиваем макс. значение в 255
analogWrite(ledPin, ledLevel); // Собственно эта строчка будет зажигать светодиод с нужной яркостью
>

Надеюсь у вас все заработало. Это конец урока.

Вы можете задать вопросы и спросить совета в комментариях.

Код программ из урока для загрузки доступен здесь: Примеры из второго урока

Источник

Что такое gpio ардуино

Распиновка arduino nano

Начнем с пинов, которых больше всего, это GPIO, с англ. General Purpose Input-Output, входы-выходы общего назначения, на плате они подписаны как D0D13 и A0A5. По картинке распиновки они называются PD*, PB* и PC*, (вместо звёздочки – цифра) отмечены тёмно-бежевым цветом. Почему “официально” они называются PD/PB/PC? Потому что пины объединены в пОрты по несколько штук (не более 8), на примере Нано есть три порта: D, B и C, соответственно пины так и подписаны: PD3 – Port D 3 – третий выход порта D. Это цифровые пины, способные выдавать логический сигнал (0 или VCC) и считывать такой же логический сигнал. VCC это напряжение питания микроконтроллера, при обычном использовании обычной платы Ардуино это 5 Вольт, соответственно это 5 вольтовая логика: 0V – сигнал низкого уровня (LOW), 5V – высокого уровня (HIGH). Напряжение питания микроконтроллера играет очень большую роль, об этом мы ещё поговорим. GPIO имеют несколько режимов работы: вход (INPUT), выход (OUTPUT) и вход с подтяжкой к питанию встроенным в МК резистором на 20 кОм (INPUT_PULLUP). Подробнее о режимах поговорим в отдельном уроке.

Все GPIO пины в режиме входа могут принять сигнал с напряжением от 0 до 5 вольт (на самом деле до 5.5 вольт, согласно даташиту на микроконтроллер). Отрицательное напряжение или напряжение, превышающее 5.5 Вольт приведёт к выходу пина или даже самого МК из строя. Напряжение 0-2.5 вольта считается низким уровнем (LOW), 2.5-5.5 – высоким уровнем (HIGH). Если GPIO никуда не подключен, т.е. “висит в воздухе”, он принимает случайное напряжение, возникающее из за наводок от сети (провода 220в в стенах) и электромагнитных волн на разных частотах, которыми пронизан современный мир.

GPIO в режиме выхода (OUTPUT) являются транзисторными выходами микроконтроллера и могут выдать напряжение 0 или VCC (напряжение питания МК). Стоит отметить, что микроконтроллер – логическое, а не силовое устройство, его выходы рассчитаны на подачу сигналов другим железкам, а не на прямое их питание. Максимальный ток, который можно снять с GPIO выхода ардуино – 40 мА. Если попытаться снять больше – пин выйдет из строя (выгорит выходной транзистор и всё). Что такое 40 мА? Обычный 5мм одноцветный светодиод потребляет 20 мА, и это практически единственное, что можно питать напрямую от Ардуино. Также не стоит забывать о максимальном токе со всех пинов, он ограничен 200 мА, то есть не более 10 светодиодов можно запитать от платы на полную яркость…

Интерфейсы

Большинство GPIO имеют дополнительные возможности, так как к ним подключены выводы с других систем микроконтроллера, с ними вы уже знакомы из предыдущего урока:

  • ADC (АЦП, аналогово-цифровой преобразователь) – зелёные подписи ADC* на распиновке
  • UART (интерфейс связи) – голубые TXD и RXD на распиновке
  • Выводы таймеров, они же ШИМ пины – светло-фиолетовые OC*A и OC*B, где * номер таймера
  • SPI (интерфейс связи) – голубые SS, MOSI, MISO, SCK
  • I2C (интерфейс связи) – голубые SDA и SCL
  • INT (аппаратные прерывания) – розовые INT0 и INT1, а также PCINT* – PinChangeInterrupt

Если про интерфейсы мы уже говорили, то АЦП, прерывания и выводы таймеров ещё не затрагивали.

ADC пины (с АЦП) помечены на плате буквой A. Да, пины A6 и A7 на плате Нано имеют только вход на АЦП и не являются GPIO пинами! АЦП – аналогово-цифровой преобразователь, позволяет измерять напряжение от 0 до VCC (напряжения питания МК) или опорного напряжения. На большинстве плат Ардуино разрядность АЦП составляет 10 бит (2^10 = 1024), что означает следующее: напряжение от 0 до опорного преобразуется в цифровую величину от 0 до 1023 (1024-1 так как отсчёт идёт с нуля). Опорное напряжение играет очень большую роль: при опорных 5V один шаг измерения АЦП составит 4.9 милливольта (0.00488 В), а при опорных 1.1В – 1.1 мВ (0.00107 В). Вся суть в точности, я думаю вы поняли. Если опорное напряжение установлено ниже напряжения питания МК, то оцифровывая напряжение выше опорного мы получим 1023. Подавая на АЦП напряжение выше 5.5 Вольт получим выгоревший порт. Подавать отрицательное напряжение также не рекомендуется. На ардуино есть несколько режимов опорного напряжения: оно может быть равно VCC (напряжению питания), 1.1V (от встроенного в МК стабилизатора) или получать значение с внешнего источника в пин Aref, таким образом можно настроить нужный диапазон и получить нужную точность. У других моделей Ардуино (например у Меги) есть и другие встроенные режимы. Опорное напряжение рекомендуется заводить на плату через резистор, например на 1 кОм. Для измерения напряжений выше 5.5 вольт необходимо использовать делитель напряжения на резисторах.

Таймеры (ШИМ)

Выводы таймеров: в микроконтроллере, помимо обычного вычислительного ядра, с которым мы работаем, находятся также “хардварные” счётчики, работающие параллельно со всем остальным железом. Эти счётчики также называют таймерами, хотя к таймерам они не имеют никакого отношения: счётчики буквально считают количество тиков, которые делает кварцевый генератор, задающий частоту работы для всей системы. Зная частоту генератора (обычно 16 МГц) можно с очень высокой точностью определять интервалы времени и делать что-то на этой основе. Какой нам прок от этих счётчиков? “Из коробки” под названием Arduino IDE мы имеем несколько готовых, основанных на таймерах инструментов (функции времени, задержек, измерения длин импульсов и другие).

В этой статье речь идёт о пинах и выходах, о них и поговорим: у каждого счётчика есть два выхода на GPIO. У нано (у МК ATmega328p) три счётчика, соответственно 6 выходов. Одной из возможностей счётчиков является генерация ШИМ сигнала, который и выводится на соответствующие GPIO. Для нано это D пины 5 и 6 (счётчик 0), 9 и 10 (таймер 1) и 3 и 11 (таймер 2). ШИМ сигналу посвящен отдельный урок, сейчас просто запомним, что с его помощью можно управлять яркостью светодиодов, скоростью вращения моторчиков, мощностью нагрева спиралей и многим другим. Но нужно помнить, что ограничение по току в 40 мА никуда не делось и питать от пинов ничего мощнее светодиодов нельзя.

Прерывания

Аппаратные прерывания позволяют процессору мгновенно переключаться на некий блок действий (функция обработчик прерывания) при изменении уровня сигнала на пине. Подробнее об этом, а также о PinChangeInterrupts поговорим в другом уроке.

Другие пины

  • Пин 3.3V может быть использован для питания маломощных датчиков и модулей: максимальный ток, который можно снять с пина 3.3V составляет 150 мА, что с головой хватает для любых датчиков и модулей, кроме пожалуй радиомодулей nrf25L01.
  • Пины GND – земля питания, все GND связаны между собой
  • Пин 5V – питание от источника с напряжением до 5.5V (подробнее о питании смотри в следующем уроке)
  • Пин Vin – питание от источника с напряжением 7-15V (подробнее о питании смотри в следующем уроке)
  • RST – перезагрузка МК. Также этот пин выведен на кнопку

Материалы взяты с сайта: alexgyver.ru/

Аналоговые и цифровые порты

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

Цифровой сигнал передается в виде единиц и нулей, для компьютеров и цифровой техники это проще реализовать (есть сигнал или нет сигнала). Для оперативной памяти в компьютерах используют конденсаторы, один заряженный конденсатор — 1 бит. На флеш-памяти используют транзисторы с плавающим затвором.

С появлением компьютеров аналоговые сигналы стали переводить в цифру, поскольку аналоговый сигнал подвержен искажениям и затуханию при передаче или записи. Наглядно продемонстрировать разницу между аналоговым и цифровым сигналом поможет картинка, где изображен процесс квантования — разбиение непрерывной величины на конечное число интервалов (перевод аналогового сигнала в цифру).

Другими словами

Получается что аналоговым сигналом можно передать и принимать диапозон значений а вот цифровым только да / нет (HIGHT/LOW). Отправляются данные командой DigitalWrite, Принимаются DigitalRead.

Что же касается аналогового то тут можно получить данные от 0 до 1023 и передать данные от 0 до 255. Отправляются данные командой AnalogWrite, Принимаются AnalogRead.

AnalogWrite работает только на пинах 3,5,6,9,10,11, на картинке распиновки в начале статьи они показаны кривой линией которая отходит от платы к пояснению пина.

Источник

Что такое gpio ардуино

Всем привет это второй урок об Arduino. В первом уроке мы говорили об азах программирования Arduino. Сегодня мы будем говорить о GPIO у Arduino и PWM сигналах. Мы будем использовать кнопки и управлять яркостью светодиода с помощью PWM сигнала. Также мы будем использовать функции в среде программирования Arduino.

Для начала давайте попробуем управлять светодиодом с помощью кнопки.

Нам понадобятся:

  1. Резистор номиналом около 100-400 ом. Для ограничения тока, который идет через светодиод, чтобы не сжечь его.
  2. Резистор номиналом около 10 ком. Для подтягивания логических уровней на входе Arduino. Если его не ставить то наша кнопка будет работать очень нестабильно, т.к. на входе Arduino вместо полезного сигнала будут помехи.
  3. СветодиодАЛ307 или любой который вам понравиться. Собственно его мы и будем зажигать.
  4. Тактовая кнопка IT-1102 или любая другая. Будет использоваться для управления светодиодом.

Теперь настало время собрать простую схему, можно это сделать используя отладочную плату BreadBoard или при помощи паяльника и проводов.

Схема подключения светодиода и кнопки к Arduino

Светодиод подключен через токоограничительный резистор 200 ом к 10 выходу Arduino, номинал резистора можно поставить 200 ом — 500 ом, от этого будет меняться ток, идущий через светодиод и соответственно его яркость. Если вы подключите светодиод напрямую то это закончится плохо, через светодиод пойдет большой ток, в результате чего либо сам светодиод либо выход Arduino выйдет из строя. Необходимо также учесть что светодиод, это как никак диод, у него есть полярность!

Если вы подключите светодиод неправильно, он не загорится, потому что ток через него не пойдет (он просто будет закрыт). Определить полярность светодиода легко, короткая нога светодиода это минус (т.е. ноль или GND), а длинная это +.

Кнопка подключена таким образом, что в момент нажатия она скоммутирует на вход №10 Arduino +5 вольт что соответствует логической единице цифрового входа Arduino. В момент когда кнопка не нажата наш резистор номиналом 10 ком, притянет вход Arduino к GND (т.е. к нулю) и на входе Arduino стабильно будет логический ноль. Если вы не будете использовать этот подтягивающий резистор, то вполне возможна ситуация, когда будут происходить ложные срабатывания, это связанно с тем что на входе Arduino будет отсутствовать подтягивающий резистор и соответственно напряжение не будет равно нулю, оно будет хаотично меняться, что влечет за собой появление ложной логической единицы на входе Arduino.

Итак, настало время написать программу для Arduino. Для начала давайте будем держать включенным светодиод до тех пор, пока нажата кнопка. Конечно решить такую задачу очень легко без микроконтроллера, но ведь нам нужно с чего-то начать. Открываем среду программирования Arduino (как программировать Arduino подробно изложено в уроке №1) и начинаем писать код:

/*
Урок 2. GPIO, Кнопки и PWM у Arduino
Мигаем светодиодом.
Будем держать включенным светодиод до тех пор, пока нажата кнопка.
Этот демонстрационный код был скачан с сайта www.trunagol.ru
*/

int switchPin = 10; // Для удобства задаем имя «switchPin» для 10 вывода
int ledPin = 13; // Для удобства задаем имя «ledPin» для 13 вывода

void setup() // Блок «Setup» запускается только 1 раз при запуске Arduino, он нужен для инициализации.
<
pinMode(switchPin, INPUT); // Конфигурируем 10 вывод Arduino на вход. Т.к. мы будем считывать состояние кнопки.
pinMode(ledPin, OUTPUT); // Конфигурируем 13 вывод Arduino на выход. С помощью него мы будем включать светодиод.
>

void loop() // Блок «loop» это цикл, т.е. код который работает раз за разом бесконечно
<
if (digitalRead(switchPin) == HIGH) // Если кнопка нажата, наша переменная switchPin будет иметь значение HIGH (логическую 1) и выполниться код на след. строке
<
digitalWrite(ledPin, HIGH); // Зажигаем светодиод, выставив логическую 1 (уровень HIGH) на выходе 13
>
else // Если кнопка не нажата выполниться код идущий ниже.
<
digitalWrite(ledPin, LOW); // Выключаем светодиод
>
>

Ну что работает?! :)

А теперь давайте усложним задачу, сделаем так, чтобы при нажатии кнопки светодиод загорался и горел до тех пор пока не нажмем еще раз и так по кругу.

Наш код для этих целей будет выглядеть так:

/*
Урок 2. GPIO, Кнопки и PWM у Arduino
Включаем/выключаем светодиод.
Будем включать светодиод после нажатия кнопки и выключать после второго нажатия.
Этот демонстрационный код был скачан с сайта www.trunagol.ru
*/

int switchPin = 10; // Для удобства задаем имя «switchPin» для 10 вывода
int ledPin = 13; // Для удобства задаем имя «ledPin» для 13 вывода
boolean lastButton = LOW; // В этой переменной мы будем хранить состояние кнопки во время предыдущей обработки нашего цикла, а также установим его в ноль.
boolean ledOn = false; // В этой переменной мы будем хранить состояние светодиода, чтобы мы могли переключать его
void setup() // Блок «Setup» запускается только 1 раз при запуске Arduino, он нужен для инициализации.
<
pinMode(switchPin, INPUT); // Конфигурируем 10 вывод Arduino на вход. Т.к. мы будем считывать состояние кнопки.
pinMode(ledPin, OUTPUT); // Конфигурируем 13 вывод Arduino на выход. С помощью него мы будем включать светодиод.
>

void loop() // Блок «loop» это цикл, т.е. код который работает раз за разом бесконечно
<
if (digitalRead(switchPin) == HIGH && lastButton == LOW) // Если кнопка нажата, и последнее состояние кнопки было «не нажата», тогда выполняем следующий код
<
ledOn = !ledOn; // Меняем значение ledOn на противоположное
lastButton = HIGH; // Меняем значение lastButton на логическую единицу
>
else
<
lastButton = digitalRead(switchPin); // Устанавливаем в переменную lastButton такое же значение как в переменной switchPin
>
digitalWrite(ledPin, ledOn); // Собственно эта строчка будет зажигать и гасить светодиод
>

Ну как работает?! Хмм… Странно.. Иногда у нас все срабатывает как ожидается, а иногда нет… Почему так могло произойти? Всё дело в эффекте «дребезга контактов»:

Как вы видите на этой осциллограмме на самом деле наша кнопка срабатывает не идеально… И если мы с большой частотой опрашиваем кнопку, то в переходный момент мы можем считать как единицу так и ноль. Лучше было бы использовать аппаратные решения проблемы, но речь сейчас идет о нашем коде. Чтобы избежать этого дребезга нам придется доработать программу и просто ввести задержку по времени:

/*
Урок 2. GPIO, Кнопки и PWM у Arduino
Включаем/выключаем светодиод.
Будем включать светодиод после нажатия кнопки и выключать после второго нажатия и устраняем дребезг кнопок.
Этот демонстрационный код был скачан с сайта www.trunagol.ru

int switchPin = 10; // Для удобства задаем имя «switchPin» для 10 вывода
int ledPin = 13; // Для удобства задаем имя «ledPin» для 13 вывода
boolean lastButton = LOW; // В этой переменной мы будем хранить состояние кнопки во время предыдущей обработки нашего цикла, а также установим его в ноль.
boolean ledOn = false; // В этой переменной мы будем хранить состояние светодиода, чтобы мы могли переключать его
boolean currentButton = LOW; // Переменная для нашей функции debounce

void setup() // Блок «Setup» запускается только 1 раз при запуске Arduino, он нужен для инициализации.
<
pinMode(switchPin, INPUT); // Конфигурируем 10 вывод Arduino на вход. Т.к. мы будем считывать состояние кнопки.
pinMode(ledPin, OUTPUT); // Конфигурируем 13 вывод Arduino на выход. С помощью него мы будем включать светодиод.
>

boolean debounce(boolean last) //функция для устранения дребезга контактов кнопки, будет возвращать предыдущее её состояние
<
boolean current = digitalRead(switchPin); // Пишем в current текущее состояние кнопки
if (last != current) // Проверяем изменилось ли состояние кнопки
<
delay(5); // Если да, делаем задержку 5 миллисекунд, для того чтобы кнопка перестала «дребезжать»
current = digitalRead(switchPin); // Считываем значение кнопки после паузы, сейчас дребезг уже должен пройти
>
return current; // возвращаем стабильное значение кнопки
>

void loop() // Блок «loop» это цикл, т.е. код который работает раз за разом бесконечно

<
currentButton = debounce(lastButton); // передаем в currentButton результат работы функции debounce с переданным в него состоянием кнопки
if (lastButton == LOW && currentButton == HIGH) // Проверяем была ли нажата кнопка
<
ledOn = !ledOn; // Меняем значение ledOn на противоположное
>
lastButton = currentButton; // Устанавливаем в переменную lastButton такое же значение как в переменной currentButton
digitalWrite(ledPin, ledOn); // Собственно эта строчка будет зажигать и гасить светодиод
>

Я думаю теперь у всех все заработало так, как и задумывалось ;)

Теперь настало время изменить нашу программу таким образом, чтобы после каждого нажатия кнопки менялась яркость светодиода, для этого мы будем использовать ШИМ сигнал или как его еще называют PWM. Если вы хотите узнать подробнее про ШИМ, можете почитать об этом в ВИКИ. А для нас на текущий момент достаточно знать лишь то, что меняя логические значения 0 и 1 в определенной последовательности можно заставить светодиод светиться по разному, но сути он просто будет по разному мигать, но так как частота миганий высокая, глазу будет казаться что он просто меняет яркость.

Но к сожалению не все выходы Arduino поддерживают PWM, поддержка PWM обозначена значком

рядом с номером контакта на шелкографии Arduino. Одним из таких контактов является контакт №11, а текущий наш контакт №13 не поддерживает PWM, следовательно нам нужно изменить схему подключения следующим образом:

Схема подключения светодиода и кнопки к Arduino c PWM

А также внести изменения в программный код, а именно нужно изменить номер контакта и добавить использование ШИМ:

/*
Урок 2. GPIO, Кнопки и PWM у Arduino
Меняем яркость светодиода.
Будем менять яркость свечения светодиода после каждого нажатия кнопки.
Этот демонстрационный код был скачан с сайта www.trunagol.ru
*/

int switchPin = 10; // Для удобства задаем имя «switchPin» для 10 вывода
int ledPin = 11; // Для удобства задаем имя «ledPin» для 11 вывода
boolean lastButton = LOW; // В этой переменной мы будем хранить состояние кнопки во время предыдущей обработки нашего цикла, а также установим его в ноль.
int ledLevel = 0; // В этой переменной мы будем хранить яркость свечения светодиода, яркость может иметь значение от 0 до 255, в момент инициализации установим его в 0, чтобы светодиод не светился
boolean currentButton = LOW; // Переменная для нашей функции debounce

void setup() // Блок «Setup» запускается только 1 раз при запуске Arduino, он нужен для инициализации.
<
pinMode(switchPin, INPUT); // Конфигурируем 10 вывод Arduino на вход. Т.к. мы будем считывать состояние кнопки.
pinMode(ledPin, OUTPUT); // Конфигурируем 13 вывод Arduino на выход. С помощью него мы будем включать светодиод.
>

boolean debounce(boolean last) //функция для устранения дребезга контактов кнопки, будет возвращать предыдущее её состояние
<
boolean current = digitalRead(switchPin); // Пишем в current текущее состояние кнопки
if (last != current) // Проверяем изменилось ли состояние кнопки
<
delay(5); // Если да, делаем задержку 5 миллисекунд, для того чтобы кнопка перестала «дребезжать»
current = digitalRead(switchPin); // Считываем значение кнопки после паузы, сейчас дребезг уже должен пройти
>
return current; // возвращаем стабильное значение кнопки
>

void loop() // Блок «loop» это цикл, т.е. код который работает раз за разом бесконечно
<
currentButton = debounce(lastButton); // передаем в currentButton результат работы функции debounce с переданным в него состоянием кнопки
if (lastButton == LOW && currentButton == HIGH) // Проверяем была ли нажата кнопка
<
ledLevel = ledLevel + 51; // Меняем значение яркости на 51
>
lastButton = currentButton; // Устанавливаем в переменную lastButton такое же значение как в переменной currentButton

if (ledLevel > 255) ledLevel = 0; // Ограничиваем макс. значение в 255
analogWrite(ledPin, ledLevel); // Собственно эта строчка будет зажигать светодиод с нужной яркостью
>

Надеюсь у вас все заработало. Это конец урока.

Вы можете задать вопросы и спросить совета в комментариях.

Код программ из урока для загрузки доступен здесь: Примеры из второго урока

Источник

Adblock
detector