Minecraft Lamp

Thingiverse

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

Minecraft Lamp

В ремиксах этой модели увидел вставки вместо рассеивателей и кронштейн для светодиодной ленты. Тоже напечатал. Оставалось разобраться с электроникой.

Электроника

Самая первая из оконных гирлянд немного пострадала, поэтому лента была заменена на другую, к тому же герметичную, а старую ленту было решено использовать в других проектах или разобрать на светодиоды. Вот она и пригодилась! Подумал, что много светодиодов ставить нет смысла – хватит и пяти: по одному на сторону. Приклеил кусочек ленты на кронштейн.

Minecraft Lamp

Управлять работой ленты будет китайский клон Arduino Nano, а менять цвета и режимы будем с помощью сенсорной кнопки TTP223, приклеенной изнутри к крышке в одном из углов куба.

Параллельно со сборкой девайса на макетной плате разрабатывал программу управления. Заодно разбирался со средой PlatformIO IDE для Visual Studio Code. Работать в ней гораздо удобнее, чем в Arduino IDE.

Скетч

  • Лента и кнопка питаются от Arduino. Лента подключена к пину D2, кнопка – к пину D4.
  • Кратковременное нажатие меняет цвет. Цветов пока всего семь – количество и последовательность, как в радуге и голубой конечно же есть!
  • Удержание в течение секунды меняет режим. Режимов пока только два: один цвет с постоянной яркостью и один цвет с меняющейся яркостью. Последний ещё называют “дыхание”.
main.cpp
#include <Arduino.h>
#include "FastLED.h"

const byte ConstantColorMode = 1;
const byte ChangeBrightnessMode = 2;
const byte StepCount = 20;
const byte LedCount = 5;
const byte ColorCount = 7;
const byte LedPin = 2;
const byte ButtonPin = 4;
const int MaxBrightness = 110;       // стандартная маскимальная яркость (0-255)
const int MinBrightness = 30;       // стандартная маскимальная яркость (0-255)
const int CurrentLimit = 300;// лимит по току в миллиамперах, автоматически управляет яркостью (пожалей свой блок питания!) 

CRGB leds[LedCount];
CRGB colors[ColorCount] = {CRGB::Red, CRGB::Orange, CRGB::Yellow, CRGB::Green, CRGB::Cyan, CRGB::Blue, CRGB::BlueViolet};
int curColor = 4;
bool isPressed = false;
int tickCount = 0;
int curMode = ChangeBrightnessMode;
unsigned long runTimer;
unsigned long holdTimer = 0;
int step = (MaxBrightness-MinBrightness) / StepCount;

boolean button;

void setup()
{
  // настройки ленты
  FastLED.addLeds<WS2812, LedPin, GRB>(leds, LedCount).setCorrection(TypicalLEDStrip);
  FastLED.setBrightness(MaxBrightness);
  
  if (CurrentLimit > 0)
    FastLED.setMaxPowerInVoltsAndMilliamps(5, CurrentLimit);
  
  runTimer = millis();
  pinMode(3,INPUT);  
      
  fill_solid(leds, LedCount, colors[curColor]);
}

void loop()
{
  if( millis() - runTimer > 100)
  {
    runTimer = millis();
  
    if(curMode == ChangeBrightnessMode)
    {
      static int i=0;
      static int dir=1;
      
      FastLED.setBrightness(MinBrightness + i * step);
      FastLED.show();
      
      i=i+dir;
  
      if ( i == StepCount )
      {
        dir = -1;  
        i = StepCount - 2;
      }

      if (i==-1)
      {
        dir=1;  
        i=1;    
      }
    }    
  }

  button = digitalRead(ButtonPin);

  if (button)
  {
    if (!isPressed)
    {
      isPressed = true; 
      holdTimer = millis();      
    }
    else
    {
      if (millis() - holdTimer > 1000)
      {
        holdTimer = millis();

        FastLED.setBrightness(10);
        FastLED.show();
        delay(200);

        if (curMode == ChangeBrightnessMode)
        {
          curMode = ConstantColorMode;
          FastLED.setBrightness(MaxBrightness);
          FastLED.show();
        }
        else
          curMode = ChangeBrightnessMode;   

        curColor--;         
      }      
    }    
  }
  else
  {
    if(isPressed)
    {
      curColor++;
      if (curColor == ColorCount)    
        curColor = 0;      

      fill_solid(leds, LedCount, colors[curColor]);
      FastLED.show();
      isPressed = false;    
    }
  }
}
platformio.ini

[env:nanoatmega328]
platform = atmelavr
board = nanoatmega328
framework = arduino

; Скорость загрузки в baud
upload_speed = 57600
; COM-порт для загрузки
upload_port = COM4
; Подрубаем все библиотеки
lib_deps = https://github.com/FastLED/FastLED

Собирался всё снабдить комментариями, как и положено, но увлёкся. Позже исправлюсь.

Результат

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

Стараюсь бороться с внутренним перфекционистом, поэтому решил не совершенствовать этот кубик бесконечно, а собрать так, как могу здесь и сейчас. Идеи же буду реализовывать в следующих экземплярах.

Снова хочется получить готовый надёжный коммерческий продукт, как и с гирляндой. Гирлянда пока буксует, но это и объяснимо – интерес к таким вещам появляется только в декабре, а кубик из Minecraft актуален в любое время года.

Может показаться, что кубик автономный, т.к. не видно проводов, но это не так – он запитан от повербанка 😉
Идея по оснащению аккумулятором есть, но отложил на будущее.

Оцените статью
( 2 оценки, среднее 5 из 5 )
МихаТроник
Добавить комментарий