Raspberry Pi Sense HAT and Blockly

DIY

Last year my son MJ and I got an extention for our Raspberry Pi, namely the Sense HAT. Great! We connected it up, started Scratch, scratched our heads and stopped. The learning curve, practical applications and online information for Scratch and the Sense Hat was just not up to scratch. And when Pi3 came out Sense Hat and Scratch just crashed.
Bugged by the potential of the Sense Hat we tried to type in a few Python examples. But typing without typos is not our thing.

Months later…..Blockly seemed to provide a hack-able answer in the way that we can visually code and copy/paste the resulting python code into a .py document. Through a process of trial and error I have pieced bits of code together making Blockly produce a code in Python for the SenceHat.

In the next paragraphs I will explain how I set about creating my own blocks for python. My methods might not be the best but it is one that works, and I hope it will help others make a start.
If you are not familiar with blocky go to their demo page https://blockly-demo.appspot.com/static/demos/code/index.html, and read up on creating custom blocks.

what you will need:

preparations

01

1) Unzip the code and closure (you should have something like this)

2) test out the demo file index.html

03

3) the result in a browser

preparing the ground for new blocks

you will need to edit the index.html that you have just opened
and create a new java-script file: SHat_LED.js in google->blockly->blocks.

04

make a new empty  SHat_LED.js file. Blockly will need this to generate your custom blocks using java-script.

Index.html and the TOOLBOX

05
within the index.html connect your new SHat_LED.js file with a link.

06

by adding a category name you can expand the ToolBox with your blocks.

If you open the index.html in your browser you should see that the left menu has added your category.

Test and try

Make your own pre-assembled block

see  <https://developers.google.com/blockly/installation/toolbox#block_groups>

Thus, the easiest way to construct the XML for such blocks is to use the Code application to build the blocks, then switch to the XML tab and copy the result. The x, y, and id properties are ignored by the toolbox and may be stripped out.

07

Make this construction in Blockly and click on the XML tab. Copy the code and remove what you do not need (ie <xml..  and id=…)

<xml xmlns=”http://www.w3.org/1999/xhtml”&gt;
<block type=”variables_set” id=”iQz3^l@i,IH*(wL%WiM@” x=”38″ y=”113″   >
<field name=”VAR”>colour_field</field>
<value name=”VALUE”>
<block type=”lists_create_with” id=”*!mKDzWmW4W45iZVQoTB”    >
<mutation items=”3″></mutation>
<value name=”ADD0″>…..

you should have something like this (below)  and ADD this to your index.html

<category name=”my_own_custom_block” colour=”202″>
<block type=”variables_set”>
<field name=”VAR”>colour_field</field>
<value name=”VALUE”>
<block type=”lists_create_with”>
<mutation items=”3″></mutation>
<value name=”ADD0″>
<block type=”colour_picker”>
<field name=”COLOUR”>#ff0000</field>
</block>
</value>
<value name=”ADD1″>
<block type=”colour_picker”>
<field name=”COLOUR”>#ff0000</field>
</block>
</value>
<value name=”ADD2″>
<block type=”colour_picker”>
<field name=”COLOUR”>#ff0000</field>
</block>
</value>
</block>
</value>
</block>
</category>

Run the new index in your browser and see the new custom block.


Work shopping through an example:

goal: blockly spits out a Python code to use <set_pixel> with the SenseHat

definition: Sets an individual LED matrix pixel at the specified X-Y coordinate to the specified colour.

from sense_hat import SenseHat
sense = SenseHat()
# examples using (x, y, r, g, b)
sense.set_pixel(0, 0, 255, 0, 0)
sense.set_pixel(0, 7, 0, 255, 0)
sense.set_pixel(7, 0, 0, 0, 255)
sense.set_pixel(7, 7, 255, 0, 255)

https://pythonhosted.org/sense-hat/api/

1) getting value inputs

we need x, y and a colour
lets set up a block using blockly factory

08

This block allows for an x, y and colour input. Click on the image to open blocky factory.

