A Monome-like 4x4 tilable pad with RGB leds

Similar projects worth following
Do you know Monome? It's a great interface for making music.
There has been some inspiring projects derived from it.
Arduinome intend to emulate the original Monome on an Arduino-based design.
Chronome is a colored one, with velocity-sensible buttons.
Sparkfun makes break-out boards and pads to build one.
Adafruit also have Trellis.

Unfortunately, all these solutions have their drawbacks to me. Arduinome and Chonome both seem to be stopped projects.
Sparkfun's button pad can handle RGB leds, but it's far bigger than the original monome, and you have to design a circuitry with shift registers to handle buttons and leds.
Adafruit's Trellis is right in size, is controlled by I2C but is limited to 8 boards (128 buttons max), and you cannot dim led independently.

This project is for solving those issues. It's a Trellis-size board compatible with their 4x4 elastomer pad, which has RGB adressable leds and a total of 32 possible I2C adresses which runs on

Monome is great. But I sometimes regret that it cannot be used as a single, "real" music instrument.
Trellis from Adafruit can be used to build one. With Arduinome it can be handled like a monome would be, and run alongside of a computer running Max or PureData.
You can also use an Arduino Leonardo board, and make it appear like a MIDI device.
Last, you can also generate sounds directly on the board using wave tables, pwm and a low-pass filter. The synth is really good at that. You can even extend the number of channels to 8.

But to me Trellis has three drawbacks:
— You cannot use more than 8 boards together, because of the chip restricted addresses. That's sad because music uses 12 notes per octave, a 12x12 monome would be great... But that's 9 Board. And a 16x16 would be even nicer!
— You can reduce led intensity for a whole 4x4 panel, but not for one specific led.
— The pad triggers when pressed around 250g, which is a bit to much. A softer press would make it more playable.

So, with these goals I started designing something in the spirit of Trellis, which is compatible with their silicone pads.
SK6812 mini leds are used. They are the same as the adafruit NeoPixel, but in a 3,5x3,5mm form factor. With these leds independent dimming will be possible, so as color. These leds are daisy-chainable up to 1024, and they use only two pins for data, one for data in, the other for data out to the next one.
Arduino is used to drive the leds and the button. This is nice because it can be used as an I2C slave device, with any address we want. It also can be reprogrammed if needed.

I project to design a softer pad too, with trigger pressure around 100 - 150grams, but silicone molding is something I don't know yet, so for know it will use the original Trellis pad from Adafruit. And having one made for me would probably be quite expensive...

  • 1 × Atmega328p Microprocessors, Microcontrollers, DSPs / ARM, RISC-Based Microcontrollers
  • 16 × sk6812 mini Addressable led (neopixel-like) in a 3535 form factor
  • 5 × 100nF capacitor decoupling capacitr on tension supply
  • 3 × 10KOhm resistor pullup resistor for I2C lines and CPU reset

  • Time to create another thing ?

    Pierre-Loup M.03/22/2019 at 23:59 0 comments

    About a week ago, I was looking for something to do... And I decided I would come back to this project, and see what was needed to finish it.

    There were two things I wanted to improve.
    The first one is that I forgot to put a diode before each button, so there were phantom pushes... not a big deal, even if there is not that much room left on the board.
    The second one was that I find the pad from Adafruit to be a bit too hard to push to make it comfortable to use as a musical instrument, so I was looking at a way to design my won silicon pad.

    I was wondering if maybe Adafruit could have update their pad in that way... And the ndiscovered that they have just made the NeoTrellis, which does... exactly what Moka does.

    So, time to move to another project ! :)

  • SK6812mini pinout...

    Pierre-Loup M.09/19/2017 at 17:00 0 comments

    Do you remember that previous log where I was talking about the SK6812 pinout? I was surprised to see two different pinouts for the same led...
    When I did the first tests on the boards I've received, I couldn't succeed in programming them. The Arduino used as ISP was shutting down when connected to the board. I didn't have much time for further testing, so I put it aside for a few weeks. It appeared there was a short somewhere on the board, with ground and VCC being tied together. And it soon appeared that it was coming from the leds, because when not mounted I was able to upload the program.
    And the problem was of course these leds' footprint. In fact there are two different one, one for the 5050-sized leds, and one for the 3535 ones. And of course they don't match, unless you turn the led 90°, but then the leads are not exactly matching the pads on PCB. So by turning leds around 80° instead of 90, I was able to test boards!

    A new batch of newly drawn boards have been ordered today. With a few other minor corrections... Wait and see!

  • Writing code...

    Pierre-Loup M.06/27/2017 at 22:54 0 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.

  • Choosing a pinout, setting a logo on silkscreen...

    Pierre-Loup M.06/25/2017 at 10:21 0 comments

    I've spent half a day redeisning the boad, because of a wrong led pintout. Can you believe it? If you look for "SK6812" in google, you will find two pinouts. I've stuck to the one of the datasheet that is chared by Adafruit for their Neopixel. Hoping that it will be fine.
    A few hours to design a logo for the board, because it's soo cool! And another half day to understand how a svg file can be imported in Kicad. It's a real pain to do! Kicad has dxf import capability, but can only manage lines. There are scripts for Inkscape to export such dxf, but I couldn't have it run... I eventually realised there is a module in Kicad that transforms an image into a footprint. But it took another hour to figure out that this module can open png files (the only image file type you can export from Inkscape), but cannot make a fotprint out of it.

    So, svg to png in Inkscape, png to jpg in Gimp, jpg to footprint in Kicad, and in the end I have nice silks on my board!
    And I could order a batch of prototypes! :)

