Getting Started With Powershell Iot & Sensehat - Temp Sensor

About the project

With this project, you will get a brief explanation about what's PowerShell, why I'm using it and how you also use it on your projects. I will guide you through how you can install PowerShell on RaspberryPi, getting started with it, and write a function to get temperature!

Project info

Difficulty: Moderate

Platforms: MicrosoftRaspberry Pi

Estimated time: 2 hours

License: GNU General Public License, version 3 or later (GPL3+)

Items used in this project

Hardware components

Raspberry Pi Sense HAT - any Raspberry Pi with 2x20 Connector Raspberry Pi Sense HAT - any Raspberry Pi with 2x20 Connector x 1

Software apps and online services

PowerShell Core PowerShell Core

Story

PowerShell Core (from now on abbreviated as PS) is a powerful scripting language that became Generally Available (GA) on January 10th this year and continues to grow every day. Quoting the Microsoft documentation,

" PowerShell is a task-based command-line shell and scripting language built on .NET. PowerShell helps system administrators and power-users can rapidly automate tasks that manage operating systems (Linux, macOS, and Windows) and processes.". As stated, it is known to be useful for automation and maintenance, offering a really useful set of commands, called command lets (cmdLets).

What will we do?

In this tutorial we will explore an unusual use case for this scripting language - IoT. We will use PowerShell to interact with Hardware and fetch information or perform actions. In this tutorial we will use the Sense Hat to get the current temperature. We will also have to read the datasheet in order to understand how get the temperature.

Before we start

Keep in mind that both PS and the IoT module are bleeding edge. PS is constantly being used and the community is always reporting bugs and improving it’s usage, but even so, we can experience bugs, crashes and unexpected behavior. If you do, check their Github pages (PowerShell and IoT Module) and report the issues, they are active and friendly! 

Are you ready? Let's go!

