Общие сведения:
В этом уроке мы создадим ночник с управлением адресными светодиодами через датчик жестов.
Выполнив один из жестов, которые распознаёт датчик, вы сможете управлять режимом работы ночника, его яркостью, цветом и скоростью анимации.
Видео:
Нам понадобится:
- 1х Arduino / Piranha UNO;
- 1х Battery Shield;
- 1х Trema Shield;
- 8х Trema-модуль Адресный светодиод NeoPixel;
- 1х Trema-модуль Датчик жестов, приближения, освещённости, цвета;
- 6х ПВХ-конструктор;
Для реализации проекта нам необходимо установить библиотеки:
- SparkFun_APDS9960 — для работы с датчиком движений;
- iarduino_NeoPixel — для работы с адресными светодиодами NeoPixel;
- Wire — библиотека входит в базовый набор Arduino IDE и не требует установки;
О том, как устанавливать библиотеки, Вы можете ознакомиться на странице Wiki - Установка библиотек в Arduino IDE.
Описание работы ночника:
После подачи питания ночник готов к работе.
Для включения ночника проведите рукой над датчиком вправо или влево, после чего ночник включит один из режимов работы:
- Перелив всеми цветами радуги;
- Случайное включение случайным цветом;
- Смена одного цвета на другой;
- Имитация пламени свечи;
- Один цвет на выбор по порядку(красный, зелёный, синий, жёлтый, фиолетовый, голубой, белый);
Для того, чтобы увеличить или уменьшить скорость анимации, достаточно провести рукой вверх (ускорить) или вниз (замедлить) над датчиком.
Для того, чтобы изменить уровень яркости ночника достаточно приблизить руку к датчику и плавно её отдалить - ночник перейдёт в режим настройки:
- При входе в режим настройки яркости ночник однократно моргнёт светодиодами белого цвета, после чего в течении времени, заданном в переменной
waiting_time, будет принимать команды настройки яркости; - Приближая или отдаляя руку к/от датчика яркость будет плавно меняться от меньшего (приближая) к большему (отдаляя);
- По истечении времени ночник вновь однократно моргнёт светодиодами белого цвета и выйдет из режима настройки яркости;
Для того, чтобы выключить ночник, достаточно поднести руку над датчиком на расстоянии 10-15 см и плавно её приблизить. После этого ночник выключится.
Схема сборки:
Arduino / Piranha UNO:

Batery Shield:
Установите Battery Shield на Arduino / Piranha UNO:
Во время установки Battery Shield должен быть в выключенном состоянии.

Trema Shield:
На Battery Shield установите Trema Shield:

Датчик жестов:
Подключите Trema-модуль Датчик жестов к Trema Shield:

Адресные светодиоды:
Подключите адресные светодиоды NeoPixel к Trema Shield:

