mirror of
https://github.com/thooge/esp32-nmea2000-obp60.git
synced 2026-08-18 10:22:31 +02:00
Add smoothing option for any chart plot
This commit is contained in:
@@ -42,6 +42,11 @@ Chart::Chart(RingBuffer<uint16_t>& dataBuf, double dfltRng, CommonData& common,
|
|||||||
dbMAX_VAL = dataBuf.getMaxVal();
|
dbMAX_VAL = dataBuf.getMaxVal();
|
||||||
bufSize = dataBuf.getCapacity();
|
bufSize = dataBuf.getCapacity();
|
||||||
|
|
||||||
|
smoothCharts = common.config->getBool(common.config->smoothCharts);
|
||||||
|
if (smoothCharts) {
|
||||||
|
chrtAvg.begin();
|
||||||
|
}
|
||||||
|
|
||||||
// Initialize chart data format; shorter version of standard format indicator
|
// Initialize chart data format; shorter version of standard format indicator
|
||||||
if (dbFormat == "formatCourse" || dbFormat == "formatWind" || dbFormat == "formatRot") {
|
if (dbFormat == "formatCourse" || dbFormat == "formatWind" || dbFormat == "formatRot") {
|
||||||
chrtDataFmt = WIND; // Chart is showing data of course / wind <degree> format
|
chrtDataFmt = WIND; // Chart is showing data of course / wind <degree> format
|
||||||
@@ -337,6 +342,23 @@ void Chart::drawChartLines(const char direction, const int8_t chrtIntv, const do
|
|||||||
double chrtVal; // Current data value
|
double chrtVal; // Current data value
|
||||||
Pos point, prevPoint; // current and previous chart point
|
Pos point, prevPoint; // current and previous chart point
|
||||||
|
|
||||||
|
if (smoothCharts) {
|
||||||
|
// prime moving average filter to ensure the first plotted point is already averaged
|
||||||
|
|
||||||
|
chrtAvg.reset();
|
||||||
|
|
||||||
|
// Feed the filter the 10 values preceding bufStart
|
||||||
|
for (int p = 10; p > 0; p--) {
|
||||||
|
// Calculate index with wrapping: (start - offset + size) % size
|
||||||
|
int primeIdx = (bufStart - (p * chrtIntv));
|
||||||
|
double primeVal = dataBuf.get(primeIdx);
|
||||||
|
|
||||||
|
if (primeVal != dbMAX_VAL) {
|
||||||
|
chrtAvg.reading(primeVal);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (int i = 0; i < (numBufVals / chrtIntv); i++) {
|
for (int i = 0; i < (numBufVals / chrtIntv); i++) {
|
||||||
|
|
||||||
chrtVal = dataBuf.get(bufStart + (i * chrtIntv)); // show the latest wind values in buffer; keep 1st value constant in a rolling buffer
|
chrtVal = dataBuf.get(bufStart + (i * chrtIntv)); // show the latest wind values in buffer; keep 1st value constant in a rolling buffer
|
||||||
@@ -345,6 +367,11 @@ void Chart::drawChartLines(const char direction, const int8_t chrtIntv, const do
|
|||||||
chrtPrevVal = dbMAX_VAL;
|
chrtPrevVal = dbMAX_VAL;
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
if (smoothCharts) {
|
||||||
|
// if chart lines shall be smoothed, apply moving average filter of the last 10 values
|
||||||
|
chrtVal = chrtAvg.reading(chrtVal);
|
||||||
|
}
|
||||||
|
|
||||||
point = setCurrentChartPoint(i, direction, chrtVal, chrtScale);
|
point = setCurrentChartPoint(i, direction, chrtVal, chrtScale);
|
||||||
|
|
||||||
// if (i >= (numBufVals / chrtIntv) - 5) // log chart data of 1 line (adjust for test purposes)
|
// if (i >= (numBufVals / chrtIntv) - 5) // log chart data of 1 line (adjust for test purposes)
|
||||||
@@ -399,7 +426,7 @@ void Chart::drawChartLines(const char direction, const int8_t chrtIntv, const do
|
|||||||
|
|
||||||
if (chrtDataFmt == WIND) { // degree of course or wind
|
if (chrtDataFmt == WIND) { // degree of course or wind
|
||||||
recalcRngMid = true;
|
recalcRngMid = true;
|
||||||
LOG_DEBUG(GwLog::DEBUG, "PageWindPlot: chart end: timAxis: %d, i: %d, bufStart: %d, numBufVals: %d, recalcRngCntr: %d", timAxis, i, bufStart, numBufVals, recalcRngMid);
|
// LOG_DEBUG(GwLog::DEBUG, "PageWindPlot: chart end: timAxis: %d, i: %d, bufStart: %d, numBufVals: %d, recalcRngCntr: %d", timAxis, i, bufStart, numBufVals, recalcRngMid);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -454,7 +481,7 @@ void Chart::drawChrtTimeAxis(const char chrtDir, const int8_t chrtSz, const int8
|
|||||||
if (chrtDir == HORIZONTAL) {
|
if (chrtDir == HORIZONTAL) {
|
||||||
getdisplay().fillRect(0, cRoot.y, dWidth, 2, fgColor);
|
getdisplay().fillRect(0, cRoot.y, dWidth, 2, fgColor);
|
||||||
|
|
||||||
LOG_DEBUG(GwLog::DEBUG, "Chart::drawChrtTimeAxis: intv: %d, axSlots: %d, timAxis: %d, chrtIntv: %d", intv, axSlots, timAxis, chrtIntv);
|
// LOG_DEBUG(GwLog::DEBUG, "Chart::drawChrtTimeAxis: intv: %d, axSlots: %d, timAxis: %d, chrtIntv: %d", intv, axSlots, timAxis, chrtIntv);
|
||||||
for (int j = intv; j < timAxis - 1; j += intv) { // fill time axis with values but keep area free on right hand side for value label
|
for (int j = intv; j < timAxis - 1; j += intv) { // fill time axis with values but keep area free on right hand side for value label
|
||||||
|
|
||||||
// draw text with appropriate offset
|
// draw text with appropriate offset
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "Pagedata.h"
|
#include "Pagedata.h"
|
||||||
#include "OBP60Extensions.h"
|
#include "OBP60Extensions.h"
|
||||||
|
#include "movingAvg.h"
|
||||||
|
|
||||||
struct Pos {
|
struct Pos {
|
||||||
int x;
|
int x;
|
||||||
@@ -44,12 +45,11 @@ protected:
|
|||||||
static constexpr bool NO_SIMUDATA = true; // switch off simulation feature of <formatValue> function
|
static constexpr bool NO_SIMUDATA = true; // switch off simulation feature of <formatValue> function
|
||||||
|
|
||||||
RingBuffer<uint16_t>& dataBuf; // Buffer to display
|
RingBuffer<uint16_t>& dataBuf; // Buffer to display
|
||||||
//char chrtDir; // Chart timeline direction: 'H' = horizontal, 'V' = vertical
|
|
||||||
//int8_t chrtSz; // Chart size: [0] = full size, [1] = half size left/top, [2] half size right/bottom
|
|
||||||
double dfltRng; // Default range of chart, e.g. 30 = [0..30]
|
double dfltRng; // Default range of chart, e.g. 30 = [0..30]
|
||||||
uint16_t fgColor; // color code for any screen writing
|
uint16_t fgColor; // color code for any screen writing
|
||||||
uint16_t bgColor; // color code for screen background
|
uint16_t bgColor; // color code for screen background
|
||||||
bool useSimuData; // flag to indicate if simulation data is active
|
bool useSimuData; // flag to indicate if simulation data is active
|
||||||
|
bool smoothCharts; // flag to indicate if charts shall be printed with smoothed gradient
|
||||||
String tempFormat; // user defined format for temperature
|
String tempFormat; // user defined format for temperature
|
||||||
double zeroValue; // "0" SI value for temperature
|
double zeroValue; // "0" SI value for temperature
|
||||||
|
|
||||||
@@ -84,6 +84,7 @@ protected:
|
|||||||
bool bufDataValid = false; // Flag to indicate if buffer data is valid
|
bool bufDataValid = false; // Flag to indicate if buffer data is valid
|
||||||
int oldChrtIntv = 0; // remember recent user selection of data interval
|
int oldChrtIntv = 0; // remember recent user selection of data interval
|
||||||
|
|
||||||
|
movingAvg<double> chrtAvg{7}; // Store average of the last 7 chart values if chart gradient shall be smoothed
|
||||||
double chrtPrevVal; // Last data value in chart area
|
double chrtPrevVal; // Last data value in chart area
|
||||||
int x, y; // x and y coordinates for drawing
|
int x, y; // x and y coordinates for drawing
|
||||||
int prevX, prevY; // Last x and y coordinates for drawing
|
int prevX, prevY; // Last x and y coordinates for drawing
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ private:
|
|||||||
bool oldShowTruW = false; // remember recent user selection of wind data type
|
bool oldShowTruW = false; // remember recent user selection of wind data type
|
||||||
|
|
||||||
int8_t dataIntv = 1; // Update interval for wind history chart:
|
int8_t dataIntv = 1; // Update interval for wind history chart:
|
||||||
// (1)|(2)|(3)|(4)|(8) x 240 seconds for 4, 8, 12, 16, 32 min. history chart
|
// (1)|(2)|(3)|(4)|(8) seconds for up to 32 min. history chart
|
||||||
bool useSimuData;
|
bool useSimuData;
|
||||||
// bool holdValues;
|
// bool holdValues;
|
||||||
String flashLED;
|
String flashLED;
|
||||||
|
|||||||
@@ -230,6 +230,17 @@
|
|||||||
"obp40": "true"
|
"obp40": "true"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "smoothCharts",
|
||||||
|
"label": "Smooth chart lines",
|
||||||
|
"type": "boolean",
|
||||||
|
"default": "false",
|
||||||
|
"description": "Print chart lines with a smoothed gradient",
|
||||||
|
"category": "OBP40 Settings",
|
||||||
|
"capabilities": {
|
||||||
|
"obp40": "true"
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "lengthFormat",
|
"name": "lengthFormat",
|
||||||
"label": "Length Format",
|
"label": "Length Format",
|
||||||
|
|||||||
@@ -230,6 +230,17 @@
|
|||||||
"obp60": "true"
|
"obp60": "true"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "smoothCharts",
|
||||||
|
"label": "Smooth chart lines",
|
||||||
|
"type": "boolean",
|
||||||
|
"default": "false",
|
||||||
|
"description": "Print chart lines with a smoothed gradient",
|
||||||
|
"category": "OBP60 Settings",
|
||||||
|
"capabilities": {
|
||||||
|
"obp40": "true"
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "lengthFormat",
|
"name": "lengthFormat",
|
||||||
"label": "Length Format",
|
"label": "Length Format",
|
||||||
|
|||||||
Reference in New Issue
Block a user