Jump to content

Graphing Flicker when refreshing


MobileWill

Recommended Posts

I am working with the graph widget and the only way I could get the graph to clear and draw the new data cleanly is to clear it and reset the graph object and then draw the data. Is this the correct way? I notice a slight flicker in doing this. I split the thread into two. One for data gathering of a ring buffer and another to redraw the graph. That way the data and graph can have separate timings. I saw the oscope demo and its redraw is super fast and smooth. I wish I could see the source code for that. I can't seem to find it. Here is my current graph code. The graph widget is in a container.

while(true){
        if(updateGraph){
            gwinClear(ghGraph);
            gwinGraphSetOrigin(ghGraph, 5, 5);
            gwinGraphSetStyle(ghGraph, &GraphStyleCurrent);
            gwinGraphDrawAxis(ghGraph);
            for (i=0; i < GRAPH_MEMORY; i++) {
                uint16_t val = mapI(graph_Mem[(i+ring_idx)%GRAPH_MEMORY], 0, autoscale_limits[graph_MAX], 0, 185);
                gwinGraphDrawPoint(ghGraph, i, val);
            }
        }
        chThdSleepMilliseconds(100);
    }

 

Link to comment
Share on other sites

As the graph doesn't keep track of the data itself (for various reasons) clearing the graph and then manually redrawing the actual data points is the correct way. Decoupling the data acquisition and the rendering of the data as per your method is also a very good idea.

The flickering occurs because gwinClear() will clear the graph (fill the entire area with the background color, then draw axis and grids) and then some time passes until you write your new data. This time in-between those two operations cause the flickering. Ideally, the rendering of the entire graph would happen off-screen and the result is copied in one operation to the frame buffer. This can be archived by using Pixmaps which provide dynamic virtual off-screen displays to which you can render just as to any display and once everything has completed it can be blitted into the frame buffer. However, note that depending on your hardware (memory bandwidth, coupling between framebuffer memory and RAM, ...) can cause to actually lower the performance.

Another solution is to write your own graph widget which would maintain a list of the data-points as per your needs. The graph widget that comes with the uGFX library is very old and doesn't provide many features. Also, it is hard to write such a specialized widget that is still generic and universal usable.

Can you tell us which scope demo you mean? Over the time many users have written a lot of different, very awesome oscilloscope demos :)

If you are referring to the demo that samples an audio input via GAUDIO and draws the volume line/graph, then that demo can be found under /demos/modules/GAUDIO/oscilloscope. However, that demo is very old and it was created even before the graph widget existed, so I assume that you are referring to another demo?

If you tell us which one we might be able to tell you who wrote the demo and what the trick was to get such amazing performance out of it.

~ Tectu

Link to comment
Share on other sites

Here you go, from naftilos76:

So, i was asked again the same question as far as the performance is concerned. With a little tweaking i was able to get more than 50 FPS. In order to be clear, i define FPS as the times per second that the waveform, grid lines and rulers are drawn. The thing is that the higher the frequency i count, the less the FPS due to the wider display area that needs to be drawn (filled with pixels). So 50 FPS may seem a lot which is actually true but the performance gets really downgraded if you fill the entire display area with the signal being measured (3-4 FPS).

So the code can be downloaded from the links inside the tutorial only if the domain naftilos76.net is substituted with the subdomain dso.naftilos76.com . To confirm my sayings, i am giving you the correct link for the tutorial file. All the other links in the tutorial will work if you substitute naftilos76.net with the subdomain dso.naftilos76.com .

http://dso.naftilos76.com/dl/tutorial.pdf (the tutorial in pdf format)

~ Tectu

Link to comment
Share on other sites

No, you don't have to increase the display count. All you have to do is enabling the pixmap in your configuration file by setting GDISP_NEED_PIXMAP to TRUE.

Note that there's currently a nasty bug/limitation that prevents you from using pixmaps when using the single-file-inclusion method. More information can be found here:

~ Tectu

Link to comment
Share on other sites

I'd recommend to write your own graph widget (it's actually a window, not a widget so it's even way simpler). That custom graph widget will contain a list of whatever it needs to keep track of. Then in the rendering routine you clear the area, draw your own axis, grid, labels and so on and then render your data on top of that.
This gives you maximum flexibility at the highest possible performance (from the GWIN point of view). For example, if you need a rolling-graph feature then you can have a push_back() function in your graph widget that will append a new point and shift all existing ones to the left. Possibilities are (nearly) endless :)

