diff --git a/esphome/owon_b35t.h b/esphome/owon_b35t.h index a96c67d..626838b 100644 --- a/esphome/owon_b35t.h +++ b/esphome/owon_b35t.h @@ -23,6 +23,44 @@ using esphome::display::Display; static const char *const TAG = "owon_b35t"; +static const uint8_t DIODE_BMP[32] = { + 0b00001000, 0b00011000, + 0b00001100, 0b00011000, + 0b00001110, 0b00011000, + 0b00001111, 0b00011000, + 0b00001111, 0b10011000, + 0b00001111, 0b11011000, + 0b00001111, 0b11111000, + 0b11111111, 0b11111111, + 0b11111111, 0b11111111, + 0b00001111, 0b11111000, + 0b00001111, 0b11011000, + 0b00001111, 0b10011000, + 0b00001111, 0b00011000, + 0b00001110, 0b00011000, + 0b00001100, 0b00011000, + 0b00001000, 0b00011000, +}; + +static const uint8_t BUZZ_BMP[32] = { + 0b00000000, 0b11000000, + 0b00000001, 0b11000000, + 0b00000011, 0b11000001, + 0b00000111, 0b11000001, + 0b00001111, 0b11000101, + 0b11111111, 0b11000101, + 0b11111111, 0b11010101, + 0b11111111, 0b11010101, + 0b11111111, 0b11010101, + 0b11111111, 0b11010101, + 0b11111111, 0b11000101, + 0b00001111, 0b11000101, + 0b00000111, 0b11000001, + 0b00000011, 0b11000001, + 0b00000001, 0b11000000, + 0b00000000, 0b11000000, +}; + class Meter { public: static constexpr uint8_t REGPLUSMINUS = 0x00; @@ -204,7 +242,8 @@ class Meter { void render(Display &it, esphome::display::BaseFont *font) { const Color bg(0, 0, 0); const Color fg(210, 210, 210); - const Color inactive(45, 45, 45); + // Chosen to map to a neutral dark gray in the RGB332 8-bit display palette. + const Color inactive(80, 80, 80); const Color yellow(255, 220, 0); const Color blue(0, 80, 255); const Color cyan(0, 255, 255); @@ -246,10 +285,10 @@ class Meter { std::string unit_line = std::string(this->scale()) + this->unit(); it.print(270, 140, font, yellow, esphome::display::TextAlign::CENTER, unit_line.c_str()); - this->label_(it, font, 240, 168, "DIODE", this->diode() ? magenta : inactive); - this->label_(it, font, 240, 190, "BUZZ", this->continuity() ? orange : inactive); this->draw_bargraph_(it, this->has_reading && !this->overload ? this->digits_from_buffer_() : 0, this->has_reading && !this->overload); + this->draw_icon_(it, 300, 148, 16, 16, DIODE_BMP, this->diode() ? magenta : inactive); + this->draw_icon_(it, 300, 174, 16, 16, BUZZ_BMP, this->continuity() ? orange : inactive); it.filled_rectangle(34, 212, 40, 24, this->write_available ? fg : inactive); it.filled_rectangle(108, 212, 100, 24, this->write_available ? fg : inactive); @@ -391,21 +430,48 @@ class Meter { } void draw_digits_(Display &it, const char *text, bool negative, Color color) { - if (negative) it.filled_rectangle(8, 88, 24, 8, color); - int x = 42; + if (negative) this->draw_segment_(it, 8, 88, 26, 9, true, color); + constexpr int digit_x = 40; + constexpr int digit_y = 35; + constexpr int digit_w = 50; + constexpr int digit_h = 88; + constexpr int digit_distance = 64; for (int i = 0; i < 4; i++) { - this->draw_seven_segment_(it, x + i * 55, 38, 42, 82, text[i], color); + this->draw_seven_segment_(it, digit_x + i * digit_distance, digit_y, digit_w, digit_h, text[i], color); } } void draw_decimal_points_(Display &it, Color color) { uint8_t p = this->value_[REGPOINT]; - if ((p & FLAGPOINT1) == FLAGPOINT1) it.filled_rectangle(92, 116, 8, 10, color); - if ((p & FLAGPOINT2) == FLAGPOINT2) it.filled_rectangle(147, 116, 8, 10, color); - if ((p & FLAGPOINT3) == FLAGPOINT3) it.filled_rectangle(202, 116, 8, 10, color); + if ((p & FLAGPOINT1) == FLAGPOINT1) it.filled_rectangle(95, 117, 8, 10, color); + if ((p & FLAGPOINT2) == FLAGPOINT2) it.filled_rectangle(159, 117, 8, 10, color); + if ((p & FLAGPOINT3) == FLAGPOINT3) it.filled_rectangle(223, 117, 8, 10, color); } - void draw_segment_(Display &it, int x, int y, int w, int h, Color color) { it.filled_rectangle(x, y, w, h, color); } + void draw_segment_(Display &it, int x, int y, int w, int h, bool horizontal, Color color) { + if (horizontal) { + int cap = h / 2; + it.filled_rectangle(x + cap, y, w - 2 * cap, h, color); + it.filled_triangle(x, y + cap, x + cap, y, x + cap, y + h, color); + it.filled_triangle(x + w, y + cap, x + w - cap, y, x + w - cap, y + h, color); + } else { + int cap = w / 2; + it.filled_rectangle(x, y + cap, w, h - 2 * cap, color); + it.filled_triangle(x + cap, y, x, y + cap, x + w, y + cap, color); + it.filled_triangle(x + cap, y + h, x, y + h - cap, x + w, y + h - cap, color); + } + } + + void draw_icon_(Display &it, int x, int y, int w, int h, const uint8_t *data, Color color) { + for (int row = 0; row < h; row++) { + for (int col = 0; col < w; col++) { + uint8_t byte = data[row * ((w + 7) / 8) + (col / 8)]; + if ((byte & (0x80 >> (col % 8))) != 0) { + it.draw_pixel_at(x + col, y + row, color); + } + } + } + } void draw_seven_segment_(Display &it, int x, int y, int w, int h, char ch, Color color) { bool a=false,b=false,c=false,d=false,e=false,f=false,g=false; @@ -425,19 +491,20 @@ class Meter { case '-': g=true; break; default: break; } - int t = 8; - if (a) this->draw_segment_(it, x + t, y, w - 2*t, t, color); - if (b) this->draw_segment_(it, x + w - t, y + t, t, h/2 - t, color); - if (c) this->draw_segment_(it, x + w - t, y + h/2, t, h/2 - t, color); - if (d) this->draw_segment_(it, x + t, y + h - t, w - 2*t, t, color); - if (e) this->draw_segment_(it, x, y + h/2, t, h/2 - t, color); - if (f) this->draw_segment_(it, x, y + t, t, h/2 - t, color); - if (g) this->draw_segment_(it, x + t, y + h/2 - t/2, w - 2*t, t, color); + int t = 10; + int half = h / 2; + if (a) this->draw_segment_(it, x + t / 2, y, w - t, t, true, color); + if (b) this->draw_segment_(it, x + w - t, y + t / 2, t, half - t, false, color); + if (c) this->draw_segment_(it, x + w - t, y + half + t / 2, t, half - t, false, color); + if (d) this->draw_segment_(it, x + t / 2, y + h - t, w - t, t, true, color); + if (e) this->draw_segment_(it, x, y + half + t / 2, t, half - t, false, color); + if (f) this->draw_segment_(it, x, y + t / 2, t, half - t, false, color); + if (g) this->draw_segment_(it, x + t / 2, y + half - t / 2, w - t, t, true, color); } void draw_bargraph_(Display &it, uint16_t digits, bool active) { const Color fg(255, 255, 255); - const Color inactive(45, 45, 45); + const Color inactive(80, 80, 80); uint16_t mapped = active ? static_cast(digits * 240 / 6000) : 0; if (mapped > 240) mapped = 240; for (uint16_t i = 0; i <= 240; i += 4) {