Включаем свет силой мысли, ну почти

в 14:47, , рубрики: diy или сделай сам, MQTT-SN, SI1143, домашняя автоматизация
KDPV

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

Сам SI1143:

SI1143

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

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

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

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

Device

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

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


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

signal

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

signal_norm

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

A B C D
===> L1+
L3+
L1>L3
L1-
L3+
L1>L3
L1-
L3+
L1>L3
L1-
L3-
L1<L3
<=== L1-
L3-
L1<L3
L1+
L3-
L1<L3
L1+
L3-
L1<L3
L1+
L3+
L1>L3

Где 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) { this.r1 = true; } 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, потом компилируется в bytecode и заливается на устройство. Разбором JavaScript и генерацией AST занимается библиотека NiL.JS от камрада IaIojek, за что ему огромное спасибо.

Logramm

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

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

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

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

Автор: hensew

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js