How to reduce 10k data points and show them on smaller display? Arduino

218 Views Asked by At

I‘m working on a visual data logger for my DMM, it writes every measurement to RS232 inteface. There I connect a Teensy 3.6 and collect the data points. For each point I have the timestamp and the measured value. I will collect 10.000 readings. I want to display the measured data on a display (800x480) in two ways. First as a rolling graph, that scrolls from right to left and shows the last minute or so. This is working fine.

Second, I want to display all collected measurements in total (max. 10k points). So I have to shrink or compress the data, but I want to preserve the shape of the curve. To give you an idea how it should look like, please watch the video from Dave on EEV at YT (https://youtu.be/SObqPuUozNo) and skip to 41:20. There you see how another DMM is shrinking the incomming data and displays it. At about 1:01:05 10k measurements are shown on the display area of only 400px wide.

Question is, how is this done? I’ve heard about Douglas-Pucker algorithm, but have no idea if this is the right way and how to use it on the Arduino/ Teensy platform.

Any help is very welcome, thank you....

2

There are 2 best solutions below

0
On

For cases where you got many more samples than pixels in x axis instead of LineTo like graph use vertical lines graph instead...

So depending on the number of samples per rendered time frame and x resolution you should compute ymin and ymax for eaxch x and render vertical line ...

V lines

something like:

xs=800;
for (x0=x,i=sample_left,y0=y1=sample[i],i<sample_right;i++)
 {
 x = (i-sample_left)*xs/(sample_right-sample_left);
 y = sample[i]; // here add y scaling and offset
 if (x0!=x) { line(x0,y0,x0,y1); x0=x; y0=y; y1=y; }
 if (y0>y) y0=y;
 if (y1<y) y1=y;
 }

where sample[] are your stored values , sample_left,sample_right is the range to render and xs is graph x resolution. To speed up you can pre-compute the y0,y1 for each x and render that (recompute only on range or samples change) ... So as you can see you will use just xs line commands which shoul dbe fast enough. The x linear interpolation can be done without multiplication nor division if you rewrite it to integer DDA style ...

These QAs might interest you:

[note]

After a second look The deleted answer is with the same approach as this (got deleted by review probably before the edit which transformed it from not an answer (comment) to the correct answer) so I voted for undelete even if it is considerably lower quality than mine but was posted sooner.

1
On

I cannot just display all data points, because I‘m using an FT81x as display controller, and this can take only up to 2000 drawing commands per frame. And it takes more time.

Anyway, I solved the problem using the simple way.

I create bins and calculate the min and max values in this bin. Then simply draw a line between these points. Works fine!

BTW, I‘m the TO :-)