Monthly Archives: March 2017

scratchClient and scroll_phat_hd

There is a nice little led matrix moard from PIMORONI, “SCROLL PHAT HD”. The form factor is for the pi zero, but it runs well also with a pi 3.

scroll_phat_hd

scratchClient offers support for this board.

The interface allows to set pixel with brightness, write large and somewhat smaller text and of course clear the display.

There is a sample scratch script in scratch/scrollphathd/scroll_phat_hd.sb

There are quite a few commands from scratch which need parameters.
This is not a trivial task with scratch. Here a variable is used as a ‘command’-Variable ‘sph_command which receives operation names optionally with parameters.


Clear the display. There is also a broadcast command for this ‘clearDisplay’


Set a pixel at x=1, y=1, brightness = 1.0. Valid ranges are x in [0..16], y in [0..6], brightness is [0.0..1.0]. Values out of scope are ignored.


Draw a box between two pixels, here between [0;0] and [17;7] with brightness 0.3. This command effectively sets all led to on.

There are two text variables provided with a 5*7-font and a 3*5 font. Not all chars are supported. The 5*7 font basically supports ascii, the 3*5 font supports digits and some extra chars as ,;.:-_+\/.
The fonts are defined in ‘pseudographics’ in a python file and can easily be expanded.

There is a sample config file available, start scratchClient with

cd ~/scratchClient
python src/scratchClient.py -c config_scrollphathd

The adapter code has been written based on code from pimoroni.

minecraft and scratchClient

On raspberry pi, there is a local minecraft release available which supports a python API.

There is a MinecraftAdapter available for scratchClient which supports this API and allows to do basic operations.

For most of the operations, there are coordinate values to be set first before the operation is performed.

Example: set position of ‘person’.

Example: set Block

There is a sample scratch application in scratch/minecraft/minecraft.sb which demonstrates the basic concepts.

There are some demo scripts in minecraft.sb. One of these writes ‘scratch’ to the landscape. There is no ‘printString’-Function in the adapter. The pixel are defined in a local list, containing x and y-values of pixels. The data for this array are generated by a small python script and then imported into the list.

The python code is in scratch/minecraft/scratch_x_y.py. Run it by

python scratch_x_y.py > scratch_x_y.txt

and import the txt-file into the array.

The python code is quite simple.

f0="                         *          *        "    
f1="                         *          *        "
f2=" ***   ***  * **   ***  ***    ***  * **     "
f3="*     *   * **  *     *  *    *     **  *    "
f4=" ***  *     *      ****  *    *     *   *    "
f5="    * *   * *     *   *  *  * *   * *   *    "
f6="****   ***  *      ****   **   ***  *   *    "

def printPixel(f, level):
    for i in range(len(f)):
        if '*' == f[i]:
            print(i)      # print x-koordinate
            print(level)  # print y-koordinate
            
printPixel(f6, 1)
printPixel(f5, 2)
printPixel(f4, 3)
printPixel(f3, 4)
printPixel(f2, 5)
printPixel(f1, 6)
printPixel(f0, 7)

