DMC, Inc.

How to Use Raspberry Pi as a DAQ Device in LabVIEW

LabVIEW simplifies the process of quickly acquiring data from hardware and processing it into an output for application users. Compared to text-based programming languages, LabVIEW’s treatment of data flow as code makes tasks like parallel processing and hardware resource management much simpler. This is especially true when using hardware created by the group behind it, National Instruments. Their DAQ (data acquisition) devices are designed for ease of use in the LabVIEW programming environment and can be configured and used in code to effectively replace typical workbench equipment.

There are, of course, other types of hardware that someone might want to acquire data from. Our clients often need us to integrate all kinds of equipment based on their technical and budget needs from a specialized hipot meter to a general-purpose DMM. One such client needed us to integrate a Raspberry Pi, which was collecting data from a set of sensors, with a LabVIEW app that was already collecting data from NI hardware.

Raspberry Pis are pretty popular among hobbyists and hardware engineers alike for prototyping and actual production use since they’re inexpensive, fairly robust, and have a broad ecosystem of products that work nicely with them. Their GPIO (General Purpose Input/Output) pins make it easy to interface with hardware over different low-level protocols like SPI or I2C. The boards also come with WiFi, Bluetooth, Ethernet, and USB if you need to connect to something over a higher-level interface. This brings us to the question of how to use a Raspberry Pi in a way that is fast and reliable from a LabVIEW application running on a separate PC—effectively using it as a DAQ device.

The Easy Way: FastAPI

Let’s begin with a simple approach—we can set up a minimal REST API service on the Raspberry Pi using FastAPI that, when queried, creates and returns your measurement.

Setting Up the API

FastAPI is a modern Python web framework that makes it simple to create REST APIs. On your Raspberry Pi, you can install it along with a production server like uvicorn:

pip install fastapi uvicorn

Then create a simple API endpoint that reads from your sensor:

Python
from fastapi import FastAPI
import time

app = FastAPI()

@app.get("/sensor/read")
def read_sensor():
    # Your sensor reading code here
    # For example, reading from an I2C device
    value = read_i2c_sensor()
    timestamp = time.time()

    return {
        "value": value,
        "timestamp": timestamp
    }

if __name__ == "__main__":
    import uvicorn
    uvicorn.run(app, host="0.0.0.0", port=8000)

From LabVIEW, you can use the HTTP Client VIs to make GET requests to <http://your-pi-ip:8000/sensor/read> and parse the JSON response to extract your sensor data.

LabVIEW block diagram performing an HTTP GET request to a Raspberry Pi, parsing JSON sensor data, timestamping results, and processing output with built-in error handling.

The Issues

While this approach is straightforward and gets you up and running quickly, it has some significant limitations for serious data acquisition:

Not Truly Time-Series: Each request creates a new measurement on demand. If you’re trying to capture a continuous stream of data, you’ll miss all the samples between requests. This is fine for slow-changing values like temperature readings every few seconds, but inadequate for high-speed data acquisition.

Request Overhead: Every HTTP request involves substantial overhead, TCP handshaking, HTTP headers, JSON serialization/deserialization, and network latency. If you need to sample at high rates (say, 1000 samples per second), making 1000 individual HTTP requests per second is inefficient and will likely introduce timing jitter and missed samples.

For applications where you need occasional readings or the data changes slowly, this approach works great. But for continuous, high-speed data acquisition, we need something better.

The High-Speed Way: Redis Streams

Redis is an in-memory data structure store that’s fast and supports various data types, including streams – perfect for time-series data collection. The architecture here is more sophisticated but provides much better performance:

In production, you may implement the sensor loop in C or another lower-level language for tighter timing, but Python is a good way to understand and prototype the architecture.

  1. A Python process on the Raspberry Pi continuously reads sensors and writes to a Redis stream.
  2. Redis stores the data in memory as a time-ordered stream.
  3. LabVIEW periodically reads from the stream, getting batches of new data.
  4. Webdis provides an HTTP interface to Redis, making it accessible from LabVIEW.

Setting Up Redis

First, install Redis on your Raspberry Pi:

sudo apt-get install redis-server

