weirddave

Oscilloscope style graph

14 posts in this topic

#1 ·  Posted

I'm looking at options for displaying some incoming data in graph form and I'm not sure where to start. The data will be continuously coming in at 100 or 1000 samples/second (TBD) so obviously the chosen method needs to be fast. I may want multple channels of data on the same graph too. The graph doesn't have to update after every sample (1000 FPS would be silly!)

I've taken a look at GDIPlus, the examples I found didn't seem very fast even after I removed the sleep()s

So, I guess the first piece of the puzzle is, should I use GUICtrlCreateGraphic() or GDIPlus?

Share this post


Link to post
Share on other sites



#2 ·  Posted

You don't seem to realize that an oscilloscope doesn't refresh the display at every sample.

Every sample gives a spot (visible dot) at a vertical position proportional to the sample value and at the current horizontal position. The X axis is a time base, with the current position function being a periodic sawtooth shape. During the blanking period, the display is wiped so that the next sweep is drawn anew.

To avoid starting the display at a random place of the input variation, a trigger value and direction (+ or - and possibly other conditions ensures that the successive sweeps start at the same input level and direction. The most common use of the device is to display essentially periodic input, but of course most advanced devices offer much more, depending on price.

But maybe you have something else in mind: an analog data recorder. A device which samples one or more input which may be completely random. Think of an audio recorder in this case.


This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Share this post


Link to post
Share on other sites

#3 ·  Posted

Obviously a scope can't update after every sample, 200MHz sampling rate is pretty common these days... (I use them all the time). 

Is wiping the display and redrawing it the best method in AutoIT though? I haven't seen anything which looks like I can double buffer and swap on Vsync.
One of the GDIPlus examples I found effectively copy/pasted the graphics left a bit then drew the new bit, but it was slow, possibly it was waiting for VSync between each draw. I'm not familiar with any of the AutoIT graphics capabilities yet (this was so easy to do on the Amiga 68000 in asm...)

So really, I'm just trying to find the right path into it.

A bit more info, which may shed some light on what I might be doing... ;)
I have lots of analogue (16 bit) and digital signals coming in via Ethernet, I want to push some of the signals to a 'scope' display. Passing the data to the display function should be easy. Scaling should also be quite easy, it's just a bunch of maths :)

So what I'm asking really, is what approach should I take?

Share this post


Link to post
Share on other sites

#4 ·  Posted

OK, I see you already know what a scope is.

It's still unclear whether you want a traditional scope display (next sweep triggered by some channel and triggering conditions) or you prefer a continuous display like you see on medical heart monitors for instance, where the input(s) are not subject to triggering, the previous trace(s) being erased on the fly. The later display is well suited to low frequency signals while the former is typical for high frequency inputs.

Say 1024 samples/s and a 1024 pixel large window to simplify things. Your refresh rate would be based on a 1s sweep, plus triggering which may delay the next trace until the triggering conditions are met, if any.

At this low rate you may want to try drawing and saving a blank display with reticule, scales and other fix information. This will be redisplayed before every sweep, about 1 time per second. Once triggered by relevant conditions, each trace would be added one pixel at vertical possition determined by trace number, color and scale.

I'm not much GDI-literate but that doesn't seem too much for a decent hardware.


This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Share this post


Link to post
Share on other sites

#5 ·  Posted


Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Share this post


Link to post
Share on other sites

#6 ·  Posted

Ha, @UEZ thanks for your help at this point!

 


This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Share this post


Link to post
Share on other sites

#7 ·  Posted

@jchd u r welcome ^^

 


Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Share this post


Link to post
Share on other sites

#8 ·  Posted

Since I repair, refurbish and recalibrate Tektronix oscillosopes like this one for a living, I've a good knowledge on the subject but I'm much less fluent in GDI, GDI+, GDI++, ...


This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Share this post


Link to post
Share on other sites

#9 ·  Posted

2 minutes ago, jchd said:

Since I repair, refurbish and recalibrate Tektronix oscillosopes like this one for a living, I've a good knowledge on the subject but I'm much less fluent in GDI, GDI+, GDI++, ...

Then it's time to start with learning GDI, GDI+, GDI++, GDI+²... :)


Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Share this post