JavaScript for the  SHat_LED.js file

copy the Language code and paste it  into your JavaScript file. (SHat_LED.js)
///////////_pixel////
////////////////////

Blockly.Blocks['_pixel'] = {
  init: function() {
    this.appendValueInput("x")
        .setCheck(null)
        .appendField("pixel")
        .appendField("X");
    this.appendValueInput("y")
        .setCheck(null)
        .appendField("Y");
    this.appendDummyInput()
        .appendField(new Blockly.FieldColour("#000000"), "colour");
    this.setOutput(true, null);
    this.setColour(330);
    this.setTooltip('specified X-Y coordinate (0-7) 
    to the specified colour (HEX)');
    this.setHelpUrl('http://www.example.com/');
  }
};

now add  <block type=”_pixel”></block> into the index.html

06

remember?

Your toolbox will now have _pixel, and your javascript can reproduce the custom block.

Extra fine tuning:
remember the pre-assembled block?
Use the maths tool to pre-insert the number  blocks, insert the XML into the index.html

generator

The Python generator ‘writes’ a bit of Python code using  java-script. We need x, y, r, g, b
Set the generator to Python, copy and past the script under your previous entry in the SHat_LED.js file

////////PYTHON///
////////_pixel//////
////////////////////

Blockly.Python['_pixel'] = function(block) {
  var value_x = Blockly.Python.valueToCode(block, 'x', 
  Blockly.Python.ORDER_ATOMIC);
  var value_y = Blockly.Python.valueToCode(block, 'y', 
  Blockly.Python.ORDER_ATOMIC);
  var colour_colour = block.getFieldValue('colour');
  // TODO: Assemble Python into code variable.
  var code = '...';
  // TODO: Change ORDER_NONE to the correct strength.
  return [code, Blockly.Python.ORDER_NONE];
};

change var code = value_x + ‘,’ + value_y + ‘,’ + colour_colour;
this will result in (example)   = 1,4,#123456

opps.. and needed  x, y, r,g,b.… lets convert the colour_colour into RGB with a function

add the function to the top of your script

///// convert a hexidecimal color string to 0..255 R,G,B
function HexToR(h) {return parseInt((cutHex(h)).substring(0,2),16)}
function HexToG(h) {return parseInt((cutHex(h)).substring(2,4),16)}
function HexToB(h) {return parseInt((cutHex(h)).substring(4,6),16)}
function cutHex(h) {return (h.charAt(0)==”#”) ? h.substring(1,7):h}
/////////////////////

and change the var code to

var code = value_x + ‘,’ + value_y+ ‘,’ + HexToR(colour_colour) + ‘,’ + HexToG(colour_colour) + ‘,’ + HexToB(colour_colour);
return code;

2 ) Make a new block  ‘set_pixel’

our goal (in Python):

from sense_hat import SenseHat
sense = SenseHat()

sense.set_pixel(..       …)

09

follow the link to blockly factory

remember:

  1. adjust your index.html by adding <block type=”set_pixel “></block>
  2. copy the Language code javascript code and the Generator stub code (Python) to SHat_LED.js.
Blockly.Python['set_pixel'] = function(block) {
  var value__pixel = Blockly.Python.valueToCode(block, '_pixel', Blockly.Python.ORDER_ATOMIC);
  // TODO: Assemble Python into code variable.
  var code = '...\n';
  return code;
};

 

change var code = ‘sense.set_pixel(‘ + value_set_led_field + ‘) # (x,y,r,g,b) \n’;
Blockly.Python.definitions_[‘sensehat’] = ‘from sense_hat import SenseHat\nsense = SenseHat()\n’;
// the previous line will import SenseHat once (very handy)
return code;

More on  create you own custom blocks:
https://developers.google.com/blockly/guides/create-custom-blocks/

at tip: save your blocks by coping the XML in a text file, then at a later moment you can load your bloacks by pasting the XML in the XML tab.

 

if you are intrested in the code head over to: https://github.com/niceprogram/blocky_raspberry_pi_sensehat