Adafruit is still trying to sell flexible 16 x 16 LED matraces for $95 each. You can buy them directly from China for less than $9. I now have 36 16 x 16 LED matraces. I am trying to combine two programming projects into one ESPHome/Home Assistant project. First, I found this tricky little callback program for custom components at https://loopylab.de/. I got it working with Home Assistant very easily. I find it interesting that it is not necessary to register the component with the “app” object. Perhaps because the component only receives information and does not provide it.
Second, just for kicks, I have been playing around with Arduino, PlatformIO, FastLED, LEDMatrix, Adafruit NeoMatrix, Adafruit GFX, Arduino GFX, etc., for almost a year without ESPHome or Home Assistant. I would like to combine all of these together and have a wireless LED panel matrix automatically turn on and off, display the date, sunrise and sunset times with graphics. Right now I use an Athom wall plug with Home Assistant to turn the 3 x 3 tiled matrix on and off. No time and date, little bitmaps, sunrise and sunset information.
I am trying to make my PlatformIO/Arduino project into an ESPHome Custom Component that works with Home Assistant. First, I struggled with adding two more callbacks for Home Assistant text sensors holding sunrise and sunset data. Second, I worked out the proper order for loading the libraries in the EspHome YAML file. The only problem left is the compilation error when PlatformIO starts to compile the ESPHome scripted main.cpp file.
Here is my code and the error message:
cst-cmpnt.yaml:
> esphome:
> name: cst-cmpnt
> friendly_name: cst-cmpnt
> includes:
> - "LEDMatrixCmpnt.h"
> libraries:
> - "Wire"
> - "SPI"
> - "fastled/FastLED"
> - "Adafruit BusIO"
> - "Adafruit GFX Library"
> - "Framebuffer GFX"
> - "FastLED NeoMatrix"
>
> esp32:
> board: esp32-s3-devkitc-1
> framework:
> type: arduino
>
> logger:
>
> api:
>
> encryption:
> key: "RBk7GAee8EMXAxo="
>
> ota:
> password: ""
>
> wifi:
> ssid: !secret wifi_ssid
> password: !secret wifi_password
>
> # Enable fallback hotspot (captive portal) in case wifi connection fails
> ap:
> ssid: "Cst-Cmpnt Fallback Hotspot"
> password: "U3BPl"
>
> captive_portal:
>
> number:
> - platform: template
> name: "Frequency"
> id: blink_frequency
> optimistic: true
> min_value: 0.1
> max_value: 100
> step: 0.1
> restore_value: true
>
> switch:
> - platform: template
> name: "Enable"
> id: panel_enable
> optimistic: true
> restore_mode: RESTORE_DEFAULT_OFF
>
> text_sensor:
> - platform: homeassistant
> name: "Sun Rise"
> entity_id: sensor.sun_next_rising
> id: sun_rise
> - platform: homeassistant
> name: "Sun Set"
> entity_id: sensor.sun_next_setting
> id: sun_set
>
> custom_component:
> - lambda: |-
> auto myMatrix = new LEDMatrixCmpnt(id(panel_enable), id(blink_frequency), id(sun_rise),
> id(sun_set));
> return {myMatrix};
LEDMatrixCmpnt.h:
> #include "esphome.h"
> #include <FastLED.h>
> #include <Adafruit_GFX.h>
> #include <FastLED_NeoMatrix.h>
>
> #define LED_PIN 38
> #define LED_PIN2 15
> #define PIN 13
>
> #define BRIGHTNESS 45
>
> #define mw 48
> #define mh 48
>
> #define NUMMATRIX (mw * mh)
>
> #define LED_BLACK 0
> #define LED_RED_VERYLOW (3 << 11)
> #define LED_RED_LOW (7 << 11)
> #define LED_RED_MEDIUM (15 << 11)
> #define LED_RED_HIGH (31 << 11)
> #define LED_GREEN_VERYLOW (1 << 5)
> #define LED_GREEN_LOW (15 << 5)
> #define LED_GREEN_MEDIUM (31 << 5)
> #define LED_GREEN_HIGH (63 << 5)
> #define LED_BLUE_VERYLOW 3
> #define LED_BLUE_LOW 7
> #define LED_BLUE_MEDIUM 15
> #define LED_BLUE_HIGH 31
>
> #define LED_GOLD (0xFF80)
> #define LED_ORANGE_VERYLOW (LED_RED_VERYLOW + LED_GREEN_VERYLOW)
> #define LED_ORANGE_LOW (LED_RED_LOW + LED_GREEN_LOW)
> #define LED_ORANGE_MEDIUM (LED_RED_MEDIUM + LED_GREEN_MEDIUM)
> #define LED_ORANGE_HIGH (LED_RED_HIGH + LED_GREEN_HIGH)
> #define LED_PURPLE_VERYLOW (LED_RED_VERYLOW + LED_BLUE_VERYLOW)
> #define LED_PURPLE_LOW (LED_RED_LOW + LED_BLUE_LOW)
> #define LED_PURPLE_MEDIUM (LED_RED_MEDIUM + LED_BLUE_MEDIUM)
> #define LED_PURPLE_HIGH (LED_RED_HIGH + LED_BLUE_HIGH)
> #define LED_CYAN_VERYLOW (LED_GREEN_VERYLOW + LED_BLUE_VERYLOW)
> #define LED_CYAN_LOW (LED_GREEN_LOW + LED_BLUE_LOW)
> #define LED_CYAN_MEDIUM (LED_GREEN_MEDIUM + LED_BLUE_MEDIUM)
> #define LED_CYAN_HIGH (LED_GREEN_HIGH + LED_BLUE_HIGH)
> #define LED_WHITE_VERYLOW (LED_RED_VERYLOW + LED_GREEN_VERYLOW + LED_BLUE_VERYLOW)
> #define LED_WHITE_LOW (LED_RED_LOW + LED_GREEN_LOW + LED_BLUE_LOW)
> #define LED_WHITE_MEDIUM (LED_RED_MEDIUM + LED_GREEN_MEDIUM + LED_BLUE_MEDIUM)
> #define LED_WHITE_HIGH (LED_RED_HIGH + LED_GREEN_HIGH + LED_BLUE_HIGH)
>
> CRGB leds[NUMMATRIX];
>
> FastLED_NeoMatrix *matrix = new FastLED_NeoMatrix(leds, 16, 16, 3, 3,
> NEO_MATRIX_BOTTOM + NEO_MATRIX_RIGHT +
> NEO_MATRIX_COLUMNS + NEO_MATRIX_ZIGZAG +
> NEO_TILE_BOTTOM + NEO_TILE_RIGHT + NEO_TILE_COLUMNS + NEO_TILE_ZIGZAG
> );
>
> class LEDMatrixCmpnt : public Component
> {
> public:
> unsigned long last_led_change;
> bool enable = false;
> float frequency = 1;
> std::string sun_rise, sun_set, last_sunrise, last_sunset;
>
> LEDMatrixCmpnt(esphome::template_::TemplateSwitch *&_enable,
> esphome::template_::TemplateNumber *&_frequency,
> esphome::homeassistant::HomeassistantTextSensor *&_sunrise,
> esphome::homeassistant::HomeassistantTextSensor *&_sunset)
> {
> _enable->add_on_state_callback([this](bool newState) { enable = newState; });
> _frequency->add_on_state_callback([this](float newFrequency) { frequency = newFrequency; });
> _sunrise->add_on_state_callback([this](std::string newSunrise)
> {
> last_sunrise = sun_rise;
> sun_rise = newSunrise;
> });
> _sunset->add_on_state_callback([this](std::string newSunset)
> {
> last_sunset = sun_set;
> sun_set = newSunset;
> });
> }
>
> void setup() override
> {
> pinMode(LED_PIN, OUTPUT);
> pinMode(LED_PIN2, OUTPUT);
> digitalWrite(LED_PIN2, HIGH);
> last_led_change = millis();
> FastLED.addLeds<NEOPIXEL,PIN>(leds, NUMMATRIX).setCorrection(TypicalSMD5050);
> matrix->begin();
> matrix->setTextWrap(false);
> matrix->setBrightness(BRIGHTNESS);
> }
> void loop() override
> {
> if (enable == false)
> {
> return;
> }
> unsigned long now = millis();
> if (last_led_change + 1000 / frequency < now)
> {
> digitalWrite(LED_PIN, !digitalRead(LED_PIN));
> digitalWrite(LED_PIN2, !digitalRead(LED_PIN2));
> last_led_change = now;
> }
> }
>
> void scrollText()
> {
> uint8_t size = max(int(mw/8), 1);
> matrix->clear();
> matrix->setTextWrap(false);
> matrix->setTextSize(2);
> matrix->setRotation(0);
> for (int8_t x=24; x>=-48; x--) {
> yield();
> matrix->clear();
> matrix->setCursor(x,4);
> matrix->setTextColor(LED_BLUE_LOW);
> matrix->print("Moon");
> if (mh>11) {
> matrix->setCursor(20-x,mh-20);
> matrix->setTextColor(LED_RED_MEDIUM);
> matrix->print("Sun");
> }
> matrix->show();
> delay(10);
> }
> matrix->setTextSize(3);
> matrix->setTextColor(LED_GOLD);
> matrix->setBrightness(4);
> for (int16_t x=8*size; x>=-4*8*size; x--) {
> yield();
> String text = "LV Pro Teams";
> matrix->clear();
> matrix->setCursor(x,mw/2-size*4+1);
> matrix->print(text);
> matrix->show();
> }
> matrix->setCursor(0,0);
> matrix->setBrightness(BRIGHTNESS);
> matrix->show();
> }
> };
The error message:
> src/main.cpp:27:34: error: invalid use of '::'
> #define delay(x) esphome::delay(x)
> ^
> /data/cst-cmpnt/.piolibdeps/cst-cmpnt/FastLED/src/FastLED.h:596:7: note: in expansion of macro 'delay'
> void delay(unsigned long ms);
> ^~~~~
> Compiling /data/cst-cmpnt/.pioenvs/cst-cmpnt/libb7e/Framebuffer GFX/Framebuffer_GFX.cpp.o
> Compiling /data/cst-cmpnt/.pioenvs/cst-cmpnt/libe4d/FastLED NeoMatrix/FastLED_NeoMatrix.cpp.o
> *** [/data/cst-cmpnt/.pioenvs/cst-cmpnt/src/main.cpp.o] Error 1
Erroneous code:
> // Auto generated code by esphome
> // ========== AUTO GENERATED INCLUDE BLOCK BEGIN ===========
>
> #include "esphome.h"
> using namespace esphome;
> using std::isnan;
> using std::min;
> using std::max;
> using namespace switch_;
> using namespace text_sensor;
> logger::Logger *logger_logger;
> web_server_base::WebServerBase *web_server_base_webserverbase;
> captive_portal::CaptivePortal *captive_portal_captiveportal;
> wifi::WiFiComponent *wifi_wificomponent;
> mdns::MDNSComponent *mdns_mdnscomponent;
> ota::OTAComponent *ota_otacomponent;
> api::APIServer *api_apiserver;
> using namespace api;
> using namespace number;
> preferences::IntervalSyncer *preferences_intervalsyncer;
> template_::TemplateNumber *blink_frequency;
> template_::TemplateSwitch *panel_enable;
> homeassistant::HomeassistantTextSensor *sun_rise;
> homeassistant::HomeassistantTextSensor *sun_set;
> #define yield() esphome::yield()
> #define millis() esphome::millis()
> #define micros() esphome::micros()
> #define delay(x) esphome::delay(x) <-- Line 27
> #define delayMicroseconds(x) esphome::delayMicroseconds(x)
> #include "LEDMatrixCmpnt.h"
>
> // ========== AUTO GENERATED INCLUDE BLOCK END ==========="
Any help would be greatly appreciated. Thank you.