Espruino:Примеры/Словесные часы

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

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


Словесные часы[1]

Word Clock final.jpg

В этом проекте мы создадим светодиодные часы, которые будут показывать время с помощью слов. Принцип работы этого устройства очень прост: это устройство будет подсвечивать нужные буквы на «дисплее», которые складываются в слова, благодаря которым пользователь и будет видеть нужное время.

Чтобы не слишком тратиться на светодиоды, время будет показываться с точностью до 5 минут.

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

Word Clock parts.jpg
  • Глубокая рама для картины (я воспользовался рамой из «Икеи»)
  • 88 светодиодов WS2811 (они будут расположены матрицей 8х11)
  • Толстый жёсткий картон и инструменты для его резки
  • Плата Espruino (если точнее, Espruino Pico – 1v4 или 1v3 с внутренним кристаллом для отслеживания времени)
  • Блок питания с USB-разъёмом
  • Инструменты для пайки

Сборка

Word Clock card.jpg


Word Clock grid.jpg

Вырежьте из картона 17 полос как показано на фото выше – отмерьте их так, чтобы они вместились в картинную раму – а затем соберите вместе.

Прорези в картонных полосах нужны для светодиодов WS2811 и их проводов. Но если вы решили воспользоваться плоской лентой светодиодов, то большие прорези делать не понадобится.

Word Clock leds part.jpg

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

Word Clock leds glued.jpg


Word Clock letters.jpg

Теперь напечатайте лист с буквами – они должны соответствовать ячейкам «клетки» из картонных пластин, которую мы собрали выше. Я распечатал буквы на простом листе бумаги (но зеркально) и так, чтобы белая сторона была повёрнута к пользователю (но, если хотите, буквы можно печатать и без отзеркаливания). Кроме того, буквы можно сделать при помощи трафарета – для этого вам понадобятся ацетатная плёнка и распылитель краски.

Если вы решили распечатать текст, то лучше делать это при помощи лазерного принтера или ксерокса. Если взять обычный струйный принтер и распечатать много чёрного цвета на тонкой бумаге, это слегка исказит буквы, из-за чего картинка будет выглядеть некрасиво.

Word Clock assembled back.jpg

Теперь соберите всё и подключите к плате Espruino следующим образом:

Провод Функция Espruino
Красный Плюс Bat
Белый Минус GND
Зелёный Передача данных B15

Вот и всё! Теперь давайте займёмся кодом...

Word Clock clock.jpg

Код

Загрузите код ниже на Espruino, напечатайте save() и готово!

Время задаётся при помощи переменных h, m и s (часы, минуты и секунды).

// Индексы для каждого слова:
var words = {
  "its":[76,77,54],
  "_five":[80,51,58,29],
  "_ten":[75,74,73],
  "_quarter":[79,52,57,30,35,8,13],
  "_twenty":[75,78,53,56,31,34],
  "_half":[32,33,10,11],

  "past":[72,81,50,59],
  "to":[36,7],

  "one":[71,82,49],
  "two":[70,83,48],
  "three":[60,27,38,5,16],
  "four":[69,68,67,66],
  "five":[84,85,86,87],
  "six":[28,37,6],
  "seven":[61,26,39,4,17],
  "eight":[47,62,25,40,3],
  "nine":[17,18,19,20],
  "ten":[15,16,17],
  "eleven":[46,63,24,41,2,19],
  "twelve":[45,64,23,42,1,20],
  "oclock":[44,65,22,43,0,21],

  "pico" : [55,9,12,14]
};
// Настраиваем SPI:
SPI2.setup({baud:3200000, mosi:B15});
var arr = new Uint8Array(8*11*3);
var pos = 0;

// Конвертируем HSV в RGB.
// Здесь мы рассчитываем, какой цвет задать для каждого слова:
function HSVtoRGB(h, s, v) {
    var r, g, b, i, f, p, q, t;
    if (h && s === undefined && v === undefined) {
        s = h.s, v = h.v, h = h.h;
    }
    i = Math.floor(h * 6);
    f = h * 6 - i;
    p = v * (1 - s);
    q = v * (1 - f * s);
    t = v * (1 - (1 - f) * s);
    switch (i % 6) {
        case 0: r = v, g = t, b = p; break;
        case 1: r = q, g = v, b = p; break;
        case 2: r = p, g = v, b = t; break;
        case 3: r = p, g = q, b = v; break;
        case 4: r = t, g = p, b = v; break;
        case 5: r = v, g = p, b = q; break;
    }
    return [Math.floor(r * 255),Math.floor(g * 255),Math.floor(b * 255)];
}

// Используя массив со словами,
// задаём нужные цвета у нужных светодиодов:
function getPattern(wordList) {
  arr.fill(0);
  var i = 0;
  pos+=0.05;
  wordList.forEach(function(word) {
    words[word].forEach(function(led) {
      arr.set(HSVtoRGB(i+pos,1,1,1),led*3);
    });
    i+=0.2;
  });
}


// Преобразовываем часы и минуты (секунды игнорируются) 
// в строку вроде «_five minutes past six» (пять минут седьмого).
// Нижнее подчёркивание в начале нужно,
// чтобы случайно не подсветить не то слово «five».
function timeToWords(h,m,s) {
  var mins = ["","_five","_ten","_quarter","_twenty","_twenty _five","_half"];
  var hours = ["", "one","two","three","four","five","six","seven","eight","nine","ten","eleven","twelve"];

  var str = "its ";
  // Ближайшие пять минут:
  var midx = Math.round(m/5);
  var hidx = h;
  // Здесь мы рассчитываем, какой час нужно показать
  // в зависимости от того, какая эта форма обозначения времени:
  // «x minutes past y» (например, «шесть минут пятого»)
  // или «x minutes to y» (например, «без шести пять»).
  if (midx>6) {
    if (midx==12) midx=0;
    hidx++;
    if (hidx>12) hidx -= 12;
  }
  // Наконец, показываем минуты и часы:
  if (midx!=0) {
    if (midx<=6)
      str += mins[midx]+" past ";
    else {
      str += mins[12-midx]+" to ";
    }
    str += hours[hidx];
  } else {
    str += hours[hidx];
    str += " oclock";
  }
  // Печатаем в консоли в отладочных целях:
  console.log(h+":"+m+":"+s+"    "+str);
  return str;
} 

// Очень упрощённое отслеживание времени:
var h=5,m=59,s=0;
setInterval(function() {
  // Увеличиваем секунды:
  s++;
  if (s>=60) {
    // Если количество секунд доходит до 60,
    // увеличиваем минуты и так далее:
    s=0;
    m+=1;
    if (m>=60) {
      m=0;
      h++;
      if (h>12)
        h=1;
    }
  }
  // Считываем время в виде строки:
  var timeWords = timeToWords(h,m,s);
  // Преобразовываем его в массив слов
  // и зажигаем нужные светодиоды:
  getPattern(timeWords.split(" "));
  SPI2.send4bit(arr, 0b0001, 0b0011);
}, 1000);

Вы также можете добавить к проекту кнопки, чтобы с их помощью задавать время. Кроме того, точное время можно прочесть из интернета или при помощи системы [GPS (для этого понадобится GPS-модуль).

См.также

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