Espruino:Примеры/Цифровые кости

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

Перевод: Максим Кузьмин (Cubewriter) Контакты:</br>* Skype: cubewriter</br>* E-mail: cubewriter@gmail.com</br>* Максим Кузьмин на freelance.ru
Проверка/Оформление/Редактирование: Мякишев Е.А.


Цифровые кости[1]

Espruino Project - Digital Dice

В этом руководстве мы расскажем, как сделать устройство на видео выше – многофункциональные цифровые кости.

Нам понадобятся

Digital Dice step1.jpg
  • Чистая и пустая банка от Pringles
  • Плата Espruino
  • Батарея
  • Переключатель и два провода для него
  • Гирлянда светодиодов WS2811
  • Обёрточная бумага, изолента и двусторонняя изолента (не показаны на фото выше)

Что надо сделать

Отмерьте 4 см с обоих концов банки, а затем отрежьте их как можно прямее с помощью монтажного ножа.

Также вырежьте ещё одно кольцо из середины банки шириной около 3 см и сделайте в нём один поперечный разрез. Это кольцо поможет закрепить светодиоды внутри банки.

Digital Dice step2.jpg

Затем проделайте в донном конце банки 12 отверстий (8 мм) так, чтобы они находились на одинаковом расстоянии друг от друга и примерно в 2 мм от края банки. Также нужно будет проделать отверстие в середине – для переключателя. Я сначала при помощи маркера отметил места для отверстий, а уже потом просверлил их.

Digital Dice step3.jpg

Теперь примкните оба конца банки друг к другу и скрепите изолентой изнутри.

Digital Dice step4.jpg

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

Digital Dice step5.jpg

Теперь повнимательнее приглянитесь к обоим концам светодиодной гирлянды. Светодиоды сделаны из прозрачного пластика, поэтому вы должны увидеть надписи на печатной плате в тех местах, куда подключены провода. На одном конце должны быть отчётливые надписи «5V, DI, GND», а на другом, возможно, «D0» (а иногда на нём вообще ничего нельзя разобрать). Пометьте провода, идущие от конца с надписями «5V, DI, GND», а оставшийся провод нам не важен – просто отогните его в сторону.

Теперь просуньте все 12 светодиодов в их отверстия в донной части банки (по порядку). Их также можно закрепить на месте при помощи клея Blu Tack или двусторонней изоленты.

Digital Dice step6.jpg

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

Digital Dice step7.jpg

Теперь подсоедините два провода к переключателю. Чтобы контакты не замыкали, я одел на них изоляционную термоусадочную трубку, но подойдёт и обычная изолента. Если контакты замкнут, это не вызовет никаких повреждений, но Espruino будет думать, что мы нажали на кнопку.

Digital Dice step8.jpg

Теперь припаяйте эти провода к Espruino:

  • Первый провод – к контакту A1 на Espruino.
  • Второй провод – к контактной площадке 3.3v (она должна быть рядом с A1).

