Tag Archives: WiFi

Управляемая RGB лампочка: Часть 1 – NeoPixel-и

Сейчас куда не глянь везде всё умное. Умные розетки, кофеварки, телевизоры и конечно же лампочки. Одной из первых таких ламп я увидел Philips HUE, и загорелся идеей сделать свою управляемую RGB лампочку. У такой лампочки масса очевидных преимуществ: задание цвета под настроение, автоматическое включение/выключение, светобудильник, плюс неочевидные, как например светомузыка. Сказано сделано – начинаем копать.

Первое, что нужно решить – это каким будет источник света. Сейчас в моде светодиоды – они компактны и потребляют мало электричества, к тому же у меня завалялось 15 NeoPixel-ей от Adafruit на основе ws2812b.

20160117_185334Это 3 светодиода в одном плюс управляющая электроника. Особенность в том, что управляются они по одному проводу (вместе с напругой и землёй – три). Грубо говоря по проводу с данными вы передаёте сигнал, представляющий массив значений цветов. А дальше первый NeoPixel “откусывает” от этого массива первый элемент, выставляет его себе и передаёт остаток дальше и так далее по цепочке.

20160117_193644Второе – это какую беспроводную технологию использовать. WiFi мне кажется более универсальной и лучше масштабируемой в отличии от Bluetooth – это позволяет добавлять огромное количество таких ламп и заодно даёт возможность управления ими с помощью любого устройства, находящегося в этой же сети (да и за её пределами). Да и радиус действия у них гораздо больше. К тому же у меня валялось 3 модуля на основе esp8266.

20160117_190110Третье – это на чем реализовать управляющую логику. В наличии был Arduino Uno к нему и решил подключить NeoPixel-и, следуя инструкции на сайте Adafruit.

20160117_195326Однако Arduino Uno слишком большой, чтобы он мог поместиться в корпус стандартной лампочки. В интернете мне попалось видео, как уменьшить свои Arduino Uno проекты используя ATTiny45/85. К тому же на instructables есть guide, как заставить ATTiny работать с NeoPixel-ями. Не долго думая я купил ATTiny45 и перенёс пример с полноценной Arduino Uno на эту мелочь.

20160117_201131 1 20160117_204324

С другой стороны esp8266 – это очень мощная штука при малых размерах. Помимо WiFi этот SoC имеет ещё и GPIO. Я взял ESP-01 у которого есть два GPIO. К тому же Arduino IDE поддерживает это семейство начиная с версии 1.6.4 и у Adafruit даже есть гайд по настройке. Единственная проблема – это то, как заливать туда свой софт. Я купил USB-Serail converter который имеет выходной сигнал на 3.3 вольта, так как 5 вольт убьет esp8266 и сделал две кнопки на макетной плате, так как для заливки нового софта требуется перевести один из пинов в Low и затем RESET-нуть esp8266, более подробно о том как заливать свои программы можно прочитать тут:

20160117_193458 20160117_193920 1

Пусть вас не смущает наличие Arduino Uno на картинке справа – его я использовал исключительно, чтобы получить 3.3 вольта и запитать esp8266, а также чтобы получить 5 вольт для NeoPixel-ей.

20160118_205216Стандартный пример от Adafruit заработал и я бросился писать простенькую программку, которая бы коннектилась к моей домашней WiFi сети, поднимала сокет и ждала число, которое бы определяло цвет светодиодов. В интернете я наткнулся на хороший пример того, как общаться с esp8266 и на его основе с небольшими изменениями, используя Adafruit API для управление светодиодами, я добился чего хотел.

Для проверки накропал простенький скрипт на Perl-е, который бы и отправлял цвет для лампы:

use strict;

use IO::Socket::INET;

my $sock = new IO::Socket::INET(PeerAddr => '192.168.1.35',
                                PeerPort => '6969',
                    Proto => 'tcp') || die "Can't bind $@\n";

$sock->send(shift."\n");

И сама прошивка

#include <Adafruit_NeoPixel.h>
#include <ESP8266WiFi.h>

#define NEOPIXEL_DATA_PIN 0
#define PIXELS_NUM 7

Adafruit_NeoPixel strip = Adafruit_NeoPixel(PIXELS_NUM,
                                            NEOPIXEL_DATA_PIN,
                                           NEO_RGB + NEO_KHZ800);

const char* ssid = "mynetworkssid";
const char* password = "mynetpass";
WiFiServer server(6969);                                           

void setup() {
  Serial.begin(115200);
  strip.begin();
  strip.show();
 
  WiFi.begin(ssid, password);

  server.begin();
  while(WiFi.status() != WL_CONNECTED)
  {
    delay(500);
  }
}

void loop() {

  WiFiClient client = server.available();  
  if (client)
  {
    Serial.println("client connected.");
    while(client.connected())
    {
      if (client.available())
      {      
        String command;
        char c = client.read();
        while(c != '\n')
        {
          command += c;
          c = client.read();
        }

        if (command != 0)
        {
          char** tmp;
          char colorcommand[10];
          command.toCharArray(colorcommand, sizeof(colorcommand));
          
          uint32_t iColor = strtoul(colorcommand, tmp, 10);
           SetStripColors(iColor);
        }
      }
    }
    Serial.println("Client disconnected.");
    client.stop();
  }
}

void SetStripColors(uint32_t color)
{
  for (uint16_t i=0; i< PIXELS_NUM; i++)
  {
    strip.setPixelColor(i, color);
  }
  strip.show();
  delay(100);
}

Теперь дело за спецэфектами!