From 2b70547227e5442b77c9ea269e160438316e2b5b Mon Sep 17 00:00:00 2001 From: egorguslyan <egorguslyan@gmail.com> Date: Wed, 8 Dec 2021 20:58:13 +0300 Subject: [PATCH] Text now works (eng + rus) --- Dashboard/Dashboard.ino | 6 +- Dashboard/font.h | 7 +- Dashboard/textbox.h | 443 +++++++++++++++++++--------------------- 3 files changed, 217 insertions(+), 239 deletions(-) diff --git a/Dashboard/Dashboard.ino b/Dashboard/Dashboard.ino index 9fe3b50..303914c 100644 --- a/Dashboard/Dashboard.ino +++ b/Dashboard/Dashboard.ino @@ -62,7 +62,7 @@ void setup() co2.begin(CO2TX, CO2RX); co2.setAutoCalibration(false); delay(500); - tb.setup("Ghbdtn vbh!", 0xFFFF, COLOR1, TB_BOUNCE, 1, 1, 14, 500, 2000); + tb.setup("Ghbdtn vbh!", 0xFFFF, COLOR1, TB_LOOP_WITH_DELAY, 1, 1, 14, 100, 2000); } void loop() @@ -103,6 +103,8 @@ void loop() } } - tb.render(); + static uint64_t timer1 = 0; + timer(timer1, 99) + if(tb.render()) timer1 = millis(); matrix.show(); } diff --git a/Dashboard/font.h b/Dashboard/font.h index da2cf0c..fbfb5c9 100644 --- a/Dashboard/font.h +++ b/Dashboard/font.h @@ -8,7 +8,7 @@ const uint8_t font_null[] PROGMEM = {0}; const uint8_t font_notdef[] PROGMEM = {cords(5, 0, 5), 0b11111110, 0b11110111, 0b01011101, 0b11101111, 0b11100000}; const uint8_t font_space[] PROGMEM = {cords(1, 6, 1), 0b00000000}; -const uint8_t font_exclamation[] PROGMEM = {cords(1, 0, 1), 0b11110100}; +const uint8_t font_exclamation[] PROGMEM = {cords(1, 1, 1), 0b11110100}; const uint8_t font_quote[] PROGMEM = {cords(3, 0, 1), 0b10110100}; const uint8_t font_hashtag[] PROGMEM = {cords(5, 2, 3), 0b01010111, 0b11010101, 0b11110101}; const uint8_t font_promt[] PROGMEM = {cords(5, 0, 5), 0b00100011, 0b10101000, 0b11100010, 0b10111000, 0b10000000}; @@ -129,7 +129,7 @@ const uint8_t font_ru_ru_Ae[] PROGMEM = {cords(4, 0, 4), 0b11100001, 0b00 const uint8_t font_ru_ru_Yu[] PROGMEM = {cords(5, 0, 5), 0b10010101, 0b01101011, 0b11011010, 0b11010110, 0b01000000}; const uint8_t font_ru_ru_Ya[] PROGMEM = {cords(4, 0, 4), 0b01111001, 0b10010111, 0b00110101, 0b10010000}; const uint8_t font_ru_ru_b[] PROGMEM = {cords(3, 0, 3), 0b01110001, 0b00111011, 0b01010000}; -const uint8_t font_ru_ru_v[] PROGMEM = {cords(3, 0, 3), 0b01010111, 0b01011010, 0b10000000}; +const uint8_t font_ru_ru_v[] PROGMEM = {cords(3, 1, 3), 0b01010111, 0b01011010, 0b10000000}; const uint8_t font_ru_ru_g[] PROGMEM = {cords(3, 2, 2), 0b11110010, 0b01001000}; const uint8_t font_ru_ru_d[] PROGMEM = {cords(5, 2, 4), 0b00110010, 0b10010101, 0b11111000, 0b10000000}; const uint8_t font_ru_ru_ye[] PROGMEM = {cords(4, 0, 4), 0b10010000, 0b01101001, 0b11101000, 0b01100000}; @@ -139,6 +139,7 @@ const uint8_t font_ru_ru_i[] PROGMEM = {cords(5, 2, 4), 0b10001100, 0b11 const uint8_t font_ru_ru_yi[] PROGMEM = {cords(5, 0, 5), 0b01110000, 0b00100011, 0b00111010, 0b11100110, 0b00100000}; const uint8_t font_ru_ru_k[] PROGMEM = {cords(4, 2, 3), 0b10011010, 0b11001010, 0b10010000}; const uint8_t font_ru_ru_l[] PROGMEM = {cords(4, 2, 3), 0b00110101, 0b01010101, 0b10010000}; +const uint8_t font_ru_ru_m[] PROGMEM = {cords(5, 2, 4), 0b01010101, 0b01101011, 0b01011010, 0b10000000}; const uint8_t font_ru_ru_n[] PROGMEM = {cords(4, 2, 3), 0b10011001, 0b11111001, 0b10010000}; const uint8_t font_ru_ru_p[] PROGMEM = {cords(4, 0, 3), 0b11111001, 0b10011001, 0b10010000}; const uint8_t font_ru_ru_t[] PROGMEM = {cords(3, 2, 2), 0b11101001, 0b00100100}; @@ -341,7 +342,7 @@ const uint8_t* const font[] /*PROGMEM*/ = { font_notdef, // NONE NONE font_ru_ru_y, // ы 115 1 font_e, // е 116 1 font_ru_ru_g, // г 117 1 - font_m, // м 118 1 + font_ru_ru_m, // м 118 1 font_ru_ru_c, // ц 119 1 font_ru_ru_ch, // ч 120 1 font_ru_ru_n, // н 121 1 diff --git a/Dashboard/textbox.h b/Dashboard/textbox.h index 661964f..b817e16 100644 --- a/Dashboard/textbox.h +++ b/Dashboard/textbox.h @@ -1,234 +1,209 @@ -#pragma once - -#include "font.h" - -enum TB_MODES -{ - TB_DISABLED, - TB_STATIC, - TB_REPEAT, - TB_LOOP, - TB_LOOP_WITH_DELAY, - TB_BOUNCE, -}; - -class textbox -{ -private: - /* data */ - uint8_t cord_x; - uint8_t cord_y; - uint8_t w; - uint8_t mode; - uint16_t speed; - uint16_t delay; - int16_t offset; - bool direction; - bool state; - mData color; - char text[64]; - uint8_t textlen; - uint16_t textwidth; - uint8_t letter[8]; - uint64_t langMask; - bool native; - void getLetter(uint8_t i, bool skipBitmap = 0); - uint64_t timer0; -public: - textbox(void); - void setup( char _text[], uint64_t _langMask, - mData _color, - uint8_t _mode, - uint8_t _x, uint8_t _y, uint8_t _w, - uint8_t _reciprocal_speed = 0, uint16_t _delay = 0); - void render(void); - void disable(void); -}; - -textbox::textbox(void) -{ - cord_x = 0; - cord_y = 0; - w = 0; - mode = 0; - speed = 0; - delay = 0; - memset(text, NULL, 64 * sizeof(char)); - langMask = 0; - // If 96th symbol is font_null there is no native language except for English - native = pgm_read_byte(font[96]) != 0; - uint8_t debugByte = pgm_read_byte(font[0]); - Serial.println(debugByte); - uint8_t debugCounter = 1; - while(debugByte != 0) - { - Serial.println(debugByte); - debugByte = pgm_read_byte(font[debugCounter]); - debugCounter++; - } -} - -void textbox::setup(char _text[], uint64_t _langMask, - mData _color, - uint8_t _mode, - uint8_t _x, uint8_t _y, uint8_t _w, - uint8_t _reciprocal_speed = 0, uint16_t _delay = 0) -{ - memset(text, NULL, 64 * sizeof(char)); - strcpy(text, _text); - textlen = strlen(text); - langMask = _langMask; - textwidth = 0; - for(uint16_t i = 0; i < textlen; i++) - { - getLetter(i, true); - textwidth += letter[0] + 1; - } - textwidth--; - color = _color; - mode = _mode; - cord_x = _x; - cord_y = _y; - w = _w; - offset = 0; - switch(mode) - { - case TB_LOOP: - delay = 0; - goto NO_DELAY; - case TB_REPEAT: - case TB_LOOP_WITH_DELAY: - case TB_BOUNCE: - delay = _delay; - NO_DELAY: - speed = _reciprocal_speed; - break; - case TB_DISABLED: - case TB_STATIC: - default: - speed = 0; - delay = 0; - break; - } - timer0 = 0; - render(); -} - -void textbox::render(void) -{ - // Do nothing if disabled - if(mode != TB_DISABLED) - { - if(timer0 == 0) - { - offset = 0 + (mode == TB_REPEAT) * w; - direction = 0; - timer0 = millis(); - } - else - { - if((millis() - timer0) > (((mode != TB_LOOP) && !state) ? delay : speed)) - { - state = 1; - timer0 = millis(); - if(mode == TB_BOUNCE) - { - if((!direction && offset == -textwidth + w) || (direction && offset == 0)) - { - direction = !direction; - state = 0; - } - else offset += direction ? 1 : -1; - } - else - { - offset += -1; - if(offset < (-textwidth - 2 * (mode == TB_LOOP || mode == TB_LOOP_WITH_DELAY) + w * (mode == TB_REPEAT))) - { - offset = 0 + (mode == TB_REPEAT) * w; - state = 0; - } - } - - } - else return; - } - } - else return; - // Clear spot - for(uint8_t i = cord_x; (i < cord_x + w) && (i < WIDTH); i++) - for(uint8_t j = cord_y; (j < cord_y + 7) && (j < HEIGHT); j++) - matrix.set(i, j, mBlack); - // Init letter counter, start X and Y - uint8_t index = 0; - int16_t positionX = cord_x + offset; - int16_t positionY = cord_y; - // Draw while in bounds - while((positionX < cord_x + w) && (index < textlen)) - { - // Recieve letter - getLetter(index); - // Relative X and Y - uint8_t x = 0; - uint8_t y = letter[1]; - // X bound - uint8_t maxX = letter[0]; - // Run thougth bytes - for(uint8_t i = 0; (i < letter[2]) && (y < 7); i++) - { - // Run througth bits - for(int8_t j = 7; (j >= 0) && (y < 7); j--) - { - // Set pixel - bool state = bitRead(letter[i + 3], j); - int16_t mx = x + positionX; - int16_t my = HEIGHT - 1 - y - positionY; - if(state && mx >= cord_x && mx < cord_x + w && my >= cord_y && my < cord_y + 7) - matrix.set(mx, my, color); - // Next pixel - x++; - if(x >= maxX) - { - x = 0; y++; - } - } - } - // Shift X and index - positionX += maxX + 1; - index++; - } - -} - -void textbox::disable(void) -{ - setup("", 0, 0, TB_DISABLED, 0, 0, 0); -} - -void textbox::getLetter(uint8_t i, bool skipBitmap = 0) -{ - // Letter and it's position in ASCII table - char c = text[i]; - uint8_t ctoi = (uint8_t)c; - // Language (0 - English, 1 - Native) - bool lang = bitRead(langMask, i); - // Clear place for letter in RAM - memset(letter, 0, 8 * sizeof(uint8_t)); - uint8_t index; - // Translate ASCII index to local - if(ctoi >= 32 && ctoi <= 126) index = ctoi - 31 + 95 * lang * native; - else index = 0; - // Read properties from semeric number - uint8_t readed = pgm_read_byte(font[index]); - letter[0] = readed / 49 + 1; // width - letter[1] = readed % 7; // offset - letter[2] = readed / 7 % 7; // bytes - // Read bitmaps - if(!skipBitmap) - { - for(uint8_t i = 0; i < letter[2]; i++) - { - letter[i + 3] = pgm_read_byte(font[index] + (i + 1) * sizeof(uint8_t)); - } - } -} \ No newline at end of file +#pragma once + +#include "font.h" + +enum TB_MODES { + TB_DISABLED, + TB_STATIC, + TB_REPEAT, + TB_LOOP, + TB_LOOP_WITH_DELAY, + TB_BOUNCE, +}; + +class textbox { +private: + /* data */ + uint8_t cord_x; + uint8_t cord_y; + uint8_t w; + uint8_t mode; + uint16_t speed; + uint16_t delay; + int16_t offset; + bool direction; + bool state; + mData color; + char text[64]; + uint8_t textlen; + uint16_t textwidth; + uint8_t letter[8]; + uint64_t langMask; + bool native; + void getLetter(uint8_t i, bool skipBitmap = 0); + uint64_t timer0; + +public: + textbox(void); + void setup(char _text[], uint64_t _langMask, + mData _color, + uint8_t _mode, + uint8_t _x, uint8_t _y, uint8_t _w, + uint8_t _reciprocal_speed = 0, uint16_t _delay = 0); + uint8_t render(void); + void disable(void); +}; + +textbox::textbox(void) +{ + cord_x = 0; + cord_y = 0; + w = 0; + mode = 0; + speed = 0; + delay = 0; + memset(text, NULL, 64 * sizeof(char)); + langMask = 0; + // If 96th symbol is font_null there is no native language except for English + native = pgm_read_byte(font[96]) != 0; +} + +void textbox::setup(char _text[], uint64_t _langMask, + mData _color, + uint8_t _mode, + uint8_t _x, uint8_t _y, uint8_t _w, + uint8_t _reciprocal_speed = 0, uint16_t _delay = 0) +{ + memset(text, NULL, 64 * sizeof(char)); + strcpy(text, _text); + textlen = strlen(text); + langMask = _langMask; + textwidth = 0; + for (uint16_t i = 0; i < textlen; i++) { + getLetter(i, true); + textwidth += letter[0] + 1; + } + textwidth--; + color = _color; + mode = _mode; + cord_x = _x; + cord_y = _y; + w = _w; + offset = 0; + switch (mode) { + case TB_LOOP: + delay = 0; + goto NO_DELAY; + case TB_REPEAT: + case TB_LOOP_WITH_DELAY: + case TB_BOUNCE: + delay = _delay; + NO_DELAY: + speed = _reciprocal_speed; + break; + case TB_DISABLED: + case TB_STATIC: + default: + speed = 0; + delay = 0; + break; + } + timer0 = 0; + render(); +} + +uint8_t textbox::render(void) +{ + // Do nothing if disabled + if (mode != TB_DISABLED) { + if (timer0 == 0) { + offset = 0 + (mode == TB_REPEAT) * w + 1 * (mode == TB_LOOP); + direction = 0; + timer0 = millis(); + } else { + if ((millis() - timer0) > (((mode != TB_LOOP) && !state) ? delay : speed)) { + state = 1; + timer0 = millis(); + if (mode == TB_BOUNCE) { + if ((!direction && offset == -textwidth + w) || (direction && offset == 0)) { + direction = !direction; + state = 0; + } else + offset += direction ? 1 : -1; + } else { + offset += -1; + if (offset < ((int16_t)-textwidth - 2 * (mode == TB_LOOP || mode == TB_LOOP_WITH_DELAY) - w * (mode == TB_REPEAT))) { + offset = 0 + (mode == TB_REPEAT) * w; + state = 0; + } + } + + } else + if(state != 0) return 0; + } + } else + return 0; + // Clear spot + for (uint8_t i = cord_x; (i < cord_x + w) && (i < WIDTH); i++) + for (uint8_t j = cord_y; (j < cord_y + 7) && (j < HEIGHT); j++) + matrix.set(i, j, mBlack); + // Init letter counter, start X and Y + uint8_t index = 0; + int16_t positionX = cord_x + offset; + int16_t positionY = cord_y; + // Draw while in bounds + while ((positionX < cord_x + w) && (index < textlen)) { + // Recieve letter + getLetter(index); + // Relative X and Y + uint8_t x = 0; + uint8_t y = letter[1]; + // X bound + uint8_t maxX = letter[0]; + // Run thougth bytes + for (uint8_t i = 0; (i < letter[2]) && (y < 7); i++) { + // Run througth bits + for (int8_t j = 7; (j >= 0) && (y < 7); j--) { + // Set pixel + bool state = bitRead(letter[i + 3], j); + int16_t mx = x + positionX; + int16_t my = HEIGHT - 1 - y - positionY; + if (state && mx >= cord_x && mx < cord_x + w && my >= cord_y && my < cord_y + 7) + matrix.set(mx, my, color); + // Next pixel + x++; + if (x >= maxX) { + x = 0; + y++; + } + } + } + // Shift X and index + positionX += maxX + 1; + index++; + } + return 1; +} + +void textbox::disable(void) +{ + setup("", 0, 0, TB_DISABLED, 0, 0, 0); +} + +void textbox::getLetter(uint8_t i, bool skipBitmap = 0) +{ + // Letter and it's position in ASCII table + char c = text[i]; + uint8_t ctoi = (uint8_t)c; + // Language (0 - English, 1 - Native) + bool lang = bitRead(langMask, i); + // Clear place for letter in RAM + memset(letter, 0, 8 * sizeof(uint8_t)); + uint8_t index; + // Translate ASCII index to local + if (ctoi >= 32 && ctoi <= 126) + index = ctoi - 31 + 95 * lang * native; + else + index = 0; + // Read properties from semeric number + uint8_t readed = pgm_read_byte(font[index]); + letter[0] = readed / 49 + 1; // width + letter[1] = readed % 7; // offset + letter[2] = readed / 7 % 7; // bytes + // Read bitmaps + if (!skipBitmap) { + for (uint8_t i = 0; i < letter[2]; i++) { + letter[i + 3] = pgm_read_byte(font[index] + (i + 1) * sizeof(uint8_t)); + } + } +} -- GitLab