• Save 15% on ALL SFF Network merch, until Dec 31st! Use code SFF2024 at checkout. Click here!

Stalled Iris 16 - RGB Vandal Button

iFreilicht

FlexATX Authority
Original poster
Feb 28, 2015
3,243
2,361
freilite.com
Small update.

Just got a quote for the LED-Ring PCB, so I'll give a little bit of insight into how much prototyping a PCB actually costs:

The 20 pieces for the first production run will cost 29.75€ each to produce, and that's only one of three PCBs. If the design isn't changed afterwards, a single piece will cost 4.85€ in a run of 100 pcs. If I have to make adjustments, one piece would cost 8.04€. A huge part of the cost is the cutting of paste stencils and films. And keep in mind, I panelized the PCBs myself to save money on payed design work by the manufacturer.

I hope this also goes to show how important a solid margin is when selling electronics like these in low-quantity production runs. The prototype parts, especially failed ones, cost an awful lot of money, and that cost has to be spread out over all the sold units equally.
 

HeroXLazer

King of Cable Management
Sep 11, 2016
707
476
Small update.

Just got a quote for the LED-Ring PCB, so I'll give a little bit of insight into how much prototyping a PCB actually costs:

The 20 pieces for the first production run will cost 29.75€ each to produce, and that's only one of three PCBs. If the design isn't changed afterwards, a single piece will cost 4.85€ in a run of 100 pcs. If I have to make adjustments, one piece would cost 8.04€. A huge part of the cost is the cutting of paste stencils and films. And keep in mind, I panelized the PCBs myself to save money on payed design work by the manufacturer.

I hope this also goes to show how important a solid margin is when selling electronics like these in low-quantity production runs. The prototype parts, especially failed ones, cost an awful lot of money, and that cost has to be spread out over all the sold units equally.
Hey, I'm just wondering, what's the best way to panelize PCBs in KiCad?
 

iFreilicht

FlexATX Authority
Original poster
Feb 28, 2015
3,243
2,361
freilite.com
Hey, I'm just wondering, what's the best way to panelize PCBs in KiCad?

