NodeMCU (Lua) — GPIO.

Опубликовано bondrogeen

Работа с внешними устройствами происходит через порты ввода-вывода (GPIO). С их помощью можно как считывать сигналы, например с различных датчиков, так и управления другими устройствами. ESP8266 не может похвастаться большим количеством свободных портов. В зависимости от исполнения модуля (см. ниже), доступно разное число портов. Например, в ревизии ESP01, если не считать UART, имеется только два порта. Но даже в версиях где все порты выведены (ESP12E), без ограничений доступны только часть их, так как остальные совмещают системные функции (выбор режима загрузки, SPI флешь, вывод из сна).

Для работа с портами ввода-вывода в NodeMCU используется модуль GPIO. Если открыть документацию, первое что бросается в глаза это нумерацией портов (см. ниже), точнее отсутствие связи в нумерации портов NodeMCU и официальным обозначением. Почему-то разработчики решили использовать свою нумерацию. При использовании официальных плат NodeMCU или WeMos D1, где все порты «правильно» подписаны проблем не возникает, но если разрабатывать свое устройство на «голом» ESP8266 и руководствуясь официальным обозначением, то довольно часто приходиться заглядывать в эту таблицу.

При проектировании устройств на NodeMCU, для себя сделал такую пометку, свободных портов которыми можно пользоваться без каких либо ограничений (вход, выход, прерывания) всего 5 — это GPIO4, GPIO5, GPIO12, GPIO13, GPIO14. При использовании остальных необходимо учитывать их особенности. Поэтому внимательно читайте документацию и во избежание проблем.

При использовании «голых» модулей ESP8266, для «нормальной» загрузки необходимо чтобы в момент старта (подачи питания) на портах GPIO0, GPIO2 присутствовал высокий уровень, а GPIO15 низкий.

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

Инициализация GPIO

Перед тем как начать работать с портом необходимо его про инициализировать, выбрав один из четырех режимов работы:

  1. Вход (gpio.INPUT)
  2. Выход (gpio.OUTPUT)
  3. Прерывания (gpio.INT)
  4. Открытый сток (gpio.OPENDRAIN)

Если не планируете менять режим работы, то делается это один раз в начале кода.

С помощью функции gpio.mode(pin,mode[,pullup]) устанавливается режим работы. Функция принимает два  обязательных параметра (номер порта и режим работы) и один не обязательный (будет ли порт подтянут к питанию)

 

Вход

Для того чтобы узнать какой логический уровень присутствует в данный момент времени на порту, можно с помощью функции gpio.read(pin). Функции принимает один параметр номер порта который необходимо считать, а возвращает его состояние, 0 или 1 в зависимости от логического уровня.

Считывать состояние порта можно как в режиме вход, так и выход.

Выход

Изменения состояние логического уровня на выходе порта выполняется с помощью функции gpio.write(pin, level). В отличии от функции чтения порта, функция записи ничего не возвращает и на вход поступает уже два параметра, это номер порта и необходимый логический уровень на его выходе.

Прерывания 

Разобрав работы функций чтения мы можем проверить текущий уровень порта, но что если нам необходимо отслеживать изменения уровня и как-то на него реагировать. В этом нам поможет функция gpio.trig(pin, [type [, callback_function]]). Функция принимает два параметра, номер порта и типа события на который хотим подписаться, а также callback функцию, которая будет вызвана если произойдет данное событие.

Типы событий.

  • up — отслеживание по переднему фронту, то есть будет вызвана в момент перехода от логического низкого уровня на высокий.
  • down — отслеживание по заднему фронту, то есть будет вызвана в момент перехода от логического  высокого уровня на низкий.
  • both — отслеживание обоих фронтов, как по переднему так и заднему фронту
  • low — отслеживание низкого логического уровня, то есть будет срабатывать пока присутствует низкий логический уровень  
  • high — отслеживание высокого логического уровня, то есть будет срабатывать пока присутствует высокий логический уровень 
  • none — отписаться от всех прерываний

Например, чтобы отследить нажатие кнопки достаточно нескольких строк кода. Для этого нужно создать событие и функцию обработки этого события. Когда событие наступит, будет запущена наша функция.

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

В случае если необходимо отписаться от всех событий, сделать это можно с помощью той же функции gpio.trig(pin, type), но указав в качестве второго параметра none.

Как видно модуль GPIO и асинхронность LUA упрощает работу с портами ввода-вывода, достаточно пары строк кода чтобы узнать, изменить состояние порта или повесить на него событие, этого более чем достаточно для простых задач «ногодрыгания». Но что касается генерации или замера цифрового сигнала, то тут не все так радужно. Если для генерацией сигналов с последними обновлениями появились новые функции (gpio.serout и gpio.pulse), которые позволяют формировать различные импульсы с минимальными интервалами по времени, то вот с подсчетом их дела обстоят немного хуже. При максимально возможной частоте, подсчет занимает все ресурсное время не оставляя его для других операций. Но и даже при подсчете коротких импульсов одного и того же сигнала можно наблюдать разный результат, особенно это заметно в нагруженных проектах. Эта расплата за асинхронность

При изучении модулей NodeMCU в первую очередь руководствуйтесь официальной документацией, т.к. постоянно вносятся изменения и возможно что некоторая информация потеряет свою актуальность.

 

Рубрики: NodeMCU

1
Отправить ответ

avatar
1 Comment threads
0 Thread replies
0 Followers
 
Most reacted comment
Hottest comment thread
1 Comment authors
Константин Recent comment authors

Этот сайт использует Akismet для борьбы со спамом. Узнайте как обрабатываются ваши данные комментариев.

  Subscribe  
newest oldest most voted
Notify of
Константин
Гость
Константин

Спасибо за информацию!