Хабрахабр

[Из песочницы] Включаем свет силой мысли, ну почти

KDPV

Написание алгоритмов наверное самая для меня интересная часть в домашней автоматизации. Но даже вся масса сенсоров и сценариев не справляется с буйной фантазией жизни и приходится добавлять способ непосредственного контроля. В качестве органов ручного управления можно поставить и обычный дверной звонок, но что делать если хочется большего? Встречаем героя этой статьи — датчик жестов на основе SI1143 от Silicon Labs.
Сам SI1143:

SI1143

Выглядит и правда футуристично.

А сколько достоинств:

  • высокочувствительный фотодиод, малошумящий АЦП
  • драйвера светодиодов с током от 6 до 360 миллиампер
  • питание от 1.71 до 3.6 вольта
  • и шустрый I2C — до 3.4 мегабит в секунду

Вот только размер подкачал всего 5 на 3 миллиметра. Такое и разглядишь то не с первого раза. Ну ладно тут нужно ещё немного обвязки.

Device

Спросило моё чувство прекрасного. А можно это убрать? Я потом постараюсь удовлетворить просьбу этого редкого в наших краях гостя и спрятать плату в корпус, а пока можно подать питание и посмотреть что-же получилось.

Тут действительно несколько больше деталей чем ожидалось. Комментарий для внимательных. Кроме микроконтроллера STM32F051 на плате установлен так-же приёмопередатчик на 868 мегагерц CC1101 от Texas Instruments и после заливки firmware достаточно подать питание и устройство подключится к MQTT-SN серверу.
В качестве основы была взята нода из проекта Enviriot.

Принцип работы основан на измерении уровня отражённого сигнала от каждого из 3 светодиодов. Попробую включить и посмотреть на отклик.

signal

Из-за несимметричного расположения светодиодов сигнал от LED 1 заметно больше и придётся первым делом результаты измерений нормировать.

signal_norm

Попробуйю закодить следуюший алгоритм:
А вот так зависимость уже вполне понятна.

Где L1+ — сигнал от LED 1 возрастает, L1>L3 — сигнал от LED 1 больше сигнала от LED 3.

Для листа белой бумаги зафиксированного на одной высоте ожидаемые результаты получались в двух случаях из трёх. Гладко было на бумаге, а вот в динамике начались проблемы. Посмотрел на руку, ну да от плоского листа белой бумаги отличий много. При попытке помахать руками сигнал начинает прыгать и мой замечательный алгоритм начинал путаться в показаниях. Ладно. Но как-то оно должно работать. Попробую прочитать документацию. Уговорили!

Для страждущих Silicon Labs выпустила AppNote AN580 — «INFRARED GESTURE SENSING». Описаны 2 основных метода определения жестов и их возможные комбинации. Первый метод — это определение позиции на каждый момент времени и на основе координат определение жестов. Во втором методе определяется сдвиг фаз между сигналами. Уже опробован был один из вариантов первого метода и он не впечатлил. Попробую реализовать второй.

Нужно реализовать аж целых два пункта. Поехали. Порог входа был определён экспериментально в 1/8 от полного сигнала. Определить момент входа и передать эти данные в конечный автомат. Для защиты от шума добавлю триггер Шмидта, включение на 15% и отключение на 10%.

Состояния с 1 по 3 — движение вверх, состояния -1 по -3 — движение вниз и состояние 4 на тот маловероятный случай, если сработают оба LED одновременно. Ну и сам конечный автомат.

ka

А теперь попробуем со всем этим взлететь.

var LSt = new Int8Array([-3, -3, -3, 1, 1, 3, 3, 4, -3, -3, -1, -1, 3, 3, 3, 4, -2, -2, -2, 4, 2, 2, 2, 4]);
/* ...... */
this.r1 = false; this.r3 = false;
this.button = new Int8(0);
/* ...... */
if(n1 > 15) else if(n1 < 10) { this.r1 = false; } if(n3 > 15) { this.r3 = true; } else if(n3 < 10) { this.r3 = false; } let st = (this.r1?1:0) | (this.r3?2:0);
if(st == 0){ // Оптимизация. На Нет и ответа нет this.button = 0;
} else { this.button = LSt[st*8 + this.button - 5]; }

В переменных n1 и n3 лежат нормализованные значения для соответствующих светодиодов. Результат находится в поле button.

Для дальнейшего использования полезны состояния 2 — вверх и -2 — вниз.

Разбором JavaScript и генерацией AST занимается библиотека NiL. Программа пишется на подмножестве JavaScript, потом компилируется в bytecode и заливается на устройство. JS от камрада IaIojek, за что ему огромное спасибо.

Logramm

3 секунды, за это отвечают блоки А14 и А15, яркость выставляется на максимум. Если состояние 2 длится меньше 0. Блоки А01 и А13 выставляют яркость в 0 при кратковременном движении вниз.

При движении вниз и удержании работают блоки А12, А11 и А08 и позволяют уменьшить уровень. При движении вверх и удержании блоки А10, А09 и А04 обеспечивают плавное увеличение яркости.

Демонстрация работы. 20 Мегабайт гифка.

demo

Ну вот пожалуй и всё. Заказчик довольна, а я начинаю думать над следующей версией. Из необходимых изменений: расположить светодиоды на одинаковом расстоянии от приёмника, вывести индикацию срабатывания и сделать опрос на отдельном контроллере, что позволит уменьшить интервал опроса.

Теги
Показать больше

Похожие статьи

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Кнопка «Наверх»
Закрыть