diff --git a/bed-controller2.yaml b/bed-controller2.yaml index 0e22a33..9dcb529 100644 --- a/bed-controller2.yaml +++ b/bed-controller2.yaml @@ -53,7 +53,8 @@ esp32: board: esp32-c3-devkitm-1 framework: type: arduino - + + # Enable logging logger: level: WARN @@ -197,11 +198,11 @@ number: - script.execute: start_motor_if_needed light: - - platform: neopixelbus - variant: WS2812 + - platform: esp32_rmt_led_strip + chipset: WS2811 pin: GPIO8 num_leds: 1 - type: GRB + rgb_order: GRB restore_mode: RESTORE_DEFAULT_ON id: onboard_led name: "Status light" diff --git a/components/adxl345/__init__.py b/components/adxl345/__init__.py index c64792a..4779d04 100644 --- a/components/adxl345/__init__.py +++ b/components/adxl345/__init__.py @@ -6,7 +6,6 @@ from esphome.components import i2c, sensor DEPENDENCIES = ['i2c'] AUTO_LOAD = ['sensor'] MULTI_CONF = True -CODEOWNERS = ["@jdillenburg"] adxl345_ns = cg.esphome_ns.namespace('adxl345') ADXL345Component = adxl345_ns.class_('ADXL345Component', cg.PollingComponent, i2c.I2CDevice) @@ -61,17 +60,15 @@ CONFIG_SCHEMA = cv.Schema({ accuracy_decimals=3, state_class=STATE_CLASS_MEASUREMENT, ), -}).extend(cv.polling_component_schema("100ms")).extend(i2c.i2c_device_schema(0x53)) +}).extend(cv.polling_component_schema("1s")).extend(i2c.i2c_device_schema(0x53)) async def to_code(config): var = cg.new_Pvariable(config[CONF_ID]) await cg.register_component(var, config) await i2c.register_i2c_device(var, config) - # Configure the range cg.add(var.set_range(config[CONF_RANGE])) - # Register sensors if configured if CONF_OFF_VERTICAL in config: sens = await sensor.new_sensor(config[CONF_OFF_VERTICAL]) cg.add(var.set_off_vertical_sensor(sens)) @@ -90,4 +87,4 @@ async def to_code(config): if CONF_ACCEL_Z in config: sens = await sensor.new_sensor(config[CONF_ACCEL_Z]) - cg.add(var.set_accel_z_sensor(sens)) \ No newline at end of file + cg.add(var.set_accel_z_sensor(sens)) diff --git a/components/adxl345/adxl345.cpp b/components/adxl345/adxl345.cpp index c9612ae..a103b5d 100644 --- a/components/adxl345/adxl345.cpp +++ b/components/adxl345/adxl345.cpp @@ -1,41 +1,44 @@ -#include "adxl345.h" +##include "adxl345.h" #include "esphome/core/log.h" +#include namespace esphome { namespace adxl345 { static const char *const TAG = "adxl345"; +// Register map +static const uint8_t REG_DEVID = 0x00; +static const uint8_t REG_POWER_CTL = 0x2D; +static const uint8_t REG_DATA_FORMAT = 0x31; +static const uint8_t REG_DATAX0 = 0x32; + void ADXL345Component::setup() { ESP_LOGCONFIG(TAG, "Setting up ADXL345..."); - - if (!accel_.begin(this->address_)) { - ESP_LOGE(TAG, "Could not find ADXL345 sensor at address 0x%02X!", this->address_); + + // Check device ID + uint8_t devid; + if (this->read_register(REG_DEVID, &devid, 1) != i2c::ERROR_OK || devid != 0xE5) { + ESP_LOGE(TAG, "ADXL345 not found at 0x%02X (id=0x%02X)", this->address_, devid); this->mark_failed(); return; } - - // Map our range enum values to Adafruit library constants - range_t adafruit_range; + ESP_LOGI(TAG, "Found ADXL345 at 0x%02X", this->address_); + + // Set range + uint8_t range_bits = 0; switch (this->range_) { - case 0: // RANGE_2G - adafruit_range = ADXL345_RANGE_2_G; - break; - case 1: // RANGE_4G - adafruit_range = ADXL345_RANGE_4_G; - break; - case 2: // RANGE_8G - adafruit_range = ADXL345_RANGE_8_G; - break; - case 3: // RANGE_16G - adafruit_range = ADXL345_RANGE_16_G; - break; - default: - adafruit_range = ADXL345_RANGE_2_G; - break; + case 0: range_bits = 0x00; break; // ±2g + case 1: range_bits = 0x01; break; // ±4g + case 2: range_bits = 0x02; break; // ±8g + case 3: range_bits = 0x03; break; // ±16g } - - accel_.setRange(adafruit_range); + this->write_register(REG_DATA_FORMAT, &range_bits, 1); + + // Enable measurement mode + uint8_t power = 0x08; + this->write_register(REG_POWER_CTL, &power, 1); + ESP_LOGD(TAG, "ADXL345 setup complete"); } @@ -43,7 +46,7 @@ void ADXL345Component::dump_config() { ESP_LOGCONFIG(TAG, "ADXL345:"); LOG_I2C_DEVICE(this); LOG_UPDATE_INTERVAL(this); - + const char* range_str; switch (this->range_) { case 0: range_str = "2G"; break; @@ -53,57 +56,46 @@ void ADXL345Component::dump_config() { default: range_str = "Unknown"; break; } ESP_LOGCONFIG(TAG, " Range: %s", range_str); - - if (this->off_vertical_ != nullptr) { - LOG_SENSOR(" ", "Off Vertical", this->off_vertical_); - } - if (this->jitter_ != nullptr) { - LOG_SENSOR(" ", "Jitter", this->jitter_); - } - if (this->accel_x_ != nullptr) { - LOG_SENSOR(" ", "Acceleration X", this->accel_x_); - } - if (this->accel_y_ != nullptr) { - LOG_SENSOR(" ", "Acceleration Y", this->accel_y_); - } - if (this->accel_z_ != nullptr) { - LOG_SENSOR(" ", "Acceleration Z", this->accel_z_); - } + + if (this->off_vertical_ != nullptr) LOG_SENSOR(" ", "Off Vertical", this->off_vertical_); + if (this->jitter_ != nullptr) LOG_SENSOR(" ", "Jitter", this->jitter_); + if (this->accel_x_ != nullptr) LOG_SENSOR(" ", "Acceleration X", this->accel_x_); + if (this->accel_y_ != nullptr) LOG_SENSOR(" ", "Acceleration Y", this->accel_y_); + if (this->accel_z_ != nullptr) LOG_SENSOR(" ", "Acceleration Z", this->accel_z_); } void ADXL345Component::update() { - sensors_event_t event; - accel_.getEvent(&event); - - // Publish raw accelerometer values if sensors are configured - if (this->accel_x_ != nullptr) { - this->accel_x_->publish_state(event.acceleration.x); + uint8_t buffer[6]; + if (this->read_register(REG_DATAX0, buffer, 6) != i2c::ERROR_OK) { + ESP_LOGW(TAG, "Failed to read data"); + return; } - - if (this->accel_y_ != nullptr) { - this->accel_y_->publish_state(event.acceleration.y); - } - - if (this->accel_z_ != nullptr) { - this->accel_z_->publish_state(event.acceleration.z); - } - - // Calculate and publish off_vertical if sensor is configured + + int16_t raw_x = (int16_t)(buffer[1] << 8 | buffer[0]); + int16_t raw_y = (int16_t)(buffer[3] << 8 | buffer[2]); + int16_t raw_z = (int16_t)(buffer[5] << 8 | buffer[4]); + + // Scale: 4 mg/LSB in full-res mode (0.004 g), convert to m/s² + float scale = 0.004f * 9.80665f; + float x = raw_x * scale; + float y = raw_y * scale; + float z = raw_z * scale; + + if (this->accel_x_ != nullptr) this->accel_x_->publish_state(x); + if (this->accel_y_ != nullptr) this->accel_y_->publish_state(y); + if (this->accel_z_ != nullptr) this->accel_z_->publish_state(z); + if (this->off_vertical_ != nullptr) { - double pitch_amount = atan(event.acceleration.y / - sqrt(pow(event.acceleration.x, 2) + pow(event.acceleration.z, 2))) * 180 / PI; - double roll_amount = atan(-1 * event.acceleration.x / - sqrt(pow(event.acceleration.y, 2) + pow(event.acceleration.z, 2))) * 180 / PI; - - this->off_vertical_->publish_state(max(abs(pitch_amount), abs(roll_amount))); + double pitch = atan(y / sqrt(pow(x, 2) + pow(z, 2))) * 180.0 / M_PI; + double roll = atan(-x / sqrt(pow(y, 2) + pow(z, 2))) * 180.0 / M_PI; + this->off_vertical_->publish_state(std::max(std::abs(pitch), std::abs(roll))); } - - // Calculate and publish jitter if sensor is configured + if (this->jitter_ != nullptr) { - float jitter_value = abs(event.acceleration.x) + abs(event.acceleration.y) + abs(event.acceleration.z); - this->jitter_->publish_state(jitter_value); + float jitter = fabs(x) + fabs(y) + fabs(z); + this->jitter_->publish_state(jitter); } } -} // namespace adxl345 -} // namespace esphome \ No newline at end of file +} // namespace adxl345 +} // namespace esphome diff --git a/components/adxl345/adxl345.h b/components/adxl345/adxl345.h index eadc93f..eb3c6a7 100644 --- a/components/adxl345/adxl345.h +++ b/components/adxl345/adxl345.h @@ -3,16 +3,13 @@ #include "esphome/core/component.h" #include "esphome/components/sensor/sensor.h" #include "esphome/components/i2c/i2c.h" -#include -#include -#include namespace esphome { namespace adxl345 { class ADXL345Component : public PollingComponent, public i2c::I2CDevice { public: - ADXL345Component() : PollingComponent(100) {} + ADXL345Component() : PollingComponent(1000) {} void setup() override; void update() override; @@ -23,18 +20,16 @@ class ADXL345Component : public PollingComponent, public i2c::I2CDevice { void set_accel_x_sensor(sensor::Sensor *accel_x) { accel_x_ = accel_x; } void set_accel_y_sensor(sensor::Sensor *accel_y) { accel_y_ = accel_y; } void set_accel_z_sensor(sensor::Sensor *accel_z) { accel_z_ = accel_z; } - void set_range(uint8_t range) { range_ = range; } protected: - Adafruit_ADXL345_Unified accel_{12345}; sensor::Sensor *off_vertical_{nullptr}; sensor::Sensor *jitter_{nullptr}; sensor::Sensor *accel_x_{nullptr}; sensor::Sensor *accel_y_{nullptr}; sensor::Sensor *accel_z_{nullptr}; - uint8_t range_{0}; // Default to 2G range (0) + uint8_t range_{0}; // Default 2G }; -} // namespace adxl345 -} // namespace esphome \ No newline at end of file +} // namespace adxl345 +} // namespace esphome diff --git a/font_5x7_aa.h b/font_5x7_aa.h new file mode 100644 index 0000000..3e37565 --- /dev/null +++ b/font_5x7_aa.h @@ -0,0 +1,308 @@ +// font_5x7_aa.h - 5x7 pixel anti-aliased font for LED Matrix +#pragma once + +#include + +// 5x7 font data - each character is 5 bytes (5 columns x 7 rows) +// Bit 0 is top row, bit 6 is bottom row +const uint8_t font_5x7[][5] = { + {0x00, 0x00, 0x00, 0x00, 0x00}, // 32 space + {0x00, 0x00, 0x5F, 0x00, 0x00}, // 33 ! + {0x00, 0x07, 0x00, 0x07, 0x00}, // 34 " + {0x14, 0x7F, 0x14, 0x7F, 0x14}, // 35 # + {0x24, 0x2A, 0x7F, 0x2A, 0x12}, // 36 $ + {0x23, 0x13, 0x08, 0x64, 0x62}, // 37 % + {0x36, 0x49, 0x56, 0x20, 0x50}, // 38 & + {0x00, 0x08, 0x07, 0x03, 0x00}, // 39 ' + {0x00, 0x1C, 0x22, 0x41, 0x00}, // 40 ( + {0x00, 0x41, 0x22, 0x1C, 0x00}, // 41 ) + {0x2A, 0x1C, 0x7F, 0x1C, 0x2A}, // 42 * + {0x08, 0x08, 0x3E, 0x08, 0x08}, // 43 + + {0x00, 0x80, 0x70, 0x30, 0x00}, // 44 , + {0x08, 0x08, 0x08, 0x08, 0x08}, // 45 - + {0x00, 0x00, 0x60, 0x60, 0x00}, // 46 . + {0x20, 0x10, 0x08, 0x04, 0x02}, // 47 / + {0x3E, 0x51, 0x49, 0x45, 0x3E}, // 48 0 + {0x00, 0x42, 0x7F, 0x40, 0x00}, // 49 1 + {0x72, 0x49, 0x49, 0x49, 0x46}, // 50 2 + {0x21, 0x41, 0x49, 0x4D, 0x33}, // 51 3 + {0x18, 0x14, 0x12, 0x7F, 0x10}, // 52 4 + {0x27, 0x45, 0x45, 0x45, 0x39}, // 53 5 + {0x3C, 0x4A, 0x49, 0x49, 0x31}, // 54 6 + {0x41, 0x21, 0x11, 0x09, 0x07}, // 55 7 + {0x36, 0x49, 0x49, 0x49, 0x36}, // 56 8 + {0x46, 0x49, 0x49, 0x29, 0x1E}, // 57 9 + {0x00, 0x00, 0x14, 0x00, 0x00}, // 58 : + {0x00, 0x40, 0x34, 0x00, 0x00}, // 59 ; + {0x00, 0x08, 0x14, 0x22, 0x41}, // 60 < + {0x14, 0x14, 0x14, 0x14, 0x14}, // 61 = + {0x00, 0x41, 0x22, 0x14, 0x08}, // 62 > + {0x02, 0x01, 0x59, 0x09, 0x06}, // 63 ? + {0x3E, 0x41, 0x5D, 0x59, 0x4E}, // 64 @ + {0x7C, 0x12, 0x11, 0x12, 0x7C}, // 65 A + {0x7F, 0x49, 0x49, 0x49, 0x36}, // 66 B + {0x3E, 0x41, 0x41, 0x41, 0x22}, // 67 C + {0x7F, 0x41, 0x41, 0x41, 0x3E}, // 68 D + {0x7F, 0x49, 0x49, 0x49, 0x41}, // 69 E + {0x7F, 0x09, 0x09, 0x09, 0x01}, // 70 F + {0x3E, 0x41, 0x41, 0x51, 0x73}, // 71 G + {0x7F, 0x08, 0x08, 0x08, 0x7F}, // 72 H + {0x00, 0x41, 0x7F, 0x41, 0x00}, // 73 I + {0x20, 0x40, 0x41, 0x3F, 0x01}, // 74 J + {0x7F, 0x08, 0x14, 0x22, 0x41}, // 75 K + {0x7F, 0x40, 0x40, 0x40, 0x40}, // 76 L + {0x7F, 0x02, 0x1C, 0x02, 0x7F}, // 77 M + {0x7F, 0x04, 0x08, 0x10, 0x7F}, // 78 N + {0x3E, 0x41, 0x41, 0x41, 0x3E}, // 79 O + {0x7F, 0x09, 0x09, 0x09, 0x06}, // 80 P + {0x3E, 0x41, 0x51, 0x21, 0x5E}, // 81 Q + {0x7F, 0x09, 0x19, 0x29, 0x46}, // 82 R + {0x26, 0x49, 0x49, 0x49, 0x32}, // 83 S + {0x03, 0x01, 0x7F, 0x01, 0x03}, // 84 T + {0x3F, 0x40, 0x40, 0x40, 0x3F}, // 85 U + {0x1F, 0x20, 0x40, 0x20, 0x1F}, // 86 V + {0x3F, 0x40, 0x38, 0x40, 0x3F}, // 87 W + {0x63, 0x14, 0x08, 0x14, 0x63}, // 88 X + {0x03, 0x04, 0x78, 0x04, 0x03}, // 89 Y + {0x61, 0x59, 0x49, 0x4D, 0x43}, // 90 Z + {0x00, 0x7F, 0x41, 0x41, 0x41}, // 91 [ + {0x02, 0x04, 0x08, 0x10, 0x20}, // 92 backslash + {0x41, 0x41, 0x41, 0x7F, 0x00}, // 93 ] + {0x04, 0x02, 0x01, 0x02, 0x04}, // 94 ^ + {0x40, 0x40, 0x40, 0x40, 0x40}, // 95 _ + {0x00, 0x03, 0x07, 0x08, 0x00}, // 96 ` + {0x20, 0x54, 0x54, 0x78, 0x40}, // 97 a + {0x7F, 0x28, 0x44, 0x44, 0x38}, // 98 b + {0x38, 0x44, 0x44, 0x44, 0x28}, // 99 c + {0x38, 0x44, 0x44, 0x28, 0x7F}, // 100 d + {0x38, 0x54, 0x54, 0x54, 0x18}, // 101 e + {0x00, 0x08, 0x7E, 0x09, 0x02}, // 102 f + {0x18, 0xA4, 0xA4, 0x9C, 0x78}, // 103 g + {0x7F, 0x08, 0x04, 0x04, 0x78}, // 104 h + {0x00, 0x44, 0x7D, 0x40, 0x00}, // 105 i + {0x20, 0x40, 0x40, 0x3D, 0x00}, // 106 j + {0x7F, 0x10, 0x28, 0x44, 0x00}, // 107 k + {0x00, 0x41, 0x7F, 0x40, 0x00}, // 108 l + {0x7C, 0x04, 0x78, 0x04, 0x78}, // 109 m + {0x7C, 0x08, 0x04, 0x04, 0x78}, // 110 n + {0x38, 0x44, 0x44, 0x44, 0x38}, // 111 o + {0xFC, 0x18, 0x24, 0x24, 0x18}, // 112 p + {0x18, 0x24, 0x24, 0x18, 0xFC}, // 113 q + {0x7C, 0x08, 0x04, 0x04, 0x08}, // 114 r + {0x48, 0x54, 0x54, 0x54, 0x24}, // 115 s + {0x04, 0x04, 0x3F, 0x44, 0x24}, // 116 t + {0x3C, 0x40, 0x40, 0x20, 0x7C}, // 117 u + {0x1C, 0x20, 0x40, 0x20, 0x1C}, // 118 v + {0x3C, 0x40, 0x30, 0x40, 0x3C}, // 119 w + {0x44, 0x28, 0x10, 0x28, 0x44}, // 120 x + {0x4C, 0x90, 0x90, 0x90, 0x7C}, // 121 y + {0x44, 0x64, 0x54, 0x4C, 0x44}, // 122 z + {0x00, 0x08, 0x36, 0x41, 0x00}, // 123 { + {0x00, 0x00, 0x77, 0x00, 0x00}, // 124 | + {0x00, 0x41, 0x36, 0x08, 0x00}, // 125 } + {0x02, 0x01, 0x02, 0x04, 0x02}, // 126 ~ +}; + +// Helper function to draw a character at position +void draw_char(light::AddressableLight &it, char c, int x_pos, int y_pos, Color color) { + if (c < 32 || c > 126) return; // Character out of range + + const uint8_t *char_data = font_5x7[c - 32]; + + for (int col = 0; col < 5; col++) { + int x = x_pos + col; + if (x < 0 || x >= 32) continue; // Skip if out of bounds + + uint8_t column = char_data[col]; + for (int row = 0; row < 7; row++) { + if (column & (1 << row)) { + int y = y_pos + row; + if (y < 0 || y >= 8) continue; // Skip if out of bounds + + // Convert to LED index with serpentine mapping + int flipped_y = 7 - y; + int led_index; + if (flipped_y % 2 == 0) { + led_index = flipped_y * 32 + x; + } else { + led_index = flipped_y * 32 + (31 - x); + } + + if (led_index >= 0 && led_index < 256) { + it[led_index] = color; + } + } + } + } +} + +// Helper function to draw a string +void draw_string(light::AddressableLight &it, const std::string &text, int x_pos, int y_pos, Color color) { + int current_x = x_pos; + + for (size_t i = 0; i < text.length(); i++) { + draw_char(it, text[i], current_x, y_pos, color); + current_x += 6; // 5 pixels for char + 1 pixel spacing + } +} + +// Calculate text width in pixels +int get_text_width(const std::string &text) { + return text.length() * 6 - 1; // 6 pixels per char minus 1 for last spacing +} + + +// Anti-aliased drawing with sub-pixel positioning +void draw_char_aa(light::AddressableLight &it, char c, float x_pos, float y_pos, Color color, float brightness = 1.0) { + if (c < 32 || c > 126) return; + + const uint8_t *char_data = font_5x7[c - 32]; + + // Calculate fractional offsets + int x_start = (int)floor(x_pos); + int y_start = (int)floor(y_pos); + float x_frac = x_pos - x_start; + float y_frac = y_pos - y_start; + + // Draw with 2x2 supersampling for anti-aliasing + for (int col = 0; col < 5; col++) { + uint8_t column = char_data[col]; + + for (int row = 0; row < 7; row++) { + if (column & (1 << row)) { + // Calculate anti-aliased pixel coverage for 4 affected pixels + float coverage[2][2] = { + {(1.0f - x_frac) * (1.0f - y_frac), x_frac * (1.0f - y_frac)}, + {(1.0f - x_frac) * y_frac, x_frac * y_frac} + }; + + // Draw to up to 4 pixels with appropriate brightness + for (int dy = 0; dy < 2; dy++) { + for (int dx = 0; dx < 2; dx++) { + int x = x_start + col + dx; + int y = y_start + row + dy; + + if (x >= 0 && x < 32 && y >= 0 && y < 8) { + // Convert to LED index + int flipped_y = 7 - y; + int led_index; + if (flipped_y % 2 == 0) { + led_index = flipped_y * 32 + x; + } else { + led_index = flipped_y * 32 + (31 - x); + } + + if (led_index >= 0 && led_index < 256) { + // Apply anti-aliased brightness + float pixel_brightness = coverage[dy][dx] * brightness; + + // Blend with existing pixel + Color existing = it[led_index].get(); + Color new_color( + existing.r + (color.r - existing.r) * pixel_brightness, + existing.g + (color.g - existing.g) * pixel_brightness, + existing.b + (color.b - existing.b) * pixel_brightness + ); + it[led_index] = new_color; + } + } + } + } + } + } + } +} + +// Helper for edge smoothing using 3x3 kernel +void apply_edge_smoothing(light::AddressableLight &it, int x, int y, Color color, float strength) { + // 3x3 Gaussian kernel for smoothing + const float kernel[3][3] = { + {0.075f, 0.124f, 0.075f}, + {0.124f, 0.204f, 0.124f}, + {0.075f, 0.124f, 0.075f} + }; + + for (int dy = -1; dy <= 1; dy++) { + for (int dx = -1; dx <= 1; dx++) { + int px = x + dx; + int py = y + dy; + + if (px >= 0 && px < 32 && py >= 0 && py < 8) { + int flipped_y = 7 - py; + int led_index; + if (flipped_y % 2 == 0) { + led_index = flipped_y * 32 + px; + } else { + led_index = flipped_y * 32 + (31 - px); + } + + if (led_index >= 0 && led_index < 256) { + float weight = kernel[dy + 1][dx + 1] * strength; + Color existing = it[led_index].get(); + Color new_color( + existing.r + (color.r - existing.r) * weight, + existing.g + (color.g - existing.g) * weight, + existing.b + (color.b - existing.b) * weight + ); + it[led_index] = new_color; + } + } + } + } +} + +// Improved string drawing with anti-aliasing +void draw_string_aa(light::AddressableLight &it, const std::string &text, float x_pos, float y_pos, Color color) { + float current_x = x_pos; + + for (size_t i = 0; i < text.length(); i++) { + draw_char_aa(it, text[i], current_x, y_pos, color); + current_x += 6.0f; // Can use fractional spacing + } +} + +// Alternative: Pre-rendered anti-aliased font (2-bit per pixel) +// This would store 4 brightness levels per pixel for better quality +struct AAGlyph { + uint8_t width; + uint8_t height; + uint8_t data[35]; // 5x7 pixels, 2 bits each = 70 bits = ~9 bytes +}; + +// Function to render with pre-computed anti-aliased glyphs +void draw_aa_glyph(light::AddressableLight &it, const AAGlyph &glyph, int x, int y, Color color) { + for (int row = 0; row < glyph.height; row++) { + for (int col = 0; col < glyph.width; col++) { + // Extract 2-bit brightness value (0, 85, 170, 255) + int bit_index = (row * glyph.width + col) * 2; + int byte_index = bit_index / 8; + int bit_offset = bit_index % 8; + + uint8_t brightness_bits = (glyph.data[byte_index] >> bit_offset) & 0x03; + float brightness = brightness_bits / 3.0f; + + if (brightness > 0) { + int px = x + col; + int py = y + row; + + if (px >= 0 && px < 32 && py >= 0 && py < 8) { + int flipped_y = 7 - py; + int led_index; + if (flipped_y % 2 == 0) { + led_index = flipped_y * 32 + px; + } else { + led_index = flipped_y * 32 + (31 - px); + } + + if (led_index >= 0 && led_index < 256) { + it[led_index] = Color( + color.r * brightness, + color.g * brightness, + color.b * brightness + ); + } + } + } + } + } +} \ No newline at end of file diff --git a/font_aa_generated.h b/font_aa_generated.h new file mode 100644 index 0000000..e7e419d --- /dev/null +++ b/font_aa_generated.h @@ -0,0 +1,199 @@ +// font_aa_generated.h - Anti-aliased font for LED Matrix +// Generated from TrueType font with 4-level anti-aliasing +#pragma once + +#include + +struct AAChar { + uint8_t width; + uint8_t data[16]; // 8x8 pixels, 2 bits each = 128 bits = 16 bytes +}; + +// Anti-aliased font data for ASCII 32-126 +const AAChar aa_font[] = { + {8, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, // 32 ' ' + {5, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, // 33 '!' + {5, {0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, // 34 '\"' + {5, {0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x90, 0x01, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, // 35 '#' + {5, {0x00, 0x00, 0x00, 0x00, 0x90, 0x00, 0x80, 0x01, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, // 36 '$' + {6, {0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0xA0, 0x01, 0x40, 0x06, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00}}, // 37 '%' + {5, {0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x80, 0x01, 0x90, 0x02, 0x40, 0x01, 0x00, 0x00, 0x00, 0x00}}, // 38 '&' + {4, {0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, // 39 '\'' + {4, {0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00}}, // 40 '(' + {5, {0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x40, 0x01, 0x40, 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00}}, // 41 ')' + {4, {0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, // 42 '*' + {5, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, // 43 '+' + {5, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, // 44 ',' + {4, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, // 45 '-' + {8, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, // 46 '.' + {4, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, // 47 '/' + {5, {0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x50, 0x01, 0x50, 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00}}, // 48 '0' + {5, {0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x40, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, // 49 '1' + {5, {0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x40, 0x01, 0x40, 0x00, 0x50, 0x01, 0x00, 0x00, 0x00, 0x00}}, // 50 '2' + {5, {0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x40, 0x01, 0x40, 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00}}, // 51 '3' + {5, {0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x40, 0x01, 0x90, 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00}}, // 52 '4' + {5, {0x00, 0x00, 0x00, 0x00, 0x40, 0x01, 0x90, 0x01, 0x40, 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00}}, // 53 '5' + {5, {0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x90, 0x01, 0x90, 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00}}, // 54 '6' + {5, {0x00, 0x00, 0x00, 0x00, 0x40, 0x01, 0x40, 0x01, 0x40, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00}}, // 55 '7' + {5, {0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x80, 0x01, 0x50, 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00}}, // 56 '8' + {5, {0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x90, 0x01, 0x80, 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00}}, // 57 '9' + {8, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, // 58 ':' + {5, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, // 59 ';' + {5, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x40, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, // 60 '<' + {5, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD0, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, // 61 '=' + {5, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, // 62 '>' + {5, {0x00, 0x00, 0x00, 0x00, 0x40, 0x01, 0x40, 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, // 63 '?' + {6, {0x00, 0x00, 0x00, 0x00, 0x80, 0x07, 0x50, 0x05, 0x50, 0x06, 0x90, 0x06, 0x00, 0x00, 0x00, 0x00}}, // 64 '@' + {5, {0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x80, 0x01, 0x90, 0x01, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00}}, // 65 'A' + {5, {0x00, 0x00, 0x00, 0x00, 0x40, 0x01, 0x90, 0x02, 0x50, 0x01, 0x40, 0x01, 0x00, 0x00, 0x00, 0x00}}, // 66 'B' + {5, {0x00, 0x00, 0x00, 0x00, 0x40, 0x01, 0x50, 0x01, 0x50, 0x01, 0x40, 0x01, 0x00, 0x00, 0x00, 0x00}}, // 67 'C' + {6, {0x00, 0x00, 0x00, 0x00, 0x40, 0x01, 0x50, 0x05, 0x50, 0x05, 0x40, 0x01, 0x00, 0x00, 0x00, 0x00}}, // 68 'D' + {5, {0x00, 0x00, 0x00, 0x00, 0x40, 0x01, 0x90, 0x01, 0x50, 0x01, 0x40, 0x01, 0x00, 0x00, 0x00, 0x00}}, // 69 'E' + {5, {0x00, 0x00, 0x00, 0x00, 0x40, 0x01, 0x90, 0x01, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, // 70 'F' + {6, {0x00, 0x00, 0x00, 0x00, 0x40, 0x01, 0x50, 0x01, 0x50, 0x06, 0x40, 0x01, 0x00, 0x00, 0x00, 0x00}}, // 71 'G' + {6, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x02, 0x50, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, // 72 'H' + {5, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x01, 0x40, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, // 73 'I' + {5, {0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x40, 0x01, 0x40, 0x01, 0x00, 0x00, 0x00, 0x00}}, // 74 'J' + {5, {0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x90, 0x01, 0x90, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00}}, // 75 'K' + {5, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x50, 0x00, 0x40, 0x01, 0x00, 0x00, 0x00, 0x00}}, // 76 'L' + {5, {0x00, 0x00, 0x00, 0x00, 0x10, 0x01, 0x60, 0x02, 0x90, 0x01, 0x40, 0x01, 0x00, 0x00, 0x00, 0x00}}, // 77 'M' + {6, {0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x90, 0x01, 0x50, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00}}, // 78 'N' + {6, {0x00, 0x00, 0x00, 0x00, 0x40, 0x01, 0x50, 0x05, 0x50, 0x05, 0x40, 0x01, 0x00, 0x00, 0x00, 0x00}}, // 79 'O' + {5, {0x00, 0x00, 0x00, 0x00, 0x40, 0x01, 0x50, 0x02, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, // 80 'P' + {6, {0x00, 0x00, 0x00, 0x00, 0x40, 0x06, 0x10, 0x04, 0x80, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, // 81 'Q' + {6, {0x00, 0x00, 0x00, 0x00, 0x40, 0x01, 0x90, 0x02, 0x50, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, // 82 'R' + {5, {0x00, 0x00, 0x00, 0x00, 0x40, 0x01, 0x40, 0x01, 0x40, 0x01, 0x40, 0x01, 0x00, 0x00, 0x00, 0x00}}, // 83 'S' + {5, {0x00, 0x00, 0x00, 0x00, 0x50, 0x01, 0x40, 0x01, 0x40, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00}}, // 84 'T' + {6, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x05, 0x50, 0x01, 0x40, 0x01, 0x00, 0x00, 0x00, 0x00}}, // 85 'U' + {5, {0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x50, 0x01, 0x40, 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00}}, // 86 'V' + {6, {0x00, 0x00, 0x00, 0x00, 0x40, 0x01, 0x50, 0x05, 0x50, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00}}, // 87 'W' + {5, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x01, 0x80, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00}}, // 88 'X' + {5, {0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x40, 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, // 89 'Y' + {5, {0x00, 0x00, 0x00, 0x00, 0x40, 0x01, 0x40, 0x01, 0x50, 0x00, 0x50, 0x01, 0x00, 0x00, 0x00, 0x00}}, // 90 'Z' + {4, {0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00}}, // 91 '[' + {4, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, // 92 '\\' + {5, {0x00, 0x00, 0x00, 0x00, 0x40, 0x01, 0x00, 0x01, 0x00, 0x01, 0x40, 0x01, 0x00, 0x00, 0x00, 0x00}}, // 93 ']' + {5, {0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x40, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, // 94 '^' + {6, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, // 95 '_' + {4, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, // 96 '`' + {5, {0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x80, 0x01, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, // 97 'a' + {5, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x01, 0x50, 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00}}, // 98 'b' + {5, {0x00, 0x00, 0x00, 0x00, 0x40, 0x01, 0x40, 0x01, 0x40, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, // 99 'c' + {5, {0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x40, 0x02, 0x40, 0x01, 0x40, 0x01, 0x00, 0x00, 0x00, 0x00}}, // 100 'd' + {5, {0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x90, 0x01, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, // 101 'e' + {5, {0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x80, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, // 102 'f' + {5, {0x00, 0x00, 0x00, 0x00, 0x40, 0x02, 0x40, 0x01, 0x40, 0x02, 0x40, 0x01, 0x00, 0x00, 0x00, 0x00}}, // 103 'g' + {5, {0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x40, 0x02, 0x40, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, // 104 'h' + {5, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x01, 0x40, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, // 105 'i' + {5, {0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x40, 0x01, 0x40, 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00}}, // 106 'j' + {5, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x80, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00}}, // 107 'k' + {5, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x01, 0x40, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, // 108 'l' + {5, {0x00, 0x00, 0x00, 0x00, 0x50, 0x01, 0x50, 0x01, 0x50, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, // 109 'm' + {5, {0x00, 0x00, 0x00, 0x00, 0x40, 0x01, 0x40, 0x01, 0x40, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, // 110 'n' + {5, {0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x50, 0x01, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, // 111 'o' + {5, {0x00, 0x00, 0x00, 0x00, 0x90, 0x01, 0x50, 0x01, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, // 112 'p' + {5, {0x00, 0x00, 0x00, 0x00, 0x40, 0x02, 0x40, 0x01, 0x40, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, // 113 'q' + {5, {0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, // 114 'r' + {5, {0x00, 0x00, 0x00, 0x00, 0x40, 0x01, 0x80, 0x01, 0x40, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, // 115 's' + {4, {0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x80, 0x00, 0x40, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00}}, // 116 't' + {5, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x01, 0x40, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, // 117 'u' + {5, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x01, 0x40, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, // 118 'v' + {5, {0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x50, 0x02, 0x40, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, // 119 'w' + {5, {0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x40, 0x01, 0x40, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, // 120 'x' + {5, {0x00, 0x00, 0x00, 0x00, 0x40, 0x01, 0x40, 0x01, 0x40, 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00}}, // 121 'y' + {5, {0x00, 0x00, 0x00, 0x00, 0x40, 0x01, 0x40, 0x01, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, // 122 'z' + {5, {0x00, 0x00, 0x00, 0x00, 0x40, 0x01, 0x40, 0x00, 0x40, 0x00, 0x40, 0x01, 0x00, 0x00, 0x00, 0x00}}, // 123 '{' + {5, {0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00}}, // 124 '|' + {5, {0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x40, 0x01, 0x40, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00}}, // 125 '}' + {5, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, // 126 '~' +}; + +// Draw anti-aliased character at position +void draw_aa_char(light::AddressableLight &it, char c, int x_pos, int y_pos, Color color, float alpha = 1.0f) { + if (c < 32 || c > 126) return; + + const AAChar &char_data = aa_font[c - 32]; + + for (int y = 0; y < 8; y++) { + for (int x = 0; x < 8; x++) { + // Extract 2-bit brightness value + int byte_idx = (y * 2) + (x / 4); + int bit_shift = (x % 4) * 2; + uint8_t brightness_level = (char_data.data[byte_idx] >> bit_shift) & 0x03; + + if (brightness_level > 0) { + float brightness = (brightness_level / 3.0f) * alpha; + + int px = x_pos + x; + int py = y_pos + y; + + if (px >= 0 && px < 32 && py >= 0 && py < 8) { + int flipped_y = 7 - py; + int led_index; + if (flipped_y % 2 == 0) { + led_index = flipped_y * 32 + px; + } else { + led_index = flipped_y * 32 + (31 - px); + } + + if (led_index >= 0 && led_index < 256) { + // Apply brightness with alpha blending + Color existing = it[led_index].get(); + it[led_index] = Color( + existing.r + (color.r - existing.r) * brightness, + existing.g + (color.g - existing.g) * brightness, + existing.b + (color.b - existing.b) * brightness + ); + } + } + } + } + } +} + +// Draw anti-aliased string at position +void draw_aa_string(light::AddressableLight &it, const std::string &text, int x_pos, int y_pos, Color color, float alpha = 1.0f) { + int current_x = x_pos; + + for (char c : text) { + if (c >= 32 && c <= 126) { + draw_aa_char(it, c, current_x, y_pos, color, alpha); + current_x += aa_font[c - 32].width + 1; // Add 1 pixel spacing + } + } +} + +// Get width of anti-aliased string in pixels +int get_aa_text_width(const std::string &text) { + int width = 0; + for (size_t i = 0; i < text.length(); i++) { + char c = text[i]; + if (c >= 32 && c <= 126) { + width += aa_font[c - 32].width; + if (i < text.length() - 1) width += 1; // spacing + } + } + return width; +} + +// Draw with sub-pixel positioning for smooth scrolling +void draw_aa_string_subpixel(light::AddressableLight &it, const std::string &text, float x_pos, float y_pos, Color color) { + float current_x = x_pos; + + for (char c : text) { + if (c >= 32 && c <= 126) { + int x_int = (int)x_pos; + float x_frac = x_pos - x_int; + + // Draw character at two positions with appropriate alpha + if (x_frac > 0.01f) { + draw_aa_char(it, c, x_int, (int)y_pos, color, 1.0f - x_frac); + draw_aa_char(it, c, x_int + 1, (int)y_pos, color, x_frac); + } else { + draw_aa_char(it, c, x_int, (int)y_pos, color, 1.0f); + } + + current_x += aa_font[c - 32].width + 1; + } + } +} diff --git a/garage-door-controller.yaml b/garage-door-controller.yaml index a20eace..16e4a02 100644 --- a/garage-door-controller.yaml +++ b/garage-door-controller.yaml @@ -16,7 +16,7 @@ substitutions: esp32: board: esp32dev framework: - type: arduino + type: esp-idf # Enable logging @@ -265,7 +265,6 @@ cover: #********** LED Strip configuration ********** light: - platform: esp32_rmt_led_strip - rmt_channel: 1 id: led_strip chipset: WS2812 pin: GPIO16 diff --git a/led_matrix_custom.h b/led_matrix_custom.h new file mode 100644 index 0000000..1ac139a --- /dev/null +++ b/led_matrix_custom.h @@ -0,0 +1,120 @@ +// led_matrix_custom.h +// Optional custom functions for the LED matrix + +#pragma once + +#include "esphome.h" + +// Helper function to convert x,y coordinates to serpentine LED index +int xy_to_serpentine(int x, int y) { + // Your layout: bottom-left start, serpentine + // Row 0 (bottom): left to right + // Row 1: right to left + // etc. + + if (y < 0 || y >= 8 || x < 0 || x >= 32) { + return -1; // Out of bounds + } + + int row = 7 - y; // Flip y coordinate (0 is bottom) + + if (row % 2 == 0) { + // Even rows go left to right + return row * 32 + x; + } else { + // Odd rows go right to left + return row * 32 + (31 - x); + } +} + +// Draw a pixel at x,y coordinates +void draw_pixel(light::AddressableLight *display, int x, int y, Color color) { + int index = xy_to_serpentine(x, y); + if (index >= 0 && index < 256) { + (*display)[index] = color; + } +} + +// Draw a horizontal line +void draw_hline(light::AddressableLight *display, int x, int y, int width, Color color) { + for (int i = 0; i < width; i++) { + draw_pixel(display, x + i, y, color); + } +} + +// Draw a vertical line +void draw_vline(light::AddressableLight *display, int x, int y, int height, Color color) { + for (int i = 0; i < height; i++) { + draw_pixel(display, x, y + i, color); + } +} + +// Draw a rectangle +void draw_rect(light::AddressableLight *display, int x, int y, int width, int height, Color color, bool filled = false) { + if (filled) { + for (int j = 0; j < height; j++) { + draw_hline(display, x, y + j, width, color); + } + } else { + draw_hline(display, x, y, width, color); + draw_hline(display, x, y + height - 1, width, color); + draw_vline(display, x, y, height, color); + draw_vline(display, x + width - 1, y, height, color); + } +} + +// Simple bitmap font (3x5 pixels for numbers) +const uint8_t FONT_3X5[][5] = { + {0x7, 0x5, 0x5, 0x5, 0x7}, // 0 + {0x2, 0x6, 0x2, 0x2, 0x7}, // 1 + {0x7, 0x1, 0x7, 0x4, 0x7}, // 2 + {0x7, 0x1, 0x3, 0x1, 0x7}, // 3 + {0x5, 0x5, 0x7, 0x1, 0x1}, // 4 + {0x7, 0x4, 0x7, 0x1, 0x7}, // 5 + {0x7, 0x4, 0x7, 0x5, 0x7}, // 6 + {0x7, 0x1, 0x1, 0x1, 0x1}, // 7 + {0x7, 0x5, 0x7, 0x5, 0x7}, // 8 + {0x7, 0x5, 0x7, 0x1, 0x7}, // 9 +}; + +// Draw a digit +void draw_digit(light::AddressableLight *display, int x, int y, int digit, Color color) { + if (digit < 0 || digit > 9) return; + + for (int row = 0; row < 5; row++) { + uint8_t line = FONT_3X5[digit][row]; + for (int col = 0; col < 3; col++) { + if (line & (1 << (2 - col))) { + draw_pixel(display, x + col, y + row, color); + } + } + } +} + +// Draw a number (up to 2 digits) +void draw_number(light::AddressableLight *display, int x, int y, int number, Color color) { + if (number < 0 || number > 99) return; + + if (number >= 10) { + draw_digit(display, x, y, number / 10, color); + draw_digit(display, x + 4, y, number % 10, color); + } else { + draw_digit(display, x, y, number, color); + } +} + +// Scrolling text buffer structure +struct ScrollBuffer { + std::vector buffer; + int width; + int position; + + ScrollBuffer(int w) : width(w), position(0) {} + + void scroll() { + position++; + if (position >= width) { + position = 0; + } + } +}; \ No newline at end of file diff --git a/packages/wifi.yaml b/packages/wifi.yaml index 21cf1a4..bab38d2 100644 --- a/packages/wifi.yaml +++ b/packages/wifi.yaml @@ -1,6 +1,18 @@ esphome: +text_sensor: + - platform: wifi_info + ip_address: + id: ip_addr + name: "IP Address" + wifi: ssid: !secret wifi_ssid password: !secret wifi_password - + on_connect: + then: + - delay: 2s # give the sensor a moment to update + - logger.log: + level: INFO + format: "Connected! IP Address: %s" + args: ["id(ip_addr).state.c_str()"] \ No newline at end of file diff --git a/trash/3d-printer-camera.yaml b/trash/3d-printer-camera.yaml deleted file mode 100644 index 82bc2df..0000000 --- a/trash/3d-printer-camera.yaml +++ /dev/null @@ -1,46 +0,0 @@ -esphome: - name: 3d-printer-camera - friendly_name: 3d-printer-camera - -esp32: - board: esp32dev - framework: - type: arduino - -# Enable logging -logger: - -# Enable Home Assistant API -api: - encryption: - key: "+b+DVoSdU4U5jlaO2hMcfj1SpIvrJS0nTY2VRz4ZJ8I=" - -ota: - password: "eda8ea0564c19dafc36915ef38f83911" - -wifi: - ssid: !secret wifi_ssid - password: !secret wifi_password - - # Enable fallback hotspot (captive portal) in case wifi connection fails - ap: - ssid: "3D-Printer-Camera" - password: "mhZotMxOa70S" - -captive_portal: - -esp32_camera: - external_clock: - pin: GPIO21 - frequency: 20MHz - i2c_pins: - sda: GPIO26 - scl: GPIO27 - data_pins: [GPIO4, GPIO5, GPIO18, GPIO19, GPIO36, GPIO39, GPIO34, GPIO35] - vsync_pin: GPIO25 - href_pin: GPIO23 - pixel_clock_pin: GPIO22 - - # Image settings - name: Camera - resolution: 1024x768 \ No newline at end of file diff --git a/trash/adxl345-test.yaml b/trash/adxl345-test.yaml deleted file mode 100644 index 0beef9d..0000000 --- a/trash/adxl345-test.yaml +++ /dev/null @@ -1,61 +0,0 @@ -esphome: - name: adxl345-test - friendly_name: ADXL345 Test - - includes: - - ADXL345.h - libraries: - - "Wire" - - "SPI" - - "Adafruit BusIO" - - "Adafruit Unified Sensor" - - "Adafruit ADXL345" - -esp32: - board: esp32dev - framework: - type: arduino - -# Enable logging -logger: - -# Enable Home Assistant API -api: - encryption: - key: "/v0qaJ9WNLlO/ceNxMjQN/4L1kDpg4xF3GB+huSE9uU=" - -ota: - password: "d29c9732c14ab553c7b61cf7518893b8" - -wifi: - ssid: !secret wifi_ssid - password: !secret wifi_password - - # Enable fallback hotspot (captive portal) in case wifi connection fails - ap: - ssid: "Adxl345-Test Fallback Hotspot" - password: "51tWtojf169e" - -captive_portal: - -i2c: - sda: 21 - scl: 22 - scan: true - -sensor: - - platform: custom - lambda: |- - auto adxl345 = new ADXL345Sensor(); - App.register_component(adxl345); - return { - adxl345->off_vertical - }; - sensors: - - name: "Off Vertical" - unit_of_measurement: percentage - filters: - - sliding_window_moving_average: - window_size: 5 - send_every: 5 - - lambda: return 100 * x / 45.0; \ No newline at end of file diff --git a/trash/basement-stairs-led-controller.yaml b/trash/basement-stairs-led-controller.yaml deleted file mode 100644 index e4207d6..0000000 --- a/trash/basement-stairs-led-controller.yaml +++ /dev/null @@ -1,31 +0,0 @@ -esphome: - name: basement-stairs-led-controller - friendly_name: basement stairs led controller - -esp32: - board: esp32dev - framework: - type: arduino - -# Enable logging -logger: - -# Enable Home Assistant API -api: - encryption: - key: "1zN1Evl3kkRYTLWmSw+iLL6Gpufn/QJru2X17YroAns=" - -ota: - password: "d980c05ac4810f46717c0d8ea10b3b2b" - -wifi: - ssid: !secret wifi_ssid - password: !secret wifi_password - - # Enable fallback hotspot (captive portal) in case wifi connection fails - ap: - ssid: "Basement-Stairs-Led-Controller" - password: "tJdG3X0m0TcY" - -captive_portal: - \ No newline at end of file diff --git a/trash/basement-stairs-mini.yaml b/trash/basement-stairs-mini.yaml deleted file mode 100644 index 3a511ee..0000000 --- a/trash/basement-stairs-mini.yaml +++ /dev/null @@ -1,31 +0,0 @@ -esphome: - name: basement-stairs-mini - friendly_name: basement stairs mini - -esp32: - board: esp32dev - framework: - type: arduino - -# Enable logging -logger: - -# Enable Home Assistant API -api: - encryption: - key: "He3sclXVKUDGA2Cv7Q0OxiOwpaAQ0CDRL8IkvfT8Zsc=" - -ota: - password: "8ded3b7c8f13033cbf018b5672b74b21" - -wifi: - ssid: !secret wifi_ssid - password: !secret wifi_password - - # Enable fallback hotspot (captive portal) in case wifi connection fails - ap: - ssid: "Basement-Stairs-Mini" - password: "4HwDF0m7w9Zb" - -captive_portal: - \ No newline at end of file diff --git a/trash/basement-stairs-mmwave-c3.yaml b/trash/basement-stairs-mmwave-c3.yaml deleted file mode 100644 index 32eec9f..0000000 --- a/trash/basement-stairs-mmwave-c3.yaml +++ /dev/null @@ -1,39 +0,0 @@ -substitutions: - device_name: basement-stairs-mmwave-c3 - device_name_pretty: "basement stairs mmwave c3" - -esphome: - name: ${device_name} - friendly_name: ${device_name_pretty} - includes: - - leapmmw_sensor.h - -esp32: - board: esp32dev - framework: - type: arduino - -# Enable logging -logger: - level: DEBUG #You Can Use "INFO" Level - baud_rate: 0 - -# Enable Home Assistant API -api: - encryption: - key: "m/VImzYhHfGuPU0NyGGiP/6tJlcv8JPy9pDXG2UtqiE=" - -ota: - password: "ebfa17f36e2d90de09facad6650e8944" - -wifi: - ssid: !secret wifi_ssid - password: !secret wifi_password - - # Enable fallback hotspot (captive portal) in case wifi connection fails - ap: - ssid: "Basement-Stairs-Mmwave-C3" - password: "uoD8kJDKcaXq" - -captive_portal: - \ No newline at end of file diff --git a/trash/basement-stairs-mmwave-sensor.yaml b/trash/basement-stairs-mmwave-sensor.yaml deleted file mode 100644 index 68c442b..0000000 --- a/trash/basement-stairs-mmwave-sensor.yaml +++ /dev/null @@ -1,199 +0,0 @@ -substitutions: - device_name: basement-stairs-mmwave-sensor - device_name_pretty: "basement stairs mmwave sensor" - -esphome: - name: ${device_name} - friendly_name: ${device_name_pretty} - includes: - - leapmmw_sensor.h - -esp32: - board: esp32dev - framework: - type: arduino - -# Enable logging -logger: - level: DEBUG #You Can Use "INFO" Level - baud_rate: 0 - -# Enable Home Assistant API -api: - encryption: - key: "gNh+IsnVWnhDp3rXf2hMHB7ZpAx6ScnZo1TCQxYibQg=" - -ota: - password: "c56a9c1d07dc8f2eff30e19b961b405c" - -wifi: - ssid: !secret wifi_ssid - password: !secret wifi_password - - # Enable fallback hotspot (captive portal) in case wifi connection fails - ap: - ssid: "Basement-Stairs-Mmwave-Sensor" - password: "zwj6vOqPQePO" - -captive_portal: - -uart: - id: SEN095_UART_BUS - rx_pin: GPIO16 - tx_pin: GPIO17 - baud_rate: 115200 - data_bits: 8 - stop_bits: 1 - parity: NONE - -# Example configuration entry -dfrobot_sen0395: - -binary_sensor: - - platform: gpio - name: "${device_name_pretty}" - id: mmwave_presence_detection - device_class: motion - pin: - number: 27 - mode: INPUT_PULLDOWN - # when motion is detected, the radar sensor is on so publish radar state to HA - on_press: - then: - lambda: !lambda |- - if (!id(mmwave_sensor).state) { - id(mmwave_sensor).publish_state(true); - } - - -sensor: - - platform: custom - lambda: |- - auto s = new leapmmw(id(SEN095_UART_BUS)); - App.register_component(s); - return {}; - sensors: - -switch: - - platform: safe_mode - name: use_safe_mode - - - platform: template - name: "${device_name_pretty} mmwave_sensor" - id: mmwave_sensor # do not change - entity_category: config - optimistic: true - turn_on_action: - - uart.write: "setUartOutput 1 0" - - delay: 1s - - uart.write: "saveConfig" - - delay: 4s - - uart.write: "sensorStart" - turn_off_action: - - uart.write: "sensorStop" - - delay: 2s - - - platform: template - name: "${device_name_pretty} led" - id: led # do not change - entity_category: config - optimistic: true - turn_on_action: - - switch.turn_off: mmwave_sensor - - delay: 2s - - uart.write: "setLedMode 1 0" - - delay: 3s - - lambda: |- - leapmmw(id(SEN095_UART_BUS)).getmmwConf("getLedMode 1"); - - delay: 2s - - switch.turn_on: mmwave_sensor - turn_off_action: - - switch.turn_off: mmwave_sensor - - delay: 2s - - uart.write: "setLedMode 1 1" - - delay: 3s - - lambda: |- - leapmmw(id(SEN095_UART_BUS)).getmmwConf("getLedMode 1"); - - delay: 2s - - switch.turn_on: mmwave_sensor - -number: - - platform: template - name: "${device_name_pretty} distance" - id: distance # do not change - entity_category: config - min_value: 0.15 - max_value: 9.45 - step: 0.15 - unit_of_measurement: M - mode: box - lambda: |- - leapmmw(id(SEN095_UART_BUS)).getmmwConf("getRange"); - return {}; - set_action: - - switch.turn_off: mmwave_sensor - - delay: 2s - - uart.write: !lambda - std::string range = "setRange 0 " + str_sprintf("%.2f", x); - return std::vector(range.begin(), range.end()); - - delay: 3s - - switch.turn_on: mmwave_sensor - - - platform: template - name: "${device_name_pretty} latency" - id: latency # do not change - entity_category: config - min_value: 1 - max_value: 600 - lambda: |- - leapmmw(id(SEN095_UART_BUS)).getmmwConf("getLatency"); - return {}; - step: 1 - unit_of_measurement: s - mode: box - set_action: - - switch.turn_off: mmwave_sensor - - delay: 2s - - uart.write: !lambda - std::string setL = "setLatency 0.1 " + str_sprintf("%.0f", x); - return std::vector(setL.begin(), setL.end()); - - delay: 3s - - switch.turn_on: mmwave_sensor - - - platform: template - name: "${device_name_pretty} sensitivity" - id: sensitivity # do not change - entity_category: config - min_value: 0 - max_value: 9 - lambda: |- - leapmmw(id(SEN095_UART_BUS)).getmmwConf("getSensitivity"); - return {}; - step: 1 - set_action: - - switch.turn_off: mmwave_sensor - - delay: 2s - - uart.write: !lambda - std::string mss = "setSensitivity " + to_string((int)x); - return std::vector(mss.begin(), mss.end()); - - delay: 3s - - switch.turn_on: mmwave_sensor - -button: - - platform: restart - name: Restart_ESP_${device_name} - entity_category: diagnostic - on_press: - - uart.write: - id: SEN095_UART_BUS - data: "resetSystem 0" - - - platform: template - name: factory_reset_mmwMCU_${device_name} - id: factory_reset_mmwMCU - entity_category: diagnostic - on_press: - - switch.turn_off: mmwave_sensor - - delay: 2s - - uart.write: "resetCfg" - - delay: 3s \ No newline at end of file diff --git a/trash/basement-stairs-presence-sensor.yaml b/trash/basement-stairs-presence-sensor.yaml deleted file mode 100644 index 9935b0a..0000000 --- a/trash/basement-stairs-presence-sensor.yaml +++ /dev/null @@ -1,232 +0,0 @@ -# https://wiki.dfrobot.com/mmWave_Radar_Human_Presence_Detection_SKU_SEN0395 -# https://docs.espressif.com/projects/esp-idf/en/latest/esp32c3/hw-reference/esp32c3/user-guide-devkitm-1.html -substitutions: - device_name: basement-stairs-presence-sensor - device_name_pretty: "basement stairs presence sensor" - -esphome: - name: ${device_name} - friendly_name: ${device_name_pretty} - includes: - - leapmmw_sensor.h - -esp32: - board: esp32-c3-devkitm-1 - framework: - type: arduino - -# Enable logging -logger: - -# Enable Home Assistant API -api: - encryption: - key: "KxojXV7TOX//Kmk+sZZmq4jOXc1DgdJ0Va9SQE4hajk=" - -ota: - password: "4ad514a273ab653495d4389be22df9e8" - -wifi: - ssid: !secret wifi_ssid - password: !secret wifi_password - - # Enable fallback hotspot (captive portal) in case wifi connection fails - ap: - ssid: "Basement-Stairs-Mmwave-Sensor" - password: "zwj6vOqPQePO" - -captive_portal: - -uart: - id: SEN095_UART_BUS - rx_pin: GPIO0 - tx_pin: GPIO1 - baud_rate: 115200 - data_bits: 8 - stop_bits: 1 - parity: NONE - -# Example configuration entry -dfrobot_sen0395: - -light: - - platform: neopixelbus - id: status_light - type: GRB - variant: WS2811 - pin: GPIO8 - num_leds: 1 - name: "Status Light" - internal: True - -binary_sensor: - - platform: gpio - name: "${device_name_pretty}" - id: mmwave_presence_detection - device_class: motion - pin: - number: 10 - mode: INPUT_PULLDOWN - # when motion is detected, the radar sensor is on so publish radar state to HA - on_press: - then: - - lambda: !lambda |- - if (!id(mmwave_sensor).state) { - id(mmwave_sensor).publish_state(true); - } - - light.turn_on: - id: status_light - brightness: 100% - red: 100% - green: 0% - blue: 0% - on_release: - then: - - light.turn_off: status_light - - -sensor: - - platform: custom - lambda: |- - auto s = new leapmmw(id(SEN095_UART_BUS)); - App.register_component(s); - return {}; - sensors: - - platform: ultrasonic - trigger_pin: 4 - echo_pin: 5 - name: "Ultrasonic Sensor" - update_interval: 100ms - timeout: 4m - pulse_time: 10us - filters: - - filter_out: nan - - sliding_window_moving_average: - window_size: 10 - send_every: 10 - - -switch: - - platform: safe_mode - name: use_safe_mode - - - platform: template - name: "${device_name_pretty} mmwave_sensor" - id: mmwave_sensor # do not change - entity_category: config - optimistic: true - turn_on_action: - - uart.write: "setUartOutput 1 0" - - delay: 1s - - uart.write: "saveConfig" - - delay: 4s - - uart.write: "sensorStart" - turn_off_action: - - uart.write: "sensorStop" - - delay: 2s - - - platform: template - name: "${device_name_pretty} led" - id: led # do not change - entity_category: config - optimistic: true - turn_on_action: - - switch.turn_off: mmwave_sensor - - delay: 2s - - uart.write: "setLedMode 1 0" - - delay: 3s - - lambda: |- - leapmmw(id(SEN095_UART_BUS)).getmmwConf("getLedMode 1"); - - delay: 2s - - switch.turn_on: mmwave_sensor - turn_off_action: - - switch.turn_off: mmwave_sensor - - delay: 2s - - uart.write: "setLedMode 1 1" - - delay: 3s - - lambda: |- - leapmmw(id(SEN095_UART_BUS)).getmmwConf("getLedMode 1"); - - delay: 2s - - switch.turn_on: mmwave_sensor - -number: - - platform: template - name: "${device_name_pretty} distance" - id: distance # do not change - entity_category: config - min_value: 0.15 - max_value: 9.45 - step: 0.15 - unit_of_measurement: M - mode: box - lambda: |- - leapmmw(id(SEN095_UART_BUS)).getmmwConf("getRange"); - return {}; - set_action: - - switch.turn_off: mmwave_sensor - - delay: 2s - - uart.write: !lambda - std::string range = "setRange 0 " + str_sprintf("%.2f", x); - return std::vector(range.begin(), range.end()); - - delay: 3s - - switch.turn_on: mmwave_sensor - - - platform: template - name: "${device_name_pretty} latency" - id: latency # do not change - entity_category: config - min_value: 1 - max_value: 600 - lambda: |- - leapmmw(id(SEN095_UART_BUS)).getmmwConf("getLatency"); - return {}; - step: 1 - unit_of_measurement: s - mode: box - set_action: - - switch.turn_off: mmwave_sensor - - delay: 2s - - uart.write: !lambda - std::string setL = "setLatency 0.1 " + str_sprintf("%.0f", x); - return std::vector(setL.begin(), setL.end()); - - delay: 3s - - switch.turn_on: mmwave_sensor - - - platform: template - name: "${device_name_pretty} sensitivity" - id: sensitivity # do not change - entity_category: config - min_value: 0 - max_value: 9 - lambda: |- - leapmmw(id(SEN095_UART_BUS)).getmmwConf("getSensitivity"); - return {}; - step: 1 - set_action: - - switch.turn_off: mmwave_sensor - - delay: 2s - - uart.write: !lambda - std::string mss = "setSensitivity " + to_string((int)x); - return std::vector(mss.begin(), mss.end()); - - delay: 3s - - switch.turn_on: mmwave_sensor - -button: - - platform: restart - name: Restart_ESP_${device_name} - entity_category: diagnostic - on_press: - - uart.write: - id: SEN095_UART_BUS - data: "resetSystem 0" - - - platform: template - name: factory_reset_mmwMCU_${device_name} - id: factory_reset_mmwMCU - entity_category: diagnostic - on_press: - - switch.turn_off: mmwave_sensor - - delay: 2s - - uart.write: "resetCfg" - - delay: 3s - \ No newline at end of file diff --git a/trash/basement-stairs-upper-motion-sensor.yaml b/trash/basement-stairs-upper-motion-sensor.yaml deleted file mode 100644 index 531d917..0000000 --- a/trash/basement-stairs-upper-motion-sensor.yaml +++ /dev/null @@ -1,31 +0,0 @@ -esphome: - name: basement-stairs-upper-motion-sensor - friendly_name: basement stairs upper motion sensor - -esp32: - board: esp32-c3-devkitm-1 - framework: - type: arduino - -# Enable logging -logger: - -# Enable Home Assistant API -api: - encryption: - key: "JAlRbqj1ibnN5gMo3eXS/7jqSaaTbSy09APYSWNUb0c=" - -ota: - password: "90e404650dd4953147f82e5e257be7b5" - -wifi: - ssid: !secret wifi_ssid - password: !secret wifi_password - - # Enable fallback hotspot (captive portal) in case wifi connection fails - ap: - ssid: "Basement-Stairs-Upper-Motion-Sensor" - password: "higGVbGCXDPT" - -captive_portal: - \ No newline at end of file diff --git a/trash/basement-stairs.yaml b/trash/basement-stairs.yaml deleted file mode 100644 index e82006e..0000000 --- a/trash/basement-stairs.yaml +++ /dev/null @@ -1,64 +0,0 @@ -esphome: - name: "basement-stairs" - friendly_name: basement stairs upper motion - -esp32: - board: esp32-c3-devkitm-1 - framework: - type: arduino - -# Enable logging -logger: - -# Enable Home Assistant API -api: - encryption: - key: "J1Pl6cIH8ormuwRNFrCU49bVDtFAOE+4r4oboq8gJnM=" - -ota: - password: "d735909e801bb482b0989c3befb43865" - -wifi: - ssid: !secret wifi_ssid - password: !secret wifi_password - - # Enable fallback hotspot (captive portal) in case wifi connection fails - ap: - ssid: "Basement-Stairs-Upper-Motion" - password: "sFbohjRvYyMn" - -captive_portal: - -binary_sensor: - - platform: gpio - pin: GPIO7 - name: "PIR Sensor" - device_class: motion - on_press: - then: - light.turn_on: - id: status_light - red: 10% - green: 0% - blue: 0% - on_release: - then: - light.turn_off: status_light - - -light: - - platform: neopixelbus - id: status_light - type: GRB - variant: WS2811 - pin: GPIO8 - num_leds: 1 - name: "Status Light" - internal: True - - - platform: neopixelbus - type: GRB - variant: WS2811 - pin: GPIO9 - num_leds: 60 - name: "Stairs Right" \ No newline at end of file diff --git a/trash/bed-controller.yaml b/trash/bed-controller.yaml deleted file mode 100644 index 2eaadcb..0000000 --- a/trash/bed-controller.yaml +++ /dev/null @@ -1,231 +0,0 @@ -esphome: - name: bed-controller - friendly_name: Bed Controller - -esp32: - board: esp32-c3-devkitm-1 - framework: - type: arduino - -# Enable logging -logger: - -# Enable Home Assistant API -api: - encryption: - key: "uyMwFllQp/7nzMdnRhAqybJymJ/IjqIl+yf1QtDEw/s=" - -ota: - password: "db4d5c0eeda9ef797ebbfbaa2b397720" - -wifi: - ssid: !secret wifi_ssid - password: !secret wifi_password - - # Enable fallback hotspot (captive portal) in case wifi connection fails - ap: - ssid: "Bed-Controller Fallback Hotspot" - password: "vHlYMuWAHvnp" - -captive_portal: - -# Sync time with Home Assistant. -time: - - platform: homeassistant - id: homeassistant_time - -# Text sensors with general information. -text_sensor: - # Expose ESPHome version as sensor. - - platform: version - name: ESPHome Version - # Expose WiFi information as sensors. - - platform: wifi_info - ip_address: - name: IP - ssid: - name: SSID - bssid: - name: BSSID - -switch: - - platform: restart - name: "Restart" - -globals: - - id: min_speed - type: float - restore_value: False - initial_value: '10' - - id: motor_speed - type: float - restore_value: False - initial_value: id(min_speed) - - id: num_speeds - type: int - restore_value: False - initial_value: '4' - -output: - - platform: ledc - pin: GPIO32 - id: motor_forward_pin - - platform: ledc - pin: GPIO33 - id: motor_reverse_pin - - platform: ledc - pin: GPIO25 - id: motor_enable - - -fan: - - platform: hbridge - id: bed_motor - name: "Bed Motor" - pin_a: motor_forward_pin - pin_b: motor_reverse_pin - enable_pin: motor_enable - # enable_pin: motor_enable - decay_mode: slow - -number: - - platform: template - name: Lower limit (meters) - id: bed_lower_limit - icon: "mdi:cogs" - optimistic: true - restore_value: true # If you don't want to store the setting at ESP, set it to false. - initial_value: "0.04" # Default bed_lower_limit Setting - min_value: 0.0 - max_value: 2.0 - step: 0.01 - on_value: - then: - - script.execute: start_motor_if_needed - - platform: template - name: Upper limit (meters) - id: bed_upper_limit - icon: "mdi:cogs" - optimistic: true - restore_value: true # If you don't want to store the setting at ESP, set it to false. - initial_value: "0.9" # Default bed_upper_limit Setting - min_value: 0.0 - max_value: 2.0 - step: 0.01 - on_value: - then: - - script.execute: start_motor_if_needed - - platform: template - name: Accuracy - id: accuracy - icon: "mdi:cogs" - optimistic: true - restore_value: true # If you don't want to store the setting at ESP, set it to false. - initial_value: "2.0" # Default accuracy Setting 2% - min_value: 0.0 - max_value: 100.0 - step: 1.0 - on_value: - then: - - script.execute: start_motor_if_needed - - platform: template - name: Desired percentage - id: bed_desired_position - icon: "mdi:cogs" - optimistic: true - restore_value: true # If you don't want to store the setting at ESP, set it to false. - initial_value: "0.0" # Default desired position Setting - min_value: 0.0 - max_value: 100.0 - step: 1.0 - unit_of_measurement: percentage - on_value: - then: - - script.execute: start_motor_if_needed - -sensor: - - platform: ultrasonic - trigger_pin: GPIO27 - echo_pin: GPIO14 - name: "Bed Position" - update_interval: 0.1s - id: bed_position - accuracy_decimals: 0 - unit_of_measurement: percentage - filters: - - filter_out: nan - - sliding_window_moving_average: - window_size: 10 - send_every: 10 - - lambda: return 100.0 * (x - id(bed_lower_limit).state) / ( id(bed_upper_limit).state - id(bed_lower_limit).state ); - on_value: - then: - - script.execute: start_motor_if_needed - -script: - - id: calc_motor_speed - then: - - lambda: |- - float diff = abs(id(bed_desired_position).state - id(bed_position).state); - float speed_size = 100.0 / id(num_speeds); - if (diff > 20) { - id(motor_speed) = 100.0; - } - else if (diff > 10 && id(num_speeds) > 1) { - id(motor_speed) = speed_size * 2; - } - else { - id(motor_speed) = speed_size; - } - - id: start_motor_if_needed - then: - - script.execute: calc_motor_speed - - if: - condition: - lambda: 'return id(bed_position).state < -id(accuracy).state;' - then: - - logger.log: 'bed lower then lower limit!' - - fan.turn_on: - id: bed_motor - direction: FORWARD - speed: - !lambda |- - return id(motor_speed); - else: - - if: - condition: - lambda: 'return id(bed_position).state > 100.0 + id(accuracy).state;' - then: - - logger.log: 'bed higher than high limit!' - - fan.turn_on: - id: bed_motor - direction: REVERSE - speed: - !lambda |- - return id(motor_speed); - else: - - if: - condition: - - lambda: 'return id(bed_position).state < id(bed_desired_position).state - id(accuracy).state;' - then: - - logger.log: 'bed lower than desired, moving up' - - fan.turn_on: - id: bed_motor - direction: FORWARD - speed: - !lambda |- - return id(motor_speed); - else: - - if: - condition: - - lambda: 'return id(bed_position).state > id(bed_desired_position).state + id(accuracy).state;' - then: - - logger.log: 'bed higher than desired, moving down' - - fan.turn_on: - id: bed_motor - direction: REVERSE - speed: - !lambda |- - return id(motor_speed); - else: - - fan.turn_off: bed_motor \ No newline at end of file diff --git a/trash/corner-sump-pump-water-level-sensor.yaml b/trash/corner-sump-pump-water-level-sensor.yaml deleted file mode 100644 index f3a80b8..0000000 --- a/trash/corner-sump-pump-water-level-sensor.yaml +++ /dev/null @@ -1,31 +0,0 @@ -esphome: - name: corner-sump-pump-water-level-sensor - friendly_name: corner-sump-pump-water-level-sensor - -esp32: - board: esp32-c3-devkitm-1 - framework: - type: arduino - -# Enable logging -logger: - -# Enable Home Assistant API -api: - encryption: - key: "/h9vgMgrlzY8kYJAiUxFnk4uEopKs1NsacRHOG7jbKQ=" - -ota: - password: "2420232558a55e485717e5a3410caac4" - -wifi: - ssid: !secret wifi_ssid - password: !secret wifi_password - - # Enable fallback hotspot (captive portal) in case wifi connection fails - ap: - ssid: "Corner-Sump-Pump-Water-Level-Sensor" - password: "dzFmWniE42y7" - -captive_portal: - \ No newline at end of file diff --git a/trash/corner-sump-water-level-sensor.yaml b/trash/corner-sump-water-level-sensor.yaml deleted file mode 100644 index 785421d..0000000 --- a/trash/corner-sump-water-level-sensor.yaml +++ /dev/null @@ -1,39 +0,0 @@ -esphome: - name: corner-sump-water-level-sensor - friendly_name: corner-sump-water-level-sensor - -esp32: - board: esp32dev - framework: - type: arduino - -# Enable logging -logger: - -# Enable Home Assistant API -api: - encryption: - key: "92TRSyzjZq5bbw8/wipmn7zWZWC2XPmxNEbJZv6+M30=" - -ota: - password: "18cb2f0dd54a6bd7e56c3e5e79efe314" - -wifi: - ssid: !secret wifi_ssid - password: !secret wifi_password - - # Enable fallback hotspot (captive portal) in case wifi connection fails - ap: - ssid: "Corner-Sump-Water-Level-Sensor" - password: "UGeBCJnN3PX2" - -captive_portal: - -# https://learn.sparkfun.com/tutorials/esp32-thing-plus-hookup-guide/all -# https://esphome.io/components/i2c.html# -# https://learn.sparkfun.com/tutorials/qwiic-ultrasonic-distance-sensor-hc-sr04-hookup-guide/all -i2c: - sda: GPIO01 - scl: GPIO02 - scan: true - id: bus_a \ No newline at end of file diff --git a/trash/garage-camera.yaml b/trash/garage-camera.yaml deleted file mode 100644 index 1bf985f..0000000 --- a/trash/garage-camera.yaml +++ /dev/null @@ -1,50 +0,0 @@ -esphome: - name: garage-camera - friendly_name: Garage Camera - comment: esp32dev - -esp32: - board: esp32dev - framework: - type: arduino - -# Enable logging -logger: - -# Enable Home Assistant API -api: - encryption: - key: "6o4U+71ZOTxfjpi1mTOG6ThajzFEWEyJPJdKk/0nUAg=" - -ota: - - platform: esphome - password: "ef8d191e2007e0fe89477dd296817f25" - -wifi: - ssid: !secret wifi_ssid - password: !secret wifi_password - - # Enable fallback hotspot (captive portal) in case wifi connection fails - ap: - ssid: "Garage-Camera Fallback Hotspot" - password: "VotNjbPdTfyf" - -captive_portal: - -esp32_camera: - external_clock: - pin: GPIO21 - frequency: 20MHz - i2c_pins: - sda: GPIO26 - scl: GPIO27 - data_pins: [GPIO4, GPIO5, GPIO18, GPIO19, GPIO36, GPIO39, GPIO34, GPIO35] - vsync_pin: GPIO25 - href_pin: GPIO23 - pixel_clock_pin: GPIO22 - - # Image settings - name: Camera - resolution: 1024x768 - vertical_flip: false - horizontal_mirror: false \ No newline at end of file diff --git a/trash/garage-ha-master.yaml b/trash/garage-ha-master.yaml deleted file mode 100644 index f543bfe..0000000 --- a/trash/garage-ha-master.yaml +++ /dev/null @@ -1,68 +0,0 @@ -esphome: - name: garage-ha-master - friendly_name: garage-ha-master - -esp32: - board: esp32dev - framework: - type: arduino - -# Enable Home Assistant API -api: - encryption: - key: "voq2rWJn8dFl/rtHRAqAnIipjcwWqdh/WAAn6BEle3Y=" - -ota: - password: "84faa1ee621712bd8c06f8382b7c1fda" - -wifi: - ssid: !secret wifi_ssid - password: !secret wifi_password - - # Enable fallback hotspot (captive portal) in case wifi connection fails - ap: - ssid: "Garage-Ha-Master" - password: "0OyBvaAOSOcL" - -captive_portal: - -external_components: - - source: - type: git - url: https://github.com/ssieb/custom_components #Thanks for @ssieb components. - components: [ serial ] - -# Enable logging -logger: - baud_rate: 0 - -uart: - rx_pin: GPIO22 - tx_pin: GPIO23 - baud_rate: 9600 - data_bits: 8 - stop_bits: 2 - parity: NONE - debug: - direction: BOTH - dummy_receiver: false - after: - delimiter: "\n" - sequence: - - lambda: UARTDebug::log_string(direction, bytes); - -text_sensor: - - platform: serial - name: Received slave text - id: slave_text - -text: - - platform: template - mode: text - name: Send to slave - id: send_to_slave - set_action: - then: - - uart.write: !lambda |- - std::string sendme = x + "\n"; - return std::vector(sendme.begin(), sendme.end()); \ No newline at end of file diff --git a/trash/garage-ha-slave.yaml b/trash/garage-ha-slave.yaml deleted file mode 100644 index 234449f..0000000 --- a/trash/garage-ha-slave.yaml +++ /dev/null @@ -1,87 +0,0 @@ -packages: - beacon: !include packages/beacon.yaml - -esphome: - name: garage-ha-slave - friendly_name: garage-ha-slave - -esp32: - board: esp32dev - framework: - type: arduino - -# Enable logging -logger: - # do not log to serial - baud_rate: 0 - -# Enable Home Assistant API -api: - encryption: - key: "SUI+2tAU4QM6jDKw4utdwmpFKyZrvoCD4IyJ8+OmwU4=" - # disable reboot because we disconnect to scan wifi - reboot_timeout: 0s - -ota: - password: "d55d376ed4bcfee485afea8865120189" - -wifi: - ssid: !secret wifi_ssid - password: !secret wifi_password - - # Enable fallback hotspot (captive portal) in case wifi connection fails - ap: - ssid: "Garage-Ha-Slave Fallback Hotspot" - password: "g3K334QqPiX7" - -captive_portal: - -esp32_ble_tracker: - scan_parameters: - window: 120ms - - -external_components: - - source: - type: git - url: https://github.com/ssieb/custom_components #Thanks for @ssieb components. - components: [ serial ] - -uart: - rx_pin: GPIO22 - tx_pin: GPIO23 - baud_rate: 9600 - data_bits: 8 - stop_bits: 2 - parity: NONE - # debug: - # direction: BOTH - # dummy_receiver: false - # after: - # delimiter: "\n" - # sequence: - # - lambda: UARTDebug::log_string(direction, bytes); - -text_sensor: - - platform: serial - name: Received master text - id: master_text - - platform: wifi_info - scan_results: - name: ESP Latest Scan Results - id: scan_results - -text: - - platform: template - mode: text - name: Send to master - id: send_to_master - set_action: - then: - - uart.write: !lambda |- - std::string sendme = x + "\n"; - return std::vector(sendme.begin(), sendme.end()); - - - - diff --git a/trash/garage-master.yaml b/trash/garage-master.yaml deleted file mode 100644 index 4bc1f29..0000000 --- a/trash/garage-master.yaml +++ /dev/null @@ -1,70 +0,0 @@ -esphome: - name: garage-master - friendly_name: garage-master - comment: esp32dev - -esp32: - board: esp32dev - framework: - type: arduino - -# Disable logging -logger: - baud_rate: 0 - -# Enable Home Assistant API -api: - encryption: - key: "RoWkhYIHXIB92Q4zNPcweZvZgWSChT1A1oRmD2hRolk=" - -ota: - password: "c279b490f4994e36755058ed0e40460b" - -wifi: - ssid: !secret wifi_ssid - password: !secret wifi_password - - # Enable fallback hotspot (captive portal) in case wifi connection fails - ap: - ssid: "Garage-Master Fallback Hotspot" - password: "a5ZRCKrJLKVt" - -captive_portal: - -uart: - rx_pin: GPIO1 - tx_pin: GPIO3 - baud_rate: 115200 - data_bits: 8 - stop_bits: 1 - parity: NONE - debug: - direction: BOTH - dummy_receiver: false - after: - delimiter: "\n" - sequence: - - lambda: UARTDebug::log_string(direction, bytes); - - -external_components: - - source: - type: git - url: https://github.com/ssieb/custom_components #Thanks for @ssieb components. - components: [ serial ] - - -# text_sensor: -# - platform: serial -# name: Slave text - -text: - - platform: template - mode: text - name: Send to slave - id: send_to_slave - set_action: - then: - - uart.write: !lambda |- - std::string sendme = x + "\n"; - return std::vector(sendme.begin(), sendme.end()); diff --git a/trash/garage-master2.yaml b/trash/garage-master2.yaml deleted file mode 100644 index a20415d..0000000 --- a/trash/garage-master2.yaml +++ /dev/null @@ -1,69 +0,0 @@ -esphome: - name: garage-control-master2 - friendly_name: garage-control-master2 - -esp32: - board: esp32dev - framework: - type: arduino - -external_components: - - source: - type: git - url: https://github.com/ssieb/custom_components #Thanks for @ssieb components. - components: [ serial ] - -# Enable logging -logger: - baud_rate: 0 - -# Enable Home Assistant API -api: - encryption: - key: "ku0BYi9By5cFFEYDyETyZmszDR7Jphpz24uJzIbQTrg=" - -ota: - password: "38913e884c1425dd1757bf7606abf233" - -wifi: - ssid: !secret wifi_ssid - password: !secret wifi_password - - # Enable fallback hotspot (captive portal) in case wifi connection fails - ap: - ssid: "Garage-Master2 Fallback Hotspot" - password: "fRCUAI46FNga" - -captive_portal: - - -uart: - rx_pin: GPIO22 - tx_pin: GPIO23 - baud_rate: 9600 - data_bits: 8 - stop_bits: 1 - parity: NONE - debug: - direction: BOTH - dummy_receiver: false - after: - delimiter: "\n" - sequence: - - lambda: UARTDebug::log_string(direction, bytes); - -text_sensor: - - platform: serial - name: Received slave text - id: slave_text - -text: - - platform: template - mode: text - name: Send to slave - id: send_to_slave - set_action: - then: - - uart.write: !lambda |- - std::string sendme = x + "\n"; - return std::vector(sendme.begin(), sendme.end()); \ No newline at end of file diff --git a/trash/garage-slave.yaml b/trash/garage-slave.yaml deleted file mode 100644 index fff22c8..0000000 --- a/trash/garage-slave.yaml +++ /dev/null @@ -1,63 +0,0 @@ -esphome: - name: garage-wifi-slave - friendly_name: garage-wifi-slave - -esp32: - board: esp32dev - framework: - type: arduino - -# Disable logging -logger: - baud_rate: 0 - -# Enable Home Assistant API -api: - encryption: - key: "M64t2wRHjGVpPBAu6AxxRKY3WyZLdB3yK7jQOJyE5AU=" - -ota: - password: "abf5c4123fd2db9bf4c5aef1237f4243" - -wifi: - ssid: !secret wifi_ssid - password: !secret wifi_password - - # Enable fallback hotspot (captive portal) in case wifi connection fails - ap: - ssid: "Garage-Slave Fallback Hotspot" - password: "f2XLmIgz8PaN" - -captive_portal: - - -uart: - rx_pin: GPIO22 - tx_pin: GPIO23 - baud_rate: 9600 - data_bits: 8 - stop_bits: 1 - parity: NONE - debug: - direction: BOTH - dummy_receiver: false - after: - delimiter: "\n" - sequence: - - lambda: UARTDebug::log_string(direction, bytes); - -# text_sensor: -# - platform: serial -# id: master_text -# name: Master text - -text: - - platform: template - mode: text - name: Send to master - id: send_to_master - set_action: - then: - - uart.write: !lambda |- - std::string sendme = x + "\n"; - return std::vector(sendme.begin(), sendme.end()); \ No newline at end of file diff --git a/trash/hires-camera.yaml b/trash/hires-camera.yaml deleted file mode 100644 index 05b0816..0000000 --- a/trash/hires-camera.yaml +++ /dev/null @@ -1,48 +0,0 @@ -esphome: - name: hires-camera - friendly_name: HiRes Camera - -esp32: - board: esp32dev - framework: - type: arduino - -# Enable logging -logger: - -# Enable Home Assistant API -api: - encryption: - key: "6qCk7lS2wL6m4yWXWy/9vj1/sY2nS3PBHEQNnS3b4z8=" - -ota: - password: "659656f65e27665316018491a0b247ba" - -wifi: - ssid: !secret wifi_ssid - password: !secret wifi_password - - # Enable fallback hotspot (captive portal) in case wifi connection fails - ap: - ssid: "Hires-Camera Fallback Hotspot" - password: "FMUtqFrZ3eUN" - -captive_portal: - -esp32_camera: - external_clock: - pin: GPIO21 - frequency: 20MHz - i2c_pins: - sda: GPIO26 - scl: GPIO27 - data_pins: [GPIO4, GPIO5, GPIO18, GPIO19, GPIO36, GPIO39, GPIO34, GPIO35] - vsync_pin: GPIO25 - href_pin: GPIO23 - pixel_clock_pin: GPIO22 - - # Image settings - name: Camera - resolution: 1600x1200 - jpeg_quality: 20 - max_framerate: 20 fps \ No newline at end of file diff --git a/trash/mmwave-detector1.yaml b/trash/mmwave-detector1.yaml deleted file mode 100644 index d1af963..0000000 --- a/trash/mmwave-detector1.yaml +++ /dev/null @@ -1,338 +0,0 @@ -# Enable Home Assistant API -api: - encryption: - key: "xyD+0n3g/k38yhwyo8uE2uMZQM/Ik5ltCUKKC3tFCv8=" - -ota: - password: "f0c5694107ac2f6a4beb6d18b0e39bb5" - -wifi: - ssid: !secret wifi_ssid - password: !secret wifi_password - power_save_mode: LIGHT - # Enable fallback hotspot (captive portal) in case wifi connection fails - ap: - ssid: "Mmwave-Detector1" - password: "qDakHkuHkpRO" - -substitutions: - devicename: "mmwave-detector1" #Rename the device what you want. - upper_devicename: ESP Radar #Rename the device what you want. -esphome: - name: $devicename - friendly_name: $devicename - on_boot: #LD1125H Initial Setting - priority: -200 - then: - - uart.write: - id: LD1125H_UART_BUS - data: !lambda |- - std::string th1stm = "mth1_mov=" + str_sprintf("%.0f",id(LD1125H_mth1_mov).state) +"\r\n"; - return std::vector(th1stm.begin(), th1stm.end()); - - uart.write: - id: LD1125H_UART_BUS - data: !lambda |- - std::string th2stm = "mth2_mov=" + str_sprintf("%.0f",id(LD1125H_mth2_mov).state) +"\r\n"; - return std::vector(th2stm.begin(), th2stm.end()); - - uart.write: - id: LD1125H_UART_BUS - data: !lambda |- - std::string th3stm = "mth3_mov=" + str_sprintf("%.0f",id(LD1125H_mth3_mov).state) +"\r\n"; - return std::vector(th3stm.begin(), th3stm.end()); - - uart.write: - id: LD1125H_UART_BUS - data: !lambda |- - std::string th1sto = "mth1_occ=" + str_sprintf("%.0f",id(LD1125H_mth1_occ).state) +"\r\n"; - return std::vector(th1sto.begin(), th1sto.end()); - - uart.write: - id: LD1125H_UART_BUS - data: !lambda |- - std::string th2sto = "mth2_occ=" + str_sprintf("%.0f",id(LD1125H_mth2_occ).state) +"\r\n"; - return std::vector(th2sto.begin(), th2sto.end()); - - uart.write: - id: LD1125H_UART_BUS - data: !lambda |- - std::string th3sto = "mth3_occ=" + str_sprintf("%.0f",id(LD1125H_mth3_occ).state) +"\r\n"; - return std::vector(th3sto.begin(), th3sto.end()); - - uart.write: - id: LD1125H_UART_BUS - data: !lambda |- - std::string rmaxst = "rmax=" + str_sprintf("%.1f",id(LD1125H_rmax).state) +"\r\n"; - return std::vector(rmaxst.begin(), rmaxst.end()); - - uart.write: - id: LD1125H_UART_BUS - data: !lambda |- - std::string getallst = "get_all\r\n"; - return std::vector(getallst.begin(), getallst.end()); -esp32: - board: nodemcu-32s - framework: - type: arduino -external_components: - - source: - type: git - url: https://github.com/ssieb/custom_components #Thanks for @ssieb components. - components: [ serial ] -logger: - level: DEBUG #You Can Use "INFO" Level - baud_rate: 0 -uart: - id: LD1125H_UART_BUS - rx_pin: GPIO16 #For ESP32, you can use any pin, Recommend Use UART_2, Don't use UART_0, It might Cause Boot Fail or System Hang - tx_pin: GPIO17 #For ESP32, you can use any pin, Recommend Use UART_2, Don't use UART_0, It might Cause Boot Fail or System Hang - baud_rate: 115200 - data_bits: 8 - stop_bits: 1 - parity: NONE -# debug: -# direction: BOTH -# dummy_receiver: false -# after: -# delimiter: "\n" -# sequence: -# - lambda: UARTDebug::log_string(direction, bytes); -globals: - - id: LD1125H_Last_Time - type: time_t - restore_value: no - initial_value: time(NULL) - - id: LD1125H_Last_Mov_Time - type: time_t - restore_value: no - initial_value: time(NULL) - - id: LD1125H_Clearence_Status - type: bool - restore_value: no - initial_value: "false" -status_led: - pin: - number: GPIO2 #ESP32 OnBroad LED - inverted: false -#web_server: #Avoid Using Web Server To Prevent Hang -# port: 80 -interval: - - interval: 1s #Clearance Scan Time - setup_priority: -200 - then: - lambda: |- - if ((time(NULL)-id(LD1125H_Last_Time))>id(LD1125H_Clear_Time).state) { - if ((id(LD1125H_Clearence_Status) == false) || (id(LD1125H_Occupancy).state != "Clearance")) { - id(LD1125H_Occupancy).publish_state("Clearance"); - id(LD1125H_Clearence_Status) = true; - } - if (id(LD1125H_MovOcc_Binary).state == true) { - id(LD1125H_MovOcc_Binary).publish_state(false); - } - if (id(LD1125H_Mov_Binary).state == true) { - id(LD1125H_Mov_Binary).publish_state(false); - } - } -number: - - platform: template - name: ${upper_devicename} LD1125H mth1 mov #mth1 mov is 0~2.8m motion detection threshold. - id: LD1125H_mth1_mov - icon: "mdi:cogs" - optimistic: true - restore_value: true #If you don't want to store the setting at ESP, set it to false. - initial_value: "30.0" #Default mth1_mov Setting - min_value: 10.0 - max_value: 600.0 - step: 5.0 - set_action: - then: - - uart.write: - id: LD1125H_UART_BUS - data: !lambda |- - std::string th1st = "mth1_mov=" + str_sprintf("%.0f",x) +"\r\n"; - return std::vector(th1st.begin(), th1st.end()); - - platform: template - name: ${upper_devicename} LD1125H mth2 mov #mth2 mov is 2.8~8m motion detection threshold. - id: LD1125H_mth2_mov - icon: "mdi:cogs" - optimistic: true - restore_value: true #If you don't want to store the setting at ESP, set it to false. - initial_value: "15" #Default mth2_mov Setting - min_value: 5 - max_value: 300 - step: 5 - set_action: - then: - - uart.write: - id: LD1125H_UART_BUS - data: !lambda |- - std::string th2st = "mth2_mov=" + str_sprintf("%.0f",x) +"\r\n"; - return std::vector(th2st.begin(), th2st.end()); - - platform: template - name: ${upper_devicename} LD1125H mth3 mov #mth3 mov is above 8m motion detection threshold. - id: LD1125H_mth3_mov - icon: "mdi:cogs" - optimistic: true - restore_value: true #If you don't want to store the setting at ESP, set it to false. - initial_value: "6" #Default mth3_mov Setting - min_value: 5 - max_value: 200 - step: 5 - set_action: - then: - - uart.write: - id: LD1125H_UART_BUS - data: !lambda |- - std::string th3st = "mth3_mov=" + str_sprintf("%.0f",x) +"\r\n"; - return std::vector(th3st.begin(), th3st.end()); - - platform: template - name: ${upper_devicename} LD1125H mth1 occ #mth1 occ is 0~2.8m detection threshold. - id: LD1125H_mth1_occ - icon: "mdi:cogs" - optimistic: true - restore_value: true #If you don't want to store the setting at ESP, set it to false. - initial_value: "30.0" #Default mth1_mov Setting - min_value: 10.0 - max_value: 600.0 - step: 5.0 - set_action: - then: - - uart.write: - id: LD1125H_UART_BUS - data: !lambda |- - std::string th1st = "mth1_occ=" + str_sprintf("%.0f",x) +"\r\n"; - return std::vector(th1st.begin(), th1st.end()); - - platform: template - name: ${upper_devicename} LD1125H mth2 occ #mth2 occ is 2.8~8m detection threshold. - id: LD1125H_mth2_occ - icon: "mdi:cogs" - optimistic: true - restore_value: true #If you don't want to store the setting at ESP, set it to false. - initial_value: "15" #Default mth2_mov Setting - min_value: 5 - max_value: 300 - step: 5 - set_action: - then: - - uart.write: - id: LD1125H_UART_BUS - data: !lambda |- - std::string th2st = "mth2_occ=" + str_sprintf("%.0f",x) +"\r\n"; - return std::vector(th2st.begin(), th2st.end()); - - platform: template - name: ${upper_devicename} LD1125H mth3 occ #mth3 occ is above 8m detection threshold. - id: LD1125H_mth3_occ - icon: "mdi:cogs" - optimistic: true - restore_value: true #If you don't want to store the setting at ESP, set it to false. - initial_value: "6" #Default mth3_mov Setting - min_value: 5 - max_value: 200 - step: 5 - set_action: - then: - - uart.write: - id: LD1125H_UART_BUS - data: !lambda |- - std::string th3st = "mth3_occ=" + str_sprintf("%.0f",x) +"\r\n"; - return std::vector(th3st.begin(), th3st.end()); - - platform: template - name: ${upper_devicename} LD1125H rmax #rmax is max detection distance. - id: LD1125H_rmax - icon: "mdi:cogs" - optimistic: true - restore_value: true #If you don't want to store the setting at ESP, set it to false. - initial_value: "8" #Default rmax Setting - min_value: 0.4 - max_value: 12 - step: 0.2 - set_action: - then: - - uart.write: - id: LD1125H_UART_BUS - data: !lambda |- - std::string rmaxst = "rmax=" + str_sprintf("%.1f",x) +"\r\n"; - return std::vector(rmaxst.begin(), rmaxst.end()); - - platform: template - name: ${upper_devicename} LD1125H Clearence Time - id: LD1125H_Clear_Time - icon: "mdi:cogs" - optimistic: true - restore_value: true #If you don't want to store the setting at ESP, set it to false. - initial_value: "5" #LD1125H Mov/Occ > Clearence Time Here - min_value: 0.5 - max_value: 60 - step: 0.5 - - platform: template - name: ${upper_devicename} LD1125H Movement Time - id: LD1125H_Mov_Time - icon: "mdi:cogs" - optimistic: true - restore_value: true #If you don't want to store the setting at ESP, set it to false. - initial_value: "1" #LD1125H Mov > Occ Time Here - min_value: 0.5 - max_value: 10 - step: 0.5 -sensor: - - platform: template - name: ${upper_devicename} LD1125H Distance - id: LD1125H_Distance - icon: "mdi:signal-distance-variant" - unit_of_measurement: "m" - accuracy_decimals: 2 - filters: # Use Fliter To Debounce - - sliding_window_moving_average: - window_size: 8 - send_every: 2 - - heartbeat: 0.2s -text_sensor: - - platform: serial - uart_id: LD1125H_UART_BUS - name: ${upper_devicename} LD1125H UART Text - id: LD1125H_UART_Text - icon: "mdi:format-text" - internal: False #If Don't Want to See UART Receive Data, Set To True - on_value: - lambda: |- - if (id(LD1125H_UART_Text).state.substr(0,3) == "occ") { - id(LD1125H_Distance).publish_state(atof(id(LD1125H_UART_Text).state.substr(9).c_str())); - if ((time(NULL)-id(LD1125H_Last_Mov_Time))>id(LD1125H_Mov_Time).state) { - id(LD1125H_Occupancy).publish_state("Occupancy"); - if (id(LD1125H_MovOcc_Binary).state == false) { - id(LD1125H_MovOcc_Binary).publish_state(true); - } - if (id(LD1125H_Mov_Binary).state == true) { - id(LD1125H_Mov_Binary).publish_state(false); - } - } - if (id(LD1125H_MovOcc_Binary).state == false) { - id(LD1125H_MovOcc_Binary).publish_state(true); - } - id(LD1125H_Last_Time) = time(NULL); - if (id(LD1125H_Clearence_Status) == true) { - id(LD1125H_Clearence_Status) = false; - } - } - else if (id(LD1125H_UART_Text).state.substr(0,3) == "mov") { - id(LD1125H_Distance).publish_state(atof(id(LD1125H_UART_Text).state.substr(9).c_str())); - id(LD1125H_Occupancy).publish_state("Movement"); - if (id(LD1125H_MovOcc_Binary).state == false) { - id(LD1125H_MovOcc_Binary).publish_state(true); - } - if (id(LD1125H_Mov_Binary).state == false) { - id(LD1125H_Mov_Binary).publish_state(true); - } - id(LD1125H_Last_Mov_Time) = time(NULL); - id(LD1125H_Last_Time) = time(NULL); - if (id(LD1125H_Clearence_Status) == true) { - id(LD1125H_Clearence_Status) = false; - } - } - - platform: template - name: ${upper_devicename} LD1125H Occupancy Status - id: LD1125H_Occupancy - icon: "mdi:motion-sensor" -binary_sensor: - - platform: template - name: ${upper_devicename} LD1125H Occupancy or Movement - id: LD1125H_MovOcc_Binary - device_class: occupancy - - platform: template - name: ${upper_devicename} LD1125H Movement - id: LD1125H_Mov_Binary - device_class: motion - \ No newline at end of file diff --git a/trash/mmwave-detector3.yaml b/trash/mmwave-detector3.yaml deleted file mode 100644 index b43a40e..0000000 --- a/trash/mmwave-detector3.yaml +++ /dev/null @@ -1,339 +0,0 @@ -# Enable Home Assistant API -api: - encryption: - key: "eBrxqMp+lU7nOEmQBcl5hZsexSr+NcdhF6xa/0HPbig=" - -ota: - password: "7ca0ac054d39eec0e41ab0e28b7916ee" - -wifi: - ssid: !secret wifi_ssid - password: !secret wifi_password - - # Enable fallback hotspot (captive portal) in case wifi connection fails - ap: - ssid: "Mmwave-Detector3" - password: "xNAPBrJVQfuy" - -captive_portal: -substitutions: - devicename: "mmwave-detector3" #Rename the device what you want. - upper_devicename: ESP Radar #Rename the device what you want. -esphome: - name: $devicename - friendly_name: $devicename - on_boot: #LD1125H Initial Setting - priority: -200 - then: - - uart.write: - id: LD1125H_UART_BUS - data: !lambda |- - std::string th1stm = "mth1_mov=" + str_sprintf("%.0f",id(LD1125H_mth1_mov).state) +"\r\n"; - return std::vector(th1stm.begin(), th1stm.end()); - - uart.write: - id: LD1125H_UART_BUS - data: !lambda |- - std::string th2stm = "mth2_mov=" + str_sprintf("%.0f",id(LD1125H_mth2_mov).state) +"\r\n"; - return std::vector(th2stm.begin(), th2stm.end()); - - uart.write: - id: LD1125H_UART_BUS - data: !lambda |- - std::string th3stm = "mth3_mov=" + str_sprintf("%.0f",id(LD1125H_mth3_mov).state) +"\r\n"; - return std::vector(th3stm.begin(), th3stm.end()); - - uart.write: - id: LD1125H_UART_BUS - data: !lambda |- - std::string th1sto = "mth1_occ=" + str_sprintf("%.0f",id(LD1125H_mth1_occ).state) +"\r\n"; - return std::vector(th1sto.begin(), th1sto.end()); - - uart.write: - id: LD1125H_UART_BUS - data: !lambda |- - std::string th2sto = "mth2_occ=" + str_sprintf("%.0f",id(LD1125H_mth2_occ).state) +"\r\n"; - return std::vector(th2sto.begin(), th2sto.end()); - - uart.write: - id: LD1125H_UART_BUS - data: !lambda |- - std::string th3sto = "mth3_occ=" + str_sprintf("%.0f",id(LD1125H_mth3_occ).state) +"\r\n"; - return std::vector(th3sto.begin(), th3sto.end()); - - uart.write: - id: LD1125H_UART_BUS - data: !lambda |- - std::string rmaxst = "rmax=" + str_sprintf("%.1f",id(LD1125H_rmax).state) +"\r\n"; - return std::vector(rmaxst.begin(), rmaxst.end()); - - uart.write: - id: LD1125H_UART_BUS - data: !lambda |- - std::string getallst = "get_all\r\n"; - return std::vector(getallst.begin(), getallst.end()); -esp32: - board: nodemcu-32s - framework: - type: arduino -external_components: - - source: - type: git - url: https://github.com/ssieb/custom_components #Thanks for @ssieb components. - components: [ serial ] -logger: - level: DEBUG #You Can Use "INFO" Level - baud_rate: 0 -uart: - id: LD1125H_UART_BUS - rx_pin: GPIO16 #For ESP32, you can use any pin, Recommend Use UART_2, Don't use UART_0, It might Cause Boot Fail or System Hang - tx_pin: GPIO17 #For ESP32, you can use any pin, Recommend Use UART_2, Don't use UART_0, It might Cause Boot Fail or System Hang - baud_rate: 115200 - data_bits: 8 - stop_bits: 1 - parity: NONE -# debug: -# direction: BOTH -# dummy_receiver: false -# after: -# delimiter: "\n" -# sequence: -# - lambda: UARTDebug::log_string(direction, bytes); -globals: - - id: LD1125H_Last_Time - type: time_t - restore_value: no - initial_value: time(NULL) - - id: LD1125H_Last_Mov_Time - type: time_t - restore_value: no - initial_value: time(NULL) - - id: LD1125H_Clearence_Status - type: bool - restore_value: no - initial_value: "false" -status_led: - pin: - number: GPIO2 #ESP32 OnBroad LED - inverted: false -#web_server: #Avoid Using Web Server To Prevent Hang -# port: 80 -interval: - - interval: 1s #Clearance Scan Time - setup_priority: -200 - then: - lambda: |- - if ((time(NULL)-id(LD1125H_Last_Time))>id(LD1125H_Clear_Time).state) { - if ((id(LD1125H_Clearence_Status) == false) || (id(LD1125H_Occupancy).state != "Clearance")) { - id(LD1125H_Occupancy).publish_state("Clearance"); - id(LD1125H_Clearence_Status) = true; - } - if (id(LD1125H_MovOcc_Binary).state == true) { - id(LD1125H_MovOcc_Binary).publish_state(false); - } - if (id(LD1125H_Mov_Binary).state == true) { - id(LD1125H_Mov_Binary).publish_state(false); - } - } -number: - - platform: template - name: ${upper_devicename} LD1125H mth1 mov #mth1 mov is 0~2.8m motion detection threshold. - id: LD1125H_mth1_mov - icon: "mdi:cogs" - optimistic: true - restore_value: true #If you don't want to store the setting at ESP, set it to false. - initial_value: "30.0" #Default mth1_mov Setting - min_value: 10.0 - max_value: 600.0 - step: 5.0 - set_action: - then: - - uart.write: - id: LD1125H_UART_BUS - data: !lambda |- - std::string th1st = "mth1_mov=" + str_sprintf("%.0f",x) +"\r\n"; - return std::vector(th1st.begin(), th1st.end()); - - platform: template - name: ${upper_devicename} LD1125H mth2 mov #mth2 mov is 2.8~8m motion detection threshold. - id: LD1125H_mth2_mov - icon: "mdi:cogs" - optimistic: true - restore_value: true #If you don't want to store the setting at ESP, set it to false. - initial_value: "15" #Default mth2_mov Setting - min_value: 5 - max_value: 300 - step: 5 - set_action: - then: - - uart.write: - id: LD1125H_UART_BUS - data: !lambda |- - std::string th2st = "mth2_mov=" + str_sprintf("%.0f",x) +"\r\n"; - return std::vector(th2st.begin(), th2st.end()); - - platform: template - name: ${upper_devicename} LD1125H mth3 mov #mth3 mov is above 8m motion detection threshold. - id: LD1125H_mth3_mov - icon: "mdi:cogs" - optimistic: true - restore_value: true #If you don't want to store the setting at ESP, set it to false. - initial_value: "6" #Default mth3_mov Setting - min_value: 5 - max_value: 200 - step: 5 - set_action: - then: - - uart.write: - id: LD1125H_UART_BUS - data: !lambda |- - std::string th3st = "mth3_mov=" + str_sprintf("%.0f",x) +"\r\n"; - return std::vector(th3st.begin(), th3st.end()); - - platform: template - name: ${upper_devicename} LD1125H mth1 occ #mth1 occ is 0~2.8m detection threshold. - id: LD1125H_mth1_occ - icon: "mdi:cogs" - optimistic: true - restore_value: true #If you don't want to store the setting at ESP, set it to false. - initial_value: "30.0" #Default mth1_mov Setting - min_value: 10.0 - max_value: 600.0 - step: 5.0 - set_action: - then: - - uart.write: - id: LD1125H_UART_BUS - data: !lambda |- - std::string th1st = "mth1_occ=" + str_sprintf("%.0f",x) +"\r\n"; - return std::vector(th1st.begin(), th1st.end()); - - platform: template - name: ${upper_devicename} LD1125H mth2 occ #mth2 occ is 2.8~8m detection threshold. - id: LD1125H_mth2_occ - icon: "mdi:cogs" - optimistic: true - restore_value: true #If you don't want to store the setting at ESP, set it to false. - initial_value: "15" #Default mth2_mov Setting - min_value: 5 - max_value: 300 - step: 5 - set_action: - then: - - uart.write: - id: LD1125H_UART_BUS - data: !lambda |- - std::string th2st = "mth2_occ=" + str_sprintf("%.0f",x) +"\r\n"; - return std::vector(th2st.begin(), th2st.end()); - - platform: template - name: ${upper_devicename} LD1125H mth3 occ #mth3 occ is above 8m detection threshold. - id: LD1125H_mth3_occ - icon: "mdi:cogs" - optimistic: true - restore_value: true #If you don't want to store the setting at ESP, set it to false. - initial_value: "6" #Default mth3_mov Setting - min_value: 5 - max_value: 200 - step: 5 - set_action: - then: - - uart.write: - id: LD1125H_UART_BUS - data: !lambda |- - std::string th3st = "mth3_occ=" + str_sprintf("%.0f",x) +"\r\n"; - return std::vector(th3st.begin(), th3st.end()); - - platform: template - name: ${upper_devicename} LD1125H rmax #rmax is max detection distance. - id: LD1125H_rmax - icon: "mdi:cogs" - optimistic: true - restore_value: true #If you don't want to store the setting at ESP, set it to false. - initial_value: "8" #Default rmax Setting - min_value: 0.4 - max_value: 12 - step: 0.2 - set_action: - then: - - uart.write: - id: LD1125H_UART_BUS - data: !lambda |- - std::string rmaxst = "rmax=" + str_sprintf("%.1f",x) +"\r\n"; - return std::vector(rmaxst.begin(), rmaxst.end()); - - platform: template - name: ${upper_devicename} LD1125H Clearence Time - id: LD1125H_Clear_Time - icon: "mdi:cogs" - optimistic: true - restore_value: true #If you don't want to store the setting at ESP, set it to false. - initial_value: "5" #LD1125H Mov/Occ > Clearence Time Here - min_value: 0.5 - max_value: 60 - step: 0.5 - - platform: template - name: ${upper_devicename} LD1125H Movement Time - id: LD1125H_Mov_Time - icon: "mdi:cogs" - optimistic: true - restore_value: true #If you don't want to store the setting at ESP, set it to false. - initial_value: "1" #LD1125H Mov > Occ Time Here - min_value: 0.5 - max_value: 10 - step: 0.5 -sensor: - - platform: template - name: ${upper_devicename} LD1125H Distance - id: LD1125H_Distance - icon: "mdi:signal-distance-variant" - unit_of_measurement: "m" - accuracy_decimals: 2 - filters: # Use Fliter To Debounce - - sliding_window_moving_average: - window_size: 8 - send_every: 2 - - heartbeat: 0.2s -text_sensor: - - platform: serial - uart_id: LD1125H_UART_BUS - name: ${upper_devicename} LD1125H UART Text - id: LD1125H_UART_Text - icon: "mdi:format-text" - internal: False #If Don't Want to See UART Receive Data, Set To True - on_value: - lambda: |- - if (id(LD1125H_UART_Text).state.substr(0,3) == "occ") { - id(LD1125H_Distance).publish_state(atof(id(LD1125H_UART_Text).state.substr(9).c_str())); - if ((time(NULL)-id(LD1125H_Last_Mov_Time))>id(LD1125H_Mov_Time).state) { - id(LD1125H_Occupancy).publish_state("Occupancy"); - if (id(LD1125H_MovOcc_Binary).state == false) { - id(LD1125H_MovOcc_Binary).publish_state(true); - } - if (id(LD1125H_Mov_Binary).state == true) { - id(LD1125H_Mov_Binary).publish_state(false); - } - } - if (id(LD1125H_MovOcc_Binary).state == false) { - id(LD1125H_MovOcc_Binary).publish_state(true); - } - id(LD1125H_Last_Time) = time(NULL); - if (id(LD1125H_Clearence_Status) == true) { - id(LD1125H_Clearence_Status) = false; - } - } - else if (id(LD1125H_UART_Text).state.substr(0,3) == "mov") { - id(LD1125H_Distance).publish_state(atof(id(LD1125H_UART_Text).state.substr(9).c_str())); - id(LD1125H_Occupancy).publish_state("Movement"); - if (id(LD1125H_MovOcc_Binary).state == false) { - id(LD1125H_MovOcc_Binary).publish_state(true); - } - if (id(LD1125H_Mov_Binary).state == false) { - id(LD1125H_Mov_Binary).publish_state(true); - } - id(LD1125H_Last_Mov_Time) = time(NULL); - id(LD1125H_Last_Time) = time(NULL); - if (id(LD1125H_Clearence_Status) == true) { - id(LD1125H_Clearence_Status) = false; - } - } - - platform: template - name: ${upper_devicename} LD1125H Occupancy Status - id: LD1125H_Occupancy - icon: "mdi:motion-sensor" -binary_sensor: - - platform: template - name: ${upper_devicename} LD1125H Occupancy or Movement - id: LD1125H_MovOcc_Binary - device_class: occupancy - - platform: template - name: ${upper_devicename} LD1125H Movement - id: LD1125H_Mov_Binary - device_class: motion - \ No newline at end of file diff --git a/trash/mmwave-georgias-room.yaml b/trash/mmwave-georgias-room.yaml deleted file mode 100644 index 20df10c..0000000 --- a/trash/mmwave-georgias-room.yaml +++ /dev/null @@ -1,32 +0,0 @@ -esphome: - name: mmwave-georgias-room - friendly_name: mmwave-georgias-room - -esp32: - board: esp32dev - framework: - type: arduino - -# Enable logging -logger: - -# Enable Home Assistant API -api: - encryption: - key: "vV0VUgxpbVcQrDGzuFY11LcGK5VJqe74NJpIZ3h8JXk=" - -ota: - - platform: esphome - password: "d97940b1e0e73dec0830379228389185" - -wifi: - ssid: !secret wifi_ssid - password: !secret wifi_password - - # Enable fallback hotspot (captive portal) in case wifi connection fails - ap: - ssid: "Mmwave-Georgias-Room" - password: "vzn4DYKUeR6m" - -captive_portal: - \ No newline at end of file