Factor out drawing into Charts

This commit is contained in:
Sassa NF
2024-09-28 22:36:48 +01:00
parent 39073dd026
commit c78fa6de7a
3 changed files with 185 additions and 26 deletions
+92
View File
@@ -0,0 +1,92 @@
#include "charts.h"
void BarChart::reset()
{
memset(ys, 0, width * sizeof(float));
memset(changed, false, width * sizeof(bool));
redraw_all = true;
}
int BarChart::updatePoint(float x, float y)
{
if (x < min_x || x >= max_x)
{
return -1;
}
size_t idx = width * (x - min_x) / (max_x - min_x);
if (idx >= width)
{
idx = width - 1;
}
if (!changed[idx] || ys[idx] < y)
{
ys[idx] = y;
changed[idx] = true;
}
return idx;
}
void BarChart::draw()
{
for (int x = 0; x < width; x++)
{
if (!changed[x] && !redraw_all)
continue;
drawOne(x);
}
redraw_all = false;
}
void BarChart::drawOne(int x)
{
if (x < 0)
return;
int y = y2pos(ys[x]);
if (y < height)
{
display.setColor(BLACK);
display.drawVerticalLine(pos_x + x, pos_y, y);
display.setColor(WHITE);
display.drawVerticalLine(pos_x + x, pos_y + y, height - y);
}
else
{
display.setColor(BLACK);
display.drawVerticalLine(pos_x + x, pos_y, height);
}
if (x % 2 == 0)
{
display.setColor(INVERSE);
display.setPixel(pos_x + x, pos_y + y2pos(level_y));
}
changed[x] = false;
}
int BarChart::x2pos(float x)
{
if (x < min_x)
x = min_x;
if (x > max_x)
x = max_x;
return width * (x - min_x) / (max_x - min_x);
}
int BarChart::y2pos(float y)
{
if (y < min_y)
y = min_y;
if (y > max_y)
y = max_y;
return height - height * (y - min_y) / (max_y - min_y);
}
+67
View File
@@ -0,0 +1,67 @@
#ifndef CHARTS_H
#define CHARTS_H
#include <OLEDDisplay.h>
#include <cstdint>
#include <stdlib.h>
struct Chart
{
uint16_t pos_x, pos_y;
uint16_t width, height;
OLEDDisplay &display;
Chart(OLEDDisplay &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) {};
/*
* This method resets the state and sets the reference time.
*/
virtual void reset() = 0;
/*
* Update one data point, and return what column needs redrawing.
*/
virtual int updatePoint(float x, float y) = 0;
/*
* If you fancy animated progress, then pass the output of updatePoint to here.
*/
virtual void drawOne(int x) = 0;
/*
* Redraw everything that needs redrawing.
*/
virtual void draw() = 0;
};
struct BarChart : Chart
{
float min_x, max_x, min_y, max_y;
float level_y;
float *ys;
bool *changed;
bool redraw_all;
BarChart(OLEDDisplay &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), min_x(min_x), max_x(max_x), min_y(min_y), max_y(max_y),
level_y(level_y), redraw_all(true)
{
ys = new float[w];
changed = new bool[w];
memset(ys, 0, w * sizeof(float));
memset(changed, 0, w * sizeof(bool));
};
void reset() override;
int updatePoint(float x, float y) override;
void drawOne(int x) override;
void draw() override;
int x2pos(float x);
int y2pos(float y);
};
#endif
+26 -26
View File
@@ -41,6 +41,7 @@
// library internals.
#define RADIOLIB_GODMODE (1)
#include <charts.h>
#include <scan.h>
#ifndef LILYGO
@@ -365,6 +366,8 @@ void osdProcess()
}
#endif
BarChart *bar;
void init_radio()
{
// initialize SX1262 FSK modem at the initial frequency
@@ -653,6 +656,14 @@ void setup(void)
#ifdef LOG_DATA_JSON
xTaskCreate(logToSerialTask, "LOG_DATA_JSON", 2048, NULL, 1, NULL);
#endif
bar = new BarChart(display, 0, START_LOW, display.width(),
display.height() / 2 - START_LOW, FREQ_BEGIN, FREQ_END,
LO_RSSI_THRESHOLD, HI_RSSI_THRESHOLD,
-(float)show_db_after); // LO_RSSI_THRESHOLD + (HI_RSSI_THRESHOLD -
// LO_RSSI_THRESHOLD) * 0.3);
bar->reset();
}
// Formula to translate 33 bin to approximate RSSI value
@@ -1060,6 +1071,7 @@ void loop(void)
detected_y[display_x] = false;
#if FILTER_SPECTRUM_RESULTS
float rr;
if (detected)
{
// calculating max window x RSSI after filters
@@ -1070,6 +1082,18 @@ void loop(void)
max_x_window[x_window] = abs_result;
LOG("MAX x window: %i %i\n", x_window, abs_result);
}
rr = -(float)result[detected_at];
}
else
{
rr = LO_RSSI_THRESHOLD;
}
int updated = bar->updatePoint(freq, rr);
if (first_run || ANIMATED_RELOAD)
{
bar->drawOne(updated);
}
#endif
@@ -1146,31 +1170,6 @@ void loop(void)
}
#endif
display.setColor(WHITE);
display.drawVerticalLine(display_x, START_LOW + detected_at,
min(RADIOLIB_SX126X_SPECTRAL_SCAN_RES_SIZE,
MAX_POWER_LEVELS - START_LOW) -
detected_at);
// -------------------------------------------------------------
// Draw "Detection Level line" every 2 pixel
// -------------------------------------------------------------
if (display_x % 2 == 0)
{
if (detected_at <= drone_detection_level)
{
display.setColor(INVERSE);
}
else
{
display.setColor(WHITE);
}
display.setPixel(display_x, drone_detection_level + START_LOW);
// display.setPixel(display_x, y + START_LOW - 1); // 2 px wide
display.setColor(WHITE);
}
#ifdef JOYSTICK_ENABLED
// Draw joystick cursor and Frequency RSSI value
if (display_x == cursor_x_position)
@@ -1258,6 +1257,7 @@ void loop(void)
}
#endif
bar->draw();
#ifdef METHOD_RSSI
// Printing Max Window DB.
for (int x2 = 0; x2 < STEPS / WINDOW_SIZE; x2++)
@@ -1270,7 +1270,7 @@ void loop(void)
max_x_window[x2] = 999;
}
#endif
// Render display data here
// Render display data here
display.display();
#ifdef OSD_ENABLED
// Sometimes OSD prints entire screen with the digits.