Astro Pi: Primer
Les Pounder gets to grips with the Sense HAT board that will be heading to the International Space Station with ESA astronaut, Tim Peake.
The Sense HAT is a remarkable platform with sensors covering temperature, humidity and pressure. It also has an accelerometer gyroscope and compass which can be used for positional data. To top it off the board has an 8x8 LED matrix and joystick. In this project we’ll be using this marvellous device to measure temperature, humidity, pressure and to draw animations on that matrix.
As well as the Sense HAT, you’ll need either a Raspberry Pi 2, A+ or B+, a copy of Raspbian and an internet connection. All of the code for this project can be found at http://bit.ly/ LXF204AstroPi. Installing the Sense HAT on top of your powered-down Pi is really easy and then you’ll need to connect all of the cables to your Pi and boot to the Raspbian desktop. To use the Sense HAT we’ll need to install its software. To do this open a LXTerminal (there’s an icon for this in the top left of the screen, it resembles a monitor), and in the LXTerminal enter the following: $ sudo apt-get update $ sudo apt-get install sense-hat $ sudo pip-3.2 install pillow
Here we’re ensuring that the list of available software is up to date, then we install the Sense HAT software. We use the pip package manager to install pillow, a fork of the Python Imaging Library (PIL). We’ll need to reboot after installation and return to the Raspbian desktop. Open LXTerminal again and type the following to launch IDLE for Python 3. $ sudo idle3 &
With IDLE3 open click on File > New to create a new blank document. Best practice is to save your work now, so click on File > Save and save your work as sensors.py. Let’s start building the project, by importing the libraries: import pygame from pygame.locals import * from sense_hat import SenseHat import time
First, we’re importing the pygame library followed by the pygame.locals library. We’ll use the pygame.locals library when detecting the joystick being used. We import the SenseHAT library to be able to use HAT board and, finally, we import the time function so that we can control the pace of our project. We create a variable called sense with sense = SenseHat() and store the SenseHat function, reducing typing strokes and we initialise the pygame library ready for use with pygame.init() .
In the next section of code we create a series of functions that will handle actions in the project. We start by displaying an image onscreen: def image(): pygame.display.set_caption("Linux Format presents...“) picture = pygame.image.load("image.png") screen = pygame.display.set_mode((688,361)) screen.blit(picture,(0,0)) pygame.display.flip()
We call the function image and it creates a window with a title. We then create a variable called picture and use it to store an image ready for use. Next, we create another variable called screen and set the screen size according to the image which we will load. We then blit the image into memory which rapidly updates the contents of memory with the image data. Last, we update the screen using the pygame. display.flip() function.
Temp and joystick functions
Our next function handles joystick input. We use an if...elseif conditional statement to control the actions for four events, pressing up, down, left and right: def joystick(event): if event.key == pygame.K_DOWN:
invader() elif event.key == pygame.K_UP:
pressure() elif event.key == pygame.K_LEFT:
temperature() elif event.key == pygame.K_RIGHT:
humidity() When a condition becomes true the corresponding function is called. Next, we create a function called temperature and this function reads the current temperature and stores it as a variable called temp : def temperature(): temp = round(sense.get_temperature(),1) if temp < 20:
sense.show_message("The temperature is %s C” % temp, text_colour=[0,0,255]) elif temp > 20 and temp < 30:
sense.show_message("The temperature is %s C” % temp, text_colour=[0,255,0]) else:
sense.show_message("The temperature is %s C” % temp, text_colour=[255,0,0])
You can see that we use round() to round the temperature value to one decimal place giving us a precise value. Next, we compare the value of temp using an if…elseif… else conditional statement so that when the temperature is below 20ºC the text is scrolled with a blue colour. If the temp is greater than 20ºC and less than 30ºC, it is green, and for everything else we get red text. For each condition we write the text to the LED matrix using the show_message function. We incorporate the value of temp in the text using %s this instructs Python to replace this value with a variable and we instruct it to use the temp variable using % temp . We can also change the text colour using RGB (Red, Green Blue) colour values.
Humidity and pressure functions
Next, we create a function to measure humidity. This uses a similar structure for storing and displaying the information as we used for the temperature function: def humidity(): humid = round(sense.get_humidity(),1) sense.show_message("Humidity: %s %%” % humid) We reuse the structure of our humidity function to create another function to retrieve and display the local air pressure: def pressure(): pressure = round(sense.get_pressure(),1) sense.show_message("Pressure %s Millibars” % pressure)
Our final function is a bit of fun and draws an animated space invader on the LED matrix: def invader(): for i in range(8): x = [0,255,0] o = [0,0,0] invader = [ o,x,o,o,o,o,x,o, o,o,x,o,o,x,o,o, o,x,x,x,x,x,x,o, x,x,o,x,x,o,x,x, x,x,x,x,x,x,x,x, x,o,x,x,x,x,o,x, x,o,x,o,o,x,o,x, o,o,x,x,x,x,o,o,
] sense.set_pixels(invader) time.sleep(0.5) Called invader , this function uses a for loop that iterates eight times. Next, we create two lists which are called x and o , where x is given the value 0,255,0 or green in RGB. For o we use 0,0,0 which is no colour, effectively turning off an LED. We create a list called invader and store eight rows and eight columns of x and o. Where an x is displayed, the colour green is seen on the matrix. Python is instructed to set the pixels using the invader list as a template. After waiting 0.5 seconds, we alter the configuration of the invader list then reset the pixels to show the changes. Once the final iteration of the loop is complete the screen is cleared. Not all of the code is shown here, but it’s in the final code example.
Our next block of code handles setting the LED matrix for low-light mode, effectively ensuring that the bright LEDs are slightly dimmed to save eyesight. We then call the image() function to display the instruction screen. Last, we clear the LED matrix before printing a “READY” message in green. sense.low_light = True image() sense.clear() sense.show_message("READY”,text_colour=[0,255,0])
Finally, a loop will constantly look for joystick input and if any input occurs then the event triggers one of the corresponding functions that we created earlier. We also create a quit method that can be called by closing the Instructions window or by pressing Ctrl+c.
With the project complete. Save your work and click on Run > Run Module to run the code. Congratulations you have taken your first steps with Sense HAT and produced a tool to measure multiple forms of inputs.