Features:
- Numbers up to 7 are instantly readable
- Numbers up to 50 can be read by a human with a little head math (or practice)
- Numbers up to 342 can be read by a human with a little calculation
- Can be read at any orientation (don’t need to know which face is 0)
- Number is shown instantly and atomically - no animations
- Uses only fully saturated primary colors (no guessing “is that magenta or fuchsia?”)
- Straightforward code
- Possible to visually see changing values for patterns and direction
Try the included demo to get a feel for how the numbers count up. You get used to it pretty quick.
LMK if you use it or if you have any questions or suggestions or problems!
-josh
// Display a number 0-342 on the LEDs
// The number is shown in base 7 format with red, green,
// and blue being the 1's, 7's, and 49's places respecitively
// A 0 digit is shown as OFF. Digits 1-6 are shown as 1-6 LEDs
// lit with the place color.
//
// 0 = All Off
// 1 = 1 RED
// 2 = 2 RED
// ...
// 6 = 6 RED
// 7 = 0 RED, 1 GREEN
// 8 = 1 RED, 1 GREEN (both on LED 0 so you see yellow)
// 9 = 2 RED, 1 GREEN (you see 1 yellow, 1 red)
// ...
// 48 = 6 RED, 6 GREEN (you see 6 yellow)
// 49 = 0 RED, 0 GREEN, 1 BLUE
// 50 = 1 RED, 0 GREEN, 1 BLUE (you see 1 purpule)
// ...
// 341 = 5 RED, 6 GREEN, 6 BLUE (you see 1 purpule, 5 white)
// 342 = 6 RED, 6 GREEN, 6 BLUE (6 white)
//
// #fin#
void showNumber( unsigned x ) {
// We are the root, so display the accumulated tile count
// Deconstruct the count "digits" into base 7 for display on our 6 LED screen (0 digit=0 LEDs on)
// This also just happens to look nice since we always count ourselves, so count never 0, so screen never totally blank
const unsigned DISPLAY_BASE = FACE_COUNT+1;
/*
byte high = count / (DISPLAY_BASE^2);
byte medium = ( count - (high * (DISPLAY_BASE^2)) ) / DISPLAY_BASE;
byte low = ( count - (high * (DISPLAY_BASE^2)) - (medium * DISPLAY_BASE ) );
*/
byte high = x / (DISPLAY_BASE*DISPLAY_BASE);
byte medium = (x - (high * DISPLAY_BASE*DISPLAY_BASE)) / DISPLAY_BASE;
byte low = x % DISPLAY_BASE;
/*
setColorOnFace( BLUE , medium );
setColorOnFace( RED , low );
*/
FOREACH_FACE( f ) {
byte r=0;
byte g=0;
byte b=0;
// Low 1-6 maps to faces 0-5
// When low==0 then no red
// Note that count never is 0 becuase we always count ourselves
// but count can be FACE_COUNT in when case no red, but green with have 1
if ( (f+1) <= low ) {
r = MAX_BRIGHTNESS_5BIT;
}
// Medium 1-6 maps to faces 0-5
// We do not show any medium when count < FACE_COUNT
if ( (f+1) <= medium ) { // Only show G when we go around at least one time
g = MAX_BRIGHTNESS_5BIT;
}
// High 1-6 maps to faces 0-5
// When do not show any high when count < FACE_COUNT^2
if ( (f+1) <= high ) { // Only show blue when it is more than 0 (count>=36)
b = MAX_BRIGHTNESS_5BIT;
}
setColorOnFace( MAKECOLOR_5BIT_RGB( r , g , b ) , f );
}
}
void setup() {
}
// DEMO
// Press button to count up 1
// Longpress button to clear back to 0
unsigned x=0;
void loop() {
if (buttonPressed()) {
x++;
}
if (buttonLongPressed()) {
x=0;
}
showNumber(x);
}