PiZero W connected to two peripherals (GPIO and USB): how to continuously read from both at same time?

Another, perhaps simpler option might be to use Redis. Redis is a very high performance, in-memory data-structure server. It is simple to install on a Raspberry Pi, Mac, Linux Windows or other machine. It allows you to share atomic integers, strings, lists, hashes, queues, sets and ordered sets between any number of clients across a network.

So the concept might be to have a separate program monitoring the flowmeter and stuffing the current reading into Redis as often as you like. Then another separate program reading barcodes and stuffing them into Redis as often as you like. And finally, have a control program, potentially somewhere else altogether on your network that can grab both the values as often as it likes.

Note you could run the Redis server on your Raspberry Pi or any other machine.

So, here is the flowmeter program – just change host to the IP address of machine running Redis:

#!/usr/bin/env python3

import redis
import time

host="localhost"
port=6379

# Connect to Redis
r = redis.Redis(host,port)

reading = 0
while True:
   # Generate synthetic reading that just increases every 500ms
   reading +=1 
   # Stuff reading into Redis as "fmReading"
   r.set("fmReading",reading)
   time.sleep(0.5)

Here is the barcode reading program:

#!/usr/bin/env python3

import redis
import time
from random import random, seed

host="localhost"
port=6379

# Connect to local Redis server
r = redis.Redis(host,port)

# Generate repeatable random numbers
seed(42)

while True:
   # Synthesize barcode and change every 2 seconds
   barcode = "BC" + str(int((random()*1000)))
   # Stuff barcode into Redis as "barcode"
   r.set("barcode",barcode)
   time.sleep(2)

And here is the master control program:

#!/usr/bin/env python3

import redis
import time

host="localhost"
port=6379

# Connect to Redis server
r = redis.Redis(host,port)

while True:
   # Grab latest flowmeter reading and barcode
   fmReading = r.get("fmReading")
   barcode   = r.get("barcode")
   print(f"Main: fmReading={fmReading}, barcode={barcode}")
   time.sleep(1)

Sample Output

Main: fmReading=b'10', barcode=b'BC676'
Main: fmReading=b'12', barcode=b'BC892'
Main: fmReading=b'14', barcode=b'BC892'
Main: fmReading=b'16', barcode=b'BC86'
Main: fmReading=b'18', barcode=b'BC86'
Main: fmReading=b'20', barcode=b'BC421'
Main: fmReading=b'22', barcode=b'BC421'
Main: fmReading=b'24', barcode=b'BC29'

Note that in order to debug this, you can also grab any readings using the command-line interface to Redis from any machine on your network, e.g. in Terminal:

redis-cli get barcode
"BC775"

If you wanted to show the values in a Web-browser written in PHP, you can use the PHP bindings to Redis to get the values too – very convenient!

Of course, you can adjust the program to send the timestamps of the readings with each one – possibly by using a Redis hash rather than a simple key. You could also implement a queue to send messages between program using Redis LPUSH and BRPOP.

Keywords: Redis, list, queue, hash, Raspberry Pi

Leave a Comment