Smartphone positional sensors connected to scratch

In a quite popular computer magazine, c’t 2015-03-07 (heise verlag), there is a nice article about how to connect a smartphone’s positional sensors to a remote server by using a web page, some javascript and websockets.

Starting from this, there was the idea to connect this to scratch (what else ?).

The basic roadmap was
– add a html-page to my scratchClient’s web server, with javascript

var addr = "ws://" + window.location.hostname + ":" + window.location.port + 
           "/pendel";
var websocket = new WebSocket( addr );
 
function handleOrientation(event) {
       var x = event.beta%90;
        var y = event.gamma;
        x += 90;
        y += 90;
          try {
                websocket.send(JSON.stringify( { x:x, y:y }));
            }
            catch(err) {
                // console.log( err.message );
            }
    }
    window.addEventListener('deviceorientation', handleOrientation);

– in scratchClient, there is cherrypy used to serve the web pages. WebSocket was a new feature to be added there.

– an adapter needed to be written adapter.websocket.WebsocketXY_Adapter, receiving the messages and converting them to scratch variable updates.

So far the plan.
Websocket implementation in sandbox environment worked well, but as I use ‘routes’ to dispatch the requests it took some time to find the correct setup.
Next finding was that the connection is really performant, and a slow movement of about a second duration provides a hundred messages flowing into scratchClient. This is far above from what scratch is able to handle.

Filtering out messages is starting in the browser. Rounding values to a tenth of a degree and sending values only on change removes quite a lot of values. After some experiments with timers in my android browser I found no viable solution to throttle update rate. Timers seem not to work in this javascript environment. Next step in filtering is in the adapter, taking most current value each 0.05sec and ignoring intermediate values.
Final step of filtering is inside scratch. When using the ‘glide’-move, scratch will ignore intermediate values. When using the ‘goto’-statement, processor load is getting much higher.

When I have seen webSocket working pretty smart, I removed the ajax-updates and webEvents from/to web browser to server. When working on the server side, some legacy code in editing values in browser was rewritten, the svg-generator is smarter now and the underlying event distribution system in scratchClient was replaced by a publish-subscribe pattern.

Installation of scratchClient now needs ‘ws4py’ in addition to cherrypy. See the docs.

Start scratchClient

cd ~/scratchClient
sudo python src/scratchClient.py -c config/config_websocket_pendel.xml -guiRemote

The guiRemote-switch is needed to allow remote browsers connecting to scratchClient.

In a smartphone browser, navigate to your pi’s address. Of course you need a (wireless) network connection between smartphone and raspberry. In my network, the RaspberryPi’s address is 192.168.2.90, most possibly different for your PI. Use ‘ifconfig’ to look it up.

http://192.168.2.90:8080

Navigate to “Smartphone as Sensor” browser

You should see rectangle with a red/green dot moving around. This is as proposed by the c’t-article.

In scratch, enable remote sensor connections and provide the following script. gotoX and gotoY are sensor values provided by the scratchClient. The xl and yl-Variables are local variables in scratch.

smart

The x and y-values are getting exchanged and the y-value gets inverted to match the coordinates of the smartphone to scratch stage.

And thats it. The sprite moves close to the smartphone movements. There is some small time lag on my PI ModelB (not a pi plus so far), but sufficient good.