diff --git a/Dashboard/Dashboard.ino b/Dashboard/Dashboard.ino index e2b245bb383ce8be8b0f68c654392b1cf89a7d56..9fe3b501a1678db3091b689ea53e2106f53baa42 100644 --- a/Dashboard/Dashboard.ino +++ b/Dashboard/Dashboard.ino @@ -27,8 +27,11 @@ #include <MHZ19_uart.h> /********************************/ -#include "font.h" +/************Marcos**************/ +#define timer(tim, del) if(millis() - (tim) > (del)) +/********************************/ +#define LANG_RU_RU #define LEDsPin 2 #define CO2RX A0 #define CO2TX A1 @@ -38,7 +41,8 @@ #define WIDTH 16 #define HEIGHT 9 #define numLeds (WIDTH * HEIGHT) -#define COLOR mHEX(0x9aa100) +#define COLOR1 mHEX(0x9aa100) +#define COLOR2 mHEX(0x000aa0) microLED<numLeds, LEDsPin, MLED_NO_CLOCK, LED_WS2812, ORDER_GRB, CLI_AVER/*, SAVE_MILLIS*/> matrix(WIDTH, HEIGHT, ZIGZAG, RIGHT_TOP, DIR_LEFT); #include "textbox.h" @@ -58,29 +62,47 @@ void setup() co2.begin(CO2TX, CO2RX); co2.setAutoCalibration(false); delay(500); - tb.setup("Mama", TB_STATIC, 0, 0, 16); - tb.render(); + tb.setup("Ghbdtn vbh!", 0xFFFF, COLOR1, TB_BOUNCE, 1, 1, 14, 500, 2000); } void loop() { - for (uint8_t i = 0; i < 9; i++) + // Terminate if buttuns are holded + static uint64_t timer_debug0 = 0; + static bool button = 0; + static bool last_button = 0; + last_button = button; + button = digitalRead(LBTN) | digitalRead(RBTN); + if(!button) + timer_debug0 = millis(); + timer(timer_debug0, 5000) { - matrix.set(matrix.getPixNumber(15, i), mHEX(0)); + timer_debug0 = millis(); + Serial.end(); } - uint16_t CO2 = co2.getPPM(); - Serial.print(CO2); - Serial.print(" "); - Serial.print(digitalRead(LBTN)); - Serial.print(" "); - Serial.println(digitalRead(RBTN)); - - CO2 = map(CO2, 300, 1500, 0, 9); - for (uint8_t i = 0; i < CO2; i++) + + static uint64_t timer0 = 0; + timer(timer0, 3000) { - matrix.set(15, i, mHEX(0x0aa100)); + timer0 = millis(); + uint16_t CO2 = co2.getPPM(); + Serial.print(CO2); + Serial.print(" "); + Serial.print(digitalRead(LBTN)); + Serial.print(" "); + Serial.println(digitalRead(RBTN)); + + CO2 = map(CO2, 300, 1500, 0, 9); + for (uint8_t i = 0; i < 9; i++) + { + matrix.set(matrix.getPixNumber(15, i), mHEX(0)); + } + for (uint8_t i = 0; i < CO2; i++) + { + matrix.set(15, i, mHEX(0x0aa100)); + } } - //matrix.fill(mHEX(0x9aa100)); + + tb.render(); matrix.show(); - delay(3000); } diff --git a/Dashboard/font.h b/Dashboard/font.h index b8d70a63c589753e44cf6b8799f00b65da30a54f..da2cf0c2162022c20c3aef7831b28c9c2c052534 100644 --- a/Dashboard/font.h +++ b/Dashboard/font.h @@ -255,7 +255,6 @@ const uint8_t* const font[] /*PROGMEM*/ = { font_notdef, // NONE NONE // Russian QWERTY-ЙЦУКЕР#ifdef LANG_RU_RU - font_notdef, // NONE NONE 1 font_space, // 32 1 font_exclamation, //! 33 1 font_ru_ru_Ae, // Р34 1 @@ -292,7 +291,7 @@ const uint8_t* const font[] /*PROGMEM*/ = { font_notdef, // NONE NONE font_ru_ru_F, // Ф 65 1 font_ru_ru_I, // И 66 1 font_C, // С 67 1 - font_ru_ru_V, // В 68 1 + font_B, // В 68 1 font_ru_ru_U, // У 69 1 font_A, // Р70 1 font_ru_ru_P, // П 71 1 diff --git a/Dashboard/textbox.h b/Dashboard/textbox.h index 10438c9e46cb4074c674ffe958c16e57ee1844eb..661964f7d3b6486d1fe2543bd2612e3f917e8785 100644 --- a/Dashboard/textbox.h +++ b/Dashboard/textbox.h @@ -1,136 +1,234 @@ -#pragma once - -#define TB_DISABLED 0 -#define TB_STATIC 1 -#define TB_REPEAT 2 -#define TB_LOOP 3 -#define TB_LOOP_WITH_DELAY 4 -#define TB_BOUNCE 5 - -class textbox -{ -private: - /* data */ - uint8_t x; - uint8_t y; - uint8_t w; - uint8_t mode; - uint8_t speed; - uint16_t delay; - uint16_t offset; - char text[64]; - uint8_t letter[8]; - uint64_t lang; - void getLetter(char c); -public: - textbox(void); - void setup(char _text[], uint8_t _mode, uint8_t _x, uint8_t _y, uint8_t _w, uint8_t _speed = 0, uint16_t _delay = 0); - void render(void); - void disable(void); -}; - -textbox::textbox(void) -{ - x = 0; - y = 0; - w = 0; - mode = 0; - speed = 0; - delay = 0; - memset(text, NULL, 64 * sizeof(char)); - lang = 0; -} - -void textbox::setup(char _text[], uint8_t _mode, uint8_t _x, uint8_t _y, uint8_t _w, uint8_t _speed = 0, uint16_t _delay = 0) -{ - memset(text, NULL, 64 * sizeof(char)); - strcpy(text, _text); - mode = _mode; - x = _x; - 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 = _speed; - break; - case TB_DISABLED: - case TB_STATIC: - default: - speed = 0; - delay = 0; - break; - } - render(); -} - -void textbox::render(void) -{ - if(mode == TB_DISABLED) return; - uint8_t index = 0; - uint8_t position = 0; - while(position < 16 && index < strlen(text)) - { - getLetter(text[index]); - uint8_t y = letter[1]; - uint8_t x = 0; - uint8_t maxX = letter[0]; - for(uint8_t i = 0; i < letter[2]; i++) - { - for(int8_t j = 7; j >= 0; j--) - { - //char sprf[25]; - uint8_t state = bitRead(letter[i + 3], j); - //sprintf(sprf, "%d %d %d %d %d %d %d\n", index, letter[0], letter[1], letter[2], i, j, state); - //Serial.print(sprf); - if(state) matrix.set(x + position, 8 - y, mHSVfast((i + j + 1) * 10, 255, 255)); - // matrix.show(); - // volatile int val = 666; - // for(volatile int v = 0; v < 5000; v++) - // { - // val = sin(val); - // } - x++; - if(x >= maxX) - { - x = 0; y++; - } - if(y > 6) goto BREAKFORS; - } - } - BREAKFORS: - position += maxX + 1; - index++; - } - -} - -void textbox::disable(void) -{ - setup("", TB_DISABLED, 0, 0, 0); -} - -void textbox::getLetter(char c) -{ - memset(letter, 0, 8 * sizeof(uint8_t)); - uint8_t index; - uint8_t ctoi = (uint8_t)c; - if(ctoi >= 32 && ctoi <= 126) index = ctoi - 31; - else index = 0; - 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 - for(uint8_t i = 0; i < letter[2]; i++) - { - letter[i + 3] = pgm_read_byte(font[index] + (i + 1) * sizeof(uint8_t)); - } +#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