The pixels are defined in ‘pseudographic’. It is simple to add more text, decorations or extend the output by colors ( * ==> green, # ==> red) and adjust the scratch script to take each third line for the color information.
But keep in mind that ‘the world’ is limited size for minecraft for py and coordinates should be kept in range.

scratchClient with MQTT-Adapter

MQTT Description

MQTT, Message Queue Telemetry Transport, is a is an ISO standard for a publish-subscribe based messaging protocol. It is based on TCP/IP (the ‘usual’ network protocol) and especially designed for small devices and low network bandwidth.

A typical infrastructure contains at least one MQTT-Broker and one to many clients connected to the broker. This infrastructure can be spread to many computers.
A broker just receives messages sent by clients and distributes these to those clients which have subscribed to messages with specific topics.

A MQTT-message is build of a topic and a payload. Topics are strings like ‘home/room1/temperature’ or ‘client1/status’. Payload can be whatever data are needed to be send, this can be strings, binary data as integers, data structures. The broker does not process the data, it is up to the subscriber to ‘know’ how to process the payload.

From the description so far it is clear that there is the need to design the topics in a way that the system is extensible. This is paperwork, most of the time.

There are many more features in MQTT. See the mqtt.org homepage for more details.

scratchClient MQTT-adapter configuration

For scratchClient, the MQTT-adapter can publish messages and subscribe to topics. The topics managed are defined in the config xml. a sample file is included in the distribution.

    <adapter class='adapter.iotAdapter.MQTT_Adapter'  name='mqtt'>
        <description>interface to a mqtt-server</description>
        
        <!--  
           this adapter does implicit input_value and output_value-configuration 
           based on the content of mqtt-Tag.
              mgtt/publish/@variable definitions are used as scratch variable names.
              mgtt/subscribe/@variable definitions are used as scratch sensor names.
        -->
        <extension>
        <mqtt>
            <!--  when @variable is omitted, the topic is taken as variable name -->
            <publish topic="scratch/sample/a_value" />
            <publish topic="scratch/sample/b_value" variable="b_value" />
            <publish topic="scratch/sample/c_value" variable="c_value" />
        
            <subscribe topic="scratch/sample/d_value" variable="d_value" />
        </mqtt>
        </extension>
        
        <parameter name="mqtt.server" value="192.168.2.133"  />
        <parameter name="mqtt.port" value="1883"  />
    </adapter>

ScratchClient needs definitions on which variables to send out ‘publish’ and which ones to provide as sensor values ‘subscribe’.

The publish definition can be as short as the example here. This short definition takes the topic name also for the scratch variable name.

<publish topic="scratch/sample/a_value" />

In scratch, a variable named ‘scratch/sample/a_value’ will be published by the topic ‘scratch/sample/a_value’.

When more control on the scratch variable name is needed, the extended definition can be used:

<publish topic="scratch/sample/b_value" variable="b_value" />

Now a variable in scratch ‘b_value’ is published with topic ‘scratch/sample/b_value’.  I prefer to take the scratch name as the last section in the topic, but the variable name can be any valid name for scratch, e.g. ‘temperature’ or ‘xyz’.

<publish topic="scratch/sample/b_value" variable="temperature" />

For the subscribers, the definition is

<subscribe topic="scratch/sample/d_value"  />

This will result in a sensor value reported with name ‘scratch/sample/d_value’. There is also the possibility to match the sensor name by using the extended form

<subscribe topic="scratch/sample/d_value" variable="temperatureOfSample" />

Please note that wildcards in topics should not be used.

The parameters for the adapter define the connection details

        <parameter name="mqtt.server" value="192.168.2.133"  />
        <parameter name="mqtt.port" value="1883"  />

For the sample, the plain IP-address is given. Use ‘localhost’ or ‘127.0.0.1’ when the mqtt-broker is on same machine.

The MQTT-Adapter is based on eclipse-paho python library and is available on raspberry pi, linux, windows and many more platforms.

For the broker there is mosquitto available for raspberry pi. Just install by

sudo apt-get install mosquitto

This installs the server and starts the server in the background. This is good for a private environment. For a public installation, be sure to look into the docs for securing the environment.

Sample setup

In the scratchClient distribution, there is a sample configuration for a small usage scenario. This requires two computers, as scratch 1.4 with scratchClient can’t be started multiple times on one machine. The sample transmits a button press from GPIO and publishes by a topic ‘scratch/sample/button’ to the second installation, where in scratch a popup is triggered.

The config files are for computer 1 scratch/mqtt/dev_0/device_0.xml
the config files are for computer 1 scratch/mqtt/dev_1/device_1.xml

Be sure to edit the files to have the correct IP-addresses for the mqtt-broker.

On computer ‘dev_0’, there is a button needed from from GPIO17 (BCM) to GND.

   <adapter class='adapter.iotAdapter.MQTT_Adapter'  name='mqtt'>
        <description>interface to a mqtt-server</description>
        <extension>
        <mqtt>
            <publish topic="scratch/sample/button" variable="button" />
        </mqtt>
        </extension>
        
        <parameter name="mqtt.server" value="192.168.2.160"  />
        <parameter name="mqtt.port" value="1883"  />
    </adapter>
    <!-- =========================================================================== -->
    <adapter class='adapter.gpio.GpioEventInput' name='button_s0'>
        <gpio port='GPIO17'>
            <default dir='IN' pull='PUD_UP'  />
            <active dir='IN' pull='PUD_UP'/>
        </gpio>
        
        <output name='button_pressed'>
            <broadcast name='s0_high'/>
        </output>
        <output name='button_released'>
            <broadcast name='s0_low'/>
        </output>
        
        <parameter name='poll.interval' value='0.05' />
        <parameter name='value.inverse' value='true' />

    </adapter>

The scratch code for dev_0 is straightforward.

The adapter GpioEventInput sends events ‘s0_low’ or ‘s0_high’ on button release/ press. The parameter ‘value.inverse’ for this adapter switches high/low values. This is needed here as the button is connected from GPIO to GND and a button pressed is electrically a low signal.
The scratch code translates the button events to variable values for the MQTT-Adapter. When the button is pressed, a value ‘pressed’ is set to variable ‘button’. This variable is then sent to scratchClient where the MQTT-Adapter publishes the value with topic ‘scratch/sample/button’.

With a mqtt-client as mqtt.fx this topic can be observed. The client ‘mqtt.fx’ is a java-fx based tool which unfortunately is not easy to execute on raspberry due to missing fx-libraries. I have this tool running on a windows machine.

For the second device another computer is needed. The config file (here only a snippet) subscribes to the well known topic “scratch/sample/button” and provides the value for a sensor variable ‘button’ in scratch.

<extension>
 <mqtt>
 <subscribe topic="scratch/sample/button" variable="button" />
 </mqtt>
</extension>

The scratch code is staightforward, the value of the variable is displayed on the stage.

scratchclient is available from the download page  http://heppg.de/ikg/wordpress/?page_id=6

python timing loop accuracy

On a raspberry pi in python, it is not possible to produce accurate timings in μs range. The question is how accurate the timing is in real live.

The issue was raised by someone asking a question in raspberry pi forum on an 80Hz timing loop “the values may not always be accurate at the milliseconds level”.

To measure this, a simple timing loop was set up in python, and the timing was measured with the help of an arduino due. The arduino due runs at 84MHz and is ideal as a versatile measuring tool for this sort of problems.

Python timing loop. The loop should produce a square wave with 12.5ms or 80Hz.

import RPi.GPIO as GPIO
import time

GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)