Теперь возьмите помеченный конец гирлянды (тот, что с надписями «5V, DI, GND») и разделите его на 3 провода, каждый из которых будет соответствовать какой-либо из пометок:

  • Подключите провод 5V к контакту VBAT на Espruino.
  • Подключите провод GND к контакту GND на Espruino.
  • Подключите провод DI к контакту B5 на Espruino (для этого провода вам понадобится контакт, помеченный как SPI#_MOSI).

Готово! Теперь можно подключать батарею.

Digital Dice step9.jpg

Теперь мы можем поместить всё это внутрь. Espruino и батарея должны плотно сесть между светодиодами. USB-коннектор должен смотреть наружу – чтобы вы могли подключить его к ПК.

Digital Dice step10.jpg

Код

Теперь код! Подключите ваш ПК к Espruino как объясняется здесь. Вы также можете поэкспериментировать с примерами кода из статьи о светодиодах WS2811, но не забывайте использовать контакт B5 для шины SPI.

Теперь просто скопируйте и вставьте код ниже, в результате чего на костях начнёт вращаться светодиодной «волчок» как показано в видео выше:

SPI1.setup({baud:3200000, mosi:B5});
var FRONT_BUTTON = A1;

var slowdown;
var speed;
var running;
var timePressed;
var pos=0;

// Нажатие на кнопку:
setWatch(function(e) {
  if (e.time < timePressed+0.01) return; // убираем «дребезг»
  timePressed = e.time;
  // Удаляем анимацию, если она выполняется в данный момент:
  clearInterval();
  // Задаём начальные значения:
  speed = 20; 
  slowdown = 1.1 + Math.random()*0.1;
  running = true;
  // Запускаем анимацию...
  setInterval(function() { 
    if (!running) { // если кнопка была отпущена...
      speed = speed * slowdown; // замедляем
      changeInterval(1,speed);  // используем это,
                                // чтобы замедлить таймер
      if (speed > 500) clearInterval(); // если стало совсем медленно,
                                        // останавливаем анимацию
    }
    pos++; // крутим
    if (pos>11) pos = 0; // дойдя до последнего светодиода,
                         // обнуляем счётчик
    // Теперь рассчитываем то, какой паттерн показать -
    // включаем один светодиод (с красным и синим огнями):
    var leds = new Uint8Array(12*3);
    leds[0+(11-pos)*3] = 255; // красный
    leds[2+(11-pos)*3] = 255; // синий
    SPI1.send4bit(leds, 0b0001, 0b0011); // отправляем на светодиоды
  }, speed); // скорость для setInterval()
}, FRONT_BUTTON, { repeat: true, edge: "rising" });

// Отпускание кнопки:
setWatch(function(e) {
  timePressed = e.time;
  // Сигнал для замедления и остановки анимации:
  running = false;
}, FRONT_BUTTON, { repeat: true, edge: "falling" });

function onInit() {
  // Притягиваем переключатель к значению «0»,
  // чтобы не использовать внешний резистор:
  pinMode(FRONT_BUTTON, "input_pulldown");
}
onInit();

Или же вы можете загрузить на Espruino код ниже, умеющий работать во всех режимах, которые были показаны на видео в самом начале статьи:

clearWatch();
SPI1.setup({baud:3200000, mosi:B5});
var FRONT_BUTTON = A1;

var hours = 3,mins = 20,secs = 0;
var slowdown;
var speed;
var running;
var mode = 0;
var timePressed;
var pos=0;

// Нажатие на кнопку:
setWatch(function(e) {
  if (e.time < timePressed+0.01) return; // убираем «дребезг»

  timePressed = e.time;
  clearInterval();
  if (mode == 0) { // часы
    setInterval(function() {
      secs++;
      if (secs>59) {
       secs = 0;
       mins++;
       if (mins>59) {
         mins = 0;
         hours++;
         if (hours>11) {
          hours = 0;
         }
       }
      }
      var leds = new Uint8Array(12*3);
      var secled = parseInt(secs/5);
      leds[1+(11-secled)*3] = 255; // зелёный
      var minled = parseInt(mins/5);
      leds[2+(11-minled)*3] = 255; // синий
      leds[0+(11-hours)*3] = 255; // красный
      SPI1.send4bit(leds, 0b0001, 0b0011);
    }, 1000);
  } else if (mode == 1) { // вращение
    speed = 20;
    slowdown = 1.1 + Math.random()*0.1;
    running = true;
    setInterval(function() {
      if (!running) {
        speed = speed * slowdown;
        changeInterval(1,speed);
        if (speed > 500) clearInterval();
      }
      pos++;
      if (pos>11) {
       pos = 0;
      }
      var leds = new Uint8Array(12*3);
      leds[0+(11-pos)*3] = 255; // красный
      leds[2+(11-pos)*3] = 255; // синий
      SPI1.send4bit(leds, 0b0001, 0b0011);
    }, speed);
  } else if (mode == 2) { // случайное число 
                          // в диапазоне между 1 и 6
    speed = 20;
    slowdown = 1.1 + Math.random()*0.1;
    running = true;
    setInterval(function () {
      if (!running) {
        speed = speed * slowdown;
        changeInterval(1,speed);
        if (speed > 500) clearInterval();
      }
      pos = parseInt(Math.random()*6)*2;
      var leds = new Uint8Array(12*3);
      var r = 1+parseInt(Math.random()*6);
      leds[0+(11-pos)*3] = (r&1)?0:255; // красный
      leds[1+(11-pos)*3] = (r&2)?0:255; // зелёный
      leds[2+(11-pos)*3] = (r&4)?0:255; // синий
      SPI1.send4bit(leds, 0b0001, 0b0011);
    }, speed);
  } else if (mode == 3) {
    speed = 20;
    slowdown = 1.2 + Math.random()*0.1;
    running = true;
    setInterval(function () {
      if (!running) {
        speed = speed * slowdown;
        changeInterval(1,speed);
        if (speed > 500) clearInterval();
      }
      var patterns = [
        [0],
        [0,5],
        [0,4,8],
        [0,3,6,9],
        [0,2,4,6,9],
        [0,2,4,6,8,10],
      ];
      var r = parseInt(Math.random()*patterns.length);
      var leds = new Uint8Array(12*3);
      for (i in patterns[r]) {   
        leds[1+patterns[r][i]*3] = 255; // зелёный
        leds[2+patterns[r][i]*3] = 255; // синий
      }
      SPI1.send4bit(leds, 0b0001, 0b0011);  
    }, speed);
  }
}, FRONT_BUTTON, { repeat: true, edge: "rising" });

// Отпускание кнопки:
setWatch(function(e) {
  if (e.time < timePressed+0.01) return; // убираем «дребезг»
  if (e.time > timePressed+1) { // долгое нажатие
    clearInterval();
    // Переходим в следующий режим:
    mode++;
    if (mode>3) mode=0;
    print(mode);
    // Выключаем все светодиоды:
    SPI1.send4bit(new Uint8Array(12*3), 0b0001, 0b0011); 
  } else {
    // Короткое нажатие – 
    // это сигнал для замедления и остановки анимации:
    running = false;
  }
  timePressed = e.time;
}, FRONT_BUTTON, { repeat: true, edge: "falling" });

function onInit() {
  // Притягиваем контакт, к которому подключена кнопка, к «0»,
  // чтобы не использовать внешний резистор:
  pinMode(FRONT_BUTTON, "input_pulldown");
}
onInit();

Вот и всё – мы сделали цифровые кости! Теперь напечатайте save(), и весь этот код будет сохранён на flash-память. В результате при следующем запуске Espruino автоматически загрузит этот код для цифровых костей!

См.также

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