Кнопка, i2c (Metro-модуль)

Исходники изображение:

Общие сведения:

Модуль Metro - Кнопка - является устройством ввода данных с подключением по шине I2C.

К одной шине I2C можно подключить более 100 модулей.

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

Видео:

Редактируется...

Спецификация:

  • Напряжение питания: 5 В (постоянного тока)
  • Потребляемый ток: до 15 мА.
  • Интерфейс: I2C.
  • Скорость шины I2C: 100 кбит/с.
  • Адрес на шине I2C: устанавливается программно (по умолчанию 0x09).
  • Уровень логической 1 на линиях шины I2C: 3,3 В (толерантны к 5 В).
  • Уровень логической 1 на выводах ADR: 3,3 В (толерантны к 5 В).
  • Рабочая температура: от -20 до +70 °С.
  • Габариты: 35,56 х 25,40 мм (1400 x 1000 mil).
  • Вес: 5 г.

Подключение:

У модуля имеются две колодки выводов: IN (вход) - штыревой разъем и OUT (выход) гнездовой разъем. Все модули подключаются друг к другу соединяя выход предыдущего модуля со входом следующего, образуя состав из модулей Metro в котором первым «вагоном» является плата управления Metro Leonardo или Metro ESP.

Подключение к управляющей плате Metro Leonardo:

К плате Metro Leonardo можно подключить только кнопки, или чередовать их с другими модулями Metro в любой последовательности.

Подключение к управляющей плате Metro ESP:

К плате Metro ESP можно подключить только кнопки, или чередовать их с другими модулями Metro в любой последовательности.

Модуль не поддерживает горячее подключение: Подключайте модуль только при отсутствии питания и данных на шине I2C. В противном случае потребуется отключить питание при уже подключённом модуле.

Вместо платы управления Metro Leonardo или Metro ESP можно использовать платы Arduino или Piranha, у которых будут задействованы 2 вывода шины I2C (SCL и SDA), 2 вывода питания (5V и GND) и один вывод установки адреса ADR, по умолчанию используется вывод D12 (можно менять в скетче).

Питание:

Входное напряжение питания 5 В постоянного тока, подаётся на выводы 5V и GND модуля.

Модуль сохраняет работоспособность при снижении напряжения питания до 3,3 В.

Подробнее о модуле:

Модуль Metro - Кнопка построен на базе микроконтроллера STM32F030F4 и снабжен собственный стабилизатором напряжения.

Модуль считывает состояние тактовой кнопки и позволяет:

  • Определить события кнопки - нажимается/отпускается.
  • Считать состояния кнопки - нажата/отпущена.
  • Определить факт смены состояния кнопки (была нажата, а сейчас отпущена и наоборот).
  • Работать в режиме триггера (включать и выключать устройства с каждым новым нажатием).
  • Определить факт удержания кнопки дольше указанного времени.
  • Указать время по истечении которого нажатая кнопка будет считаться удерживаемой.
  • Узнать время прошедшее с момента установки текущего состояния кнопки нажата/отпущена.
  • Узнать количество совершенных нажатий на кнопку, которые не были прочитаны.

Специально для работы с модулями Metro нами разработана библиотека iarduino_Metro, одна библиотека для всех модулей линейки Metro. Библиотека сама определяет наличие и тип модулей на шине I2C, присваивает им адреса и создаёт массив объектов Metro для работы с найденными модулями. Стоит отметить что пользователю даже не обязательно знать адреса присвоенные модулям, так как для обращения к любому модулю достаточно знать его номер по порядку от платы управления Metro Leonardo или Metro ESP.

    Количество элементов массива Metro совпадает с количеством найденных модулей:
  • Metro[0] - объект для управления первым модулем (ближайшим к управляющей плате);
  • Metro[1] - объект для управления вторым модулем (следующим после первого);
  • Metro[2] - объект для управления третьим модулем (и т.д. до последнего модуля).

Подробнее про установку библиотеки читайте в нашей инструкции.

