views:

459

answers:

6

I'm going to write a program that plots data from a sensor connected to the computer. The sensor value is going to be plotted as a function of the time (sensor value on the y-axis, time on the x-axis). I want to be able to add new values to the plot in real time. What would be best to do this with in C++?

Edit: And by the way, the program will be running on a Linux machine

A: 

Write a function that can plot a std::deque in a way you like, then .push_back() values from the sensor onto the queue as they come available, and .pop_front() values from the queue if it becomes too long for nice plotting.

The exact nature of your plotting function depends on your platform, needs, sense of esthetics, etc.

jilles de wit
That looks promising. I'll have a look at it. Thanks!
Paul
You can't iterate over a `std::queue`, so you'd probably want to use `std::deque` directly instead; you can still `push_back` and `pop_front` with a deque.
James McNellis
that is a very good point, I'll update my answer.
jilles de wit
A: 

You can use ring buffers. In such buffer you have read position and write position. This way one thread can write to buffer and other read and plot a graph. For efficiency you usually end up writing your own framework.

Size of such buffer can be estimated using eg.: data delivery speed from sensor (40KHz?), size of one probe and time span you would like to keep for plotting purposes.

It also depends whether you would like to store such data uncompressed, store rendered plot - all for further offline analysis. In non-RTOS environment your "real-time" depends on processing speed: how fast you can retrieve/store/process and plot data. Usually it is near-real time efficiency.

Marcin Gil
A: 

I did a similar thing for a device that had a permeability sensor attached via RS232.

  • package bytes received from sensor into packets
  • use a collection (mainly a list) to store them
  • prevent the collection to go over a fixed size by trashing least recent values before new ones arrive
  • find a suitable graphics library to draw with (maybe SDL if you wanna keep it easy and cross-platform), but this choice depends on what kind of graph you need (ncurses may be enough)
  • last but not least: since you are using a sensor I suppose your approach will be multi-threaded so think about it and use a synchronized collection or a collection that allows adding values when other threads are retrieving them (so forgot iterators, maybe an array is enough)

Btw I think there are so many libraries, just search for them:

Jack
A: 

I assume that you will deploy this application on a RTOS. But, what will be the data rate and what are real-time requirements! Therefore, as written above, a simple solution may be more than enough. But, if you have hard-real time constraints everything changes drastically. A multi-threaded design with data pipes may solve your real-time problems.

baris_a
+1  A: 

Are you particularly concerned about the C++ aspect? I've done 10Hz or so rate data without breaking a sweat by putting gnuplot into a read/plot/refresh loop or with LiveGraph with no issues.

Digikata
+1  A: 

You might want to check out RRDtool to see whether it meets your requirements.

RRDtool is a high performance data logging and graphing system for time series data.

Dave Bacher