Install the Python Redis client as well:

pip install redis

Configure Redis to start on boot and ensure it’s listening on the network if your LabVIEW application is on a different machine:

sudo systemctl enable redis-server
sudo systemctl start redis-server

The Data Collection Process

Create a Python script that continuously reads your sensors and writes to a Redis stream:

Python
import time
import json
import redis

r = redis.Redis(host='localhost', port=6379, decode_responses=True)

def collect_data():
    interval = 0.001  # 1ms = 1000 Hz sampling
    cycle_time = time.time()
    while True:

        # Read your sensor
        sensor_value = read_i2c_sensor()

        # Add to Redis stream
        r.xadd('sensor_stream', {
            'value': sensor_value,
            'timestamp': cycle_time
        })

        # Delay enough to start next loop at the interval rate
        time_to_next_cycle = cycle_time + interval - time.time()
        sleep_time = max(0, time_to_next_cycle)
        time.sleep(sleep_time)
        cycle_time += interval

if __name__ == "__main__":
    collect_data()

This process runs independently, continuously writing data to the stream regardless of whether anyone is reading it. Redis handles the buffering and ensures data isn’t lost.

Accessing Redis from LabVIEW with Webdis

Webdis is a simple web server that provides an HTTP interface to Redis. Install it on your Raspberry Pi:

git clone https://github.com/nicolasff/webdis.git
cd webdis
make
./webdis &

Now you can access Redis commands via HTTP. From LabVIEW, you can read from the stream using the HTTP Client VIs to make requests like:

http://your-pi-ip:7379/XREAD/COUNT/<count>/STREAMS/sensor_stream/$

The $ special ID means “only entries added after this request begins” – it’s useful for your initial read when you want to ignore old buffered samples and start with future data. For subsequent reads to get all new data since your last read, you’ll need to use the actual stream ID you received from the previous read instead of $.

The <count> value represents the maximum number of entries to return. Based on your sample rate and how often you want to read buffered data from the device, you will want to modify this value to keep up with data production on the Raspberry Pi.

LabVIEW Implementation

In your LabVIEW VI:

  1. Store the last stream ID you read (starting with “$”).
  2. Periodically poll the stream using XREAD with your last ID.
  3. Parse the JSON response to extract the sensor values.
  4. Update your last stream ID for the next request.
  5. Process the batch of samples.
LabVIEW block diagram showing an HTTP GET request to a Raspberry Pi, with JSON parsing and a loop for processing response data, including error handling clusters.

This approach dramatically reduces overhead; instead of 1000 requests per second for 1000 samples, you might make 10 requests per second and get 100 samples each time.

Advantages

  • Continuous Collection: The Python process collects data continuously without gaps.
  • Buffering: Redis buffers recent data in memory, so if LabVIEW is briefly busy, samples remain available.
  • Batch Processing: LabVIEW can read multiple samples per request, reducing overhead.

Adding Time Synchronization

When combining data from multiple sources (like your NI DAQ and Raspberry Pi), timestamp synchronization becomes critical. The Raspberry Pi’s clock and your Windows PC’s clock will drift apart over time, making it difficult to properly align and correlate data.

There are several approaches to tackle this problem:

Measuring Clock Offset: Create a calibration routine in which LabVIEW requests the current time from the Pi and measures the round-trip time to calculate the clock offset. Apply this offset to align timestamps. Keep in mind that different hardware clocks will experience drift and you will need to regularly re-calibrate to account for this.

Network Time Protocol (NTP): Configure both systems to sync with the same NTP server. This gets you in the ballpark but won’t give you perfect alignment due to network delays and update intervals.

Conclusion

Integrating a Raspberry Pi as a data acquisition device in your LabVIEW application enables cost-effective, flexible hardware integration. Your chosen approach depends on your requirements.

For our client’s application, we used the Redis approach with time synchronization to integrate their Raspberry Pi sensors with their LabVIEW system, achieving reliable 1 kHz data collection aligned with their NI DAQ data.

Have an upcoming project? DMC can help you take the next step.

Whether integrating Raspberry Pis, NI DAQs, mixed or specialized hardware, DMC can help build robust test and measurement systems.