Примеры:

Чтение событий и состояний кнопки:

#include <Wire.h>                         // Подключаем библиотеку Wire.
#include <iarduino_Metro.h>               // Подключаем библиотеку iarduino_Metro.
                                          //
void setup(){                             //
    iarduino_Metro_Start();               // Определяем подключённые модули.
    Serial.begin(9600);                   // Инициируем связь с монитором последовательного порта на скорости 9600 бит/сек.
    while(!Serial){;}                     // Ждём готовность к работе аппаратной шины UART.
}                                         //
                                          //
void loop(){                              //
    if(   Metro[0].read( KEY_PUSHED   )   ){ Serial.println("Кнопка нажимается."  );}
    if(   Metro[i].read( KEY_RELEASED )   ){ Serial.println("Кнопка отпускается." );}
    if(   Metro[i].read( KEY_PRESSED  )   ){ Serial.println("Кнопка удерживается.");}
    delay(1000);                          // Ждём секунду, чтоб не загромождать монитор данными.
}                                         //

Данный скетч будет выводить в монитор последовательного порта следующие строки:
Однократно после нажатия на кнопку - «Кнопка нажимается».
Постоянно пока кнопка нажата - «Кнопка удерживается».
Однократно после отпускания кнопки - «Кнопка отпускается».

Управление нажатием на кнопку (вариант 1):

#include <Wire.h>                         // Подключаем библиотеку Wire.
#include <iarduino_Metro.h>               // Подключаем библиотеку iarduino_Metro.
                                          //
void setup(){                             //
    iarduino_Metro_Start();               // Определяем подключённые модули.
    pinMode(LED_BUILTIN, OUTPUT);         // Конфигурируем вывод светодиода D13 как выход.
}                                         //
                                          //
void loop(){                              //
    bool i = Metro[0].read(KEY_PRESSED);  // Считываем состояние кнопки.
    digitalWrite( LED_BUILTIN, i );       // Устанавливаем состояние светодиода.
}                                         //

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

Управление нажатием на кнопку (вариант 2):

#include <Wire.h>                         // Подключаем библиотеку Wire.
#include <iarduino_Metro.h>               // Подключаем библиотеку iarduino_Metro.
                                          //
void setup(){                             //
    iarduino_Metro_Start();               // Определяем подключённые модули.
    pinMode(LED_BUILTIN, OUTPUT);         // Конфигурируем вывод светодиода D13 как выход.
}                                         //
                                          //
void loop(){                              //
    bool i;                               //
    if( Metro[0].read(KEY_CHANGED) ){     // Если состояние кнопки изменилось, то ...
        i = Metro[0].read(KEY_PRESSED);   // Считываем состояние кнопки.
        digitalWrite( LED_BUILTIN, i );   // Устанавливаем состояние светодиода.
    }                                     //
}                                         //

Данный скетч делает тоже самое что и предыдущий (вариант 1), но только состояние выхода светодиода D13 обновляется не постоянно (в каждом проходе цикла loop), а только после каждого нажатия/отпускания кнопки.

Определение удержания кнопки (вариант 1):

#include <Wire.h>                         // Подключаем библиотеку Wire.
#include <iarduino_Metro.h>               // Подключаем библиотеку iarduino_Metro.
                                          //
void setup(){                             //
    iarduino_Metro_Start();               // Определяем подключённые модули.
    pinMode(LED_BUILTIN, OUTPUT);         // Конфигурируем вывод светодиода D13 как выход.
    Metro[0].set(1000,5000,10000);        // Задаём время удержания кнопки в мс.
}                                         // (KEY_HOLD1 1сек, KEY_HOLD2 5сек, KEY_HOLD3 10сек).
                                          //
void loop(){                              //
    bool i = Metro[0].read(KEY_HOLD2);    // Считываем флаг удержания кнопки KEY_HOLD2.
    digitalWrite( LED_BUILTIN, i );       // Устанавливаем состояние светодиода.
}                                         //