pin_AO = 17
GPIO.setup(pin_AO, GPIO.OUT)

dt = 0
diff = 0.0115
while True:
    drun = diff - dt
    
    t0 = time.time()
    for _ in range(0, 1000):
        GPIO.output(pin_AO, GPIO.LOW)
        time.sleep(0.001)
        GPIO.output(pin_AO, GPIO.HIGH)
        time.sleep(drun)
    t1 = time.time();
    # calculate the deviation from ideal value 12.5 ms.
    dt = (t1 - t0) / 1000 - 0.0115 - 0.001
    print(dt)

The idea is to adjust timing based on average of last 1000 pulses.

The output of the arduino due is printed to Serial and looks like (values in μs):

...
12508
12509
12509
12514
12513
12516
12513
12509
12510
12512
12510
12515
12510
12515
12514
12515
12508
12512
12508
12514
12514
...

Grouping the output values into 10 μs slots and calculating the the number of events per group yields this bar chart. There are prox 27.000 events included the chart.

12-5ms

X-axis is slot times in μs; y-axis is count of events in the slot.

The printout of the script is (shortened)

9.77396965027e-06
0.000155053138733
1.0488986969e-05
0.000154378175735
1.00150108337e-05
0.000154267787933
9.80496406555e-06
0.000156002044678
8.39877128601e-06
0.000155970096588

This demonstrates some oscillation. Values like 0.00015 and ‘something- e-05’ are repeating. The two peaks in the diagram reflect this behavior.

Summary: precise timing with loops in python is accurate only to prox 0.2 ms.