Driving Matrix Orbital LCD Displays with Python

Admittedly, this post is even more “techie” than my last one on hardware RNGs. I feel compelled to deliver the same public service announcement: If learning how to use python to drive a Matrix Orbital display is not your cup of tea, this might be a hard pass. Otherwise, read on if you’re technically curious. If I can save one person hours of work, then the effort was well worth it.

I’m a big fan of the Matrix Orbital VK204-25 LCD module and have used it in a bunch of projects. It’s an older device, but you can’t beat how good the throwback vacuum fluorescent display looks when you want a retro type aesthetic.

A new module can be expensive, however, you can find older ones relatively cheap on eBay if you keep your eyes open.

The older boards communicated over either I2C or RS232. I prefer using I2C as my projects typically use Raspberry Pis, and the GPIO includes native support. I’m not going to spend any time here on how to connect the module to a Pi as Adafruit has a wonderful in-depth tutorial on interfacing Pis with I2C components.

When I first started using these displays I was surprised (and frustrated) that there were limited python libraries available for driving the display over I2C. I eventually decided to hack together my own since the command structure is well documented and easy to implement with python’s smbus module. You can find my code here.

Usage is straight forward. Characters to display on the LCD are chosen by using the correct binary or hex value. The Matrix Orbital documentation includes a matrix that maps each ASCII character to the appropriate hex code.

The script takes a single word as input, iterates over each character in the word to find the corresponding hex value and then sends the display command using the board’s bus address.

In addition to the character mappings, the script includes a few basic commands that can turn the display on or off or clear any text.

Here are a few usage examples. First, turning on the display:

orbitalWrite.on_display(busAddr)

busAddr is the I2C address for the board. You can determine this on a Raspberry Pi by using the i2cdetect command as discussed here. If my board was addressed using 0x28 I would issue the following:

orbitalWrite.on_display(0x28)

Here the script will use the busAddr, send 0xFE (a code prefix that indicates a control command is being issued), and then send the hex value for the command itself. In the above case 0x42, which means turn on the display.

Here’s how to write single or multiple words to the display:

orbitalWrite.write_display(busAddr,wordDisp)

busAddr is the board I2C address and wordDisp is the word to display. For example:

orbitalWrite.write_display(0x28,some words here)

Behind the scenes, the script will iterate through each letter (including spaces) and send each character individually to the display.

Just for fun, I included a timer as part of the character display function so that there’s a slight pause of random length before writing. The effect is like an old style typewriter.

That’s it! If you have a Matrix Orbital display and use my code, drop me a line and let me know about your project.

Getting Random with REST

Public service announcement: This is going to be a “techie” post.

If interfacing with hardware random number generators via REST API is not your thing, you might want to pass on this one.

Over the years, I’ve built a number of devices that investigate the influence of intention on random events. These will undoubtedly be topics for future posts, but suffice to say, all required the use of a hardware based random number generator.

I’ve tried several different hardware RNGs, and have even built my own, but the two I like the best are the OneRNG and TrueRNG devices pictured to the right.

OneRNG Hardware Random Number Generator
TrueRNG Hardware Random Number Generator

They both work well with linux and SBCs like a RaspberryPi or BeagleBone. They also both use an avalanche effect from a diode circuit to generate the random noise. The data fills the entropy pool of the operating system and can be accessed (in linux) via /dev/random or /dev/urandom.

I haven’t done any analysis to see which has a higher bit rate, but both are sufficient for my purposes. I would give OneRNG a slight edge in that the hardware and software are open and fully published. Also, I find the onboard LED highly convenient as it can be used to test whether it’s operating properly. Otherwise, there’s no easy way to verify you’re getting output from the hardware versus the OS pseudo-random number generator.

RNG server using OneRNG in the Enigmatic lab

Both have thorough documentation on how to set up on a linux based system, but where I found info scarce is how to query the device to get a random number in the format that I wanted. Output is a stream of binary data by default, but for my purposes I need string representations of integers and floats.

After much Googling, I put together a solid setup for returning an integer within a set range (like between 1-100) and a float between 0 and 1. I wanted to share as a time saver for anyone interested.

Here’s the command I run from the linux CLI to get an integer within a range of 100 and 1000:

echo $(( 100+(`od -An -N2 -i /dev/random` )%(1000-100+1)))
decker@sonoya:~/scripts# echo $(( 100+(`od -An -N2 -i /dev/random` )%(1000-100+1)))
312

To change the range, substitute the two ‘100’ occurrences with a value for the low end and substitute ‘1000’ for the high end.

Here’s the code to get a single float value between 0 and 1:

(printf '%.19f\n' "0x0.$(od -N 8 -An -tx1 /dev/random | tr -d ' ')")
decker@sonoya:~/scripts# (printf '%.19f\n' "0x0.$(od -N 8 -An -tx1 /dev/random | tr -d ' ')")
0.6726632392320606169