Светодиод D13 на управляющей плате будет светиться если кнопка удерживается дольше 5 секунд. Время удержания кнопки установлено однократно функцией set() в коде loop.

Определение удержания кнопки (вариант 2):

#include <Wire.h>                         // Подключаем библиотеку Wire.
#include <iarduino_Metro.h>               // Подключаем библиотеку iarduino_Metro.
                                          //
void setup(){                             //
    iarduino_Metro_Start();               // Определяем подключённые модули.
    pinMode(LED_BUILTIN, OUTPUT);         // Конфигурируем вывод светодиода D13 как выход.
}                                         //
                                          //
void loop(){                              //
    if(Metro[0].read(KEY_PRESSED)==0){    // Если кнопка отпущена, то ...
        digitalWrite(LED_BUILTIN, LOW);   // Выключаем светодиод.
    }else                                 // Иначе (если кнопка нажата), то ...
    if(Metro[0].read(KEY_TIME)>=5000){    // Если текущее состояние кнопки длится дольше 5 секунд, то ...
        digitalWrite(LED_BUILTIN, HIGH);  // Включаем светодиод.
    }                                     // 
}                                         //

Данный скетч делает тоже самое что и предыдущий (вариант 1), но не отслеживая предварительно указанное время, а сравнивая состояние кнопки и время длительности этого состояния.

Триггер:

#include <Wire.h>                         // Подключаем библиотеку Wire.
#include <iarduino_Metro.h>               // Подключаем библиотеку iarduino_Metro.
                                          //
void setup(){                             //
    iarduino_Metro_Start();               // Определяем подключённые модули.
    pinMode(LED_BUILTIN, OUTPUT);         // Конфигурируем вывод светодиода D13 как выход.
}                                         //
                                          //
void loop(){                              //
    bool i = Metro[0].read(KEY_TRIGGER);  // Считываем состояние триггера кнопки (состояние меняется с каждым новым нажатием на кнопку).
    digitalWrite( LED_BUILTIN, i );       // Устанавливаем состояние светодиода.
}                                         //

Данный скетч включает или выключает светодиод с каждым нажатием на кнопку. Это похоже на включение/выключение телевизора, монитора и т.д., любого устройства которое включается и выключается одной кнопкой без фиксации её положения.

Описание функций библиотеки:

В данном разделе описаны функции библиотеки iarduino_Metro для работы с кнопкой, при работе с другими модулями Metro те же функции могут иметь другое назначение.

Подключение библиотеки:

#include <Wire.h>           // Подключаем библиотеку Wire. Для работы с Arduino, Piranha или Metro Leonardo, библиотеку Wire можно не подключать.
#include <iarduino_Metro.h> // Подключаем библиотеку iarduino_Metro.

После подключения библиотеки iarduino_Metro создавать объекты не требуется, вместо этого необходимо однократно вызвать функцию iarduino_Metro_Start(); в коде setup. Эта функция обнаружит все модули Metro, назначит им адреса на шине I2C и создаст массив объектов Metro, количество элементов которого будет совпадать с количеством найденных модулей Metro.

Определение подключённых модулей Metro:

iarduino_Metro_Start();     // В качестве аргумента функции можно указать вывод Arduino к которому подключен вход ADR модуля Metro (по умолчанию используется вывод D12).

Определение подключённых модулей Metro с возвращением их количества:

i = iarduino_Metro_Start(); // Определить все модули и записать их количество в переменную i.

После определения подключенных модулей станет доступен массив Metro, каждый элемент которого является объектом подключенного модуля Metro и предназначен для управления им.

    Например, если к управляющей плате подключено 3 любых модуля Metro, то массив Metro будет содержать 3 элемента:
  • Metro[0] - объект для управления первым модулем (ближайшим к управляющей плате);
  • Metro[1] - объект для управления вторым модулем (следующим после первого);
  • Metro[2] - объект для управления третьим модулем (дальним от управляющей платы).

