Yet Another Rainbowduino Firmware

Starting with the premise that the Rainbowduino should have plenty of processing power to do stuff on its own, I took the v3.0h source and hacked the pieces I don’t need out of it, and generally molest the otherwise good code.

The result is SmithDuino firmware. Autonomous Agent Smith. Get it? :unamused:

Anyway, eventually I will hook it up to accelerometer and RTC to get it to keep time on its own and react to shakes and stuff. For now I have it display simple addition problems in continuous loop without a Duino attached. Video can be found at youtube.com/watch?v=ltv_gSB711k

Comments and abuses welcome :laughing:

Cheers

oops, Youtube could not be opened here in China. :imp:

Almost ready to release it.

New in this version, coordinate transform! Now that I have access to a working accelerometer I was experimenting with drawing in virtual 8x8 coordinate and transforming to the hardware coordinate using one of the four transform matrices (up / down / left / right).

It’s all array-based, not algebra rotation matrix. A quick demo using ANSI escape code is below if you’re impatient.

[code]#include <stdint.h>
#include <stdio.h>

#if 0
#define DEBUG
#endif

typedef uint8_t transform_t[64];

transform_t right_transform = {
0x70,0x60,0x50,0x40,0x30,0x20,0x10,0x00,
0x71,0x61,0x51,0x41,0x31,0x21,0x11,0x01,
0x72,0x62,0x52,0x42,0x32,0x22,0x12,0x02,
0x73,0x63,0x53,0x43,0x33,0x23,0x13,0x03,
0x74,0x64,0x54,0x44,0x34,0x24,0x14,0x04,
0x75,0x65,0x55,0x45,0x35,0x25,0x15,0x05,
0x76,0x66,0x56,0x46,0x36,0x26,0x16,0x06,
0x77,0x67,0x57,0x47,0x37,0x27,0x17,0x07
};

transform_t left_transform = {
0x07,0x17,0x27,0x37,0x47,0x57,0x67,0x77,
0x06,0x16,0x26,0x36,0x46,0x56,0x66,0x76,
0x05,0x15,0x25,0x35,0x45,0x55,0x65,0x75,
0x04,0x14,0x24,0x34,0x44,0x54,0x64,0x74,
0x03,0x13,0x23,0x33,0x43,0x53,0x63,0x73,
0x02,0x12,0x22,0x32,0x42,0x52,0x62,0x72,
0x01,0x11,0x21,0x31,0x41,0x51,0x61,0x71,
" );0x00,0x10,0x20,0x30,0x40,0x50,0x60,0x70
return 0;
}

transform_t up_transform = {
0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,
0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,
0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,
0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,
0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,
0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,
};

transform_t down_transform = {
0x77,0x76,0x75,0x74,0x73,0x72,0x71,0x70,
0x67,0x66,0x65,0x64,0x63,0x62,0x61,0x60,
0x57,0x56,0x55,0x54,0x53,0x52,0x51,0x50,
0x47,0x46,0x45,0x44,0x43,0x42,0x41,0x40,
0x37,0x36,0x35,0x34,0x33,0x32,0x31,0x30,
0x27,0x26,0x25,0x24,0x23,0x22,0x21,0x20,
0x17,0x16,0x15,0x14,0x13,0x12,0x11,0x10,
0x07,0x06,0x05,0x04,0x03,0x02,0x01,0x00,
};

uint8_t envelope_icon[] = {
26, /* number of coordinate pairs /
0x01,0x02,0x03,0x04,0x05,0x06, /
col[3:0] | row[3:0], … */
0x16,0x17,0x27,0x37,0x47,0x56,
0x55,0x54,0x53,0x52,0x51,0x40,
0x30,0x20,0x10,0x11,0x22,0x33,
0x34,0x25
};

void draw_shape( uint8_t *shape )
{
uint8_t count = *shape++;
while ( count-- ) {
uint8_t coordinate = shape++, transformed_coordinate;
transformed_coordinate = left_transform[((coordinate & 0xf0) >> 1)|(coordinate & 0x07)];
#if defined(DEBUG)
printf( “%d;%d\n”, transformed_coordinate >> 4, transformed_coordinate & 0x07 );
#else
printf( "e[%d;%dH
", 1 + (transformed_coordinate >> 4), 1 + (transformed_coordinate & 0x07) );
#endif
}
}

int main ( int argc, char *argv[] )
{
draw_shape( envelope_icon );
}[/code]

Why is this useful, you might ask? Well, you might, for example, attach a particular function to each of the four (or six) orientations of the device. Perhaps in the “normal (up)” orientation, you’d want the matrix to display the time. When rotated 90CCW you’d want it to display a count-down hourglass, and maybe play a game of pong or something when rotated 90CW …

This lets you do it all without having to hard-code for the orientation (e.g., you’d tell the firmware what orientation it is at, based on accelerometer output) and you’d continue to draw in the natural coordinate as you always have.