HawkEYE PLUS

Raspberry Pi programming

The HawkEYE PLUS is a mains electricityfrequency monitor with 3 relays which control external devices when certain preset frequency thresholds are reached. It also contains a Raspberry Pi 3b which can communicate with the frequency monitor and the front mounted TFT display using Serial Peripheral Interface (SPI).

HawkEYE PLUS does not require the Pi to monitor and react to frequency thresholds. However the Pi can be used to query the current frequency and the status of the Relays from the HawkEYE PLUS. As the Raspberry Pi has local storage and also connectivity to wired and wireless LAN, it is possible to locally or remotely store readings or communicate with a central monitoring point.

The rest of this page contains Pi programming examples in Python to query the frequency, status of the Relays of the HawkEYE PLUS and display the information on the built in TFT.

Python and library installation on the Pi

The Raspberry Pi 3 supplied with the HawkEYE PLUS is installed with Raspbian and the following configuration steps have been applied. These instructions will help you if you decide to re-install the Pi.

  1. Install git

    $ sudo apt-get install git

  2. Install Python and the required libraries

    $ sudo apt-get install build-essential python-dev python-pip python-imaging python-numpy
    $ sudo pip install RPi.GPIO
    $ sudo pip install Adafruit_GPIO

  3. Clone the ST7735 library to control the TFT display

    $ cd
    $ git clone https://github.com/cskau/Python_ST7735

  4. Add the ST7735 library to Python

    $ cd Python_ST7735
    $ sudo python setup.py install

More information about the libraries can be found from these links:

RPi.GPIOAdafruit_GPIOPython_ST7735, python-imaging and python_numpy


Preparing for the examples

This section helps you prepare the Raspberry Pi for the Python code examples. The files and folders mentioned in this section are supplied on Pi inside the HawkEYE PLUS. You can use the following for reference or to prepare a newly installed SD card.

The graphics library (Pillow) can work with various font formats including TrueType (TTF). A good source for fonts is Google. For the examples in this section I have downloaded the EXO 2 font package from Google and copied 2 of the TTF files. I recommend using an SCP client such as WinSCP for file handling on the HawkEYE PLUS Pi.

1. Create the directories ~/fonts and ~/mmix in the home folder of pi

2. Download the EXO 2 font from Google, extract the contents and copy Exo2-Regular.ttf and Ex02-SemiBold.ttf to the ~/fonts directory.

All code is expected be copied to and run from the ~/mmix folder.

I expect that you have a working knowledge of Python and do not require explanations for normal code associated with a Python script. Because of this you will find that there are gaps in the line numbers. The entire script is shown at the bottom of this page.

The code samples

The following code snippets will explain parts of the code necessary to be able to read from the frequency monitor and write to the TFT display.

Declare the Libraries

The Pillow libraries are used to create a virtual screen which is copied to the TFT when all changes are complete in memory. This simplifies and speeds the control of the pixels on the display.

During the startup of the Python an image is displayed on the screen. Sleep is used from the time library to create a pause so that the splash remains visible for a few seconds.

  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
# Import the needed parts of Pillow
from PIL import Image
from PIL import ImageDraw
from PIL import ImageFont

# time only needed for sleep function
import time 

# Import the SPI and TFT libraries
import Adafruit_GPIO as GPIO
import Adafruit_GPIO.SPI as SPI
import ST7735 as TFT
Constants

The TFT constants are used to setup the screen in Pillow and also as dimensions for the TFT libraries. Following those from line 24 to 27 are codes used to send commands directly to the ST7735 TFT controller chip. These are from the data sheet for the ST7735 and set the orientation of the display to the same as the device in the HawkEYE PLUS. At the same time this also sets the colour map to a RED GREEN BLUE octet combination.

Lines 30 and 31 define the additional GPIO ports on the Raspberry Pi that are used when driving the ST7735.

Finally we set up the SPI device and port values for the Raspberry Pi. As with the GPIO ports, these constants cannot be changed without making hardware changes to the PCB in the HawkEYE PLUS.

 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
