Home Automation

Enter Your Electronics & Design Project for a chance to win a $100 Shopping Cart!

Back to The Project14 homepage

Project14 Home
Monthly Themes
Monthly Theme Poll


Interfacing the Matrix Creator with MATRIX Lite Python



Previously I posted an overview of the Home Automation project I am creating using the MATRIX Creator, Raspberry Pi 3 A+ and OpenHAB 2 and part of the configuration involves collecting sensor data from the MATRIX Creator to present in the OpenHAB UI. Here, I will describe how I am using the MATRIX Lite Python interfaces to collect this data from the Creator.


Related posts:

OpenHAB 2 with Matrix Creator and RasPi 3 A+: Intro

OpenHAB 2 with Matrix Creator and RasPi 3 A+: OpenHAB 2 Exec Binding

OpenHAB 2 with Matrix Creator and RasPi 3 A+: OpenHAB 2 MQTT Binding

OpenHAB 2 with Matrix Creator and RasPi 3 A+: Everloop and demo

OpenHAB 2 with Matrix Creator and RasPi 3 A+: GPIO and Postmortem


MATRIX Creator Set-up


The MATRIX Labs website has very good instruction on how to set-up and configuration the MATRIX Creator and the first place to start is the Overview page.



There is plenty of info at the site and elsewhere on element14 to get started with the MATRIX Creator so I will not cover getting the Raspberry Pi OS installed and configured.


A Raspberry Pi 3 A+ running the '2018-11-13-raspbian-stretch-full' image was used to host the MATRIX Creator for this project.


To get started, the matrix-creator-init was installed to initialize the MATRIX Creator code on the Raspberry Pi



# Add repo and key
curl https://apt.matrix.one/doc/apt-key.gpg | sudo apt-key add -
echo "deb https://apt.matrix.one/raspbian $(lsb_release -sc) main" | sudo tee /etc/apt/sources.list.d/matrixlabs.list

# Update packages and install
sudo apt-get update
sudo apt-get upgrade

# Installation
sudo apt install matrixio-creator-init


After the Raspberry Pi is up and running and the MATRIX Creator is installed, the next step is to select which MATRIX Ecosystem to select.



In this example, the MATRIX Hardware Abstraction Layer (HAL) and MATRIX Lite Python was used to interface with the MATRIX Creator


First, install the MATRIX HAL software.



There are 2 different options to install the MATRIX HAL software:

   1. From Package - This is the easiest option



   2. From Source -  This requires downloading the code and building and installing the software manually.

       It might be a good idea to perform this step just to ensure the latest HAL software is used



To install from package, perform the following.

Add the MATRIX source repo to the package manager on the Pi.

curl https://apt.matrix.one/doc/apt-key.gpg | sudo apt-key add -
echo "deb https://apt.matrix.one/raspbian $(lsb_release -sc) main" | sudo tee /etc/apt/sources.list.d/matrixlabs.list


Ensure the packages on the system are updated

sudo apt-get update
sudo apt-get upgrade


Install MATRIX HAL packages

sudo apt-get install matrixio-creator-init libmatrixio-creator-hal libmatrixio-creator-hal-dev


Reboot the system

sudo reboot


Check the system to ensure the software was installed.

ls /usr/lib/libmatrix_creator_hal.so 


ls -d /usr/include/matrix_hal/


The following link shows how to test the MATRIX HAL code.



Second, install MATRIX Lite Python.

The MATRIX Lite software includes both a Javascript and a Python option to interface the MATRIX Creator. In  this example , only the MATRIX Lite Python code was used.


The MATRIX Lite Python code can be obtained from the MATRIX GiHub repo



Install the dependencies

sudo apt-get install swig
sudo apt-get install python3-pip


Create a location on the Raspberry Pi for the code and then use the git tool to down load the code.