Both these commands are useful in a quick linux shell script, but I also needed a more flexible way to get random numbers from different programing languages and from remote hosts.

Python Flask to the rescue! Flask is useful to setup quick python server with REST endpoints, perfect for my use case.

Before I share my code, a warning or two:

First, I’m not a programmer. I hack together quick scripts to get what I need done, there are probably (definitely) more elegant ways to accomplish this. Second, I’m running my flask server as root and using python to call a shell script that executes OS commands. Don’t do this in a production or public facing environment!

You can find the code at my github repository below. You will need to install flask prior to running.

https://github.com/deckerEnigmatic/rngRESTServer/tree/master

When you run the script you should see output like the below. This will create a server running on the local machine using TCP port 5000.

root@sonoya:~/scripts/rngrestserver# ./rngrestserver.py
 * Serving Flask app "rngrestserver" (lazy loading)
 * Environment: production
   WARNING: This is a development server. Do not use it in a production deployment.
   Use a production WSGI server instead.
 * Debug mode: off
 * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)

I have this running on a Raspberry Pi in my lab and use it to serve random numbers to remote hosts. A remote client can request a random number by hitting the correct REST endpoint with the appropriate parameters. Here’s the usage below:

Endpoint to request a random number within a range:

http://192.168.1.133:5000/rangeInt/1/100

Output is JSON key value pair. In this case a single integer between 1 and 100.

http://192.168.1.133:5000/rangeFloat

Output is a JSON key value pair returning a float.

If you work with hardware based RNGs I hope you found this post helpful. I spent some “quality” time learning cryptic shell commands to get the output in the format I needed. If you use any of my code, reach out and let me know!

Pareidolia in Practice. Avoiding the Pitfalls of Patterning with EVPs

Sitting in the woods attempting to record spirit voices with a home-made Raudive diode detector got me thinking a lot about pareidolia.

For those who might not know, pareidolia represents how we as humans are hard-wired to find patterns in randomness – things that are familiar, like faces in trees or rock formations.

It turns out that this “patterning” is an evolutionary advantage – helps us quickly identify potential predators hiding in the bushes, and why we can’t just shut it off.

And it’s not just limited to visual stimuli, you can find plenty of audio and tactile examples as well. Hearing spirit voices when listening to electronic voice phenomena (EVP) recordings is a mainstay of paranormal TV shows.

Konstantin Raudive, one of the early pioneers of EVP (he called it instrumental trans-communication) had a set of “guidelines” to help extract the elusive spirits recorded on his hardware. These are all from his book “Breakthrough: An Amazing Experiment in Electronic Communication with the Dead“:

  • The voice-entities speak very rapidly, in a mixture of languages, sometimes as many as five or six in one sentence
  • They speak in a definite rhythm, which seems to be forced upon them by the means of communication they employ
  • The rhythmic mode of speech imposes a shortened, telegram-style phrase or sentence
  • Presumably arising from these restrictions, grammatical rules are frequently abandoned and neologisms abound
The Viking 1 “Face on Mars” image of the Cydonian mesa. NASA/JPL
Ghost Adventures: Guess that EVP
Konstantin Raudive

In addition, he describes techniques such as varying the speed of the playback, re-recording the output over and over, and setting the mics to the highest possible input levels.

Clearly, all of the shenanigans with the audio processing and interpretation leave a lot of room for finding meaning in anything captured.

Raudive was no doubt an intellectual. He was a student of Carl Jung, a trained psychologist and a writer. I respect the fact that he dedicated his life to the study of EVP. He must of strongly believed something was there or he wouldn’t have dedicated so much time and energy studying the topic over the course of his life.

However, even an intellect can fall victim to what notorious skeptic, Michael Shermer describes as an “error in cognition” when it comes to pareidolia. We are simply hard-wired to find meaningful patterns in meaningless noise. In statistics, this would be considered a Type I error – the false identification of patterns in data. There’s also the problem of confirmation bias – if you’re an EVP proponent, you’re going to expect to hear something.

Some obvious EVP pareidolia pitfalls can be easily avoided. First, avoid the temptation to process the recordings. Analyze the raw data. While researching examples of audio captured with diode detectors, frustratingly I found very few cases that weren’t run through some type of processing filter (such as Audacity’s voice isolation effect). With enough post-processing you can make audio sound like anything you’d like.

Second, take steps to avoid confirmation bias. Have people listen to recordings and ask them what they hear without first sharing what you’ve heard. Get a wide set of opinions. Unfortunately, leading the witness with “I heard this, do you hear it too?” is a staple of most ghost hunting TV programming.

The fundamental question is whether EVP even exists. One empirical study concluded that the evidence presented did not provide a definitive answer and found psychological causes more fitting. For me the jury is out.

What are your thoughts about EVP? Drop me a line and let me know your EVP experiences or opinions.