Skip to content
This repository has been archived by the owner on Sep 27, 2023. It is now read-only.

Commit

Permalink
Add neopixelbus component (#352)
Browse files Browse the repository at this point in the history
* Add neopixelbus component

Co-Authored-By: Patrick Huy <[email protected]>

* Change API for yaml
  • Loading branch information
OttoWinter authored Jan 5, 2019
1 parent 9472e89 commit 2e181ac
Show file tree
Hide file tree
Showing 11 changed files with 411 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,5 +31,7 @@ matrix:
if: branch = dev AND type = push
- env: BUILD_TARGET=fastled
if: branch = dev AND type = push
- env: BUILD_TARGET=neopixelbus
if: branch = dev AND type = push
- env: BUILD_TARGET=sonoff-b1
if: branch = dev AND type = push
35 changes: 35 additions & 0 deletions examples/neopixelbus/neopixelbus.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#include <esphomelib.h>

using namespace esphomelib;

uint16_t pixel_count = 30;
uint8_t pixel_pin = 2;
// in Neo800KbpsMethod (dma) the pixel_pin is not used and is always PIN 2 (RX)
NeoPixelBus<NeoGrbwFeature, Neo800KbpsMethod> strip(pixel_count, pixel_pin);

void setup() {
App.set_name("neopixelbus");
App.init_log();

App.init_wifi("YOUR_SSID", "YOUR_PASSWORD");
App.init_mqtt("MQTT_HOST", "USERNAME", "PASSWORD");
App.init_ota()->start_safe_mode();

auto neopixel = App.make_neo_pixel_bus_rgbw_light<Neo800KbpsMethod, NeoGrbwFeature>("NeoPixelBus SK 6812 Light");
neopixel.output->set_pixel_order(light::ESPNeoPixelOrder::GRBW);
neopixel.output->add_leds(&strip);
neopixel.state->set_default_transition_length(800);

neopixel.state->add_effects({
new light::RandomLightEffect("Random"),
new light::AddressableColorWipeEffect("Color Wipe"),
new light::AddressableRainbowLightEffect("Rainbow"),
});

App.setup();
}

void loop() {
App.loop();
delay(16);
}
2 changes: 2 additions & 0 deletions examples/neopixelbus/neopixelbus.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// This file intentionally left blank
// See other tab for the code
4 changes: 4 additions & 0 deletions library.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@
{
"name": "FastLED",
"version": "3.2.0"
},
{
"name": "NeoPixelBus",
"version": "2.4.1"
}
],
"build": {
Expand Down
9 changes: 9 additions & 0 deletions platformio.ini
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ lib_deps =
[email protected]
ESP Async [email protected]
[email protected]
[email protected]
build_flags = -Wno-reorder
src_filter = +<src>

Expand Down Expand Up @@ -104,3 +105,11 @@ framework = arduino
lib_deps = ${common.lib_deps}
build_flags = ${common.build_flags}
src_filter = ${common.src_filter} +<examples/sonoff-b1/sonoff-b1.cpp>

[env:neopixelbus]
platform = espressif32
board = nodemcu-32s
framework = arduino
lib_deps = ${common.lib_deps}
build_flags = ${common.build_flags}
src_filter = ${common.src_filter} +<examples/neopixelbus/neopixelbus.cpp>
43 changes: 43 additions & 0 deletions src/esphomelib/application.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
#include "esphomelib/light/light_output_component.h"
#include "esphomelib/light/light_state.h"
#include "esphomelib/light/mqtt_json_light_component.h"
#include "esphomelib/light/neo_pixel_bus_light_output.h"
#include "esphomelib/mqtt/custom_mqtt_device.h"
#include "esphomelib/mqtt/mqtt_client_component.h"
#include "esphomelib/mqtt/mqtt_component.h"
Expand Down Expand Up @@ -1196,6 +1197,23 @@ class Application {
MakeFastLEDLight make_fast_led_light(const std::string &name);
#endif

#ifdef USE_NEO_PIXEL_BUS_LIGHT
template<typename T_METHOD, typename T_COLOR_FEATURE>
struct MakeNeoPixelBusLight {
light::NeoPixelRGBLightOutput<T_METHOD, T_COLOR_FEATURE> *output;
light::LightState *state;
light::MQTTJSONLightComponent *mqtt;
};

/// Create an RGB NeoPixelBus light.
template<typename T_METHOD, typename T_COLOR_FEATURE = NeoRgbFeature>
MakeNeoPixelBusLight<T_METHOD, T_COLOR_FEATURE> make_neo_pixel_bus_rgb_light(const std::string &name);

/// Create an RGBW NeoPixelBus light.
template<typename T_METHOD, typename T_COLOR_FEATURE = NeoRgbwFeature>
MakeNeoPixelBusLight<T_METHOD, T_COLOR_FEATURE> make_neo_pixel_bus_rgbw_light(const std::string &name);
#endif




Expand Down Expand Up @@ -1489,6 +1507,31 @@ GlobalVariableComponent<T> *Application::make_global_variable(T initial_value) {
return this->register_component(new GlobalVariableComponent<T>(initial_value));
}

#ifdef USE_NEO_PIXEL_BUS_LIGHT
template<typename T_METHOD, typename T_COLOR_FEATURE>
Application::MakeNeoPixelBusLight<T_METHOD, T_COLOR_FEATURE> Application::make_neo_pixel_bus_rgb_light(const std::string &name) {
auto *neo_pixel = this->register_component(new light::NeoPixelRGBLightOutput<T_METHOD, T_COLOR_FEATURE>());
auto make = this->make_light_for_light_output(name, neo_pixel);

return MakeNeoPixelBusLight<T_METHOD, T_COLOR_FEATURE> {
.output = neo_pixel,
.state = make.state,
.mqtt = make.mqtt,
};
}
template<typename T_METHOD, typename T_COLOR_FEATURE>
Application::MakeNeoPixelBusLight<T_METHOD, T_COLOR_FEATURE> Application::make_neo_pixel_bus_rgbw_light(const std::string &name) {
auto *neo_pixel = this->register_component(new light::NeoPixelRGBWLightOutput<T_METHOD, T_COLOR_FEATURE>());
auto make = this->make_light_for_light_output(name, neo_pixel);

return MakeNeoPixelBusLight<T_METHOD, T_COLOR_FEATURE> {
.output = neo_pixel,
.state = make.state,
.mqtt = make.mqtt,
};
}
#endif

ESPHOMELIB_NAMESPACE_END

#endif //ESPHOMELIB_APPLICATION_H
1 change: 1 addition & 0 deletions src/esphomelib/defines.h
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@
#define USE_HOMEASSISTANT_SENSOR
#define USE_HOMEASSISTANT_TEXT_SENSOR
#define USE_APDS9960
#define USE_NEO_PIXEL_BUS_LIGHT
#endif

#ifdef USE_REMOTE_RECEIVER
Expand Down
Empty file.
Empty file.
126 changes: 126 additions & 0 deletions src/esphomelib/light/neo_pixel_bus_light_output.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
#ifndef ESPHOMELIB_LIGHT_NEO_PIXEL_BUS_LIGHT_OUTPUT_H
#define ESPHOMELIB_LIGHT_NEO_PIXEL_BUS_LIGHT_OUTPUT_H

#include "esphomelib/defines.h"

#ifdef USE_NEO_PIXEL_BUS_LIGHT

#include "esphomelib/helpers.h"
#include "esphomelib/light/light_state.h"
#include "esphomelib/light/addressable_light.h"
#include "esphomelib/power_supply_component.h"
#include "NeoPixelBus.h"

ESPHOMELIB_NAMESPACE_BEGIN

namespace light {

enum class ESPNeoPixelOrder {
GBWR = 0b11000110,
GBRW = 0b10000111, GBR = 0b10000111,
GWBR = 0b11001001,
GRBW = 0b01001011, GRB = 0b01001011,
GWRB = 0b10001101,
GRWB = 0b01001110,
BGWR = 0b11010010,
BGRW = 0b10010011, BGR = 0b10010011,
WGBR = 0b11011000,
RGBW = 0b00011011, RGB = 0b00011011,
WGRB = 0b10011100,
RGWB = 0b00011110,
BWGR = 0b11100001,
BRGW = 0b01100011, BRG = 0b01100011,
WBGR = 0b11100100,
RBGW = 0b00100111, RBG = 0b00100111,
WRGB = 0b01101100,
RWGB = 0b00101101,
BWRG = 0b10110001,
BRWG = 0b01110010,
WBRG = 0b10110100,
RBWG = 0b00110110,
WRBG = 0b01111000,
RWBG = 0b00111001,
};

/** This component implements support for many types of addressable LED lights.
*
* To do this, it uses the NeoPixelBus library. The API for setting up the different
* types of lights NeoPixelBus supports is intentionally kept as close to NeoPixelBus defaults
* as possible. To use NeoPixelBus lights with esphomelib, first set up the component using
* the helper in Application, then add the LEDs using the `add_leds` helper functions.
*
* These add_leds helpers can, however, only be called once on a NeoPixelBusLightOutputComponent.
*/
template<typename T_COLOR_FEATURE, typename T_METHOD>
class NeoPixelBusLightOutputBase : public LightOutput, public Component, public AddressableLight {
public:
void schedule_show();

#ifdef USE_OUTPUT
void set_power_supply(PowerSupplyComponent *power_supply);
#endif

NeoPixelBus<T_COLOR_FEATURE, T_METHOD> *get_controller_() const;

void set_correction(float red, float green, float blue, float white = 0.0f);

void clear_effect_data() override;

void setup_state(LightState *state) override;

/// Add some LEDS, can only be called once.
void add_leds(uint16_t count_pixels, uint8_t pin);
void add_leds(uint16_t count_pixels, uint8_t pin_clock, uint8_t pin_data);
void add_leds(uint16_t count_pixels);
void add_leds(NeoPixelBus<T_COLOR_FEATURE, T_METHOD> *controller);

// ========== INTERNAL METHODS ==========
void write_state(LightState *state) override;

void setup() override;

void loop() override;

float get_setup_priority() const override;

int32_t size() const override;

void set_pixel_order(ESPNeoPixelOrder order);

protected:
NeoPixelBus<T_COLOR_FEATURE, T_METHOD> *controller_{nullptr};
bool next_show_{true};
ESPColorCorrection correction_{};
uint8_t *effect_data_{nullptr};
uint8_t rgb_offsets_[4];
#ifdef USE_OUTPUT
PowerSupplyComponent *power_supply_{nullptr};
bool has_requested_high_power_{false};
#endif
};

template<typename T_METHOD, typename T_COLOR_FEATURE = NeoRgbFeature>
class NeoPixelRGBLightOutput : public NeoPixelBusLightOutputBase<T_COLOR_FEATURE, T_METHOD> {
public:
inline ESPColorView operator[](int32_t index) const override;

LightTraits get_traits() override;
};

template<typename T_METHOD, typename T_COLOR_FEATURE = NeoRgbwFeature>
class NeoPixelRGBWLightOutput : public NeoPixelBusLightOutputBase<T_COLOR_FEATURE, T_METHOD> {
public:
inline ESPColorView operator[](int32_t index) const override;

LightTraits get_traits() override;
};

} // namespace light

ESPHOMELIB_NAMESPACE_END

#include "esphomelib/light/neo_pixel_bus_light_output.tcc"

#endif //USE_NEO_PIXEL_BUS_LIGHT

#endif //ESPHOMELIB_LIGHT_NEO_PIXEL_BUS_LIGHT_OUTPUT_H
Loading

0 comments on commit 2e181ac

Please sign in to comment.