Writing code...

A project log for Moka

A Monome-like 4x4 tilable pad with RGB leds

Pierre-Loup M.Pierre-Loup M. 06/27/2017 at 22:540 Comments

I've been in the process of writing code for the board for two days now.

First part is of course the code that will run on the board. I spent some times looking for something efficient for I2C communication. Usually I2C is used with chip that do a special job (like driving a led matrix, reading light intensity, etc.), and have registers that you set and read, whom are described in the datasheet. But the Atmega 328p that is the main components of most Arduino and this board is an "empty" component. So registers have to be write from scratch. And as it could be up to 32 boards running together, communication has to be quite efficient!
I've tried to distinguish led and buttons reads for more general commands:
Commands addresses are composed of arbitrary bits. In order to save bandwidth, when a setting has a boolean as parameter, the parameter is included as the LS bit of the address. An example would be Display state turned on when sending 0x01100001, and off whe nsending 0x01100000.
Led and button addresses are composed of the four MS bits designing the setting to modify, and the four LS bits corresponding to the led or button ID. That way we can save one byte of data for each command.

Each SK6812 led needs three bytes of data to set their three colors. One for each of red, green and blue. But as this is an interface and not a display, maybe having that much color isn't a real need. So the color can be handled in two ways. The heavy one is to set the complete color for each led. When updating a whole panel you got 72 bytes going from control boad to Moka. But there's a lighter way to manage color: having each color set on two bits, you can have 64 colors, and that left two bits unused. So the lighter mode is to define a color with a 0xAARRGGBB byte, with an alpha channel. So intensity can be set for each color. The I2C is happy with only 16 bytes to update a whole panel, and the program running on board computes corresponding value for leds when receiving commands.

Another big deal is the led data stream: these leds need a waveform that give both the bit stream and the clock reference. Each 1 is to be sent as a 0,6us high level followed by a 0,6us low level, and each 0 is a 0,3us high level followed by a 0,9us low level. Running ont he internal chip oscillator at 8MHz, a low level is 2,4 clock cycle. So that part has to be really efficient! Adafruit and pololu have libraries for driving this kind of led, and both use direct ASM programming for that purpose. I hope I can rely on PWM for that. For each cycle I have to update the PWM value according to the bit to be sent, and I don't know if it will be fast enough. I'll give it a try when I will receive the leds. If not, I'll have to learn ASM!

The other part of code is of course th library users will use to run the Moka board. I've started to work on it today, but this part is easier.
For now it can handle a board, with all necessary functions implemented. One can set a led color or brightness (that is linked to color, as explained above), read switch, update display. The I2C can be set both normal (100KHz) and fast (400KHz). I hope it will be fine, but I've never had problem on Arduino running fast I2C.
Color can be set for one led of for global panel, thus saving data stream.

The next step is to create a global object that handles all needed board has a big one. I'll look at it in the days to come.
And the step after will be to port a library I had written for Trellis to this board, that handles a virtual pad larger than the physical one, trough which we can move. As if the physical pad was a window openned over a larger one.

But for now, I'm gonna go to bed. :)

The github repositories have been updated, feel free to share your toughts.