git clone --recurse-submodules https://github.com/matrix-io/matrix-lite-py
Cloning into 'matrix-lite-py'...
remote: Enumerating objects: 184, done.
remote: Counting objects: 100% (184/184), done.
remote: Compressing objects: 100% (124/124), done.
remote: Total 184 (delta 75), reused 155 (delta 50), pack-reused 0
Receiving objects: 100% (184/184), 25.83 KiB | 0 bytes/s, done.
Resolving deltas: 100% (75/75), done.
Submodule 'matrix-hal-swig' (https://github.com/matrix-io/matrix-hal-swig) registered for path 'matrix-hal-swig'
Cloning into '/home/pi/development/matrix-test/matrix-lite-py/matrix-hal-swig'...
remote: Enumerating objects: 52, done.        
remote: Counting objects: 100% (52/52), done.        
remote: Compressing objects: 100% (37/37), done.        
remote: Total 52 (delta 18), reused 42 (delta 11), pack-reused 0        
Submodule path 'matrix-hal-swig': checked out '6fc66b98160144f14db072f8ece92f2a138078ba'


Once downloaded, there should be a matrix-lite-py folder present.

ls -lt
total 4
drwxr-xr-x 5 pi pi 4096 Mar  1 23:11 matrix-lite-py


Change directory into the matrix-lite-py folder and run make to build the code

cd matrix-lite-py
# build destination
mkdir -p build;
# generate HAL wrapper
swig -python -c++ -outdir build matrix-hal-swig/matrix.i;
# generate Python library
gcc -O2 -fPIC -c -std=gnu++11 -fno-threadsafe-statics matrix-hal-swig/matrix.cpp matrix-hal-swig/drivers/*.cpp matrix-hal-swig/drivers/sensors/*.cpp
mv *.o build
# handy to use: python-config --cflags
gcc -O2 -fPIC -c -o build/matrix_wrap.o -std=gnu++11 -fno-threadsafe-statics matrix-hal-swig/matrix_wrap.cxx -I/usr/include/python3.5m
gcc -lmatrix_creator_hal -shared -std=gnu++11 -fno-threadsafe-statics build/*.o -o build/_matrix.so
# remove generated HAL wrapper
rm matrix-hal-swig/matrix_wrap.cxx;



Run the swigExamples.py script to test that the matrix-lite-py has been installed correctly.

NOTE: This does require Python 3.0.

 python3 swigExamples.py INFO: [/dev/spidev0.0] was opened
['SwigPyIterator', 'SwigPyIterator_swigregister', '__builtin__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', '_matrix', '_newclass', '_object', '_swig_getattr', '_swig_property', '_swig_repr', '_swig_setattr', '_swig_setattr_nondynamic', 'cvar', 'everloop', 'everloopImage', 'everloopImage_swigregister', 'everloop_swigregister', 'gpio', 'gpio_swigregister', 'humidity', 'humidity_struct', 'humidity_struct_swigregister', 'humidity_swigregister', 'imu', 'imu_struct', 'imu_struct_swigregister', 'imu_swigregister', 'led', 'led_swigregister', 'pressure', 'pressure_struct', 'pressure_struct_swigregister', 'pressure_swigregister', 'uv', 'uv_struct', 'uv_struct_swigregister', 'uv_swigregister']


If successful, the Everloop LEDs should all run Blue.

A piece of paper was used to cover the MATRIX Creator to show the LEDs more clearly.



The swigExamples.py script has code in it run examples for the other sensors but are comment out.  To run these, just comment out the appropriate code to run another example.

import build.matrix as hal
from time import sleep

# Print exported objects/functions

## LED Example ##
everloop = hal.everloop()

leds = []
for i in range(everloop.ledCount):
    led = hal.led(0,0,1,0)#led.r led.g led.b led.w


## IMU Example ##
# imu = hal.imu()
# while True:
#     data = imu.read()
#     print ("Accelerometer: (xyz)",data.accel_x, data.accel_y, data.accel_z)
#     print ("Gyroscope: (xyz)",data.gyro_x, data.gyro_y, data.gyro_z)
#     print ("Magnetometer:(xyz)", data.mag_x, data.mag_y, data.mag_z)
#     print ("Yaw Pitch Roll:", data.yaw, data.pitch, data.roll)
#     sleep(0.05)

## UV Example ##
# uv = hal.uv()
# while True:
#     data = uv.read()
#     print ("UV: ", data.uv)
#     sleep(0.05)

## Humidity Example ##
# humidity = hal.humidity()
# while True:
#     data = humidity.read()
#     print("Humidity: ", data.humidity)
#     print("Temperature: ", data.temperature)
#     sleep(0.05)


Humidity example

INFO: [/dev/spidev0.0] was opened

Humidity:  29.045000076293945
Temperature:  29.53700065612793
Humidity:  29.045000076293945
Temperature:  29.53700065612793
Humidity:  29.045000076293945
Temperature:  29.53700065612793
Humidity:  29.045000076293945
Temperature:  29.53700065612793
Humidity:  29.045000076293945



For my project, to get the Sensor values to display in OpenHAB, I took the basic swigExamples.py script and modified it by creating a MatrixSensors class and associated methods for each sensors. Also, I added argparse to the script so that a arguments can be passed to the script to retrieve the sensor values without having to edit the script each time.  A dictionary is used to change the colors on the Everloop based on predefined values.   Eventually this will be modified so the intensity and colors can be adjusted dynamically.

I guess I need to set-up a github repo for this but this is what I have thus far.


#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import sys
import os
import build.matrix as hal
from time import sleep

ledMatrix = {'red': {'ledr' : 1, 'ledg' : 0 , 'ledb' : 0, 'ledw' : 0},
            'green': {'ledr' : 0, 'ledg' : 1 , 'ledb' : 0, 'ledw' : 0},
            'blue': {'ledr' : 0, 'ledg' : 0 , 'ledb' : 1, 'ledw' : 0},
            'white': {'ledr' : 0, 'ledg' : 0 , 'ledb' : 0, 'ledw' : 1},
            'off': {'ledr' : 0, 'ledg' : 0 , 'ledb' : 0, 'ledw' : 0},
# Print exported objects/functions
class MatrixSensors(object):
    Setup Matrix Sensor  Python examples
    def __init__(self):
        self.leds = []
        self.everloop = hal.everloop()
        self.imu = hal.imu()
        self.gpio = hal.gpio()
        self.uv = hal.uv()
        self.humidity = hal.humidity()
        self.pressure = hal.pressure()
        self.gpioIN = 15
        self.gpioOUT = 14

    ## LED Example ##
    def runEverloop(self, color):
        print ("Color: %s" % color)
        for i in range(self.everloop.ledCount):
            #led = hal.led(0,0,0,0)#led.r led.g led.b led.w
            led = hal.led(ledMatrix.get(color, {}).get('ledr'),
                          ledMatrix.get(color, {}).get('ledg'),
                          ledMatrix.get(color, {}).get('ledb'),
                          ledMatrix.get(color, {}).get('ledw'),
                          )#led.r led.g led.b led.w


    ## IMU Example ##
    def getIMU(self, args):
        ## IMU Example ##
        data = self.imu.read()
        result = ""
        if (args == "accel"):
            return  (data.accel_x, data.accel_y, data.accel_z)
        elif (args == "gyro"):
            return  (data.gyro_x, data.gyro_y, data.gyro_z)
        elif (args == "mag"):
            return  (data.mag_x, data.mag_y, data.mag_z)
        elif (args == "euler"):
            return  (data.yaw, data.pitch, data.roll)
            return  (0, 0, 0)

    ## UV Example ##
    def getUV(self):

        data = self.uv.read()
        return data.uv

    ## Humidity Example ##
    def getHumid(self, args):

        data = self.humidity.read()
        result = ""
        if (args == "temp"):
            result = ((9.00 / 5.00 * data.temperature)+32.00)
        elif (args == "humid"):
            result = data.humidity
            result = 0
            print ("%s not found!" % arg.pressure)

        return ('{0:.2f}'.format(result))

    ## Pressure Example ##
    def getPressure(self, args):
        data = self.pressure.read()
        result = ""
        if (args == "temp"):
            result = ((9.00 / 5.00 * data.temperature)+32.00)
        elif (args == "alt"):
            result = data.altitude
        elif (args == "pressure"):
            result = data.pressure
            result = 0

        return ('{0:.2f}'.format(result))

    def runGPIO(self):
        ## GPIO ##


        while True:
            pinState = self.gpio.getValue(self.gpioIN)
            print("GPIO State: %d" % pinState)

    def initGPIO(self):
        # turn pin 1 on

        # read pin 0

def main(args):
    matrixSen = MatrixSensors()
    if args.eLoop:
    elif args.gpio:
    elif args.imu:
        imu_x, imu_y, imu_z = matrixSen.getIMU(args.imu)
        if (args.imu == "euler"):
            print("yaw:%f pitch:%f roll:%f" % (imu_x, imu_y, imu_z))
            print("x:%f y:%f z:%f" % (imu_x, imu_y, imu_z))
    elif args.humid:
        envCond = matrixSen.getHumid(args.humid)
        print (envCond)
    elif args.pressure:
        press = matrixSen.getPressure(args.pressure)
        print (press)
    elif args.uv:
        print("ERROR: option not recognized!")
        raise Exception('Options not found')

if __name__ == "__main__":
    import argparse

    parser = argparse.ArgumentParser(description="matrix-lite script")
    parser.add_argument("-g", "--gpio", dest="gpio",
                        action="store_true", default=False,
                        help="run gpio") 
    parser.add_argument("-e", "--eloop", dest="eLoop",
                        action="store", help="run eloop")
    parser.add_argument("-i", "--imu", dest="imu",
                        action="store", help="run IMU; -u or --imu")
    parser.add_argument("-p", "--press", dest="pressure",
                        action="store", help=" -p or --press; \"temp\", \"alt\", \"pressure\"")
    parser.add_argument("-u", "--uv", dest="uv",
                        action="store_true", default=False,
                        help="run UV") 
    parser.add_argument("-hu", "--humid", dest="humid",
                        action="store", help="run Humidity")

    args = parser.parse_args()
    if len(sys.argv) == 1:

        #user_input = input()
    except KeyboardInterrupt:


Running this looks like this.

Pressure sensor example:

/usr/bin/python3 matrixSensors.py -p "temp"
INFO: [/dev/spidev0.0] was opened


/usr/bin/python3 matrixSensors.py -p "alt"
INFO: [/dev/spidev0.0] was opened


/usr/bin/python3 matrixSensors.py -p "pressure"
INFO: [/dev/spidev0.0] was opened


Humidity Sensor example:

/usr/bin/python3 matrixSensors.py -hu "humid"
INFO: [/dev/spidev0.0] was opened


/usr/bin/python3 matrixSensors.py -hu "temp"
INFO: [/dev/spidev0.0] was opened


NOTE: The temperature is in Fahrenheit and the temp is a bit high due to the proximity of the sensors to the Raspberry Pi. The recommendation is to separate the MATRIX Creator and the Raspberry Pi so the heat from the Pi does not interfere with the sensors.


IMU Example

/usr/bin/python3 matrixSensors.py --imu "gyro"
INFO: [/dev/spidev0.0] was opened
x:0.844000 y:3.140000 z:0.942000


/usr/bin/python3 matrixSensors.py --imu "accel"
INFO: [/dev/spidev0.0] was opened
x:0.002000 y:0.012000 z:0.982000


/usr/bin/python3 matrixSensors.py --imu "mag"
INFO: [/dev/spidev0.0] was opened
x:-0.190000 y:0.293000 z:0.000000


 /usr/bin/python3 matrixSensors.py --imu "euler"
INFO: [/dev/spidev0.0] was opened
yaw:56.446461 pitch:-0.525565 roll:0.934405


GPIO Example - Push Button connected to Pin 15 and a LED connected to Pin 14.

/usr/bin/python3 matrixSensors.py -g

GPIO State: 1


Everloop Example

/usr/bin/python3 matrixSensors.py -e "green"
INFO: [/dev/spidev0.0] was opened
Color: green



/usr/bin/python3 matrixSensors.py -e "red"
INFO: [/dev/spidev0.0] was opened
Color: red



That is all I have at this point for the Python interfaces.