Reverse ingeneering "Blinky POV"

This open source blinky can get programmed just by pointing it to a couple of blinking squares on a web page (one for clock and one for data). Basically you enter some text in the web page and it converts your text to a binary string and sends it over "visually" to the blinky. I think this is really cool and can see myself using this programming method for many projects but don't fully understand how to do it. The project was not done using Arduino so reading their github repo is not much help.

This is what I know how to do:

  • Create a binary stream from some text or image.
  • Convert a photoresistor's data into 1s and 0s.

These are my questions:

  • This looks like some sort of serial communication but I don't know how to implement this in Arduino. I've gone over the Serial docs but it always assumes that you already have serial data coming in. I need to go one step before this so that I can turn my photoresistor data into serial data.
  • Is there a common serial protocol available that's easy to use? I would need to re-implement this in some server side web technology. This is not really a problem as I'm proficient with web development but I would need to fully understand the protocol before I even attempt this.

I anyone's attempted this before, any help, comments, gotchas, will be greatly appreciated.

Thanks!

Just read the photoresistor at the data rate and shift the resultant bits into bytes. You'll probably need some start and stop bits and a parity bit to ensure your reads are correct.

It has clock and a data so it's probably setting the data square to the bit value (black = 0 / white = 1) and then pulsing the clock square so the blinky knows to read the data and add it to the values already read, much like I2C protocol but a lot slower. It must be sending configuration info on how the message is displayed along with the message data in ASCII/bitmap data. To detect programming errors it must also be sending a data checksum or CRC value. I would also assume the message is stored in EEPROM so you don't need to program it every time it's turned on. It would read the message into RAM and if it checks out then copy into EEPROM.

Reverse engineering an open-source product is an oxymoron. :D

ardilla: The project was not done using Arduino so reading their github repo is not much help.

Arduino and this project are both C, as evidenced by this file from their git repo: https://github.com/wayneandlayne/blinky/blob/master/bootloader/bootloader.c

Whilst not directly compilable via Arduino IDE, there is a lot of useful information to be gleaned from their source code.

Hey there, this is Wayne and Layne, we created the Blinky kits! Glad you like the blinking programming interface, it's pretty slick. We certainly aren't the first people to come up with this sort of thing (the Timex Datalink watch from the 80s, and the BBC Micro computer that could be reprogrammed via a photosensor + tv back in the 70s, were certainly inspiration for these kits), but we really like how simple it can be. Also you don't need to install any device drivers on computer lab computers when we do summer camps and other group projects at schools :)

You can definitely do this on Arduino, but it may be harder than you think to make it work consistently and reliably. We have a lot of design documentation about the details of how it all works: http://www.wayneandlayne.com/projects/blinky/design/

We ended up taking hundreds of data points across multiple screen types in order to get the thresholding between light and dark squares to work reliably for all different types of displays and computers, but if you're just doing it on your own screen you should be able to get it to work pretty well without that. We have the phototransistors paired with resistors, in a sort of voltage divider configuration. If the sensor observes bright light, it conducts very well, and pulls the analog input pin down near 0v. If the sensor observes no light, it doesn't conduct very well, and the pull-up resistor pulls the analog input pin up near the battery voltage.

Start simple, trying to just transmit a byte string and echo it over Serial. We picked a pretty simple line encoding with separate clock and data signals, but there are bajillions of other options. (http://en.wikipedia.org/wiki/Line_coding)

If you had a clockless protocol, you could do it with a single sensor, but usually this costs you in increased transmission time, and you have to recover the clock. We found that javascript isn't very good at being accurate that way, but it's good at displaying multiple squares at nearly the exact same time. Additionally, there is a lot of extra code complexity in your bootloader and transmitter when you are using a clockless signal, while the I2C-like clock+data method is very simple to do (and also takes up less code space, which was a big constraint on the blinky kits).

We use a modified version of the standard Intel HEX file format for our blinky message transmission, which includes a per-"record" checksum (a record is 16 bytes). As as side effect of this, you can actually re-flash the user code in the same way, via the blinky bootloader, but it takes a while to transmit kb and kb of code :)