We will start by installing PowerShell on our Raspberry Pi (Note: As stated here, currently it's only supported on Raspbian Stretch and on Pi 2 and 3). Head to the Github page and select whichever version you want to use. Don't get intimidated with the multiple files there to choose. This is because PS is cross-platform and can run on Windows, Linux and MacOS. The "installer" for raspberry Pi is the *-linux-arm32.tar.gz. In this case, we will use the powershell-6.1.0-linux-arm32.tar.gzWe will rely heavily on the terminal during this tutorial, so start your SSH session or open your terminal if you are doing this directly on your raspberry Pi. PS has its' dependencies, so let's start by installing them and install it right after

  1. # Install prerequisites
  2. sudo apt-get install libunwind8
  3.  
  4. # Grab the latest tar.gz
  5. wget https://github.com/PowerShell/PowerShell/releases/download/v6.1.0/powershell-6.1.0-linux-arm32.tar.gz
  6.  
  7. # Make folder to put powershell
  8. mkdir ~/powershell
  9.  
  10. # Unpack the tar.gz file
  11. tar -xvf ./powershell-6.1.0-linux-arm32.tar.gz -C ~/powershell

After doing this, if we simply do 

  1. ~/powershell/pwsh

PS will be launched. I suggest that you create a symbolic link, so that you don't have to specify the full path whenever you want to launch PowerShell. In order to do so, simply run the following:

  1. sudo ln -s ~/powershell/pwsh /usr/bin/pwsh

After this, we can simply type pwsh whenever we want to launch PS! Let’s check if it is working as expected. The following command shows you the information regarding both PS and your OS:

  1. $psversiontable

If you are more familiar with the unix commands, those are still supported on PS.

One thing to keep in mind: Get-help cmdlet is really helpful and provides explanations and examples. Don’t be afraid to use it!

Next Step: Install-Module  Microsoft.PowerShell.IoT

We already have PS installed, but we still need the cmdlets to interact with hardware. Let's install them and explore those commands.

NOTE: Because we have to work with hardware, we have to run PS with higher privileges (either with  sudo or as root user)

After launching PS, we need to install the IoT Module, so we do

  1. Install-Module Microsoft.PowerShell.IoT

As the command name implies, this will install the module that we specified. You might be questioning “Install from where? I haven’t specified any path!”. Using the command

  1. Get-Help Install-Module

we can read the following “Downloads one or more modules from an online gallery, and installs them on the local computer.”. After the installation is successful we can start messing around with what can we do with this module.

Exploring the Module

PS is a self-documented language, meaning we have cmdlets that help us find other commands, or to get information about a specific cmdlet (as we have seen with the Get-Help). The easiest and best way to explore the module, is by doing

  1. Get-Command -Module Microsoft.PowerShell.IoT

This will list all the commands that are available on the IoT module, let's see what we have:

So we only have 6 commands... that seems a small set... But it's not! It has all we need. As you might notice, it has support for GPIO, SPI and I2C. In this tutorial we will focus on the I2C, since it's what the Sense Hat uses to communicate.

About the I2C protocol

Regarding the I2C protocol, I will not enter in details, but basically what we need to know is that it has a master (device) and a set of registers (slaves). We can Get and Set values for those registers. What we will do, will depend on how the chip works (which we will see in a few moments)

Back to the SenseHat

As mentioned before, we will work with the temperature sensor. Before jumping into the code, we should analyse its' datasheet. Here are the important notes:

    • On address 0x20 we have our "control register". We want it to activate it and block the update data until we read the values. This corresponds to the value 0x84.

    • On address 0x21 we have another "control register". This is the one used to request a new sample. We will set its value to 0x83.

    • When we set the values for this register, it will affect two registers with the result of this request: TEMP_OUT_L and  TEMP_OUT_H with addresses 0x2A and 0x2B respectively.

    • As stated on the datasheet: "The relative humidity and temperature values must be computed by linear interpolation of current registers with calibration registers"

    • Those calibration registers are on addresses 0x32 and 0x33. On either case we need to get the Most Significant Bit - address 0x35

With this in mind, let's check the code!

I will place here the whole code required to get the temperature. The code is like the "translation" of what we've just pointed above. Although this might be a "wall of code", i'll explain it through.

  1. Import-Module Microsoft.PowerShell.IoT
  2. #Get the device (master).
  3. #after checking this website, found that the address is 0x5F
  4. #https://pinout.xyz/pinout/sense_hat
  5. $deviceAddress = 0x5F
  6. $Device = Get-I2CDevice -Id $deviceAddress -FriendlyName tempSensor
  7.  
  8. #Set the configuration register with the values we talked
  9. #Check the datasheet if you have any doubts
  10. $controlRegisterAddress = 0x20 #CTRL_REG1
  11. $controlRegisterValue = 0x84 # Active mode (8), do not update until values are read (4)
  12. Set-I2CRegister -Device $Device -Register $controlRegisterAddress -Data $controlRegisterValue
  13.  
  14.  
  15. #Define a function that reads the actual temperature from the registers.
  16. #Remember that the values obtained here will have to be calculated with the calibration values!
  17. #As we have seen before, we can set values to registers and read values from them. In the next functions,
  18. #we will read the values.
  19. function Read-TemperatureSample(){
  20. $tempLowRegisterAddress = 0x2A
  21. $tempHighRegisterAddress = 0x2B
  22. #READ VALUES
  23. [int16]$temperatureOutL = (Get-I2CRegister -Device $Device -Register $tempLowRegisterAddress).Data[0]
  24. [int16]$temperatureOutH = (Get-I2CRegister -Device $Device -Register $tempHighRegisterAddress).Data[0]
  25. #because it is 2s complement, we need to do a "bitwise or" between the lsb and the msb
  26. [int16]($temperatureOutH -shl 8) -bor $temperatureOutL
  27. }
  28.  
  29. #The following four functions calculate the calibration values
  30. #in order to calculate those values, we need to get the less significant byte (LSB) and the most significant byte (MSB)
  31. #After it we need to "merge" them, by doing a bitwise or (bor operator)
  32. function Get-T0_degC_x8(){
  33. $lsbTemperatureCalibrationRegisterAddress = 0x32
  34. $msbTemperatureCalibrationRegisterAddress = 0x35
  35.  
  36. [int16]$lsb = (Get-I2CRegister -Device $Device -Register $lsbTemperatureCalibrationRegisterAddress).Data[0]
  37. [int16]$msb = ((Get-I2CRegister -Device $Device -Register $msbTemperatureCalibrationRegisterAddress).Data[0]) -band 0x03 # 0011
  38.  
  39. [int16]($msb -shl 8) -bor $lsb
  40. }
  41.  
  42. function Get-T1_degC_x8(){
  43. $lsbTemperatureCalibrationRegisterAddress = 0x33
  44. $msbTemperatureCalibrationRegisterAddress = 0x35
  45.  
  46. [int16]$lsb = (Get-I2CRegister -Device $Device -Register $lsbTemperatureCalibrationRegisterAddress).Data[0]
  47. [int16]$msb = ((Get-I2CRegister -Device $Device -Register $msbTemperatureCalibrationRegisterAddress).Data[0]) -band 0x0C # 1100
  48. $msb = $msb -shr 2 # we need to shift twice because it was on the 3rd and 4th position, wee need to be on 1st and 2nd
  49.  
  50. [int16](($msb -shl 8) -bor $lsb)
  51. }
  52.  
  53. #Again, T0_OUT and T1_OUT are needed to do the maths. Check page 25 of the datasheet.
  54.  
  55. function Get-T0_OUT(){
  56. [int16]$registerAddressL = 0x3C
  57. [int16]$registerAddressH = 0x3D

Code

Repository that contains modules to interact with SenseHat

So far we have the joystick, 8x8 led matrix and temperature (partially) working

Credits

Photo of DanielSSilva

DanielSSilva

Software developer, focused on .NET Core and EF Core. DYI enthusiast and like to explore new things. Mainly focusing on PowerShell Core IoT and Raspberry Pi

   

Leave your feedback...