# include <Adafruit_NeoPixel.h>
# ifdef __AVR__
# include <avr/power.h>
# endif
// from 8X8wtfREAL - adding select and automate mechanisms
// ready for buttons and lamps
// this is UI3 hacked for just one piece of hardware
// non-animated. 1st - non-blovked 16 LEDs on 8x8 field.
// # include "junk.h" just had notes, no code
//void checkButtons(void);
# define SIXTYFOUR 64
// unsigned char bits[SIXTYFOUR];
unsigned char result[SIXTYFOUR];
/* kludge support */
/* always del ay by anim, add pattern at phase 0 */
//# define NSPEEDS 5
struct {
int anim, pattern;
} speeds[] = {
{220, 100},
{50, 200},
{0, 300},
{0, 400},
{400, 500},
{400, 600},
{400, 900},
{400, 1300},
};
const byte NSPEEDS = sizeof speeds / sizeof *speeds;
unsigned char speedIndex;
# define SWFIX 0 // determine by wiring/layout 0 .. 7
unsigned char kDirection;
// unsigned int lamp; - sign propagation in shift NOT!
unsigned int lamp;
unsigned char nextBit; /* kludge for bit15 "next" value */
unsigned char animPhase; /* 0..3 */
unsigned char havent; /* kludge to slow animation at phase 0 */
unsigned char x4LEDs[68] = { /* 68 becuase we ran off/over impossible 16 2x2 LED clusters */
0, 1, 8, 9, 2, 3, 10, 11,
4, 5, 12, 13, 6, 7, 14, 15,
16, 17, 24, 25, 18, 19, 26, 27,
20, 21, 28, 29, 22, 23, 30, 31,
32, 33, 40, 41, 34, 35, 42, 43,
36, 37, 44, 45, 38, 39, 46, 47,
48, 49, 56, 57, 50, 51, 58, 59,
52, 53, 60, 61, 54, 55, 62, 63, 64, 64, 64, 64,
};
unsigned char fixedLamps[69] = { /* just so we can write bbbeyond the array */
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 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,
0, 0, 0, 0, 0, 0, 1, 0,
0, 0, 0, 0, 0, 1, 0, 1,
};
const unsigned char devMap[SIXTYFOUR] = {
0, 1, 2, 3, 16, 17, 18, 19,
7, 6, 5, 4, 23, 22, 21, 20,
8, 9, 10, 11, 24, 25, 26, 27,
15, 14, 13, 12, 31, 30, 29, 28,
32, 33, 34, 35, 48, 49, 50, 51,
39, 38, 37, 36, 55, 54, 53, 52,
40, 41, 42, 43, 56, 57, 58, 59,
47, 46, 45, 44, 63, 62, 61, 60,
};
const unsigned char transMap[8][64] = {
{
0, 1, 2, 3, 4, 5, 6, 7,
8, 9, 10, 11, 12, 13, 14, 15,
16, 17, 18, 19, 20, 21, 22, 23,
24, 25, 26, 27, 28, 29, 30, 31,
32, 33, 34, 35, 36, 37, 38, 39,
40, 41, 42, 43, 44, 45, 46, 47,
48, 49, 50, 51, 52, 53, 54, 55,
56, 57, 58, 59, 60, 61, 62, 63,
},
{
56, 57, 58, 59, 60, 61, 62, 63,
48, 49, 50, 51, 52, 53, 54, 55,
40, 41, 42, 43, 44, 45, 46, 47,
32, 33, 34, 35, 36, 37, 38, 39,
24, 25, 26, 27, 28, 29, 30, 31,
16, 17, 18, 19, 20, 21, 22, 23,
8, 9, 10, 11, 12, 13, 14, 15,
0, 1, 2, 3, 4, 5, 6, 7,
},
{
7, 6, 5, 4, 3, 2, 1, 0,
15, 14, 13, 12, 11, 10, 9, 8,
23, 22, 21, 20, 19, 18, 17, 16,
31, 30, 29, 28, 27, 26, 25, 24,
39, 38, 37, 36, 35, 34, 33, 32,
47, 46, 45, 44, 43, 42, 41, 40,
55, 54, 53, 52, 51, 50, 49, 48,
63, 62, 61, 60, 59, 58, 57, 56,
},
{
63, 62, 61, 60, 59, 58, 57, 56,
55, 54, 53, 52, 51, 50, 49, 48,
47, 46, 45, 44, 43, 42, 41, 40,
39, 38, 37, 36, 35, 34, 33, 32,
31, 30, 29, 28, 27, 26, 25, 24,
23, 22, 21, 20, 19, 18, 17, 16,
15, 14, 13, 12, 11, 10, 9, 8,
7, 6, 5, 4, 3, 2, 1, 0,
},
{
7, 15, 23, 31, 39, 47, 55, 63,
6, 14, 22, 30, 38, 46, 54, 62,
5, 13, 21, 29, 37, 45, 53, 61,
4, 12, 20, 28, 36, 44, 52, 60,
3, 11, 19, 27, 35, 43, 51, 59,
2, 10, 18, 26, 34, 42, 50, 58,
1, 9, 17, 25, 33, 41, 49, 57,
0, 8, 16, 24, 32, 40, 48, 56,
},
{
0, 8, 16, 24, 32, 40, 48, 56,
1, 9, 17, 25, 33, 41, 49, 57,
2, 10, 18, 26, 34, 42, 50, 58,
3, 11, 19, 27, 35, 43, 51, 59,
4, 12, 20, 28, 36, 44, 52, 60,
5, 13, 21, 29, 37, 45, 53, 61,
6, 14, 22, 30, 38, 46, 54, 62,
7, 15, 23, 31, 39, 47, 55, 63,
},
{
63, 55, 47, 39, 31, 23, 15, 7,
62, 54, 46, 38, 30, 22, 14, 6,
61, 53, 45, 37, 29, 21, 13, 5,
60, 52, 44, 36, 28, 20, 12, 4,
59, 51, 43, 35, 27, 19, 11, 3,
58, 50, 42, 34, 26, 18, 10, 2,
57, 49, 41, 33, 25, 17, 9, 1,
56, 48, 40, 32, 24, 16, 8, 0,
},
{
56, 48, 40, 32, 24, 16, 8, 0,
57, 49, 41, 33, 25, 17, 9, 1,
58, 50, 42, 34, 26, 18, 10, 2,
59, 51, 43, 35, 27, 19, 11, 3,
60, 52, 44, 36, 28, 20, 12, 4,
61, 53, 45, 37, 29, 21, 13, 5,
62, 54, 46, 38, 30, 22, 14, 6,
63, 55, 47, 39, 31, 23, 15, 7,
},
};
unsigned char quadMap[16] = {0, 1, 2, 3, 8, 9, 10, 11, 16, 17, 18, 19, 24, 25, 26, 27,};
/* total shift and spray test */
/* 0 - four copies at same (no) flip or rotation */
void moberly0()
{
unsigned int tLamp = lamp;
Serial.print(" "); Serial.println(tLamp, HEX);
for (unsigned char ii = 0; ii < 16; ii++) {
fixedLamps[quadMap[ii]] = tLamp & 0x1;
fixedLamps[quadMap[ii] + 4] = tLamp & 0x1;
fixedLamps[quadMap[ii] + 32] = tLamp & 0x1;
fixedLamps[quadMap[ii] + 36] = tLamp & 0x1;
tLamp >>= 1;
}
advance();
}
void moberlyx0()
{
unsigned int tLamp = lamp;
Serial.print(" "); Serial.println(tLamp, HEX);
for (unsigned char ii = 0; ii < 16; ii++) {
fixedLamps[quadMap[ii]] = tLamp & 0x1;
fixedLamps[quadMap[ii] + 4] = tLamp & 0x1;
fixedLamps[quadMap[ii] + 32] = tLamp & 0x1;
fixedLamps[quadMap[ii] + 36] = tLamp & 0x1;
tLamp >>= 1;
}
advance();
}
void moberlyKk()
{
unsigned char ii;
int tLamp;
advance();
tLamp = lamp;
for (ii = 0; ii < 64; ii += 4) {
fixedLamps[x4LEDs[ii]] = tLamp & 0x1; // tLamp & 0x80;
fixedLamps[x4LEDs[ii + 1]] = tLamp & 0x1; // tLamp & 0x80;
fixedLamps[x4LEDs[ii + 2]] = tLamp & 0x1; // tLamp & 0x80;
fixedLamps[x4LEDs[ii + 3]] = tLamp & 0x1; // tLamp & 0x80;
tLamp >>= 1;
}
}
void moberlyID()
{
unsigned char ik;
for (ik = 0; ik < 60; ik++) fixedLamps[ik] = 0;
for (ik = 60; ik < 64; ik++) fixedLamps[ik] = 1;
}
/* gack! gigundakludge */
void moberly()
{
if (kDirection) moberlyF();
else moberlyR();
}
void moberlyF()
{
unsigned char ik, ii;
unsigned int tLamp;
// some one else does so
// animPhase++; animPhase &= 0x3;
if (!animPhase) advance();
tLamp = lamp;
for (ik = 0; ik <= 15; ik++, tLamp <<= 1) {
ii = (ik << 2) + animPhase;
fixedLamps[x4LEDs[ii]] = (tLamp & 0x8000) ? 1 : 0;
fixedLamps[x4LEDs[ii + 1]] = (tLamp & 0x8000) ? 1 : 0;
fixedLamps[x4LEDs[ii + 2]] = (tLamp & 0x8000) ? 1 : 0;
fixedLamps[x4LEDs[ii + 3]] = (tLamp & 0x8000) ? 1 : 0;
}
/* now fix up animPhase number of lamps into 2x2 pixel 0 */
switch (animPhase) {
case 3 :
fixedLamps[x4LEDs[2]] = nextBit;
case 2 :
fixedLamps[x4LEDs[1]] = nextBit;
case 1 :
fixedLamps[x4LEDs[0]] = nextBit;
case 0:
break;
}
}
void moberlyR()
{
unsigned char ik, ii;
unsigned int tLamp;
// some one else does so
// animPhase++; animPhase &= 0x3;
if (!animPhase) advance();
tLamp = lamp;
for (ik = 15; !(ik & 0x80); ik--, tLamp >>= 1) { /* not OK with ik 0, must fix */
ii = (ik << 2) + 3 - animPhase;
fixedLamps[x4LEDs[ii]] = (tLamp & 0x1) ? 1 : 0;
if (ii == 0) break;
fixedLamps[x4LEDs[ii - 1]] = (tLamp & 0x1) ? 1 : 0;
if ((ii - 1) == 0) break;
fixedLamps[x4LEDs[ii - 2]] = (tLamp & 0x1) ? 1 : 0;
if ((ii - 2) == 0) break;
fixedLamps[x4LEDs[ii - 3]] = (tLamp & 0x1) ? 1 : 0;
}
// nextBit = 1;
/* now fix up animPhase number of lamps into 2x2 pixel 15 */
switch (animPhase) {
case 3 :
fixedLamps[x4LEDs[61]] = nextBit;
case 2 :
fixedLamps[x4LEDs[62]] = nextBit;
case 1 :
fixedLamps[x4LEDs[63]] = nextBit;
case 0:
break;
}
/* */
}
void moberlyUK()
{
unsigned char ik, ii;
unsigned int tLamp;
if (!animPhase) advance();
tLamp = lamp;
for (ik = 0; ik <= 15; ik++, tLamp <<= 1) {
ii = (ik << 2);// + animPhase;
fixedLamps[x4LEDs[ii]] = (tLamp & 0x8000) ? 1 : 0;
fixedLamps[x4LEDs[ii + 1]] = 0;
fixedLamps[x4LEDs[ii + 2]] = 0;
fixedLamps[x4LEDs[ii + 3]] = 0;
/* fixedLamps[x4LEDs[ii + 1]] = (tLamp & 0x8000) ? 1 : 0;
fixedLamps[x4LEDs[ii + 2]] = (tLamp & 0x8000) ? 1 : 0;
fixedLamps[x4LEDs[ii + 3]] = (tLamp & 0x8000) ? 1 : 0;
*/
}
/* now fix up animPhase number of lamps into 2x2 pixel 0 */
/* switch (animPhase) {
case 3 :
fixedLamps[x4LEDs[2]] = nextBit;
case 2 :
fixedLamps[x4LEDs[1]] = nextBit;
case 1 :
fixedLamps[x4LEDs[0]] = nextBit;
case 0:
break;
}
*/
}
void moberlyDB()
{
unsigned char ik, ii;
unsigned int tLamp;
if (!animPhase) advance();
tLamp = lamp;
Serial.print(animPhase); Serial.println(" <- phase");
for (ik = 1; ik <= 15; ik++, tLamp <<= 1) {
ii = (ik << 2) + animPhase;
Serial.print(ik); Serial.print(" ik, so ");
Serial.print(ii); Serial.print(" filling "); Serial.println((tLamp & 0x8000) ? 1 : 0);
fixedLamps[x4LEDs[ii]] = (tLamp & 0x8000) ? 1 : 0;
fixedLamps[x4LEDs[ii + 1]] = (tLamp & 0x8000) ? 1 : 0;
fixedLamps[x4LEDs[ii + 2]] = (tLamp & 0x8000) ? 1 : 0;
fixedLamps[x4LEDs[ii + 3]] = (tLamp & 0x8000) ? 1 : 0;
}
fixedLamps[x4LEDs[animPhase]] = nextBit;
fixedLamps[x4LEDs[animPhase + 1]] = nextBit;
fixedLamps[x4LEDs[animPhase + 2]] = nextBit;
fixedLamps[x4LEDs[animPhase + 3]] = nextBit;
}
// void process() -> xform
void xform(unsigned char *from, unsigned char *to, unsigned char *map)
{
unsigned char ii;
ii = SIXTYFOUR;
do {
ii--;
to[map[ii]] = from[ii];
} while (ii);
}
# define PIN 6 /* my Hz pin */
# define NPIN 7 /* neopixel pin */
Adafruit_NeoPixel strip = Adafruit_NeoPixel(SIXTYFOUR, NPIN, NEO_GRB + NEO_KHZ800);
unsigned long roller;
unsigned char tog, uu;
void setup() {
Serial.begin(115200);
Serial.println("\nmoberly8X8UI\n");
pinMode(PIN, OUTPUT);
pinMode(8, OUTPUT); // loop activity outside of timing/delay
pinMode(9, OUTPUT); // strip.show activity
roller = millis();
tog = 0;
uu = 0;
animPhase = 0; /* if we don't use it, it better is zero */
havent = 0;
speedIndex = NSPEEDS - 1;
lamp = 0x6c4; /* well not zero pair, single anim test */
// lamp = 0x800; /* well not zero pair, single anim test */
kDirection = 1; /* forward */
strip.begin();
strip.setPixelColor(1, 0xff0000);
strip.setPixelColor(2, 0x00ff00);
strip.setPixelColor(3, 0x0000ff);
strip.setPixelColor(63, 0xffffff);
strip.show();
strip.clear();
lamp = 0xaa00;
delay(1777);
}
/*
if (Serial.available() > 0) {
// get incoming byte:
inByte = Serial.read();
*/
unsigned char xIdx = SWFIX; // default orientation for default settings
const unsigned char uiTable[8][4] = {
{4, 2, 1, 7},
{5, 3, 0, 6},
{6, 0, 3, 5},
{7, 1, 2, 4},
{3, 5, 6, 0},
{2, 4, 7, 1},
{1, 7, 4, 2},
{0, 6, 5, 3}
};
const unsigned char just16Lamps[] = {
1, 3, 5, 7,
17, 19, 21, 23,
33, 35, 37, 39,
49, 51, 53, 55,
};
void loop()
{
digitalWrite(8, HIGH);
for (byte ik = 0; ik < SIXTYFOUR; ik++) fixedLamps[ik] = 0;
unsigned int lampMask = 0x1;
for (byte ik = 0; ik < 16; ik++, lampMask <<= 1)
fixedLamps[just16Lamps[ik]] = lamp & lampMask ? 1 : 0;
xform(fixedLamps, result, transMap[xIdx]);
for (byte ik = 0; ik < 64; ik++, lampMask <<= 1)
strip.setPixelColor(ik, result[ik] ? 0xff0000 : 0x0);
digitalWrite(9, HIGH);
strip.show();
digitalWrite(9, LOW);
// advance();
advanceG15();
checkButtons();
digitalWrite(8, LOW);
// delay(5);
delay(speeds[speedIndex].pattern);
}
void loop_X() {
/* moberlyID();
xform(fixedLamps, result, transMap[xIdx]);
for (int ik = 0; ik < 64; ik++)
strip.setPixelColor(ik, result[ik] ? 0x040008 : 0x0);
strip.show();
*/
checkButtons();
loopIS();
// delay(100);
}
void loopISnot() {}
void loopIS()/*was*/
{
unsigned char ik;
if (1) {
Serial.println("WTF?");
for (; ; );
}
if (0) {
static int couter;
Serial.print(couter); couter++;
Serial.println(" loop.");
}
digitalWrite(PIN, HIGH);
/* moberly0 runs four identical 4x4 copies of the sequence */
// moberly0(); // ->
/* moberlyKk fills 2x2 cells for a 4x4 array */
// moberlyKk(); // is not making lights on 32 -63
/* moberly is oldest (?) still needs four calls per advance, that loopISnot from...*/
// no one else does so
animPhase++; animPhase &= 0x3;
moberly();
/* moberlyUK dot in 0 of 2x2 - using the 8x8 as a spacey 4x4 */
// moberlyUK();
/* final transform and disply */
xform(fixedLamps, result, transMap[xIdx]);
for (ik = 0; ik < 64; ik++)
strip.setPixelColor(ik, result[ik] ? 0x0c0008 : 0x0);
strip.show();
// delay(166); /* kludge */
if (!animPhase) delay(speeds[speedIndex].pattern); /* kludge */
delay(speeds[speedIndex].anim);
/* for RTOS */
digitalWrite(PIN, LOW);
}
/* advance with (attempted)real reverse */
/* waht about the IFM505s? */
/* UGH! */
void advance() {
// advanceDB();
advanceNORM();
if (0) Serial.println(lamp, HEX);
}
void advanceNORM() // NewWIP()
{
if (kDirection) { // forward
lamp >>= 1;
if (lamp & 1)
if (lamp & 2) lamp &= 0x7fff;
else lamp |= 0x8000;
else if (lamp & 2) lamp |= 0x8000;
else lamp &= 0x7fff;
/* precalculate next bit for anim fixup */
if (lamp & 2)
if (lamp & 4) nextBit = 0;
else nextBit = 1;
else if (lamp & 4) nextBit = 1;
else nextBit = 0;
}
else { // reverse
lamp <<= 1; lamp &= 0xffff;
// Serial.println("true reverse");
if (lamp & 0x8000)
if (lamp & 2) lamp &= ~1;
else lamp |= 1;
else if (lamp & 2) lamp |= 1;
else lamp &= ~1;
/* precalculate next bit for anim fixup */
if (lamp & 0x4000)
if (lamp & 1) nextBit = 0;
else nextBit = 1;
else if (lamp & 1) nextBit = 1;
else nextBit = 0;
}
}
void advanceDB() // NewWIP()
{
unsigned int lost;
if (kDirection) { // forward
lost = lamp & 0x1;
lamp >>= 1;
if (lost) lamp |= 0x8000;
nextBit = lamp & 0x1;
}
else {
lost = lamp & 0x8000;
lamp <<= 1;
if (lost) {
lamp |= 1;
nextBit = 1;
}
// nextBit = lamp & 0x1;
// nextBit = lost;
}
}
void checkButtons()
{
bool disposed = true;
if (!Serial.available()) return;
int theChar = Serial.read();
switch (theChar) {
case '1' : case 'a' :
Serial.println(" clock ");
xIdx = uiTable[xIdx][0];
break;
case '2' : case 'b' :
Serial.println(" horizontal ");
xIdx = uiTable[xIdx][1];
break;
case '3' : case 'c' :
Serial.println(" vertical ");
xIdx = uiTable[xIdx][2];
break;
case '4' : case 'd' :
Serial.println(" anti-clock ");
xIdx = uiTable[xIdx][3];
break;
case '6' : case 'r' :
Serial.println(" reset ");
lamp = 0x10; /* one pixel in the middle */
kDirection = 1; /* in the traditional forward mode */
break;
case '5' : case 's' :
Serial.println(" speed ");
if (++speedIndex >= NSPEEDS) speedIndex = 0;
break;
case '0' :
Serial.println(" + ");
xIdx += 1; xIdx &= 0x7;
break;
case '7' :
Serial.println(" direction ");
kDirection = !kDirection;
break;
case '9' :
Serial.println(" - ");
xIdx -= 1; xIdx &= 0x7;
break;
default :
disposed = false;
break;
}
if (disposed) {
Serial.print("Transform "); Serial.print(xIdx);
// " no rotate "
Serial.print(xIdx & 0x4 ? " rotate " : " no rotate ");
Serial.print(xIdx & 0x2 ? " h-flip " : " no h-flip ");
Serial.print(xIdx & 0x1 ? " v-flip " : " no v-flip ");
Serial.println("");
Serial.print("speed "); Serial.print(speedIndex);
Serial.print(" "); Serial.println(kDirection ? "FORWARD" : "BACKWARDS");
Serial.println("");
}
}
void advanceG15()
{
lamp = advanceG15(lamp);
}
unsigned int advanceG15(unsigned tLamp)
{
bool bit14 = (tLamp & 0x4000u) != 0; /* bit 13 (i.e., the output bit). */
tLamp <<= 1;
if (bit14)
tLamp ^= 0x3;
tLamp &= 0xffff;
return tLamp;
}