Wolfram Blog
Brett Haines

Using the Sense HAT on a Raspberry Pi with Mathematica 11

April 27, 2017 — Brett Haines, Junior Release Engineer

Raspberry Pi with Sense HAT

Ever since the partnership between the Raspberry Pi Foundation and Wolfram Research began, people have been excited to discover—and are often surprised by—the power and ease of using the Wolfram Language on a Raspberry Pi. The Wolfram Language’s utility is expanded even more with the addition of the Sense HAT, a module that gives the Raspberry Pi access to an LED array and a collection of environmental and movement sensors. This gives users the ability to read in data from the physical world and display or manipulate it in the Wolfram Language with simple, one-line functions. With the release of Mathematica 11, I’ve been working hard to refine functions that connect to the Sense HAT, allowing Mathematica to communicate directly with the device.

The Sense HAT functionality is built on Wolfram’s Device Driver Framework, so connecting to the device is incredibly simple. To start, use the DeviceOpen function to establish a connection. This will return a DeviceObject, which we will use later to tell Mathematica which device we are wanting to read from or write to.

hat = DeviceOpen["SenseHAT"]

In the case of the Sense HAT, there are three onboard sensors that Mathematica can read from. Accessing the data from these sensors is as easy as calling DeviceRead with the name of the measurement wanted. For instance:

temp = DeviceRead[hat, "Temperature"] hum = DeviceRead[hat, "Humidity"]

temp = DeviceRead[hat, "Temperature"]

hum = DeviceRead[hat, "Humidity"]

There are a total of seven measurements that can be read from the Sense HAT: temperature, humidity, air pressure, acceleration, rotation, magnetic field and orientation. All readings are returned with appropriate units, making it easy to convert the values to other formats if necessary.

accel = DeviceRead[hat, "Acceleration"] accelSI = UnitConvert[accel, "Meters"/"Seconds"^2]

accel = DeviceRead[hat, "Acceleration"]

accelSI = UnitConvert[accel, "Meters"/"Seconds"^2]

The other physical component of the Sense HAT is the 8-by-8 LED array. Similar to reading data with DeviceRead, it is only a matter of calling the DeviceWrite function to send either an image or a string to the array. For strings, the text scrolls across the device sideways. You can manipulate the speed and color of the scrolling text with relevant options as well.

DeviceWrite[hat, "Hello, world!"]

DeviceWrite[hat, {"Now in color!", "ScrollSpeed" \[RightArrow] 0.25,    "Color" \[RightArrow] {255, 0, 128}}]

Alternatively, the Sense HAT can receive an 8-by-8 list of RGB values to be displayed on the LED array. Using this method, it’s possible to display small images on the screen of the Sense HAT.

Sense HAT on Raspberry Pi--color LED array list

DeviceWrite[hat, list];

Here is a picture of what this looks like when written to a Sense HAT:

Sense HAT on Raspberry P--color LED array

Using these functions, you can write Mathematica programs that process the data received from the sensors on the Sense HAT. For example, here is a demo I ran at the Wolfram Technology Conference in October 2016. It reads the temperature, humidity and air pressure around the Pi every five minutes and pushes that data to the Wolfram Data Drop.

db = CreateDatabin[]

SaveReadingToDataDrop[    bin_Databin] := (Module[{dev, hum, temp, pres},      dev = DeviceOpen["SenseHAT"];     temp = DeviceRead[dev, "Temperature"];     pres = DeviceRead[dev, "Pressure"];     hum = DeviceRead[dev, "Humidity"];     DatabinAdd[      bin, <|"temperature" -> temp, "humidity" -> hum,        "air pressure" -> pres|>];     DeviceClose[dev];]);

cronTask = RunScheduledTask[SaveReadingToDataDrop[db], 300]

The above function generates a new databin to record data to, but what does that data look like once it’s been recorded? Let’s look at the recordings I made at the aforementioned Wolfram Technology Conference.

That data can be downloaded into Mathematica by anyone anytime after the conference to show the changes in atmospheric conditions over the course of the conference using DateListPlot. Below, you can see the rise in air pressure inside the conference center as more people gathered to see the many demos Wolfram employees had set up, followed by a drop as the conference ended.

DateListPlot[Databin["gwSkMvMW"]]["air pressure"]

Another demo I ran at the Wolfram Tech Conference made use of DeviceWrite. Using the Wolfram Language’s financial database, I turned the Sense HAT into a miniature stock ticker. This demo downloads the current stock market data from Wolfram’s servers, then displays them by picking a random stock from the list and showing the stock’s name and price on the Sense HAT’s LED array.

StockTickerPi[    dev_DeviceObject] := (Module[{len, price, str, stock, stockList},      stockList = FinancialData["NYSE:*", "Lookup"];     Do[stock = RandomChoice[stockList];      price = FinancialData[stock];      If[Head[price] === Real,        str = StringDrop[ToString[stock], 5] <> "$" <> ToString[price];       DeviceWrite[        dev, {str, "ScrollSpeed" \[RightArrow] 0.05,          "Color" -> {200, 0, 0}}]], 100];]);


The final demo that was run at the Wolfram Tech Conference this year used the Sense HAT’s LED array to run Conway’s Game of Life, a famous cellular automaton. For those unfamiliar with the “Game,” imagine each lit LED is a cell in a Petri dish. If a cell has too few or too many neighbors, it dies out. If an empty space has exactly three living neighbors, a new cell appears there. When these rules have been applied to all of the spaces on the grid, a new “generation” begins and the rules are reapplied. This pattern can continue indefinitely, given the right conditions. In my demo, a random array of lit and unlit LEDs constitutes the starting pattern; then the automaton runs for a given number of iterations.

GameOfLifePi[sh_DeviceObject, rounds_Integer, pause_Real,     color_List] :=    Module[{GameOfLife, StartingImage, images},     GameOfLife = {224, {2, {{2, 2, 2}, {2, 1, 2}, {2, 2, 2}}}, {1, 1}};    StartingImage = RandomInteger[{0, 1}, {8, 8}];    images = # & /@       CellularAutomaton[GameOfLife, StartingImage, rounds];    (DeviceWrite[sh, {#, "Color" \[RightArrow] color}];       Pause[pause]) & /@ images;];

GameOfLifePi[hat, 25, 0.5, {128, 128, 128}];

The rounds, pause and color parameters can all be modified to change how the automaton is displayed and how long Mathematica waits before displaying the next iteration.

These demos give a taste of what is possible when Mathematica connects with the Sense HAT. Have a look yourself at the Sense HAT documentation page, and send a note to Wolfram Community if you come up with something interesting!

Download this post as a Computable Document Format (CDF) file. New to CDF? Get your copy for free with this one-time download.

Leave a Comment


Fredrik D

Great that this work now! Will Wolfram on the Raspberry update itself or is it best to download a new version of the whole Raspberry initial installation?

Posted by Fredrik D    May 4, 2017 at 1:48 am
    Brett Haines

    No need to reinstall anything, just update the Pi’s software as you normally would:

    sudo apt-get update && sudo apt-get upgrade

    This will update the Wolfram Engine to 11.0, the latest version on the Pi.

    Posted by Brett Haines    May 8, 2017 at 3:04 pm

Leave a comment


Or continue as a guest (your comment will be held for moderation):