Все используемые в уроке Trema-модули NeoPixel соединены друг c другом, а первый модуль можно подключить к любому выводу Arduino. Номер вывода указывается в скетче (в примере используется вывод D10). Чем больше модулей в цепи, тем больше тока она потребляет, по этому в схеме используется стабилизированный источник питания Battery Shield на 5В постоянного тока.
Код программы (скетч):
// Подключаем библиотеки: #include// Для работы с шиной I2C #include // Для работы с датчиком APDS-9960 #include // Подключаем библиотеку iarduino_NeoPixel для работы со светодиодами NeoPixel uint8_t neo_pin = 10; // Вывод, к которому подключены модули NeoPixel uint16_t modul_number = 8; // Количество модулей iarduino_NeoPixel led(neo_pin, modul_number*4 ); // Объявляем объект LED указывая (№ вывода Arduino к которому подключён модуль NeoPixel, количество используемых светодиодов) SparkFun_APDS9960 apds = SparkFun_APDS9960(); // Определяем объект apds, экземпляр класса SparkFun_APDS9960 // Объявляем переменные: uint8_t j; // Объявляем переменную для хранения значения сдвига спектра цветов для всех светодиодов (от 0 до 255) uint8_t k; // Объявляем переменную для хранения положения сдвига спектра цвета для каждого светодиода на спектре j (зависит от количества светодиодов) uint8_t r, g, b; // Объявляем переменную для хранения цветов RGB для каждого светодиода uint8_t z = 1; // Определяем константу указывающую задержку в мс (чем выше значение, тем медленнее перелив цветов) uint8_t flg, setting = 0; // Флаг включения/выключения света uint8_t mode = 0; // Флаг режима работы светодиодов uint8_t proximityData = 0; // Переменная, хранящая значение расстояния до модуля APDS9960 uint8_t brightness = 255; // Переменная значения яркости uint32_t waiting_time = 7000; // Время ожидания при настройке яркости uint32_t work_time; // Счётчик времени при настройке яркости byte on_off = 0; // Триггер включения/выключения света void setup() { // Инициализируем адресные светодиоды: led.begin(); // Инициализируем модуль жестов: apds.init(); // Если инициализация модуля жестов прошла успешно, то ... // Устанавливаем коэффициент усиления приёмника: // Доступные значения: 1х, 2х, 4х, 8х (GGAIN_1X, GGAIN_2X, GGAIN_4X, GGAIN_8X). Чем выше коэффициент тем выше чувствительность apds.setGestureGain(GGAIN_4X); // Если установлен коэффициент усиления приёмника в режиме обнаружения жестов, то ... // Устанавливаем силу тока драйвера ИК-светодиода: // Доступные значения: 100мА, 50мА, 25мА, 12.5мА (LED_DRIVE_100MA, LED_DRIVE_50MA, LED_DRIVE_25MA, LED_DRIVE_12_5MA). Чем выше сила тока, тем выше чувствительность. apds.setGestureLEDDrive(LED_DRIVE_100MA); // Если устанавлена сила тока драйвера (яркость) ИК-светодиода для обнаружения жестов, то ... // Разрешаем режим обнаружение жестов: apds.enableGestureSensor(false); // Если инициализация режима обнаружения жестов прошла успешно, то led.setColor(NeoPixelAll,0, 0, 0); // Выключаем светодиоды led.write(); // // Ждём завершение инициализации и калибровки: delay(500); // Задержка 0,5с } void loop() { // Проверяем наличие движения if (apds.isGestureAvailable()) { // Если зафиксировано движение, то ... switch (apds.readGesture()) { // Сверяем значение соответствующее жесту ... // Проверяем жест: //==========================================================// // "СЕВЕР" - УВЕЛИЧЕНИЕ СКОРОСТИ АНИМАЦИИ case DIR_UP: if(z>=1 && z <=11) {z += 5;} else // Если параметр скорости задан от 1мс до 11мс, то шаг равен 5мс if(z > 11 && z <=101) {z += 20;}else // Если параметр скорости задан от 11мс до 101мс, то шаг равен 20мс if(z > 101 && z <=500){z += 50;}else // Если параметр скорости задан от 101мс до 500мс, то шаг равен 50мс if(z > 500) {z = 1;} // При превышении значения шаг сбрасывается break; //==========================================================// // "ЮГ" - УМЕНЬШЕНИЕ СКОРОСТИ АНИМАЦИИ case DIR_DOWN: if(z<1) {z = 500;}else // При выходе из заданного промежутка значений шаг сбрасывается if(z >=1 && z <=11) {z -= 5;} else // Если параметр скорости задан от 1мс до 11мс, то шаг равен 5мс if(z > 11 && z <= 101){z -= 20;}else // Если параметр скорости задан от 1мс до 11мс, то шаг равен 5мс if(z > 101 && z <=500){z -= 50;} // Если параметр скорости задан от 1мс до 11мс, то шаг равен 5мс break; //==========================================================// // "ЗАПАД" - ЛИСТАЕМ РЕЖИМЫ ВНИЗ case DIR_LEFT: mode--; // Уменьшаем номер режима на единицу if(mode < 1){mode = 11;} // Если значение меньше допустимого, то переходим к максимально большому значению break; //==========================================================// // "ВОСТОК" - ЛИСТАЕМ РЕЖИМЫ ВВЕРХ case DIR_RIGHT: mode++; // Увеличиваем номер режима на единицу if(mode > 11){mode = 1;} // Если значение больше допустимого, то переходим к минимальному значению break; //==========================================================// // "ОТДАЛЕНИЕ" - ПЕРЕХОД В РЕЖИМ ЯРКОСТИ case DIR_FAR: setting = 1; // Ставим флаг перехода в режим настройки яркости flg = 1; // Ставим флаг смены работы режима датчика жестов - с чтения жестов на чтение приближения work_time = millis(); // Обновляем счётчик break; //==========================================================// // "ПРИБЛИЖЕНИЕ" - ПЕРЕХОД В РЕЖИМ ВЫКЛЮЧЕНИЯ СВЕТА case DIR_NEAR: mode = 12; // Устанавливаем режим выключения света break; } } // РЕЖИМЫ РАБОТЫ СВЕТОДИОДОВ: switch (mode) { // Сверяем значение соответствующее режиму работы //==========================================================// // ПЕРЕЛИВ ВСЕХ ЦВЕТОВ РАДУГИ case 1: j++; // Смещаем спектр цветов для всех светодиодов for(uint16_t i=0; i millis()){ // с момента входа в режим настройки не прошло ли время waiting_time, и если не прошло то... if(flg){ // проверяем, стоит ли флаг смены режима работы датчика жестов. Если стоит, то flg = 0; // сбрасываем флаг, apds.disableGestureSensor(); delay(500); // выключаем режим чтения жестов, ждём 0,5с, apds.enableProximitySensor(false); // включаем режим чтения приближения, led.setColor(NeoPixelAll,0 ,0 ,0 ); led.write(); delay(500); // выключаем светодиоды, ждём 0,5с, led.setColor(NeoPixelAll,25 ,25 ,25 ); led.write(); delay(500); // включаем светодиоды, ждём 0,5с, led.setColor(NeoPixelAll,0 ,0 ,0 ); led.write(); // выключаем светодиоды. } if(apds.readProximity(proximityData)){ // Если датчик считывает приближение, то... brightness = map(proximityData,0, 255,255,10); // регулируем яркость, "перевернув" диапазон значений, приходящий с датчика } } else { // Если время waiting_time прошло, то setting = 0; // сбрасываем флаг режима настройка яркости, apds.disableProximitySensor(); delay(500); // выключаем режим чтения приближения, ждём 0,5с, apds.enableGestureSensor(false); // включаем режим чтения жестов, led.setColor(NeoPixelAll,0 ,0 ,0 ); led.write(); delay(500); // выключаем светодиоды, ждём 0,5с, led.setColor(NeoPixelAll,25 ,25 ,25 ); led.write(); delay(500); // включаем светодиоды, ждём 0,5с, led.setColor(NeoPixelAll,0 ,0 ,0 ); led.write(); // выключаем светодиоды. } } delay(100); // Задержка, чтобы не перегружать шину I2C постоянными запросами }
Алгоритм работы скетча:
До кода void setup() определяются переменные, подключаются необходимые библиотеки.
В коде void setup() инициализируется датчик жестов, адресные светодиоды NeoPixel, выключаются светодиоды, если до этого они горели.
Код void loop() делится на несколько частей:
- Проверяется, определил ли датчик жестов какой-то жест;
- Если жест определён, тогда выполняется одно из действий, назначенное на этот жест: изменение режима работы светодиодов, изменение скорости анимации, изменение яркости, выключение;
- После того, как жест определён, в зависимости от того, какой был жест, скетч переходит к выбору режима работы (переменная
mode):- Работать в режиме плавного перелива RGB-цветами;
- Работать в режиме случайного выбора цветов;
- Работать в режиме случайного включения светодиодов случайным цветом;
- Работать в режиме переключения цветов;
- Работать в режиме имитации горения пламени свечи;
- Работать в режиме одного цвета (красный, зелёный, синий, жёлтый, фиолетовый, голубой, белый);
- Работать в режиме настройки яркости;
- Выключить свет;
- Если выбран режим настройки яркости, тогда:
- Перед входом в режим однократное включение светодиодов белым оповестит вас о том, что вы вошли в режим;
- Датчик будет переведён из режима чтения жестов в режим чтения расстояния до руки;
- В течении фиксированного времени
waiting_timeвы можете настраивать яркость работы светодиодов (поднесите руку к датчику и движением вверх-вниз регулируйте яркость); - По окончании режима настройки светодиоды снова однократно моргнут белым и ночник вернётся в рабочий режим;
- Если необходимо изменить скорость работы анимации, тогда:
- По умолчанию скорость анимации указана в переменной
z, а в скетче есть алгоритм изменения скорости:- Если
zпринимает значение от 1 до 10, то каждое движение вверх или вниз будет увеличивать или уменьшать его значение на 5; - Если
zпринимает значение от 10 до 100, то каждое движение вверх или вниз будет увеличивать или уменьшать его значение на 20; - Если
zпринимает значение от 100 до 500, то каждое движение вверх или вниз будет увеличивать или уменьшать его значение на 50;
- Если
- По умолчанию скорость анимации указана в переменной
- Если выбран режим выключения света, тогда все светодиоды потухнут, а для того, чтобы их снова зажечь, достаточно будет просто выполнить жест смены режима работы;

Обсуждение