Сторонние модули ша шине I2C: На шине I2C могут присутствовать сторонние модули* (не принадлежащие линейке Metro) со своими библиотеками. Это не повлияет на корректность обнаружения модулей Metro, не приведёт к присвоению неуникального адреса модулю и не нарушит очерёдность следования элементов массива Metro.
* Кроме сторонних модулей с адресом 0x09.

Функция read();

  • Назначение: Чтение событий и состояний кнопки.
  • Синтаксис: Metro[ индекс ].read( [ПАРАМЕТР] );
  • Параметры:
    • KEY_PUSHED - Вернуть true только если было событие «нажимается», при этом не важно как давно это событие происходило, после чего функция будет возвращать false, пока опять не произойдёт событие «нажимается».
    • KEY_RELEASED - Вернуть true только если было событие «отпускается», при этом не важно как давно это событие происходило, после чего функция будет возвращать false, пока опять не произойдёт событие «отпускается».
    • KEY_PRESSED - Вернуть true если кнопка нажата, иначе вернуть false. Данный параметр используется по умолчанию (если функция read() вызвана без параметра).
    • KEY_TRIGGER - Вернуть либо true, либо false, меняя это значение с каждым новым нажатием на кнопку (можно использовать для вкл/выкл устройств нажатием одной кнопки).
    • KEY_HOLD1 - Вернуть true если кнопка удерживается дольше чем время указанное ранее в качестве 1 агрумента функции set (по умолчанию 1 секунда), иначе вернуть false.
    • KEY_HOLD2 - Вернуть true если кнопка удерживается дольше чем время указанное ранее в качестве 2 агрумента функции set (по умолчанию 2 секунды), иначе вернуть false.
    • KEY_HOLD3 - Вернуть true если кнопка удерживается дольше чем время указанное ранее в качестве 3 агрумента функции set (по умолчанию 3 секунды), иначе вернуть false.
    • KEY_CHANGED - Вернуть true если состояние кнопки изменилось (нажалась/отпустилась), при этом не важно как давно изменилось состояние, после чего функция будет возвращать false, пока состояние кнопки опять не изменится.
    • KEY_TIME - Вернуть время прошедшее с момента установки текущего состояния кнопки в миллисекундах, от 0 до 25500 мс (кратно 100 мс). Если кнопка нажата то возвращается время с момента её нажатия, а если кнопка отпущена то возвращается время с момента её отпускания. Если прошло более 25500 мс, то время останавливается на данном значении.
    • KEY_SUM - Вернуть количество нажатий на кнопку за то время пока не было обращений к функции read(). Это позволяет зафиксировать нажатия выполненные во время ожиданий delay() и т.д.
  • Возвращаемые значения: Зависят от параметра функции.
  • Примечание:
    • Вызов функции без параметра аналогичен вызову с параметром KEY_PRESSED.
  • Пример:
if (  Metro[0].read(KEY_PUSHED ) ){                            // Если кнопка нажимается, то ...
  if( Metro[0].read(KEY_TRIGGER) ){ Serial.println("Вкл." ); } // вывести текст "Вкл."
  else                            { Serial.println("Выкл."); } // или текст "Выкл."
}                                                              // Текст будет выводиться и меняться с каждым нажатием на кнопку.

Функция set();

  • Назначение: Функция задаёт время удержания кнопки для срабатывания функции read с параметрами KEY_HOLD1, KEY_HOLD2, или KEY_HOLD3.
  • Синтаксис: Metro[ индекс ].set( ВРЕМЯ1 , ВРЕМЯ2 , ВРЕМЯ3 );
  • Параметры:
    • ВРЕМЯ1 - Целочисленное значение определяющее время удержания кнопки по истечении которого функция read() вызванная с параметром KEY_HOLD1 станет возвращать true.
    • ВРЕМЯ2 - Целочисленное значение определяющее время удержания кнопки по истечении которого функция read() вызванная с параметром KEY_HOLD2 станет возвращать true.
    • ВРЕМЯ3 - Целочисленное значение определяющее время удержания кнопки по истечении которого функция read() вызванная с параметром KEY_HOLD3 станет возвращать true.
  • Возвращаемые значения: Нет.
  • Примечание:
    • Время указывается в миллисекундах от 0 до 25500 мс и округляется до сотых.
    • Если функцию set() не вызывать, то будут использоваться значения установленные по умолчанию: ВРЕМЯ1=1000мс, ВРЕМЯ2=2000мс, ВРЕМЯ3=3000мс.
  • Пример:
    Metro[0].set(1000, 10000, 5000); // Задаём время: 1 сек, 10 сек и 5 сек.