Link to post
Share on other sites

#10 ·  Posted

I never liked Tek scopes, LeCroy all the way :D

I don't need any scope functionality at all, I'll be quite happy just having wavy lines, no triggering, just display whatever is happening. I have the capability to save all the data as a csv file for later viewing, this is just a facility to see what's happening live, I have numbers and 0/1 for the digitals on an autoit screen already, but for some of the analogue signals it's convenient to have a live graph rather than just rapidly changing numbers.

The multigraph looks amazing, much more than I need. My German sucks, as does the google translation of the page :(
I shall take a closer look in the morning when my head is clearer. Ran the purebasic exe's and they seem quite fast, shall test autoit versions when I'm back on my own PC :)
 

Share this post


Link to post
Share on other sites

#11 ·  Posted

Just the AutoIt examples are pretty amazing. Very nice find!


This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Share this post


Link to post
Share on other sites

#12 ·  Posted

I've tried to create a scrolling graph, I have essentially copied the code for the 2nd graph in the first example. Problem is, it's not running at anything like the speed of the example. Any idea what might be slowing it down?

#include "MultiGraph.au3"

$hGUI = GUICreate("", 1000, 1000)
Opt("GUIOnEventMode", 1)
GUISetOnEvent($GUI_EVENT_CLOSE, "_Exit", $hGUI)
GUISetState()

;ID, gui handle, x, y, width, height
_MG_Graph_erstellen (1, $hGUI, 50, 50, 900, 900)
;ID, X-axis samples, min val, max val, background colour, antialiasing
_MG_Graph_optionen_allgemein (1, 900, 0, 65535, 0x303030, 0)
;ID, mode (0-1), samples per plot, clearing mode(0-2), Interpolation
_MG_Graph_optionen_Plottmodus           (1, 1, 1, 1, False)
;ID, Activate frame, Frame Colour, Frame Width
_MG_Graph_optionen_Rahmen               (1, False, 0x000000, 1)
;_MG_Graph_optionen_Rahmen              (1, True, 0x000000, 1)
;ID, Main Gridlines, X Gridline spacing, Y Gridline spacing, Grid thickness, Grid Colour, Grid Transparency (0-255)
_MG_Graph_optionen_Hauptgitterlinien    (1, True, 50, 50, 1,0x000000, 190)
;ID, Minor Gridlines, X Gridline spacing, Y Gridline spacing, Grid thickness, Grid Colour, Grid Transparency (0-255)
_MG_Graph_optionen_Hilfsgitterlinien    (1, True, 10, 10, 1,0x000000, 220)
;ID, Left Y-Axis, min val, max val, decimal places, units, Text Colour, Background colour (or Default), font size, label width, label every'n' main gridline
_MG_Graph_Achse_links                   (1, True,  0, 65535, 0, "", 0x000000, Default, 9, 50, 1)
;ID, Right Y-Axis, min val, max val, decimal places, units, Text Colour, Background colour (or Default), font size, label width, label every'n' main gridline
_MG_Graph_Achse_rechts                  (1, True, -100, 100,   1, "", 0x000000, Default, 9, 50, 1)
;ID, Bottom X-Axis, min val, max val, decimal places, units, Text Colour, Background colour (or Default), font size, label width, label every'n' main gridline
_MG_Graph_Achse_unten                   (1, True,  900, 0, 0, "", 0x000000, Default, 9, 50, 1)
;ID, Channel Index, Active, Plot Thickness, Plot Colour, Transparency
_MG_Kanal_optionen                      (1, 1, True, 1, 0x0044FF, 0)
_MG_Kanal_optionen                      (1, 2, True, 1, 0xFF6600, 0)
;Plot the graph, ID
_MG_Graph_initialisieren (1)

$counter = 0

While 1

    if $counter = 65535 then
        $counter = 0
    else
        $counter += 1
    endif
    ;ID, Channel index, Next Value
    ;_MG_Wert_setzen (1, 1, random(0,65535))
    _MG_Wert_setzen (1, 1, $counter)
    ;_MG_Wert_setzen (1, 2, random(0,65535))
    _MG_Graph_plotten (1)                               ; Graph 1 plotten