# TFT defaults for size and max SPI bus speed
WIDTH = 160
HEIGHT = 128
SPEED_HZ = 400000000

# Constants for controlling the ST7735 to set the rotation of the screen
ST77XX_MADCTL_RGB=  0x00
ST77XX_MADCTL_MV =  0x20
ST77XX_MADCTL    =  0x36
ST77XX_MADCTL_MY =  0x80

# Extra GPIO lines needed for SPI connectivity with the TFT
TFT_DC = 24          # TFT Data/Command BCGPIO 24 - PIN 18
TFT_RST = 18         # TFT Reset        BCGPIO 18 - PIN 12

# SPI port and device selection for TFT and 
TFT_SPI_PORT = 0
TFT_SPI_DEVICE = 1
HEP_SPI_PORT = 0
HEP_SPI_DEVICE = 0
Set up the TFT class and controlling the chip

The Python library for controlling the ST7735 is simple to set up and direct communication with the device is easy. If you want to perform more complex control of the chip, it can be done with the help of the ST7735 datasheet. Controlling the ST7735 is as simple as creating the display class and then sending the command and data sequence (lines 60 and 61).

 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
# Create TFT display class.
disp = TFT.ST7735(
    TFT_DC,
    rst=TFT_RST,
    spi=SPI.SpiDev(
        TFT_SPI_PORT,
        TFT_SPI_DEVICE,
        max_speed_hz=SPEED_HZ),
        width = WIDTH,
        height = HEIGHT)

# Initialize display.
disp.begin()

# Set TFT rotation and select R,G,B for colour tuple format
madctl = ST77XX_MADCTL_MY | ST77XX_MADCTL_MV | ST77XX_MADCTL_RGB
disp.command(ST77XX_MADCTL)
disp.data(madctl)
Using Pillow

Once the PIL drawing object is created we can start using it as a canvas for drawing and writing text to (later examples). Starting at line 66 there is a error checked segment of code to load and display a png file.You will require a 160 x 128 pixel image for this example. Here is one you are welcome to use:

 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
# Get a PIL Draw object for the display buffer.
draw = disp.draw()

# Load the splash screen(s) ignoring errors (files missing, etc.)
try:
   im = Image.open("/home/pi/mmix/mmixLogoBlueOnWhite.png")
   disp.display(im)
   time.sleep(3)
except:
   pass

digit_font = ImageFont.truetype("/home/pi/fonts/Exo2-SemiBold.ttf", 36)
minmax_font = ImageFont.truetype("/home/pi/fonts/Exo2-SemiBold.ttf", 20)
mmtxt_font = ImageFont.truetype("/home/pi/fonts/Exo2-Regular.ttf", 16)
Creating the SPI interface to HawkEYE PLUS

The SPI interface is created through the Adafruit GPIO libraries. The important parts of the SPI device creation are the bit order and the clock Hz. SPI data communication with the HawkEYE PLUS must always be most significant bit first.

 90
 91
 92
 93
 94
 95
 96
# Create and configure the SPI device for HawkEYE communication
hawkeye = SPI.SpiDev(HEP_SPI_PORT,
          HEP_SPI_DEVICE,
          max_speed_hz=SPEED_HZ)
hawkeye.set_mode(0)
hawkeye.set_bit_order(SPI.MSBFIRST)
hawkeye.set_clock_hz(600000)
Priming the SPI communications

It is crucial  to prime the 2 way SPI communications with the HawkEYE PLUS. This ensures that the data stream is in a known state before the main query/transfer loop begins.

 98
 99
100
# Prime the data transfer -- crucial to getting the SPI transfer working
hi = 6
ho = hawkeye.read(hi)

Reading the frequency

Having primed the SPI communications it is now possible to start reading the frequency from the HawkEYE plus. The nature of SPI data transfer means that it is possible to transmit a character while receiving one. You can take advantage of this by sending the number of the character in the frequency string you would like to receive. As the first priming request was for character 6 ("hi = 6")