if( Metro[0].read(KEY_HOLD1) ){ Serial.println("Кнопка удерживается дольше 1  секунды"); }
if( Metro[0].read(KEY_HOLD2) ){ Serial.println("Кнопка удерживается дольше 10 секунд" ); }
if( Metro[0].read(KEY_HOLD3) ){ Serial.println("Кнопка удерживается дольше 5  секунд" ); }

Переменная address:

  • Тип: uint8_t.
  • Данные: Адрес модуля на шине I2C.
  • Примечание: Адрес формируется и присваивается во время определения модулей функцией iarduino_Metro_Start(); Не меняйте адрес, так как он используется библиотекой.
  • Пример чтения адреса модуля:
Serial.print  ( "Адрес модуля на шине I2C = " );
Serial.println( Metro[0].address              );

Переменная model:

  • Тип: uint8_t.
  • Данные: Идентификатор типа модуля.
  • Примечание: Тип модуля считывается во время определения модулей функцией iarduino_Metro_Start(); Не меняйте тип модуля, так как он используется библиотекой.
  • Пример определения типа модуля:
switch( Metro[0].model ){
    case MOD_KEY: Serial.println( "кнопка"                         ); break;
    case MOD_RGB: Serial.println( "светодиод"                      ); break;
    case MOD_RES: Serial.println( "потенциометр"                   ); break;
    case MOD_BUZ: Serial.println( "звукоизлучатель"                ); break;
    case MOD_DHT: Serial.println( "датчик влажности и температуры" ); break;
    case MOD_DSL: Serial.println( "датчик освещённости"            ); break;
    case MOD_8X8: Serial.println( "светодиодная матрица 8х8"       ); break;
    default:      Serial.println( "неизвестный модуль"             ); break;
}

Переменная version:

  • Тип: uint8_t.
  • Данные: Версия прошивки модуля.
  • Примечание: Версия прошивки считывается во время определения модулей функцией iarduino_Metro_Start(); Изменение значения переменной не изменит версию модуля и не повлияет на работу модуля, и библиотеки.
  • Пример чтения версии прошивки модуля:
Serial.print  ( "Версия прошивки модуля = " );
Serial.println( Metro[0].version            );

Переменная size:

  • Тип: uint8_t.
  • Данные: Объем памяти ОЗУ в байтах, используемый библиотекой для данного модуля.
  • Примечание: Библиотека создаёт массив объектов Metro с помощью функции iarduino_Metro_Start(); в коде setup (при старте скетча), значит и память ОЗУ для работы с модулями выделяется там же, а не во время компиляции скетча. Зная объем выделенной памяти можно определить объем свободной и рассчитать, какое количество модулей Metro ещё можно подключить. Изменение значения переменной не изменит объём выделенной памяти и не повлияет на работу модуля, и библиотеки.
  • Пример чтения объема памяти ОЗУ выделенного для работы с модулем:
Serial.print  ( "Для работы данного модуля выделено " );
Serial.print  ( Metro[0].size                         );
Serial.println( " байт памяти ОЗУ."                   );

Применение:

Модуль Metro - Кнопка можно использовать в любых проектах где требуется тактовая кнопка, например, для подачи сигналов, ввода данных, управления устройствами и т.д.

Ссылки:

Обсуждение