Académique Documents
Professionnel Documents
Culture Documents
#define PBRIGHTNESS A1
#define PR A2
#define PG A4
#define PB A6
#define PIXEL_PIN 13
#define PIXEL_COUNT 250
byte pixels[PIXEL_COUNT * 3];
int demoCounter = 0;
byte loopDelay = 5, delayValue = 0, lastRed, lastGreen, lastBlue, demoEffectCoun
ter, mode = 1, speedValue = 11, brightness = 16;
bool nextStep = true, demoMode = false, hiSpeed = false;
void setup()
{
randomSeed(analogRead(3));
pinMode(PIXEL_PIN, OUTPUT);
digitalWrite(PIXEL_PIN, LOW);
pinMode(9, OUTPUT);
pinMode(8, OUTPUT);
pinMode(7, OUTPUT);
pinMode(6, OUTPUT);
pinMode(5, INPUT_PULLUP);
pinMode(4, INPUT_PULLUP);
pinMode(3, INPUT_PULLUP);
pinMode(2, INPUT_PULLUP);
digitalWrite(9, HIGH);
digitalWrite(8, HIGH);
digitalWrite(7, HIGH);
digitalWrite(6, HIGH);
}
// --- SendDataToLEDs ----------------------------------------------------------
----------------------------------
void show()
{
noInterrupts();
volatile uint16_t i = PIXEL_COUNT * 3;
volatile uint8_t *ptr = pixels, b = *ptr++, hi, lo, bright = brightness, temp;
const volatile uint8_t *port = portOutputRegister(digitalPinToPort(13));
uint8_t pinMask = digitalPinToBitMask(13);
volatile uint8_t next, bit;
hi = *port | pinMask;
lo = *port & ~pinMask;
next = lo;
bit = 8;
b = ((int)b * bright) >> 8;
asm volatile(
"push R0" "\n\t"
"push R1" "\n\t"
"start:" "\n\t"
"st %a[port], %[hi]" "\n\t"
"sbrc %[byte], 7" "\n\t"
"mov %[next], %[hi]" "\n\t"
"dec %[bit]" "\n\t"
"st %a[port], %[next]" "\n\t"
"mov %[next] , %[lo]" "\n\t"
"breq nextbyte" "\n\t"
"rol %[byte]" "\n\t"
"ld %[temp], %a[ptr]" "\n\t"
"nop" "\n\t"
"st %a[port], %[lo]" "\n\t"
"nop" "\n\t"
"mul %[bright], %[temp]" "\n\t"
"rjmp start" "\n\t"
"nextbyte:" "\n\t"
"ldi %[bit], 8" "\n\t"
"adiw %[ptr], 1" "\n\t"
"st %a[port], %[lo]" "\n\t"
"mov %[byte], R1" "\n\t"
"sbiw %[count], 1" "\n\t"
"brne start" "\n\t"
"pop R1" "\n\t"
"pop R0" "\n"
: [port] "+e" (port),
[byte] "+r" (b),
[bit] "+r" (bit),
[next] "+r" (next),
[count] "+w" (i)
: [ptr] "e" (ptr),
[hi] "r" (hi),
[lo] "r" (lo),
[bright] "d" (bright),
[temp] "r" (temp));
interrupts();
}
// --- Keyboard ----------------------------------------------------------------
----------------------------------
byte ReadKeypad(void)
{
byte keyState = 0, value;
PORTB &= 0xfd;
delayMicroseconds(1);
value = PIND;
if ((value & 0x3c) != 0x3c)
{
if ((value & 0x20) == 0) keyState = 1;
else if ((value & 0x10) == 0) keyState = 2;
else if ((value & 0x08) == 0) keyState = 3;
else keyState = 4;
}
PORTB |= 0x02;
PORTB &= 0xfe;
delayMicroseconds(1);
value = PIND;
if ((value & 0x3c) != 0x3c)
{
if ((value & 0x20) == 0) keyState = 5;
else if ((value & 0x10) == 0) keyState = 6;
else if ((value & 0x08) == 0) keyState = 7;
else keyState = 8;
}
PORTB |= 0x01;
PORTD &= 0x7f;
delayMicroseconds(1);
value = PIND;
if ((value & 0x3c) != 0x3c)
{
if ((value & 0x20) == 0) keyState = 9;
else if ((value & 0x10) == 0) keyState = 10;
else if ((value & 0x08) == 0) keyState = 11;
else keyState = 12;
}
PORTD |= 0x80;
PORTD &= 0xbf;
delayMicroseconds(1);
value = PIND;
if ((value & 0x3c) != 0x3c)
{
if ((value & 0x20) == 0) keyState = 13;
else if ((value & 0x10) == 0) keyState = 14;
else if ((value & 0x08) == 0) keyState = 15;
else keyState = 16;
}
PORTD |= 0x40;
return keyState;
}
// --- Get color values --------------------------------------------------------
----------------------------------
byte GetRed()
{
int value = (analogRead(PR) >> 2);
if (abs(value - lastRed) > 3 || value == 0 || value == 255)
lastRed = value;
return lastRed;
}
byte GetGreen()
{
int value = (analogRead(PG) >> 2);
if (abs(value - lastGreen) > 3 || value == 0 || value == 255)
lastGreen = value;
return lastGreen;
}
byte GetBlue()
{
int value = (analogRead(PB) >> 2);
if (abs(value - lastBlue) > 3 || value == 0 || value == 255)
lastBlue = value;
return lastBlue;
}
// --- Rainbow colors ----------------------------------------------------------
----------------------------------
void Rainbow(int index, byte pos)
{
if(pos < 85)
{
pixels[index * 3 + 0] = 255 - pos * 3;
pixels[index * 3 + 1] = 0;
pixels[index * 3 + 2] = pos * 3;
}
else if(pos < 170)
{
pos -= 85;
pixels[index * 3 + 0] = 0;
pixels[index * 3 + 1] = pos * 3;
pixels[index * 3 + 2] = 255 - pos * 3;
}
else
{
pos -= 170;
pixels[index * 3 + 0] = pos * 3;
pixels[index * 3 + 1] = 255 - pos * 3;
pixels[index * 3 + 2] = 0;
}
}
void Rainbow(byte pos, byte *r, byte *g, byte *b)
{
if(pos < 85)
{
*r = 255 - pos * 3;
*g = 0;
*b = pos * 3;
}
else if(pos < 170)
{
pos -= 85;
*r = 0;
*g = pos * 3;
*b = 255 - pos * 3;
}
else
{
pos -= 170;
*r = pos * 3;
*g = 255 - pos * 3;
*b = 0;
}
}
// --- Mode 1 ------------------------------------------------------------------
----------------------------------
void Mode1(bool init)
{
static byte phase;
if (init)
phase = 0;
if (nextStep)
{
for(int i = PIXEL_COUNT - 1; i >= 0; i--)
Rainbow(i, (phase + i) & 255);
phase++;
}
}
// --- Mode 2 ------------------------------------------------------------------
----------------------------------
void Mode2(bool init)
{
static byte delayLoop;
byte r = GetRed() >> 3;
byte g = GetGreen() >> 3;
byte b = GetBlue() >> 3;
if (init)
{
delayLoop = 0;
if (v2 > 0)
{
v2 = -v;
p2 = PIXEL_COUNT - 1;
}
else
{
v2 = v;
p2 = 0;
}
demoEffectCounter++;
}
}
d3++;
if (d3 >= abs(v3))
{
d3 = 0;
colorPhase3 = 0;
p3 += (v3 > 0) ? 1 : -1;
byte r = GetRed();
byte g = GetGreen();
byte b = GetBlue();
if ((r | g | b) == 0)
r = g = b = 1;
if (init)
{
delayLoop = 0;
for(int i = 0; i < PIXEL_COUNT; i++)
{
pixels[i * 3 + 0] = r;
pixels[i * 3 + 1] = g;
pixels[i * 3 + 2] = b;
}
for(int i = 0; i < PIXEL_COUNT / 4; i++)
{
int index;
do
{
index = random(PIXEL_COUNT);
} while ((pixels[index * 3 + 0] | pixels[index * 3 + 1] | pixels[index * 3
+ 2]) == 0);
pixels[index * 3 + 0] = 0;
pixels[index * 3 + 1] = 0;
pixels[index * 3 + 2] = 0;
}
}
if (nextStep && ++delayLoop == 3)
{
delayLoop = 0;
byte numberOfDiodes = (18 - loopDelay) >> 1;
while(numberOfDiodes > 0)
{
int index1, index2;
do
{
index1 = random(PIXEL_COUNT);
} while ((pixels[index1 * 3 + 0] | pixels[index1 * 3 + 1] | pixels[index1
* 3 + 2]) == 0);
do
{
index2 = random(PIXEL_COUNT);
} while ((pixels[index2 * 3 + 0] | pixels[index2 * 3 + 1] | pixels[index2
* 3 + 2]) > 0);
pixels[index1 * 3 + 0] = 0;
pixels[index1 * 3 + 1] = 0;
pixels[index1 * 3 + 2] = 0;
pixels[index2 * 3 + 0] = r;
pixels[index2 * 3 + 1] = g;
pixels[index2 * 3 + 2] = b;
numberOfDiodes--;
}
}
}
// --- Mode 6 ------------------------------------------------------------------
----------------------------------
void Mode6(bool init)
{
static byte phase, colorPhase, delayLoop;
if (init)
delayLoop = phase = colorPhase = 0;
byte r = GetRed();
byte g = GetGreen();
byte b = GetBlue();
colorPhase++;
if (nextStep && ++delayLoop == 8)
{
delayLoop = 0;
colorPhase = 0;
if (++phase == 15)
{
phase = 0;
colorIndex += 15;
}
}
}
// --- Mode 9 ------------------------------------------------------------------
----------------------------------
void Mode9(bool init)
{
static byte phase, colorIndex, previousColorIndex, colorPhase;
byte r, g, b, pr, pg, pb;
if (init)
{
colorPhase = phase = 0;
colorIndex = random(256);
previousColorIndex = colorIndex ^ 0x80;
Rainbow(previousColorIndex, &r, &g, &b);
for(int i = 0; i < PIXEL_COUNT; i++)
{
pixels[i * 3 + 0] = r;
pixels[i * 3 + 1] = g;
pixels[i * 3 + 2] = b;
}
}
int maxColorPhase = loopDelay;
if (colorPhase > maxColorPhase)
colorPhase = maxColorPhase;
Rainbow(colorIndex, &r, &g, &b);
Rainbow(previousColorIndex, &pr, &pg, &pb);
for(int i = 0; i < 15; i++)
for(int k = 0; k < PIXEL_COUNT; k += 15)
{
int pos = k + i;
if (pos >= PIXEL_COUNT)
break;
int actualPhase = phase - i;
if (actualPhase < 0)
continue;
long factor = (actualPhase >= 8) ? 256 : ((long)actualPhase << 5) + ((long
)colorPhase << 5) / maxColorPhase;
pixels[pos * 3 + 0] = (factor * r + (256 - factor) * pr) >> 8;
pixels[pos * 3 + 1] = (factor * g + (256 - factor) * pg) >> 8;
pixels[pos * 3 + 2] = (factor * b + (256 - factor) * pb) >> 8;
}
colorPhase++;
if (nextStep)
{
colorPhase = 0;
if (++phase == 25)
{
phase = 0;
previousColorIndex = colorIndex;
do
{
colorIndex = random(256);
} while (abs((int)previousColorIndex - colorIndex) < 64);
}
}
}
if (init)
{
for(int i = 0; i < PIXEL_COUNT; i++)
Rainbow(i, random(256));
phase = 0;
pos = random(PIXEL_COUNT);
r = pixels[pos * 3 + 0];
g = pixels[pos * 3 + 1];
b = pixels[pos * 3 + 2];
do
{
Rainbow(random(256), &nr, &ng, &nb);
} while (abs((int)nr - r) < 64 && abs((int)ng - g) < 64 && abs((int)nb - b)
< 64);
}
if (nextStep)
{
byte ar, ag, ab;
startPosition++;
if (startPosition == lastPosition + 10)
{
startPosition = 0;
demoCounter = 0;
do
{
colorIndex = random(256);
} while (abs((int)colorIndex - lastColorIndex) < 64);
lastColorIndex = colorIndex;
lastPosition -= 15;
if (lastPosition < 0)
{
entering = false;
lastPosition = PIXEL_COUNT;
}
}
}
else
{
startPosition++;
for(int i = 0; i < PIXEL_COUNT - startPosition; i++)
{
pixels[i * 3 + 0] = pixels[(i + 1) * 3 + 0];
pixels[i * 3 + 1] = pixels[(i + 1) * 3 + 1];
pixels[i * 3 + 2] = pixels[(i + 1) * 3 + 2];
}
Rainbow(firstColorIndex, &r, &g, &b);
for(int i = 0; i <= 10; i++)
{
pos = PIXEL_COUNT - startPosition + i;
if (pos < PIXEL_COUNT && pos >= 0)
{
pixels[pos * 3 + 0] = (10 - i) * r / 10;
pixels[pos * 3 + 1] = (10 - i) * g / 10;
pixels[pos * 3 + 2] = (10 - i) * b / 10;
}
}
if (startPosition == PIXEL_COUNT + 10)
{
entering = true;
firstColorIndex = lastColorIndex;
lastPosition = PIXEL_COUNT;
startPosition = 0;
demoCounter = 10000;
}
}
}
}
// --- Moin loop ---------------------------------------------------------------
----------------------------------
void loop()
{
byte oldMode = 0;
bool init;
while (true)
{
if (mode != oldMode)
{
oldMode = mode;
init = true;
delayValue = 0;
nextStep = true;
hiSpeed = false;
}
else
init = false;
switch(mode)
{
case 1: Mode1(init); break;
case 2: Mode2(init); break;
case 3: Mode3(init); break;
case 4: Mode4(init); break;
case 5: Mode5(init); break;
case 6: Mode6(init); break;
case 7: Mode7(init); break;
case 8: Mode8(init); break;
case 9: Mode9(init); break;
case 10: Mode10(init); break;
case 11: Mode11(init); break;
case 12: Mode12(init); break;
case 13: Mode13(init); break;
case 14: Mode14(init); break;
case 15: Mode15(init); break;
}
show();
byte key = ReadKeypad();
if (key == 16)
{
if (!demoMode)
{
demoMode = true;
demoCounter = 0;
mode = 1;
}
key = 0;
}
else if (key > 0)
{
mode = key;
demoMode = false;
}
int value = (analogRead(PBRIGHTNESS) >> 2) + 1;
if (abs(value - brightness) > 3 || value == 1 || value == 256)
brightness = value;
value = analogRead(PSPEED) >> 6;
loopDelay = (hiSpeed) ? 4 - (value >> 2) : 16 - value;
delayValue++;
if (delayValue >= loopDelay)
{
delayValue = 0;
nextStep = true;
}
else
nextStep = false;
if (demoMode && nextStep)
{
if (++demoCounter >= PIXEL_COUNT * 2)
{
demoCounter = 0;
if (++mode == 16)
mode = 1;
}
}
}
}