Since you can store multiple messages in the blinky kit, we have defined a message encapsulation format (also explained on that design page) with a header that specifies the type of message (pixel vs text), the message speed, and other details. We store the messages in EEPROM so they persist even after the power is turned off. With the text messages, we have a font table built-in so you only need to transmit one byte per character, instead of five bytes per character (each character is 5 columns wide).

Thank you everyone for their help. I love it when you mention a project on a forum and the author pops in (thanks wayneandlayne!).

I wish I had read your answers yesterday. I stayed up until 5am working on this and came to a lot of conclusions (a lot of which have been suggested here!).

I made a small sketch that read the values of two photoresistors, turned that into 1s and 0s and after some bitwise operator crunching got my bytes set up. The problem was that I didn't know what those particular bytes meant. Using Firebug I started hacking the Pov programmer webpage and found that there are a few hidden textboxes that hold the data in DEC, HEX, and BIN which is great because I could compare them to what I was getting and check if my receiver was working. It wasn't, but after some debugging I realized the polarity was wrong.

I finally made something that could properly read whatever the Pov programmer was outputting. Then I went to sleep!

You can definitely do this on Arduino, but it may be harder than you think to make it work consistently and reliably. We have a lot of design documentation about the details of how it all works: http://www.wayneandlayne.com/projects/blinky/design/

This link is exactly what I needed. I love the detail you put into describing the serial protocol!

We ended up taking hundreds of data points across multiple screen types in order to get the thresholding between light and dark squares to work reliably for all different types of displays and computers, but if you're just doing it on your own screen you should be able to get it to work pretty well without that.

I don't have the resources to do that so I'm going to go with an extra "Calibrate" button on the programmer that will flash a few times so that I can get min and max brightness values and work off of that. It's an extra step but I think it's good enough for me learning all this.

Regarding storing in EEPROM, that might be a little too advanced for me right now but will definitely look into it as, again, I can see myself using this in the future!

Can't thank you enough for all the info!

Reverse engineering an open-source product is an oxymoron.

hahaha! True! I guess I called it reverse engineering since I didn't understand the source code so it was not much use for me :)

Oh yeah, I had forgotten about the debug info on the webpage! :astonished: If you add "?debug=true" to the end of the URL, like this http://www.wayneandlayne.com/blinky_programmer/?debug=true then the debug boxes show up at the bottom of the screen. message_data is the data that needs to be transmitted to the blinky. xmit_data is the message data after it has been packed into intel hex records. xmit_raw are the 0s and 1s that get flashed out to the screen.

Glad the info was helpful, please let us know if you have any questions. A quick disclaimer on the webpage javascript that does the translation from message data into flashing squares: We aren't really "web guys" and only know enough html, css, and javascript to get the job done. So, it's probably not very optimal, and I'm sure a real web dev could do a better job with it. Let us know if you have questions.

-Matthew Wayne and Layne, LLC

wayneandlayne, I've successfully recreated the whole project from top to bottom thanks to your detailed blog post describing the protocol, Google, Wikipedia, and Stackoverflow. The thing is that with electronics I can't pretend to understand 100% of what's going on -I'm just a hobbyist- but being a software developer I couldn't just blindly copy/paste code so I decided to write my own implementation from scratch and learn what I can from the process.

I've split the whole thing into several libraries that I will publish on github.com. So far I have written these libraries:

  • javascript library that wraps arbitrary data into the IntelHEX format.
  • A jQuery configurable plugin that handles the actual blinking.
  • An Arduino library that calibrates sensors on analog inputs.
  • An Arduino library that converts the readings of two analog sensors (clock + data) into a byte array.
  • An Arduino library that parses and verifies the checksum of the IntelHEX Protocol.

I will post back when all is published and documented.