From 0c760610dfd3f37633252b683cdf47a5df4e2f41 Mon Sep 17 00:00:00 2001 From: Sassa NF Date: Thu, 3 Oct 2024 07:28:51 +0100 Subject: [PATCH] Status Bar --- include/ui.h | 26 +++-- lib/charts/charts.h | 25 +++-- lib/scan/scan.h | 14 +++ src/main.cpp | 195 +++++++++++++-------------------- src/ui.cpp | 256 +++++++++++++------------------------------- 5 files changed, 198 insertions(+), 318 deletions(-) diff --git a/include/ui.h b/include/ui.h index 2f18a7b..ddf7a73 100644 --- a/include/ui.h +++ b/include/ui.h @@ -8,6 +8,9 @@ #include #endif +#include +#include + // #include // (optional) major and minor tick-marks at x MHz @@ -31,14 +34,21 @@ #define SCREEN_HEIGHT 64 // ???? not used -// publish functions -#ifdef Vision_Master_E290 -extern void UI_Init(DEPG0290BxS800FxX_BW *); -#else -extern void UI_Init(SSD1306Wire *); -#endif -extern void UI_displayDecorate(int, int, bool); -extern void UI_setLedFlag(bool); +extern void UI_Init(Display_t *); extern void UI_clearPlotter(void); extern void UI_clearTopStatus(void); extern void UI_drawCursor(int16_t); + +struct StatusBar : Chart +{ + Scan &r; + bool ui_initialized; + uint16_t scan_progress_count; + + StatusBar(Display_t &d, uint16_t x, uint16_t y, uint16_t w, Scan &r) + : Chart(d, x, y, w, LABEL_HEIGHT), r(r), ui_initialized(false), + scan_progress_count(0) {}; + + virtual void clearStatus(); + virtual void draw() override; +}; diff --git a/lib/charts/charts.h b/lib/charts/charts.h index 53b4f31..d6d11b4 100644 --- a/lib/charts/charts.h +++ b/lib/charts/charts.h @@ -1,7 +1,14 @@ #ifndef CHARTS_H #define CHARTS_H +#ifdef Vision_Master_E290 +#include "HT_DEPG0290BxS800FxX_BW.h" +typedef DEPG0290BxS800FxX_BW Display_t; +#else #include +typedef OLEDDisplay Display_t; +#endif + #include #include #include @@ -10,9 +17,9 @@ struct Chart { uint16_t pos_x, pos_y; uint16_t width, height; - OLEDDisplay &display; + Display_t &display; - Chart(OLEDDisplay &d, uint16_t x, uint16_t y, uint16_t w, uint16_t h) + Chart(Display_t &d, uint16_t x, uint16_t y, uint16_t w, uint16_t h) : display(d), pos_x(x), pos_y(y), width(w), height(h) {}; /* @@ -37,7 +44,7 @@ struct Chart */ struct ProgressChart : Chart { - ProgressChart(OLEDDisplay &d, uint16_t x, uint16_t y, uint16_t w, uint16_t h) + ProgressChart(Display_t &d, uint16_t x, uint16_t y, uint16_t w, uint16_t h) : Chart(d, x, y, w, h) {}; /* @@ -60,7 +67,7 @@ struct BarChart : ProgressChart bool *changed; bool redraw_all; - BarChart(OLEDDisplay &d, uint16_t x, uint16_t y, uint16_t w, uint16_t h, float min_x, + BarChart(Display_t &d, uint16_t x, uint16_t y, uint16_t w, uint16_t h, float min_x, float max_x, float min_y, float max_y, float level_y) : ProgressChart(d, x, y, w, h), min_x(min_x), max_x(max_x), min_y(min_y), max_y(max_y), level_y(level_y), redraw_all(true) @@ -81,7 +88,7 @@ struct BarChart : ProgressChart int y2pos(float y); }; -#define LABEL_HEIGHT 6 +#define LABEL_HEIGHT 7 #define X_AXIS_WEIGHT 1 #define MAJOR_TICK_LENGTH 2 #define MAJOR_TICKS 10 @@ -92,7 +99,7 @@ struct DecoratedBarChart : Chart { BarChart bar; - DecoratedBarChart(OLEDDisplay &d, uint16_t x, uint16_t y, uint16_t w, uint16_t h, + DecoratedBarChart(Display_t &d, uint16_t x, uint16_t y, uint16_t w, uint16_t h, float min_x, float max_x, float min_y, float max_y, float level_y) : Chart(d, x, y, w, h), bar(d, x, y + LABEL_HEIGHT, w, h - LABEL_HEIGHT - AXIS_HEIGHT, min_x, max_x, @@ -107,7 +114,7 @@ struct StackedChart : Chart Chart **charts; size_t charts_sz; - StackedChart(OLEDDisplay &d, uint16_t x, uint16_t y, uint16_t w, uint16_t h) + StackedChart(Display_t &d, uint16_t x, uint16_t y, uint16_t w, uint16_t h) : Chart(d, x, y, w, h), charts(NULL), charts_sz(0) {}; /* @@ -138,7 +145,7 @@ struct WaterfallChart : Chart WaterfallModel *model; - WaterfallChart(OLEDDisplay &d, uint16_t x, uint16_t y, uint16_t w, uint16_t h, + WaterfallChart(Display_t &d, uint16_t x, uint16_t y, uint16_t w, uint16_t h, float min_x, float max_x, float level_y, float threshold, WaterfallModel *m) : Chart(d, x, y, w, h), model(m), min_x(min_x), max_x(max_x), level_y(level_y), @@ -157,7 +164,7 @@ struct UptimeClock : Chart { uint64_t t0; uint64_t t1; - UptimeClock(OLEDDisplay &d, uint64_t t0) : Chart(d, 0, 0, 0, 0), t0(t0), t1(t0) {}; + UptimeClock(Display_t &d, uint64_t t0) : Chart(d, 0, 0, 0, 0), t0(t0), t1(t0) {}; void draw(uint64_t t); virtual void draw() override; diff --git a/lib/scan/scan.h b/lib/scan/scan.h index f5af2c6..b471e7e 100644 --- a/lib/scan/scan.h +++ b/lib/scan/scan.h @@ -33,6 +33,20 @@ constexpr float LO_RSSI_THRESHOLD = HI_RSSI_THRESHOLD - 66; struct Scan { + uint64_t epoch; + float current_frequency; + uint64_t fr_begin; + uint64_t fr_end; + uint64_t drone_detection_level; + bool sound_on; + bool led_flag; + uint64_t detection_count; + + Scan() + : epoch(0), current_frequency(0), fr_begin(0), fr_end(0), + drone_detection_level(0), sound_on(false), led_flag(false), + detection_count(0) {}; + virtual float getRSSI() = 0; // rssiMethod gets the data similar to the scan method, diff --git a/src/main.cpp b/src/main.cpp index b26b32d..1a6590a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -172,13 +172,11 @@ constexpr int WINDOW_SIZE = 15; #define SINGLE_STEP (float)(RANGE / (STEPS * SCAN_RBW_FACTOR)) uint64_t range = (int)(FREQ_END - FREQ_BEGIN); -uint64_t fr_begin = FREQ_BEGIN; -uint64_t fr_end = FREQ_BEGIN; uint64_t iterations = RANGE / RANGE_PER_PAGE; // uint64_t range_frequency = FREQ_END - FREQ_BEGIN; -uint64_t median_frequency = FREQ_BEGIN + FREQ_END - FREQ_BEGIN / 2; +uint64_t median_frequency = (FREQ_BEGIN + FREQ_END) / 2; // #define DISABLE_PLOT_CHART false // unused @@ -190,8 +188,7 @@ bool filtered_result[RADIOLIB_SX126X_SPECTRAL_SCAN_RES_SIZE]; int max_bins_array_value[MAX_POWER_LEVELS]; int max_step_range = 32; -// Waterfall array -bool waterfall[STEPS], detected_y[STEPS]; // 20 - ??? steps of the waterfall +bool detected_y[STEPS]; // 20 - ??? steps // global variable @@ -203,9 +200,7 @@ uint64_t drone_detection_level = DEFAULT_DRONE_DETECTION_LEVEL; uint64_t show_db_after = 80; uint64_t drone_detected_frequency_start = 0; uint64_t drone_detected_frequency_end = 0; -uint64_t detection_count = 0; bool single_page_scan = false; -bool SOUND_ON = false; // #define PRINT_DEBUG #define PRINT_PROFILE_TIME @@ -225,7 +220,6 @@ uint64_t x, y, range_item, w = WATERFALL_START, i = 0; int osd_x = 1, osd_y = 2, col = 0, max_bin = 32; uint64_t ranges_count = 0; -float freq = 0; int rssi = 0; int state = 0; @@ -238,7 +232,6 @@ constexpr int samples = SAMPLES_RSSI; uint8_t result_index = 0; uint8_t button_pressed_counter = 0; -uint64_t loop_cnt = 0; #ifndef LILYGO // #define JOYSTICK_ENABLED @@ -366,6 +359,27 @@ void osdProcess() } #endif +struct RadioScan : Scan +{ + float getRSSI() override; +}; + +float RadioScan::getRSSI() +{ +#ifdef USING_SX1280PA + // radio.startReceive(); + // get instantaneous RSSI value + // When PR will be merged we can use radi.getRSSI(false); + uint8_t data[3] = {0, 0, 0}; // RssiInst, Status, RFU + radio.mod->SPIreadStream(RADIOLIB_SX128X_CMD_GET_RSSI_INST, data, 3); + return ((float)data[0] / (-2.0)); +#else + return radio.getRSSI(false); +#endif +} + +RadioScan r; + #define WATERFALL_SENSITIVITY 0.05 DecoratedBarChart *bar; WaterfallChart *waterChart; @@ -532,7 +546,6 @@ void setup(void) #endif float vbat; float resolution; - loop_cnt = 0; bt_start = millis(); wf_start = millis(); @@ -551,7 +564,7 @@ void setup(void) delay(10); if (button.pressed()) { - SOUND_ON = !SOUND_ON; + r.sound_on = !r.sound_on; tone(BUZZER_PIN, 205, 100); delay(50); tone(BUZZER_PIN, 205, 100); @@ -662,12 +675,17 @@ void setup(void) xTaskCreate(logToSerialTask, "LOG_DATA_JSON", 2048, NULL, 1, NULL); #endif + stacked.reset(0, 0, display.width(), display.height()); + bar = new DecoratedBarChart(display, 0, 0, display.width(), 0, FREQ_BEGIN, FREQ_END, LO_RSSI_THRESHOLD, HI_RSSI_THRESHOLD, -(float)show_db_after); - stacked.reset(0, 0, display.width(), display.height() - 6); + size_t b = stacked.addChart(bar); + Chart *statusBar = new StatusBar(display, 0, 0, display.width(), r); + +#if (WATERFALL_ENABLED == true) size_t *multiples = new size_t[6]{5, 3, 4, 15, 4, 3}; WaterfallModel *model = new WaterfallModel((size_t)display.width(), 1000, 6, multiples); @@ -679,12 +697,11 @@ void setup(void) new WaterfallChart(display, 0, WATERFALL_START, display.width(), 0, FREQ_BEGIN, FREQ_END, -(float)show_db_after, WATERFALL_SENSITIVITY, model); - stacked.reset(0, 0, display.width(), display.height() - 6); - - size_t b = stacked.addChart(bar); size_t c = stacked.addChart(waterChart); + stacked.setHeight(c, stacked.height - WATERFALL_START - statusBar->height); +#endif - stacked.setHeight(c, stacked.height - WATERFALL_START); + size_t d = stacked.addChart(statusBar); stacked.setHeight(b, stacked.height); #ifdef UPTIME_CLOCK @@ -788,12 +805,12 @@ void drone_sound_alarm(int drone_detection_level, int detection_count, tone_freq_db = 285 - tone_freq_db; } - if (detection_count == 1 && SOUND_ON) + if (r.detection_count == 1 && r.sound_on) { tone(BUZZER_PIN, tone_freq_db, 10); // same action ??? but first time } - if (detection_count % 5 == 0 && SOUND_ON) + if (r.detection_count % 5 == 0 && r.sound_on) { tone(BUZZER_PIN, tone_freq_db, 10); // same action ??? but every 5th time @@ -801,7 +818,7 @@ void drone_sound_alarm(int drone_detection_level, int detection_count, } else { - if (detection_count % 20 == 0 && SOUND_ON) + if (r.detection_count % 20 == 0 && r.sound_on) { tone(BUZZER_PIN, 205, 10); // same action ??? but every 20th detection @@ -815,7 +832,7 @@ void joystickMoveCursor(int joy_x_pressed) if (joy_x_pressed > 0) { cursor_x_position--; - display.drawString(cursor_x_position, 0, String((int)freq)); + display.drawString(cursor_x_position, 0, String((int)r.current_frequency)); display.drawLine(cursor_x_position, 1, cursor_x_position, 10); display.display(); delay(10); @@ -823,7 +840,7 @@ void joystickMoveCursor(int joy_x_pressed) else if (joy_x_pressed < 0) { cursor_x_position++; - display.drawString(cursor_x_position, 0, String((int)freq)); + display.drawString(cursor_x_position, 0, String((int)r.current_frequency)); display.drawLine(cursor_x_position, 1, cursor_x_position, 10); display.display(); delay(10); @@ -831,7 +848,7 @@ void joystickMoveCursor(int joy_x_pressed) if (cursor_x_position > DISPLAY_WIDTH || cursor_x_position < 0) { cursor_x_position = 0; - display.drawString(cursor_x_position, 0, String((int)freq)); + display.drawString(cursor_x_position, 0, String((int)r.current_frequency)); display.drawLine(cursor_x_position, 1, cursor_x_position, 10); display.display(); delay(10); @@ -869,45 +886,23 @@ void check_ranges() } } -struct RadioScan : Scan -{ - float getRSSI() override; -}; - -float RadioScan::getRSSI() -{ -#ifdef USING_SX1280PA - // radio.startReceive(); - // get instantaneous RSSI value - // When PR will be merged we can use radi.getRSSI(false); - uint8_t data[3] = {0, 0, 0}; // RssiInst, Status, RFU - radio.mod->SPIreadStream(RADIOLIB_SX128X_CMD_GET_RSSI_INST, data, 3); - return ((float)data[0] / (-2.0)); -#else - return radio.getRSSI(false); -#endif -} - // MAX Frequency RSSI BIN value of the samples int max_rssi_x = 999; -RadioScan r; - void loop(void) { - UI_displayDecorate(0, 0, false); // some default values + r.led_flag = false; - detection_count = 0; + r.detection_count = 0; drone_detected_frequency_start = 0; ranges_count = 0; // reset scan time #ifdef PRINT_PROFILE_TIME scan_time = 0; - // general purpose loop counter - loop_cnt++; loop_start = millis(); #endif + r.epoch++; if (!ANIMATED_RELOAD || !single_page_scan) { @@ -923,8 +918,8 @@ void loop(void) RANGE_PER_PAGE = range; } - fr_begin = FREQ_BEGIN; - fr_end = fr_begin; + r.fr_begin = FREQ_BEGIN; + r.fr_end = r.fr_begin; // 50 is a single-screen range // TODO: Make 50 a variable with the option to show the full range @@ -946,14 +941,14 @@ void loop(void) range = RANGE_PER_PAGE; if (ranges_count == 0) { - fr_begin = (range_item == 0) ? fr_begin : fr_begin += range; - fr_end = fr_begin + RANGE_PER_PAGE; + r.fr_begin = (range_item == 0) ? r.fr_begin : r.fr_begin + range; + r.fr_end = r.fr_begin + RANGE_PER_PAGE; } else { - fr_begin = SCAN_RANGES[range_item] / 1000; - fr_end = SCAN_RANGES[range_item] % 1000; - range = fr_end - fr_begin; + r.fr_begin = SCAN_RANGES[range_item] / 1000; + r.fr_end = SCAN_RANGES[range_item] % 1000; + range = r.fr_end - r.fr_begin; } #ifdef DISABLED_CODE @@ -964,11 +959,6 @@ void loop(void) } #endif - if (single_page_scan == false) - { - UI_displayDecorate(fr_begin, fr_end, true); - } - drone_detected_frequency_start = 0; display.setTextAlignment(TEXT_ALIGN_RIGHT); @@ -999,26 +989,29 @@ void loop(void) // Because of the SCAN_RBW_FACTOR x is not a display coordinate anymore // x > STEPS on SCAN_RBW_FACTOR int display_x = x / SCAN_RBW_FACTOR; - waterfall[display_x] = false; float step = (range * ((float)x / (STEPS * SCAN_RBW_FACTOR))); - freq = fr_begin + step; - LOG("setFrequency:%f\n", freq); + r.current_frequency = r.fr_begin + step; + LOG("setFrequency:%f\n", r.current_frequency); #ifdef USING_SX1280PA - state = radio.setFrequency(freq); // 1280 doesn't have calibration + state = + radio.setFrequency(r.current_frequency); // 1280 doesn't have calibration radio.startReceive(RADIOLIB_SX128X_RX_TIMEOUT_INF); #elif USING_SX1276 state = radio.setFrequency(freq); #else - state = radio.setFrequency(freq, false); // false = no calibration need here + state = radio.setFrequency(r.current_frequency, + false); // false = no calibration need here #endif int radio_error_count = 0; if (state != RADIOLIB_ERR_NONE) { - display.drawString( - 0, 64 - 10, "E(" + String(state) + "):setFrequency:" + String(freq)); - Serial.println("E(" + String(state) + "):setFrequency:" + String(freq)); + display.drawString(0, 64 - 10, + "E(" + String(state) + + "):setFrequency:" + String(r.current_frequency)); + Serial.println("E(" + String(state) + + "):setFrequency:" + String(r.current_frequency)); display.display(); delay(2); radio_error_count++; @@ -1026,7 +1019,7 @@ void loop(void) continue; } - LOG("Step:%d Freq: %f\n", x, freq); + LOG("Step:%d Freq: %f\n", x, r.current_frequency); // SpectralScan Method #ifdef METHOD_SPECTRAL { @@ -1106,9 +1099,13 @@ void loop(void) rr = LO_RSSI_THRESHOLD; } - waterChart->updatePoint(millis(), freq, rr); + r.drone_detection_level = drone_detection_level; - int updated = bar->bar.updatePoint(freq, rr); +#if (WATERFALL_ENABLED == true) + waterChart->updatePoint(millis(), r.current_frequency, rr); +#endif + + int updated = bar->bar.updatePoint(r.current_frequency, rr); if (first_run || ANIMATED_RELOAD) { @@ -1121,30 +1118,18 @@ void loop(void) if (detected_y[display_x] == false) // detection threshold match { // Set LED to ON (filtered in UI component) - UI_setLedFlag(true); -#if (WATERFALL_ENABLED == true) - if (single_page_scan) - { - // Drone detection true for waterfall - if (!waterfall[display_x]) - { - waterfall[display_x] = true; - display.setColor(WHITE); - // display.setPixel(display_x, w); - } - } -#endif + r.led_flag = true; if (drone_detected_frequency_start == 0) { // mark freq start - drone_detected_frequency_start = freq; + drone_detected_frequency_start = r.current_frequency; } // mark freq end ... will shift right to last detected range - drone_detected_frequency_end = freq; - if (SOUND_ON == true) + drone_detected_frequency_end = r.current_frequency; + if (r.sound_on) { - drone_sound_alarm(drone_detection_level, detection_count, + drone_sound_alarm(r.drone_detection_level, r.detection_count, max_rssi_x * 2); } @@ -1165,34 +1150,13 @@ void loop(void) #endif } } -#if (WATERFALL_ENABLED == true) - if ((single_page_scan) && (waterfall[display_x] != true) && new_pixel) - { - // If drone not found set dark pixel on the waterfall - // TODO: make something like scrolling up if possible - waterfall[display_x] = false; - display.setColor(BLACK); - // display.setPixel(display_x, w); - display.setColor(WHITE); - } -#endif } -#ifdef PRINT_DEBUG - for (int y = 0; y < RADIOLIB_SX126X_SPECTRAL_SCAN_RES_SIZE; y++) - { - if (filtered_result[y] == 1) - { - LOG("Pixel:%i(%i):%i,", display_x, x, y); - } - } -#endif - #ifdef JOYSTICK_ENABLED // Draw joystick cursor and Frequency RSSI value if (display_x == cursor_x_position) { - display.drawString(display_x - 1, 0, String((int)freq)); + display.drawString(display_x - 1, 0, String((int)r.current_frequency)); display.drawLine(display_x, 1, display_x, 12); // if method scan RSSI we can get exact RSSI value display.drawString(display_x + 17, 0, "-" + String((int)max_rssi_x * 4)); @@ -1205,7 +1169,7 @@ void loop(void) // count detected if (detected) { - detection_count++; + r.detection_count++; } #ifdef PRINT_DEBUG @@ -1216,7 +1180,7 @@ void loop(void) display.display(); } - if (buttonPressHandler(freq) == false) + if (buttonPressHandler(r.current_frequency) == false) break; // wait a little bit before the next scan, @@ -1265,15 +1229,6 @@ void loop(void) { w = WATERFALL_START; } -#if (WATERFALL_ENABLED == true) - // Draw waterfall position cursor - if (single_page_scan) - { - display.setColor(BLACK); - // display.drawHorizontalLine(0, w, STEPS); - display.setColor(WHITE); - } -#endif stacked.draw(); // Render display data here diff --git a/src/ui.cpp b/src/ui.cpp index ea376dd..e488060 100644 --- a/src/ui.cpp +++ b/src/ui.cpp @@ -2,6 +2,8 @@ #include "RadioLib.h" #include "global_config.h" #include "images.h" +#include +#include // ------------------------------------------------- // LOCAL DEFINES @@ -12,24 +14,9 @@ // #define SCALE_TEXT_TOP (HEIGHT + X_AXIS_WEIGHT + MAJOR_TICK_LENGTH) -static unsigned int start_scan_text = (128 / 2) - 3; -// initialized flag -static bool ui_initialized = false; -static bool led_flag = false; -static unsigned short int scan_progress_count = 0; - -#ifdef Vision_Master_E290 -static DEPG0290BxS800FxX_BW *display_instance; -#else -//(0x3c, SDA_OLED, SCL_OLED, DISPLAY_GEOMETRY); -static SSD1306Wire *display_instance; -#endif // temporary dirty import ... to be solved durring upcoming refactoring -extern unsigned int drone_detection_level; extern unsigned int RANGE_PER_PAGE; extern unsigned int median_frequency; -extern unsigned int detection_count; -extern bool SOUND_ON; extern unsigned int drone_detected_frequency_start; extern unsigned int drone_detected_frequency_end; extern unsigned int ranges_count; @@ -40,230 +27,138 @@ extern unsigned int range_item; extern uint64_t loop_time; -#ifndef Vision_Master_E290 -void UI_Init(SSD1306Wire *display_ptr) +void UI_Init(Display_t *display_ptr) { - // init pointer to display instance. - display_instance = display_ptr; // check for null ??? - display_instance->clear(); + display_ptr->clear(); // draw the UCOG welcome logo - display_instance->drawXbm(0, 2, 128, 64, epd_bitmap_ucog); - display_instance->display(); + display_ptr->drawXbm(0, 2, 128, 64, epd_bitmap_ucog); + display_ptr->display(); } -#endif -#ifdef Vision_Master_E290 -void UI_Init(DEPG0290BxS800FxX_BW *display_ptr) -{ - // init pointer to display instance. - display_instance = display_ptr; - // check for null ??? - display_instance->clear(); - // draw the UCOG welcome logo - display_instance->drawXbm(0, 2, 128, 64, epd_bitmap_ucog); - display_instance->display(); -} -#endif - -void UI_setLedFlag(bool new_status) { led_flag = new_status; } - -void clearStatus(void) +void StatusBar::clearStatus(void) { // clear status line - display_instance->setColor(BLACK); - display_instance->fillRect(0, ROW_STATUS_TEXT + 2, 128, 13); - display_instance->setColor(WHITE); + display.setColor(BLACK); + display.fillRect(pos_x, pos_y, width, height); } void UI_clearPlotter(void) { // clear the scan plot rectangle (top part) - display_instance->setColor(BLACK); - display_instance->fillRect(0, 10, STEPS, HEIGHT - 10); - display_instance->setColor(WHITE); + // display_instance->setColor(BLACK); + // display_instance->fillRect(0, 10, STEPS, HEIGHT - 10); + // display_instance->setColor(WHITE); } void UI_clearTopStatus(void) { // clear the scan plot rectangle (top part) - display_instance->setColor(BLACK); - display_instance->fillRect(0, 0, STEPS, 10); - display_instance->setColor(WHITE); -} - -/** - * @brief Draws ticks on the display at regular whole intervals. - * - * @param every The interval between ticks in MHz. - * @param length The length of each tick in pixels. - */ -void drawTicks(float every, int length) -{ - int first_tick; - bool correction; - int pixels_per_step; - int correction_number; - int tick; - int tick_minor; - int median; - - first_tick = 0; - //+ (every - (fr_begin - (int)(fr_begin / every) * every)); - /*if (first_tick < fr_begin) - { - first_tick += every; - }*/ - correction = false; - pixels_per_step = STEPS / (RANGE_PER_PAGE / every); - if (STEPS / RANGE_PER_PAGE != 0) - { - correction = true; - } - correction_number = STEPS - (int)(pixels_per_step * (RANGE_PER_PAGE / every)); - tick = 0; - tick_minor = 0; - median = (RANGE_PER_PAGE / every) / 2; - // TODO: (RANGE_PER_PAGE / every) - // * 2 has twice extra steps we need to figureout correct logic or minor - // ticks is not showing to the end - for (int t = 0; t <= (RANGE_PER_PAGE / every) * 2; t++) - { - // fix if pixels per step is not int and we have shift - if (correction && t % 2 != 0 && correction_number > 1) - { - // pixels_per_step++; - correction_number--; - } - tick += pixels_per_step; - tick_minor = tick / 2; - if (tick <= 128 - 3) - { - display_instance->drawLine(tick, HEIGHT + X_AXIS_WEIGHT, tick, - HEIGHT + X_AXIS_WEIGHT + length); - // Central tick - if (tick > (128 / 2) - 3 && tick < (128 / 2) + 3) - { - display_instance->drawLine(tick + 1, HEIGHT + X_AXIS_WEIGHT, tick + 1, - HEIGHT + X_AXIS_WEIGHT + length); - } - } -#ifdef MINOR_TICKS - // Fix two ticks together - if ((tick_minor + 1 != tick) && (tick_minor - 1 != tick) && - (tick_minor + 2 != tick) && (tick_minor - 2 != tick)) - { - display_instance->drawLine(tick_minor, HEIGHT + X_AXIS_WEIGHT, tick_minor, - HEIGHT + X_AXIS_WEIGHT + MINOR_TICK_LENGTH); - } - // Central tick - if (tick_minor > (128 / 2) - 3 && tick_minor < (128 / 2) + 3) - { - display_instance->drawLine(tick_minor + 1, HEIGHT + X_AXIS_WEIGHT, - tick_minor + 1, - HEIGHT + X_AXIS_WEIGHT + MINOR_TICK_LENGTH); - } -#endif - } + // display_instance->setColor(BLACK); + // display_instance->fillRect(0, 0, STEPS, 10); + // display_instance->setColor(WHITE); } void UI_drawCursor(int16_t possition) { // Draw animated vertical cursor on reload process - display_instance->setColor(BLACK); - display_instance->drawVerticalLine(possition, 0, HEIGHT); - display_instance->drawVerticalLine(possition + 1, 0, HEIGHT); - display_instance->drawVerticalLine(possition + 2, 0, HEIGHT); - display_instance->setColor(WHITE); + // display_instance->setColor(BLACK); + // display_instance->drawVerticalLine(possition, 0, HEIGHT); + // display_instance->drawVerticalLine(possition + 1, 0, HEIGHT); + // display_instance->drawVerticalLine(possition + 2, 0, HEIGHT); + // display_instance->setColor(WHITE); } /** * @brief Decorates the display: everything but the plot itself. */ -void UI_displayDecorate(int begin = 0, int end = 0, bool redraw = false) +void StatusBar::draw() { + uint16_t text_y = pos_y + height - 10; + if (!ui_initialized) { // Drone detection level - display_instance->setTextAlignment(TEXT_ALIGN_RIGHT); - display_instance->drawString(128, 0, String(drone_detection_level)); + display.setTextAlignment(TEXT_ALIGN_RIGHT); + display.drawString(width, 0, String(r.drone_detection_level)); } - if (!ui_initialized || redraw) + if (!ui_initialized) { // Clear something - display_instance->setColor(BLACK); - display_instance->fillRect(0, SCALE_TEXT_TOP + 1, 128, 12); - display_instance->setColor(WHITE); - + /* display_instance->setColor(BLACK); + display_instance->fillRect(0, SCALE_TEXT_TOP + 1, 128, 12); + display_instance->setColor(WHITE); + */ // Drone detection level - display_instance->setTextAlignment(TEXT_ALIGN_RIGHT); - display_instance->drawString(128, 0, String(drone_detection_level)); + display.setTextAlignment(TEXT_ALIGN_RIGHT); + display.drawString(pos_x + width, 0, String(r.drone_detection_level)); // Frequency start - display_instance->setTextAlignment(TEXT_ALIGN_LEFT); - display_instance->drawString(0, ROW_STATUS_TEXT, - (begin == 0) ? String(FREQ_BEGIN) : String(begin)); + display.setTextAlignment(TEXT_ALIGN_LEFT); + display.drawString(pos_x, text_y, + (r.fr_begin == 0) ? String(FREQ_BEGIN) : String(r.fr_begin)); // Frequency detected - display_instance->setTextAlignment(TEXT_ALIGN_CENTER); - display_instance->drawString(128 / 2, ROW_STATUS_TEXT, - (begin == 0) ? String(median_frequency) - : String(begin + ((end - begin) / 2))); + display.setTextAlignment(TEXT_ALIGN_CENTER); + display.drawString(pos_x + width / 2, text_y, + (r.fr_begin == 0) + ? String(median_frequency) + : String(r.fr_begin + ((r.fr_end - r.fr_begin) / 2))); // Frequency end - display_instance->setTextAlignment(TEXT_ALIGN_RIGHT); - display_instance->drawString(128, ROW_STATUS_TEXT, - (end == 0) ? String(FREQ_END) : String(end)); + display.setTextAlignment(TEXT_ALIGN_RIGHT); + display.drawString(pos_x + width, text_y, + (r.fr_end == 0) ? String(FREQ_END) : String(r.fr_end)); } // Status text block - if (led_flag) // 'drone' detected + if (r.led_flag) // 'drone' detected { - display_instance->setTextAlignment(TEXT_ALIGN_CENTER); + display.setTextAlignment(TEXT_ALIGN_CENTER); // clear status line clearStatus(); - display_instance->drawString(start_scan_text + 2, ROW_STATUS_TEXT, - String(drone_detected_frequency_start) + ">RF<" + - String(drone_detected_frequency_end)); + display.setColor(WHITE); + display.drawString(pos_x + width / 2, text_y, + String(drone_detected_frequency_start) + ">RF<" + + String(drone_detected_frequency_end)); } else { // "Scanning" - display_instance->setTextAlignment(TEXT_ALIGN_CENTER); + display.setTextAlignment(TEXT_ALIGN_CENTER); // clear status line clearStatus(); - if (scan_progress_count == 0) + String s = "Scan \\"; + if (scan_progress_count == 1) { - display_instance->drawString(start_scan_text, ROW_STATUS_TEXT, "Scan \\"); - } - else if (scan_progress_count == 1) - { - display_instance->drawString(start_scan_text, ROW_STATUS_TEXT, "Scan |"); + s = "Scan |"; } else if (scan_progress_count == 2) { - display_instance->drawString(start_scan_text, ROW_STATUS_TEXT, "Scan /"); + s = "Scan /"; } else if (scan_progress_count == 3) { - display_instance->drawString(start_scan_text, ROW_STATUS_TEXT, "Scan -"); + s = "Scan -"; } scan_progress_count++; if (scan_progress_count >= 4) { scan_progress_count = 0; } + display.setColor(WHITE); + display.drawString(pos_x + width / 2 - 3, text_y, s); } - if (led_flag == true && detection_count >= 5) + if (r.led_flag && r.detection_count >= 5) { digitalWrite(LED, HIGH); - if (SOUND_ON) + if (r.sound_on) { tone(BUZZER_PIN, 104, 100); } digitalWrite(REB_PIN, HIGH); - led_flag = false; + r.led_flag = false; } - else if (!redraw) + else if (!r.led_flag) { digitalWrite(LED, LOW); } @@ -271,29 +166,28 @@ void UI_displayDecorate(int begin = 0, int end = 0, bool redraw = false) if (ranges_count == 0) { #ifdef DEBUG - display_instance->setTextAlignment(TEXT_ALIGN_LEFT); - display_instance->drawString(0, ROW_STATUS_TEXT, String(loop_time)); + display.setTextAlignment(TEXT_ALIGN_LEFT); + display.drawString(pos_x, text_y, String(loop_time)); #else - display_instance->setTextAlignment(TEXT_ALIGN_LEFT); - display_instance->drawString(0, ROW_STATUS_TEXT, String(FREQ_BEGIN)); + display.setTextAlignment(TEXT_ALIGN_LEFT); + display.drawString(pos_x, text_y, String(FREQ_BEGIN)); #endif - display_instance->setTextAlignment(TEXT_ALIGN_RIGHT); - display_instance->drawString(128, ROW_STATUS_TEXT, String(FREQ_END)); + display.setTextAlignment(TEXT_ALIGN_RIGHT); + display.drawString(pos_x + width, text_y, String(FREQ_END)); } else if (ranges_count > 0) { - display_instance->setTextAlignment(TEXT_ALIGN_LEFT); - display_instance->drawString(0, ROW_STATUS_TEXT, - String(SCAN_RANGES[range_item] / 1000) + "-" + - String(SCAN_RANGES[range_item] % 1000)); + display.setTextAlignment(TEXT_ALIGN_LEFT); + display.drawString(pos_x, text_y, + String(SCAN_RANGES[range_item] / 1000) + "-" + + String(SCAN_RANGES[range_item] % 1000)); if (range_item + 1 < iterations) { - display_instance->setTextAlignment(TEXT_ALIGN_RIGHT); - display_instance->drawString(128, ROW_STATUS_TEXT, - String(SCAN_RANGES[range_item + 1] / 1000) + - "-" + - String(SCAN_RANGES[range_item + 1] % 1000)); + display.setTextAlignment(TEXT_ALIGN_RIGHT); + display.drawString(pos_x + width, text_y, + String(SCAN_RANGES[range_item + 1] / 1000) + "-" + + String(SCAN_RANGES[range_item + 1] % 1000)); } } ui_initialized = true;