View all 4 project logs

Enjoy this project?



Per-Olov Jernberg wrote 08/16/2018 at 22:15 point

this looks perfect, i was modifying the boards myself to fit regular neopixel leds, but they were too big for the pads, and i didn't know there was smaller ones...

  Are you sure? yes | no

psynautic wrote 12/19/2017 at 22:38 point

Do you think that v0.95 is at a point that's safe for me to get some boards printed? Or should I wait for you to do some more finalization?

  Are you sure? yes | no

Pierre-Loup M. wrote 01/12/2018 at 15:02 point


This project is unfortunately stand by... the v0.95 boards do work, with two limitations:
First, there is a missing via on the 16th led's GND, so it has strange behavior. The schematics in v0.96 is fixed, but boards have not been ordered.
The second limitations is coming from buttons read: they are disposed as a matrix, and they share their pins: there are one for each row, and one for each column. Row are read sequentially, by turning their pin LOW, then each column pin is read. I think you see it coming: without diodes on each button, when three different ones are pushed with one being on the same row as the second and on the same column as the third, a forth is registered as pushed two... So I'll have to figure out how to add 16 diodes on the board...

That said, they work well: I've mounted two version for testing, one with only board, and the other with 4 boards mounted 2x2.

There are yet choices to be made for the firmware on the boards: I intended to have the possibility to command leds by using either full RGB values (8 bits per channel) either 1 bit limited set of color (AARRGGBB). This one bit limited set works well, but the full one faces a problem: updating a full board with full set would be at least 48 bytes to send via Wire (plus addressing and register selection), and Arduino limits its Wire buffer to 32 bytes. I don't know yet what decision should be took. Maybe using different library versions, following what's intended.

But his works too. I've written several patches for puredata to test them.

For board firmware, you can use either master or dev, the differences are in the comments only. Dev is fully commented on twi file, which can be usefull.

For Arduino library You can use master, it's up to date.

  Are you sure? yes | no

psynautic wrote 01/12/2018 at 16:53 point

Since the 368p has 2,048bytes of SRAM, have you thought about increasing the buffer for the i2c to solve that problem.

afaik you can just do this in the arduino wire lib:

Also i get a sense you're plan to use the default 8mhz worked as well as expected?

  Are you sure? yes | no

Pierre-Loup M. wrote 01/12/2018 at 19:10 point

You are right, the buffer size can be extended. Altough it would not be a problem on the board itself as there is some room (the sketch uses 11%, and global variables 18%), it can be on the Arduino you plan to use these boards with: according to what you wanna do you can run out of memory pretty quickly! And as you said, you have to modify the core libraries, which I don't like to do, because not anyone knows how to do it. With the updated architecture of Arduino it could be done by adding a new "hardware" board.
This is only a problem if using 24bits RGB values. 8 bits ARGB works well and give sufficient control of the leds for most projects (64 colors * 4 intensity steps). Each led has its current state independently set, so you don't have to set the color to 0 to shut it, neither to set the color again when you light it.

The 8 MHz onboard clock works as expected, yes. I thought I would use a timer interrupt to update leds (the data stream has to be quite fast for them!), but it was too slow, updating only the first few led reliably. I've switched to an ASM chunck of code for that, inspired by code from PJRC and Adafruit.

  Are you sure? yes | no

Nathan Stanley wrote 06/28/2017 at 01:18 point

Interesting project! I am an electronic musician myself so this could be something useful for me, especially if it's in some way customisable. If you're worried about the speed for PWM control of the LEDs, why not run the ATMEGA328 with a 16MHz external crystal instead of 8MHz internal?

  Are you sure? yes | no

Pierre-Loup M. wrote 06/28/2017 at 08:05 point

There are two reasons I chose to run on the internal 8MHz oscillator instead of a 16MHz (or better, 20Mhz, as atmega 328 handles it) external crystal.
The first one is cost saving. A smd crystal doesn't cost much, but I wanted to keep the price as low as possible: when using several boards together I think it can make a difference in the end.
The second one is space saving: putting 16 button traces, 16 led, 5 address jumpers on a 6x6cm board isn't much a problem, but if we want something that is easy to mount in an enclosure, their are a few more constraints, like clearing the back surface of components in front of the mounting holes, both horizontally and vertically, as well as the sides. And this lets very few room left for anything!

But the thing is also I knew the  atmega could run on internal oscillator, so I designed the board this way, and a then ordered a batch of prototypes. And then discovered that the oscillator was a 8MHz one! :D

  Are you sure? yes | no

Similar Projects

Does this project spark your interest?

Become a member to follow this project and never miss any updates