wend


Func _Exit()
    Exit
EndFunc

 

Share this post


Link to post
Share on other sites

#13 ·  Posted

I added a Sample frequency counter (stolen from example 3) and get 120 updates/S, if I reduce the graph height to 100, I get around 1100 . If I make the graph twice as wide it drops to 60.

A bit of playing with example 3 shows that when I set the zoom to 1 (Auflosung 608 for me), plotfrequenz to 1, I get 336.

So it seems that the area of the graph is the top problem with regards to speed. Given that I may want the graph quite large, it looks like I will have to look at other methods :(

Share this post


Link to post
Share on other sites

#14 ·  Posted

Well, I've had a play with GUICtrlCreateGraphic() and its family, I've seen ants swim the channel quicker....

So, I've started looking at C++ and LibSDL.org, it's not the route I want to go because I love the generally easy nature of AutoIT, but I have generated a very basic non-optimised rolling graph which is scrolling at an insane speed, which makes sense since I was able to do this on 30 year old hardware with ease (admittedly at a lower resolution and I had to use either asm or a decent compiler). It's a complete clear/redraw affair (not even circling the buffer to save 1799 memory moves [~2us?], I went straight for the big graph).

I just added a 2nd channel of data and it's  still insane.
I've included my experimental code in case anyone stumbles upon this thread (yes, I'be broken a few coding laws). I used Dev C++ 'cos it's free :)

#include <SDL.h>
#include <iostream>
#include <stdlib.h>

const int SCREEN_WIDTH = 2000;
const int SCREEN_HEIGHT = 1000;
const int GRAPH_WIDTH = SCREEN_WIDTH-100;
const int GRAPH_HEIGHT = 900;
SDL_Point Channel1_Data[GRAPH_WIDTH];
SDL_Point Channel2_Data[GRAPH_WIDTH];

int main( int argc, char* args[] )
{   
    for(int i=0;i<GRAPH_WIDTH;i++)
    {
        Channel1_Data[i].x = i+50;
        Channel1_Data[i].y = GRAPH_HEIGHT/2+50;
        Channel2_Data[i].x = i+50;
        Channel2_Data[i].y = GRAPH_HEIGHT/2+50;
    }
    if (SDL_Init(SDL_INIT_VIDEO) == 0) {
        SDL_Window* window = NULL;
        SDL_Renderer* renderer = NULL;
        if (SDL_CreateWindowAndRenderer(SCREEN_WIDTH, SCREEN_HEIGHT, 0, &window, &renderer) == 0) {
            SDL_bool done = SDL_FALSE;
            while (!done) {
                SDL_Event event;
                SDL_SetRenderDrawColor(renderer, 0, 0, 0, SDL_ALPHA_OPAQUE);
                SDL_RenderClear(renderer);
                SDL_SetRenderDrawColor(renderer, 255, 255, 255, SDL_ALPHA_OPAQUE);
                SDL_RenderDrawLines(renderer, Channel1_Data, GRAPH_WIDTH);
                SDL_SetRenderDrawColor(renderer, 255, 0, 0, SDL_ALPHA_OPAQUE);
                SDL_RenderDrawLines(renderer, Channel2_Data, GRAPH_WIDTH);
                SDL_RenderPresent(renderer);
                while (SDL_PollEvent(&event)) {
                    if (event.type == SDL_QUIT) {
                        done = SDL_TRUE;
                    }
                }
                for(int i=0;i<GRAPH_WIDTH-1;i++)
                {
                    Channel1_Data[i].y = Channel1_Data[i+1].y;
                    Channel2_Data[i].y = Channel2_Data[i+1].y;
                }
                Channel1_Data[GRAPH_WIDTH-1].y = rand() % GRAPH_HEIGHT+50;
                Channel2_Data[GRAPH_WIDTH-1].y = rand() % GRAPH_HEIGHT+50;
            }
        }

        if (renderer) {
            SDL_DestroyRenderer(renderer);
        }
        if (window) {
            SDL_DestroyWindow(window);
        }
    }
    SDL_Quit();

    return 0;

 

Share this post


Link to post
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