Software Circular Buffer in LabVIEW

Publish Date: Nov 30, 2018 | 15 Ratings | 3.33 out of 5 | Print | 1 Customer Review | Submit your review

Overview

A circular buffer is a data structure of a fixed size which operates as if its ends were connected together to form a ring. The circular buffer is a useful way to buffer data between two operations such as data acquisition and analysis. It allows you to decouple and parallelize different operations which would normally be used in a sequential manner. It is also useful in applications where operations using the same data set are happening at different intervals.

Table of Contents

Implementation

This software circular buffer is implemented in LabVIEW as a functional global variable.  Each instance of the circular buffer is a non-entrant VI which holds the data buffer in an uninitialized shift register.  The following datatypes are supported:

  • Waveform (single channel, multiple channels)
  • Waveform with Attributes (single channel, multiple channels)
  • EXT (1D, 2D)
  • DBL (1D, 2D)
  • SGL (1D, 2D)
  • I64 (1D, 2D)
  • U64 (1D, 2D)
  • I32 (1D, 2D)
  • U32 (1D, 2D)
  • I16 (1D, 2D)
  • U16 (1D, 2D)
  • I8 (1D, 2D)
  • U8 (1D, 2D)
  • Boolean (1D, 2D)
  • String (1D, 2D)

Use

As mentioned above, the circular buffer is implemented as a functional global variable.  There are five operations that the circular buffer supports.  They are Initialize, Get Backlog, Write, Read (continuous), and Read (most recent).  Below is a screenshot of the controls/indicators for the circular buffer:

To use the circular buffer, first the size of the buffer must be initialized.  The Initialize function allocates an array of the desired size for the circular buffer.  Once the circular buffer is initialized, data can be written to and read from it.  The read and write operations can happen in parallel.  

There are two different supported read modes: Read (continuous) and Read (most recent).  The Read (continuous) function always reads data out in the same order that it was written.  It reads out like a FIFO.  The Read (most recent) only returned the most recent data in the circular buffer.

The picture below illustrates the difference between these two types of reads.  In this case, there is a 1000 point circular buffer.  Data is written to it in 500 point blocks.  Both the Read (continuous) and Read (most recent) are reading 100 points at a time.  The read operation are happening more often than the write operation.

The Read (continuous) operates in a FIFO manner and moves the read pointer.  The Read (most recent) does not move the read pointer and is not concerned with buffer overflows.  Also, it could return the same data from the circular buffer in successive reads.

Applications

Data Acquisition Logging and Monitoring -

In this scenario, there is data that needs to be continuously acquired and logged without losing any data.  Occasionally, the user would like to monitor the signal to make sure everything is operating properly.  This monitoring could be visually with a graph of the time domain or a measurement such as RMS on a chart.  The acquisition and logging is a critical task while the monitoring is not.  

Inside the critical acquisition and logging loop, the data can be written to the circular buffer.  In a separate loop used for monitoring, the data can be read from the circular buffer using the Read (most recent) operation and graphed or analyzed.  The monitoring loop will be a lower priority loop which does not interfere with the execution of the acquisition and logging.  The rate at which the monitoring loop is executed can be varied such that a balance between the user interface and application performance is achieved.

Decoupling of Acquisition and Analysis Block Sizes -

In this scenario, data must be acquired and analyzed continuously.  The resolution of the analysis which is performed is dependent on the amount of data it is given (such as a FFT).  The optimal data acquisition block size is not always the same as the desired analysis block size.

The circular buffer allows the user to decouple the acquisition block size from the analysis block size.  This is not possible in a traditional acquisition to analysis flow.  Using two parallel loops, one for acquisition and one for analysis, the acquisition loop can write data to the circular buffer in one block size while the analysis loop reads data from the loop in a different block size.  During runtime, the user can change the analysis block size without needing to worry about effects on the acquisition loop.  If the analysis loop can't execute quickly enough, the circular buffer will overflow, but the user can continue to acquire data in the acquisition loop.

Download

Download the Software Circular Buffer component from here.

 

 

Back to Top

Customer Reviews
1 Review | Submit your review

Buffer Initialise 2x the initialized space. Not good on RT  - Oct 10, 2012

When you want use this library on RT and you want Initialise nearly whole RT memory this function is not working. Problem is that code combination, in Initialise Use Case, of Initialize Array and Shift register allocate 2x more memory. Initialise Array must be replaced by Reshape Array. For more information follow this discussion: http://forums.ni.com/t5/LabVIEW/Array-functional-global-uses-2x-the-initialized-space/td-p/923292 LabVIEW 2011 SP1 RT

Bookmark & Share


Ratings

Rate this document

Answered Your Question?
Yes No

Submit