Manually :( You have to create a new pcb file and use "Append PCB" to place your fully finished single PCB on it. Then "Create Array" to make an array of them and from there work out the outer panel with fiducials and testing traces and all that. I'd recommend noting down your array dimensions so you can update the panel easily after changes on the single PCB.
 

iFreilicht

FlexATX Authority
Original poster
Feb 28, 2015
3,243
2,361
freilite.com
Just to keep you guys in the loop, I left the form open because only 9 people answered it. So those 9 will all get a button, and if anyone else still wants to join, they can.

However, I made a small mistake when calculating the cost. I didn't understand that the initial offer I got didn't include the actual parts for the PCB, even though it did include the assembly. So we're looking at 42.5€ per LED ring now. So now, before going forward, I'll have to ask for quotes for all parts, otherwise it could very well be that I run out of money before the buttons are finished.
I could of course start crowdfunding then, but I really don't want to do that unless I have a working prototype and am 100% certain that this will work.

Worst case I'll have to reduce the number of prototypes I produce, in that case I'll only consider the first 9 answers for the prototype run. I do want to have at least 2 leftovers (ideally more) that I can send out for review during the campaign.
 

iFreilicht

FlexATX Authority
Original poster
Feb 28, 2015
3,243
2,361
freilite.com
Update! Programming troubles.

TL;DR: Software is going forward, but there's only enough storage for 1 second of animations.

Currently, I'm trying to test the Mass Storage implementation that will be running the data transfer. That has already consumed a lot of time, but with every step I'm getting more confident that it will work the way I want at some point. The issue is that nobody seems to have ever attempted doing this with an Arduino, so I have to implement part of the USB Mass Storage Class on top of the existing implementation for plug-able endpoints in the Arduino Library. It's important to do it this way because it means that - unlike many programmable keyboards - the button won't have to be reset to be re-programmed, e.g. when installing a firmware update.

Initially, I had the idea to implement this as part of the bootloader, but that is not recommendable because it means that this part of the firmware couldn't be updated easily. Ideally, the bootloader should do as little as possible.

Now, for an excursion into the world of memory:

The Atmega32u4 I'm using has (as most microcontrollers) three types of memory. EEPROM (1KB), SRAM (2.5KB) and Flash (32KB).

Flash memory is the part that stores the program and constant data like pin mappings. You can think of that as the hard-drive of the chip that contains the operating systems and all programs you can run. It has 10,000 write cycles and is only writable during programming, so during firmware updates or when uploading a sketch with the Arduino IDE.

SRAM is very similar to the RAM in your PC. It is volatile, so it will lose its contents when not powered. It can be written to as often as you want.

EEPROM is a small additional portion of memory that can be written to while the program is running and that will keep its contents even without power. Here, the animation and configuration data will be stored so that the user can modify them as often as they want to. EEPROM also has limited write cycles, at least 100,000. Much better than flash, but no match for SRAM.

Now, why is this important? Well, the EEPROM limits the amount of animations that can be stored on the button.
We only have 1024 bytes at our disposal, and we need a few for configuration storage (pin configuration, colour mode, high frequency mode, beginning and end of each animation). Let's set 25 bytes aside for configuration, so we have 999 left. Now, each LED can display three colours, each of which needs one byte to store. With 12 LEDs, this means that one single frame of an animation is 36 bytes large, which means we can only store 27 frames. At 30FPS, that is less than 1 second worth of animations.

Oops, not good.

Additionally, SRAM is only 2560B large, so even if we send animations from the PC, the maximum length for a single animation would be 2 seconds, as long as we interpolate between frames on-the-fly to reach the maximum FPS the button supports.

So, I'm trying to solve this now as well. I do have a few ideas, but I think there's no getting around the fact that it won't be possible to simply store animations as a series of frames. Serious bit-stuffing will have to happen.

Thanks for reading!
 

Bruman

Trash Compacter
Feb 24, 2017
47
37
Could you store something like 2 colours and an int, and have the programming on the Arduino programmatically change the LED colours between those two colours taking $int seconds? I mean, it's not the best, and means you can't have hugely complicated animations in terms of FPS but it's a compromise.

Note I haven't messed with an Arduino since last year, or the lower level storage and processing, so might be rusty.
 
  • Like
Reactions: ricochet

The Dude

Chassis Packer
May 25, 2016
13
8
8-bit color palette will give you 2.7 seconds (you can store and choose different palettes from flash). Even more if you willing to compromise on True color and 30FPS. But yeah, frame animation with constant frame rate is a dead end with 1kB. Your best bet is a variable frame rate with some compression and probably parametric representation.
 
  • Like
Reactions: ricochet and Phuncz

iFreilicht

FlexATX Authority
Original poster
Feb 28, 2015
3,243
2,361
freilite.com
Could you store something like 2 colours and an int, and have the programming on the Arduino programmatically change the LED colours between those two colours taking $int seconds? I mean, it's not the best, and means you can't have hugely complicated animations in terms of FPS but it's a compromise.

Note I haven't messed with an Arduino since last year, or the lower level storage and processing, so might be rusty.

Yes, that's one idea. This falls under the general idea of "parametric representation" that @The Dude mentioned.

There might be different ways to do this and extend your idea, for example one could also define a movement velocity for a segment, so you could have a dot that spins around once every second and changes its colour from orange to white and back every four seconds.

Very complicated animations will have to be programmed directly as an Arduino sketch anyway, the user just gets much more freedom there than I could ever give them.

8-bit color palette will give you 2.7 seconds (you can store and choose different palettes from flash). Even more if you willing to compromise on True color and 30FPS. But yeah, frame animation with constant frame rate is a dead end with 1kB. Your best bet is a variable frame rate with some compression and probably parametric representation.

I think at a certain point, variable frame rate will just lead to keyframing, which might be a better approach in the first place.

Very interesting idea with the colour palettes, that might indeed allow to get more subtle colour changes without increasing the size of an animation, and would decouple movement patterns from the colour.

Perhaps it might also be a good idea to store certain complicated movement patterns in Flash as well, which could then be addressed in the configuration to further increase the space for custom animations.
 
  • Like
Reactions: ricochet and Phuncz

The Dude

Chassis Packer
May 25, 2016
13
8
Perhaps it might also be a good idea to store certain complicated movement patterns in Flash as well, which could then be addressed in the configuration to further increase the space for custom animations.
Something like MIDI/FM synthesys might work. Where 12 LEDs are 12 channels and flash contains bank of instruments (functions) that play on a loop until changed. So a command would consist of: channel_id, instrument_id, frequency, length, starting_color.
 

iFreilicht

FlexATX Authority
Original poster
Feb 28, 2015
3,243
2,361
freilite.com
Something like MIDI/FM synthesys might work. Where 12 LEDs are 12 channels and flash contains bank of instruments (functions) that play on a loop until changed. So a command would consist of: channel_id, instrument_id, frequency, length, starting_color.

Oh, very interesting idea. This might actually allow pretty much any effect to be encoded very densely.

Not sure what kind of functions I'd actually implement. The only thing I have in mind are periodic blinks with different combinations of attack, sustain and release values, as well as always on. For more complicated blinking patterns, one could then play multiple functions on one channel.

I think I need a few basic animations to evaluate the effectiveness of each approach, because some approaches will work better for some animations than others, and I need a good middle-ground.

I know builders get a lot of feedback which is good "when filtered". But this forum genuinely amazes me in the level of sharing of information it is fantastic.

@iFreilicht keep up the good work.

Which is exactly why I share so much on here. :) The desire to develop everything in secret and then come out with an amazing product as a surprise to everyone is big, but the feedback I get from all of you during development is so valuable, I wouldn't want to miss it.
It's awesome here!

That and people telling me that I'm doing good work is very reassuring and helps me power through :D