Boogie Board Rip on Linux
I’m fed up of making notes on scrappy bits of paper that I lose, so with some money I got for Christmas I got myself a Boogie Board Rip. I’m not going to do a full-blown review here, but essentially it’s an etch-a-sketch on top of a portable graphics tablet. The graphics tablet bit is battery powered, and converts what you draw to PDF. The PDFs can be accessed by plugging the board into a PC via a Micro USB cable. Some people complain that it’s not very good for drawing, but I only wanted it for writing and it’s great for that.
After using the board for a couple of days, it turns out that as well as appearing as a USB storage device when plugged in, it also appears as a human interface device and spits out a stream of binary (32 bytes of it to be exact) for each event that occurs on the device (button presses, movement of the stylus, etc). With a bit of help from the aforementioned blog post I’ve managed to decode the binary and write a short Ruby script that reports what’s happened each time you do something.
The script as it stands at time of posting is shown below. The latest version is available on github.
begin lsusb = `lsusb` if lsusb.split("\n").select{|l| l.include? "2047:ffe7"}.count == raise "Boogie Board Rip not currently connected" end begin dmesg = `dmesg` bbdev = dmesg.split("\n").select{|l| l.match "2047:FFE7.*hidraw[0-9]"}.pop.match("(hidraw[0-9]+)").to_s raise RuntimeError if bbdev.empty? rescue NoMethodError, RuntimeError raise "Boogie Board Rip detected, but device's path could not be determined" end events = [] threads = [] thread = Thread.new do board = File.new("/dev/"+bbdev, 'r') while true do data = board.sysread(32) event = Array.new() data.bytes { |b| event << b } events << event end end threads << thread thread = Thread.new do previous = Array.new(32, ) current = [] while true do current = events.shift next if current.nil? if current[10] != previous[10] state = current[10] pstate = previous[10] lock = 32 erase = 4 wake = 2 if (pstate == pstate | lock) && (state != state | lock) puts "Board unlocked" elsif (pstate != pstate | lock) && (state == state | lock) puts "Board locked" end if (pstate == pstate | erase) && (state != state | erase) puts "Erase released" elsif (pstate != pstate | erase) && (state == state | erase) puts "Erase Pressed" end if (pstate == pstate | wake) && (state != state | wake) puts "Wake released" elsif (pstate != pstate | wake) && (state == state | wake) puts "Wake Pressed" end end if current[3] != previous[3] state = current[3] pstate = previous[3] detected = 32 contact = 1 if (pstate == pstate | detected) && (state != state | detected) puts "Pen Lost" elsif (pstate != pstate | detected) && (state == state | detected) puts "Pen Detected" end if (pstate == pstate | contact) && (state != state | contact) puts "Pen contact lost" elsif (pstate != pstate | contact) && (state == state | contact) puts "Pen contact detected" end end cury = current[4]+(current[5]*256) curx = current[6]+(current[7]*256) prey = previous[4]+(previous[5]*256) prex = previous[6]+(previous[7]*256) if cury != prey || curx != prex puts "Pen moved from ("+prex.to_s+","+prey.to_s+") to ("+curx.to_s+","+cury.to_s+")" end previous = current end end threads << thread threads.each{ |thread| thread.join} rescue RuntimeError => error puts error end
It’s very rudimentary at the moment, and needs to be run as root so the device can be accessed, but hopefully with a bit more hacking I’ll be able to get something graphical up and running. It also strikes me that you should be able to use the Boogie Board like a Wacom tablet if someone would be good enough to write a device driver. It’s a bit beyond me but the information’s pretty much all there in the script!