Colorduino plasma demo, matrix test and browser simulator

- ColorduinoPlasma sketch and Colorduino library v1.2.6 (lincomatic @ fff7bd3)
- ColorduinoMatrixTest hardware test sketch
- web/index.html: bit-accurate port of the plasma with large resolutions
- prebuilt 16 MHz firmware (with and without Optiboot)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
mangavalkandClaude Opus 5.5 committed 2026-11-07 22:28:12 +01:00
commit a18f081e0a
15 files changed
+3103

No files matched your search

@@ -0,0 +1,111 @@
/*
Colorduino 8x8 RGB matrix hardware test
Needs the Colorduino library (lincomatic).
Sequence (loops forever):
1. Full screen: RED, GREEN, BLUE, WHITE -> dead colour channel / driver (DM163)
2. Rows one at a time (white) -> dead row driver (M54564)
3. Columns one at a time, R then G then B -> dead column channel
4. Every LED one by one, R, G, B each -> single dead / stuck LEDs
5. Brightness ramp 0..255 per colour -> PWM / greyscale problems
6. Checkerboard + inverse -> shorts between neighbours
Note: Colorduino drives all of PORTD, so Serial cannot be used while it runs.
*/
#include <Colorduino.h>
const uint8_t W = ColorduinoScreenWidth;
const uint8_t H = ColorduinoScreenHeight;
void show() { Colorduino.FlipPage(); }
void fill(uint8_t r, uint8_t g, uint8_t b) {
Colorduino.ColorFill(r, g, b); // ColorFill flips the page itself
}
void clearBuf() {
for (uint8_t y = 0; y < H; y++)
for (uint8_t x = 0; x < W; x++)
Colorduino.SetPixel(x, y, 0, 0, 0);
}
void fullColours() {
fill(255, 0, 0); delay(1500);
fill(0, 255, 0); delay(1500);
fill(0, 0, 255); delay(1500);
fill(255, 255, 255); delay(1500);
fill(0, 0, 0); delay(300);
}
void rowScan() {
for (uint8_t y = 0; y < H; y++) {
clearBuf();
for (uint8_t x = 0; x < W; x++) Colorduino.SetPixel(x, y, 255, 255, 255);
show();
delay(400);
}
}
void columnScan() {
const uint8_t cols[3][3] = {{255, 0, 0}, {0, 255, 0}, {0, 0, 255}};
for (uint8_t c = 0; c < 3; c++) {
for (uint8_t x = 0; x < W; x++) {
clearBuf();
for (uint8_t y = 0; y < H; y++)
Colorduino.SetPixel(x, y, cols[c][0], cols[c][1], cols[c][2]);
show();
delay(250);
}
}
}
void pixelWalk() {
for (uint8_t y = 0; y < H; y++) {
for (uint8_t x = 0; x < W; x++) {
clearBuf(); Colorduino.SetPixel(x, y, 255, 0, 0); show(); delay(120);
clearBuf(); Colorduino.SetPixel(x, y, 0, 255, 0); show(); delay(120);
clearBuf(); Colorduino.SetPixel(x, y, 0, 0, 255); show(); delay(120);
}
}
}
void ramps() {
for (uint8_t c = 0; c < 4; c++) {
for (int v = 0; v <= 255; v += 3) {
uint8_t r = (c == 0 || c == 3) ? v : 0;
uint8_t g = (c == 1 || c == 3) ? v : 0;
uint8_t b = (c == 2 || c == 3) ? v : 0;
fill(r, g, b);
delay(12);
}
}
}
void checker() {
for (uint8_t i = 0; i < 6; i++) {
for (uint8_t y = 0; y < H; y++)
for (uint8_t x = 0; x < W; x++) {
bool on = ((x + y + i) & 1);
Colorduino.SetPixel(x, y, on ? 255 : 0, on ? 255 : 0, on ? 255 : 0);
}
show();
delay(500);
}
}
void setup() {
Colorduino.Init();
// white balance (R, G, B), 0..63 - same default as the Plasma example
unsigned char whiteBal[3] = {36, 63, 63};
Colorduino.SetWhiteBal(whiteBal);
}
void loop() {
fullColours();
rowScan();
columnScan();
pixelWalk();
ramps();
checker();
}
@@ -0,0 +1,202 @@
/*
ColorduinoPlasma - Plasma demo using Colorduino Library for Arduino
Copyright (c) 2011 Sam C. Lin lincomatic@hotmail.com ALL RIGHTS RESERVED
based on Color cycling plasma
Version 0.1 - 8 July 2009
Copyright (c) 2009 Ben Combee. All right reserved.
Copyright (c) 2009 Ken Corey. All right reserved.
Copyright (c) 2008 Windell H. Oskay. All right reserved.
Copyright (c) 2011 Sam C. Lin All Rights Reserved
This demo is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This demo is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <Colorduino.h>
// To show off our hardware PWM LED driver (capable of displaying 16M colors),
// we will add gamma correction to show more accurate colors, and we will
// see better color transition.
#include "gamma8.h"
typedef struct
{
unsigned char r;
unsigned char g;
unsigned char b;
} ColorRGB;
//a color with 3 components: h, s and v
typedef struct
{
unsigned char h;
unsigned char s;
unsigned char v;
} ColorHSV;
// increase the scaling of the plasma to see more details of the color transition.
const float PlasmaScaling = 10.0;
unsigned char plasma[ColorduinoScreenWidth][ColorduinoScreenHeight];
long paletteShift;
//Converts an HSV color to RGB color
void HSVtoRGB(void *vRGB, void *vHSV)
{
float r, g, b, h, s, v; //this function works with floats between 0 and 1
float f, p, q, t;
int i;
ColorRGB *colorRGB=(ColorRGB *)vRGB;
ColorHSV *colorHSV=(ColorHSV *)vHSV;
h = (float)(colorHSV->h / 256.0);
s = (float)(colorHSV->s / 256.0);
v = (float)(colorHSV->v / 256.0);
//if saturation is 0, the color is a shade of grey
if(s == 0.0) {
b = v;
g = b;
r = g;
}
//if saturation > 0, more complex calculations are needed
else
{
h *= 6.0; //to bring hue to a number between 0 and 6, better for the calculations
i = (int)(floor(h)); //e.g. 2.7 becomes 2 and 3.01 becomes 3 or 4.9999 becomes 4
f = h - i;//the fractional part of h
p = (float)(v * (1.0 - s));
q = (float)(v * (1.0 - (s * f)));
t = (float)(v * (1.0 - (s * (1.0 - f))));
switch(i)
{
case 0: r=v; g=t; b=p; break;
case 1: r=q; g=v; b=p; break;
case 2: r=p; g=v; b=t; break;
case 3: r=p; g=q; b=v; break;
case 4: r=t; g=p; b=v; break;
case 5: r=v; g=p; b=q; break;
default: r = g = b = 0; break;
}
}
colorRGB->r = (int)(r * 255.0);
colorRGB->g = (int)(g * 255.0);
colorRGB->b = (int)(b * 255.0);
// gamma correction
colorRGB->r = pgm_read_byte(&gamma8[colorRGB->r]);
colorRGB->g = pgm_read_byte(&gamma8[colorRGB->g]);
colorRGB->b = pgm_read_byte(&gamma8[colorRGB->b]);
}
float
dist(float a, float b, float c, float d)
{
return sqrt((c-a)*(c-a)+(d-b)*(d-b));
}
void
plasma_morph()
{
unsigned char x,y;
float value;
ColorRGB colorRGB;
ColorHSV colorHSV;
for(y = 0; y < ColorduinoScreenHeight; y++)
for(x = 0; x < ColorduinoScreenWidth; x++) {
{
value = sin((x + paletteShift) / PlasmaScaling)
+ sin(dist(x, y, 64.0, 64.0) / PlasmaScaling)
+ sin((y + paletteShift / 7.0) / PlasmaScaling)
+ sin(dist(x, y, 192.0, 100.0) / PlasmaScaling);
colorHSV.h=(unsigned char)((value) * 128)&0xff;
colorHSV.s=255;
colorHSV.v=255;
HSVtoRGB(&colorRGB, &colorHSV);
Colorduino.SetPixel(x, y, colorRGB.r, colorRGB.g, colorRGB.b);
}
}
paletteShift++;
Colorduino.FlipPage(); // swap screen buffers to show it
}
/********************************************************
Name: ColorFill
Function: Fill the frame with a color
Parameter:R: the value of RED. Range:RED 0~255
G: the value of GREEN. Range:RED 0~255
B: the value of BLUE. Range:RED 0~255
********************************************************/
void ColorFill(unsigned char R,unsigned char G,unsigned char B)
{
PixelRGB *p = Colorduino.GetPixel(0,0);
for (unsigned char y=0;y<ColorduinoScreenWidth;y++) {
for(unsigned char x=0;x<ColorduinoScreenHeight;x++) {
p->r = R;
p->g = G;
p->b = B;
p++;
}
}
Colorduino.FlipPage();
}
void setup()
{
Colorduino.Init(); // initialize the board
// compensate for relative intensity differences in R/G/B brightness
// array of 6-bit base values for RGB (0~63)
// whiteBalVal[0]=red
// whiteBalVal[1]=green
// whiteBalVal[2]=blue
unsigned char whiteBalVal[3] = {36,63,63}; // for LEDSEE 6x6cm round matrix
Colorduino.SetWhiteBal(whiteBalVal);
// start with morphing plasma, but allow going to color cycling if desired.
paletteShift=128000;
unsigned char bcolor;
//generate the plasma once
for(unsigned char y = 0; y < ColorduinoScreenHeight; y++)
for(unsigned char x = 0; x < ColorduinoScreenWidth; x++)
{
//the plasma buffer is a sum of sines
bcolor = (unsigned char)
(
128.0 + (128.0 * sin(x*8.0 / 16.0))
+ 128.0 + (128.0 * sin(y*8.0 / 16.0))
) / 2;
plasma[x][y] = bcolor;
}
// to adjust white balance you can uncomment this line
// and comment out the plasma_morph() in loop()
// and then experiment with whiteBalVal above
// ColorFill(255,255,255);
}
void loop()
{
plasma_morph();
}
+25
View File
@@ -0,0 +1,25 @@
// A simple gamma look-up-table, stored in Program Memory
// To access the table, must use: pgm_read_byte()
#ifndef _INC_GAMMA8_H_
#define _INC_GAMMA8_H_
const uint8_t PROGMEM gamma8[] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2,
2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5,
5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10,
10, 10, 11, 11, 11, 12, 12, 13, 13, 13, 14, 14, 15, 15, 16, 16,
17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 24, 24, 25,
25, 26, 27, 27, 28, 29, 29, 30, 31, 32, 32, 33, 34, 35, 35, 36,
37, 38, 39, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 50,
51, 52, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 66, 67, 68,
69, 70, 72, 73, 74, 75, 77, 78, 79, 81, 82, 83, 85, 86, 87, 89,
90, 92, 93, 95, 96, 98, 99,101,102,104,105,107,109,110,112,114,
115,117,119,120,122,124,126,127,129,131,133,135,137,138,140,142,
144,146,148,150,152,154,156,158,160,162,164,167,169,171,173,175,
177,180,182,184,186,189,191,193,196,198,200,203,205,208,210,213,
215,218,220,223,225,228,231,233,236,239,241,244,247,249,252,255 };
#endif