From the architecture point of view you should not care of rendering the widget internally itself first and then show the result at the end. That is what the GWIN and the GDISP module take care of. If you want to optimize this then Pixmaps are definitely the way to go.

Note that the single-file-inclusion mechanism is just a mechanism we provide for stating quickly. It has a couple of limitations such as the pixmaps and support for custom fonts that have not been resolved yet. It is ALWAYS possible not to use the single-file-inclusion and therefore being able to use the pixmap feature.

Link to comment
Share on other sites

So in the widget I would use gdispDraw instead of gwinDraw which I am using now inside a container. 

 

I need to stick with single file because using a makefile in Embitz I lose a lot of functionally since it spawns it as a external process. I keep thinking I should of used Eclipse but really like Embitz. 

 

Link to comment
Share on other sites

Yes that is correct. You never ever want to call gwinDrawXxx(), gwinFillXxx() or similar functions inside a GWIN rendering routine as that would cause the widget to be updated again and therefore creating an endless-loop.

If you are using EmBitz with a Makefile then just integrate uGFX into that makefile! uGFX comes with a built-in Makefile system. You just have to include the main makefile and add a variable to your sources and include path lists. That is explained here: http://wiki.ugfx.org/index.php/Getting_Started#Makefiles
And for a real-world example thake a look at the ChibiOS/RT example: http://wiki.ugfx.org/index.php/Using_ChibiOS/RT

Link to comment
Share on other sites

2 minutes ago, MobileWill said:

I meant that Embitz can use a Makefile but is it external to Embitz so you lose debugging and all the integration. It basically becomes a glorified notepad. 

I don't think that that is true. The last time I used EmBitz with Makefiles it worked like a charm - no issues debugging.
Note that the debugger just relies on parsing files. Makefile just controls how these files are built. Once all files are there the debugger is happy.

Link to comment
Share on other sites

I suppose I can try it again. I do believe you can't use the GUI to include files and has to be done in the Makefile and such. I remember it was a pain figuring all that out but I did have it working at one point. I think my issue was the file paths of the hex/elf files was different from the makefile vs compiling with the IDE. So the debugger couldn't load the hex/elf to the target. But right now I can't use the debugger with win10 because it only sees the stm32f411 and not the stm32429. THey haven't fixed the stlinkdbg. So when I need to debug I have to copy the project to a Win7 VM that works. There are weired issues in Win10 with the stlinkdbg. Anyways that's another subject. 

Link to comment
Share on other sites

It is because of the problems with stlinkdbg that we generally use openocd to debug. You will find the appropriate openocd.ini files in the various board project sample directories.

You pathing problems may also be caused by using cygwin programs. Cygwin is a great unix compatibility layer but it does some strange things to paths in order to make it as unix like as possible. Often the equivalent MINGW programs are better in a windows environment because they don't try quite so hard to be unix compatible but instead concentrate on functionality.

Our makefiles have a fair amount of code buried in them to handle cygwin strangeness.

Link to comment
Share on other sites

I couldn't get openocd working either. Oh well. Win7VM is it.

 

As for the flickering I changed my loop to only redraw the y at the x we are updating instead of the entire graph. Then I changed it again to only redraw the pixel of the last value and then draw the new line. Therefore I can use a bitmap for the graph and maintain performance.

Edited by MobileWill
Link to comment
Share on other sites

So I was able to try pixmaps in Eclipse and wow its fast. So much better. Took awhile to implement. I may have to rethink all my logic now that I have so much more flexibility. What I ended up doing is keeping the pixmap open and just update the graph in the pixmap and just write to the display once. Hope I don't run out of RAM later. 

Should be fast enough that the user won't notice the draw after the splash page is closed.

Only thing now that I am using Windows in an container is the list box doesn't work right. I have it hidden and then visible when a button was pressed. The list box parent is the that page so not tied to any of the other containers that are on top. The issue is I can't interact with it once its displayed on top of the container that has a window in it. 

Any ideas? It won't even scroll. Must be a conflict with the window or maybe the pixmap?

I just noticed you added option 2. That sounds like that could work very nicely. Hmm. Will it know to redraw if I update the pixmap or I just issue a redraw? The issue with the list box will probably still be there. 

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...