Thursday, 1 November 2012

Windows Phone to Arduino (via Python)

 (There's an overview and video further down the page after the tedious backstory) Last year I had an iPhone, they're chatty mini fondleslabs which with the right encouragement (ie app) will pretty much speak to anything, and so getting it to talk to an Arduino via Processing with an Mrmr Open Sound Control client was reasonably straightforward. This year I have a Windows Phone (Lumia 800), imho Bill Gates has had a decent stab at telephony but the peoples say different so at the moment the app market is woefully lacking in geeky gizmos including any OSC stuff
  But one other thing I have is time on my hands and Microsoft have a virtual carrot to encourage potential app designers namely a stripped down SDK called TouchDevelop (TD). Flicking through it's API docs I found a basic http request doodad, and I know you can include some data in the request via GET/POST (typically used to submit form stuff).

 Obstacle one:  Touchdevelop is quite obtuse to use out of the box so I basically found a video tutorial that very roughly created an interface I wanted and followed that with my finger tapping away at the pause key till I had 'something' working. Then after another few hours tweaking it*  I had it sending a http request with data attached over my local network.

 Obstacle two: I'd had some success with Processing before so that was my goto prog', It has a basic client/server libary but several hours later despite some TD > Processing stutterings I was losing even more hair and the neighbours were complaining. Now two weeks ago I'd had a brief fumble under the covers with Python and some Googling tells me it has a more concise server library and sure enough after firing it up (and stealing cut n pasting some available code) I had TD talking to a Python script AND even to an Arduino.

  Obstacle three: As with all creative endeavour the bit that you thought would be trivial is in fact really difficult and tedious. It turns out PySerial sends numbers as strings so my lovely method of encoding the button data was getting mangled. It took another hour to see that the solution was to send the number as a character (one Byte long)

My Touchdevelop app has four 'buttons'. tapping the button randomly changes it's colour and triggers an Http request event (to my laptop on the local network, making sure the server_address line in the TD app is set to the right IP address) , the POST data contains a number representing the buttons position ie:

Button 1 =  0001  (1)
Button 2 =  0010  (2)
Button 3 =  0100  (4)
Button 4 =  1000  (8)

  Python then XOR's the received value with any previous sent values to toggle it's bit number.
Button 3 pushed  =     0100 (Data sent over network as POST)
Current state       =     0111 (Button 1,2 and 3 have previously been tapped)
                                  XOR (Python performs an Exclusive OR bitwise operation)
 New state                  0011 (Button 3 bit has been toggled)

   Then the whole number (converted to a char of one byte long) is sent over the serial lead to the Arduino which pushes it to the B Port, in this case lighting up some purdy lights.
  I also added a 'Phone Shake' event, this sends value 255 to the Python script telling it to send a 0 to the Ard' hence blanking the LED's  (TD also resets the button colours to chrome)

Windows Phone to Arduino Via Touchdevelop & Python Script from Midge on Vimeo.

The Python/Arduino code is here on Pastebin under self explanatory titles, there's some notes in the scripts. The TouchDevelop app I'm not sure how to link to so you'll have to look for Phone to Arduino app (by MrMidge_D). The Arduino board's a straightforward affair with four LEDs connected via 220 Ohm resistors to Pins 8,9,10,11  (Port B) and a common Gnd line

To Do: Take a holiday :S.more intuitive button feedback (indicating on/off). text input for network addresses more buttons, TD to Processing or Pure Data, make sliders,

*Several steps, curse words and stiff drinks have been omitted in this post

No comments: