SenseBoard, Raspberry Pi and making them talk with Python 3

Share

Read on to find out how I made a Raspberry Pi talk to a SenseBoard using Python, and how you can do it too.

R-Pi SenseBoard

Two tiny devices, lots of big potential

Fair warning: what follows is quite a lot of largely irrelevant ramble. To skip straight to the code, click here.

A while ago I studied the Open University’s TU100 – My Digital Life course. A big part of this course involved [extremely] basic programming using an OU developed version of Scratch; Sense; and a sensor equipped piece of hardware called the SenseBoard.

Around the same time as starting this, I was excitedly awaiting delivery of my Raspberry Pi. Instantly, the idea of somehow making the SenseBoard and R-Pi work together appealed to me. Of course Arduino users were immediately off the starting mark with Python, easily writing programs to make their R-Pis and Arduinos interact with one another in no time. Unfortunately, the only way to talk to the SenseBoard (as far as I knew at the time) was via the OU’s Sense software, which although fairly flexible didn’t allow much interaction outside of it’s own VM (although it does have the ability to post to an RSS feed and read/write files so it’s still a great jump off point for new programmers).

Time passed, uni work got more involved and I largely forgot about my plans for the R-Pi and SenseBoard, until now.

I recently volunteered as a mentor at the Young Rewired State Festival of Code – a really fantastic event organised every year all over the UK (in fact, it’s now spread to Germany and New York too!) to get young programmers aged 18 and under together for a week to code something together. It was a fantastic and inspiring week, and I recommend you go and read more about it here: https://youngrewiredstate.org/

By chance, Martin O’Hanlon (of <Stuff about=”code” /> fame) was a mentor at the same centre as myself and showed us some of the interesting projects he’s been doing with his multitude of R-Pis (Car Cam anyone?). After spending the weekend seeing some of the fantastic projects the youngsters had come up with, including many utilising the R-Pi and Arduino, I was inspired to get home and start working again on my SenseBoard.

My first port of call, of course, was the Raspberry Pi forums where I immediately came across this post. I read with interest about serial interaction (something I’ve never looked at before) and then discovered a very useful post from a user by the name of berry120. They had provided a link to a document they had been working on, detailing all of the possible commands that can be sent to the SenseBoard as well as the responses to expect – exactly what I needed to get started! (The link inside that post appears to be broken, however a Google search turned up a working link here)

After a couple of hours of playing with PySerial, I finally managed to get connected to the SenseBoard and could turn LEDs on and off. Great! With a little more work, I was also receiving sensor values and in no time at all had written a basic Python script to turn LEDs on in sequence as I slid the SenseBoard’s slider. Exciting! And so, here’s how to talk to your SenseBoard (and some pitfalls to avoid!)

The first thing we need to do is determine which port the SenseBoard is connected to. Under Raspbian, I found the default port was ‘/dev/ttyUSB0′. We also need to tell PySerial the baudrate that the SenseBoard operates at which, thanks to berry120′s document, we know is 115200. I wasted a lot of time here as I’d previously skim read Sense’s source code (available here) which stated the baudrate is 38400 – presumably this refers to the GoGo board which the SenseBoard seems to be based on.

Once the serial interface is connected, it’s simply a case of transmitting the necessary messages to the SenseBoard as detailed in berry120′s document. Here’s where I hit another stumbling block – these messages are always preceded by two header messages; all three bytes must be transmitted individually! This may be common to all serial interfaces but as this is my first time using one I feel it’s worth mentioning; I won’t admit how long I spent head scratching that my byte array did nothing!

I’m working on a wrapper class which I’m calling PySense which will make interacting with the SenseBoard as simple as possible. The problem at the moment is that each set of sensor values is sent as 3 bytes and these must be read and parsed to get a usable value. Doing this on the fly in Python (at least on the R-Pi) causes you to gradually fall out of sync with the data being transmitted back from the SenseBoard. The aim of PySense is to provide a set of common functions (such as toggling LEDs on and off) and constantly up to date sensor values, as well as providing buffered IO to prevent situations whereby you are trying to read and write to the SenseBoard at the same time, causing PySerial to throw an exception. It’s almost ready for an initial release, but still needs a couple of bugs ironing out.

In the meantime, here is a simple Python script demonstrating how to connect to the SenseBoard, send a message to start monitoring the status of the button and then cycle all of the LEDs on and off when it is pressed. There’s a short video showing what should happen, then the full code for you to play with. Enjoy!

import serial
import time

# connect to SenseBoard 'sb'
sb = serial.Serial('/dev/ttyUSB0', '115200', timeout=0.2)

# send message to sb that we want to reset it
# I find this is good practice when testing to ensure no LEDS
# or sensors from previous code runs are still active
sb.write(chr(0x54))		# header part 1
sb.write(chr(0xFE))		# header part 2
sb.write(chr(0x10))		# 'Reset'
time.sleep(2)

# send message to sb that we want to receive data from the button sensor
sb.write(chr(0x54))			# header part 1
sb.write(chr(0xFE))			# header part 2
sb.write(chr(0xA0))			# 'Burst Mode'
sb.write(chr(0b00001000))	# sensors selected by on bit,
							# from right to left (button is sensor 4)
time.sleep(2)

while sb.isOpen():
	rcv = sb.read(1)	# read first byte
	if rcv:				# check we succesffully read the byte before
						# acting on it
		"""
		as PySerial communicates in chars and 0xC (the receiving
		message header) is equal to 'U', I found it best to always
		convert the byte to an int for readability
		"""
		if type(rcv) == str:
			rcv = int(ord(rcv))
		else:
			rcv = int(rcv)

		if rcv == int('0xC', 16):	# if we received a header, we know the next
									# two bytes are data
			data = bytearray([sb.read(1), sb.read(1)])	# read our two data bytes

			"""
			next we seperate out the high 2 bits for the sensor number
			and the remaining 10 bits are the sensor's value
			if you're unsure how this works, there is a good article
			on bit manipulation here: <insert link>
			"""
			sensor = data[0] >> 4
			value = (data[0] << 8) & 1023 | data[1] & 0xFF

			if sensor == 3:	# confirm value corresponds to button

				"""
				all of the SenseBoard's sensors return a 10 bit value
				some, like the button, return a boolean value in the form of
				all 10 bits 'on' (1111111111 == 1023) for True or all 'off'
				(0000000000 == 0) for False
				"""
				if value == 0:	# indicates button is pressed
					"""
					each LED can be turned on/off by sending the appropriate
					message followed by a series of bits, with each of the
					bits 1 thru 7 representing an LED. Here, we will use bit
					shifting to turn on all the LEDs one by one, then off
					again in reverse
					"""
					LEDbits = 0b00000001
					for i in range(0,6):     
						sb.write(chr(0x54))			# header part 1
						sb.write(chr(0xFE))			# header part 2
						sb.write(chr(0xC1))			# 'LED On'
						sb.write(chr(LEDbits)) 
						LEDbits = LEDbits << 1		# shift bits 1 to the left
						time.sleep(0.2)
                        
					for i in range(0,7):    
						sb.write(chr(0x54))			# header part 1
						sb.write(chr(0xFE))			# header part 2
						sb.write(chr(0xC0))			# 'LED Off'
						sb.write(chr(LEDbits)) 
						LEDbits = LEDbits >> 1		# shift bits 1 to the right
						time.sleep(0.2)

3 thoughts on “SenseBoard, Raspberry Pi and making them talk with Python

  1. Reply Lisa Mar 11,2014 1:25 pm

    Hi Josh!

    :) I stumbled onto your post here whilst searching about possibly trying to make use of the GPIO pins on the SENSE board, yours is the only one I have found that has done anything like it. So I was wondering if, when working out about connecting SENSE to the r-Pi you managed to work out how to use those pins? (or, would I be better getting an Arduino? )

    Thanks,

    Lisa

    • Reply geekjosh Mar 11,2014 8:42 pm

      Hi Lisa,

      I’m afraid I didn’t look at the GPIO pins on the SenseBoard – just out of curiosity, are they attached now? On my early model, there is no sign of GPIO but it was presumably one of the first batch (I did TU100 on it’s first run).

      I think the first problem you’d have to overcome would be to make them actually transmit any data… it’s possible they already do, as why else would they be present? Unless the OU plans to make use of them in future but is not doing so yet.

      Your best bet will be to dive in to Sense’s source code (available here: http://sense.open.ac.uk/) and see if you can find any information about the GPIO in there.

      Let me know if you find anything interesting and good luck! :)

      Josh

  2. Pingback: Python + Sqlite

Leave a Reply

Please note that the Akismet spam filter is in use on this website. If your comment does not appear and there is no message explaining why, please contact me so that I can remove your comment from the spam.