Espruino:Примеры/Управление колонкой IKEA ENEBY

Материал из Онлайн справочника
Перейти к навигацииПерейти к поиску

Перевод: Максим Кузьмин
Проверка/Оформление/Редактирование: Мякишев Е.А.


Управление колонкой IKEA ENEBY[1]

Hacking Ikea Eneby Speakers

Динамик IKEA ENEBY славится хорошим отношением цены и качества (включая качество звука). Но если вы планируете ставить его поодаль от себя, то столкнётесь с несколькими проблемами:

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

Но всего этого можно избежать, оснастив динамик функцией дистанционного управления.

Что вам понадобится

Подсоединение

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

Что ещё лучше, ко всем кнопкам подключены резисторы на 1 кОм, что даёт возможность подключиться напрямую к Espruino и перезаписать сигнал, идущий от кнопки, не рискуя вызвать короткое замыкание.

  • Переверните динамик и вытащите 8 резиновых затычек.
  • Выкрутите 10 шурупов. 8 из них находятся по периметру динамика, ещё 2 – чуть ближе к центру (см. фото ниже):
  • Осторожно подковырните заднюю крышку динамика и вытащите её
  • Внутри будет печатная плата включения питания:
  • Подключите модуль MDBT42Q как показано в таблице ниже:
ENEBY Espruino
GND GND
3-3V 3.3v
PO-KEY D14
VL- D15
VL+ D16
WHITE-LED D17

Как видите, мы решили воспользоваться контактами D14-D17 на Espruino (это подойдёт и для Puck.js, если вы используете именно его), но вы можете задать любые другие GPIO-контакты.

  • Надёжно приклейте модуль, проверьте все соединения и соберите ENEBY.

Код

Будучи подключенным к модулю MDBT42Q (установленному внутри ENEBY) при помощи Web IDE Espruino, загрузите на него вот этот код:

var BTN_PWR = D14;
var BTN_V1 = D15;
var BTN_V2 = D16;
var BTNS_VOL = [BTN_V1,BTN_V2];
var LED_PWR = D17;
var VOLUME_PATTERN = [ 0b00,0b10,0b11,0b01 ];

function pressPower() {
  digitalWrite(BTN_PWR,0);
  setTimeout(function() {
    digitalRead(BTN_PWR); // разомкнутая цепь
  }, 200);
}

function turnOn(callback) {
  if (!LED_PWR.read()) pressPower();
  if (callback) setTimeout(callback,1000);
}

function turnOff(callback) {
  if (LED_PWR.read()) pressPower();
  if (callback) setTimeout(callback,1000);
}

function setVolume(dir, callback) {
  if (!dir) return callback?callback():undefined;
  var sign = dir>0?1:-1;
  var idx = VOLUME_PATTERN.indexOf(
    digitalRead(BTNS_VOL));
  function moveKnob() {
    idx = (idx+sign)&3;
    digitalWrite(BTNS_VOL, VOLUME_PATTERN[idx]);
  }
  moveKnob();
  setTimeout(moveKnob, 100);
  setTimeout(moveKnob, 200);
  // Возвращаем громкость на позицию по умолчанию:
  setTimeout(_=>digitalRead(BTNS_VOL), 300);
  setTimeout(_=>setVolume(dir - sign,callback), 400);
}

function onInit() {
  // Оставляем 30 секунд на то,
  // чтобы подключиться к MDBT42Q с помощью IDE,
  // а потом отключаем соединение:
  setTimeout(function() {
    NRF.setServices({
      "5c02000124f80e9c425c263166152320" : {
        "5c02000224f80e9c425c263166152320" : {
          writable : true,
          onWrite : function(evt) {
            var cmd = evt.data[0];
            if (cmd===0) turnOff();
            else if (cmd==1) turnOn(_=>setVolume(4));
            else if (cmd==2) setVolume(1);
            else if (cmd==3) setVolume(-1);
          }
        }
      }
    },{uart:false});
    NRF.setAdvertising({},{name:"IkeaSpk"});
  }, 30*1000);
}

Напечатайте save() и отключитесь.

Примечание: Код выше устроен так, что вы можете подключиться к MDBT42Q (при помощи Web IDE) только в первые 30 секунд после включения питания, после чего соединение будет отключено, чтобы злоумышленники (или вы сами – случайно) не смогли перепрограммировать ваше устройство. Обычно MDBT42Q можно перепрограммировать, зажав кнопку (и тем самым инициировав перезагрузку), но в данном случае MDBT42Q находится внутри корпуса ENEBY, так что добраться до него будет затруднительно! То есть в результате дистанционное управление динамиком будет возможно только спустя 30 секунд после включения питания.

Загрузите на Puck.js, с помощью которого будет управляться ENEBY, вот этот код:

function sendCommand(cmd) {
  var gatt;
  digitalPulse(LED3,1,[100]); // начинаем – мигаем синим 
  NRF.requestDevice({ filters: [{ name: 'IkeaSpk' }] }).then(function(device) {
    digitalPulse(LED3,1,[100]); // нашли – мигаем синим
    return device.gatt.connect();
  }).then(function(g) {
    gatt = g;
    return gatt.getPrimaryService("5c02000124f80e9c425c263166152320");
  }).then(function(service) {
    return service.getCharacteristic("5c02000224f80e9c425c263166152320");
  }).then(function(characteristic) {
    return characteristic.writeValue([cmd]);
  }).then(function() {
    gatt.disconnect();
    // Один раз мигаем зелёным:
    digitalPulse(LED2,1,[100]);
    NRF.sleep(); // переводим Bluetooth в режим сна
  }).catch(function() {
    // Два раза мигаем красным:
    digitalPulse(LED1,1,[100,100,100]);
    // Возможно, не получится:
    try { gatt.disconnect(); } catch (e) {}
    NRF.sleep(); // переводим Bluetooth в режим сна
  });
}

function onButton(e) {
  var d = e.time - e.lastTime;
  if (d>0.5) sendCommand(0); // выкл
  else sendCommand(1); // вкл
}


setWatch(onButton, BTN, {repeat:true, edge:"falling"});

function onInit() {
  NRF.setServices({},{uart:false});
  NRF.setAdvertising({},{connectable:false,showName:false});
}

Напечатайте save(), чтобы сохранить код. В результате код сохранится даже после того, как вы вынете батарею.

См.также

Внешние ссылки