# include <Adafruit_NeoPixel.h>
# define PIN 2 // the pin
# define NPIXELS (16) // number of LEDs on strip
Adafruit_NeoPixel stab(NPIXELS, PIN, NEO_GRB + NEO_KHZ800);
void setup() {
Serial.begin(115200);
Serial.println("\nHi Mom!\n");
// Serial.pr intln(1 << 15);
// Serial.pr intln(1ul << 15);
pinMode(3, INPUT_PULLUP);
smartLampSetup();
stab.show();
delay(777);
// for (; ; );
}
void smartLampSetup() {
stab.begin();
stab.setPixelColor(0, 0xff0000);
stab.setPixelColor(1, 0x00ff00);
stab.setPixelColor(2, 0x0000ff);
stab.setPixelColor(NPIXELS - 1, 0x808080);
stab.show();
stab.clear();
delay(1777);
for (byte ii = 0; ii < NPIXELS; ii++) stab.setPixelColor(ii, 0x000001);
}
//unsigned long it = 1;
// unsigned long long it = 1; // 0xa5f9;
unsigned long long it = 0x4000; // 0xa5f9;
/*
15 15,14 15, 14, 13, 11 // 37 37, 36, 33, 31 59 59, 57, 55, 52
16 16, 14, 13, 11
*/
void loop() {
static unsigned long lastTick;
static int bpm;
unsigned long now = millis();
if (now - lastTick < bpm) { delay(1); return;}
lastTick = now;
// one chatGPT idea
float t = analogRead(A0) / 1023.0;
float bpmx = 25.0 * pow(300.0 / 25.0, t);
float period_ms = 60000.0 / bpmx;
bpm = period_ms + 0.5 - 2;
// Serial.println(bpm);
/*
if (0)
if (digitalRead(2) == LOW) stabIt();
else stabIt5X5();
if (0) stabIt2X3();
*/
stabIt();
stab.show();
// delay(227); // so sue me.
// now show 64 is ~ 2 ms. we will assume that, and slide fade from 40 to 220 BPM
mobe16();
// xAdvance();
// advance();
// advanceG();
}
void advance16()
{
unsigned char a = it & (1ul << 15) ? 1 : 0; // 15 (16/1)
unsigned char b = it & (1 << 13) ? 1 : 0; // 13 (14/1)
unsigned char c = it & (1 << 12) ? 1 : 0; // 12 (13/1)
unsigned char d = it & (1 << 10) ? 1 : 0; // 10 (11/1)
// unsigned char e = a ^ b ^ c ^ d;
unsigned char e = a + b + c + d;
it <<= 1;
if (e & 1) it |= 0x1;
}
// central mapping location.
// just linear
void stabIt() {
// hardcode ... 5x5 inset on 8x8 x+1 y+2 ??
unsigned long long fIt = it;
for (byte ii = 0; ii < NPIXELS; ii++) {
stab.setPixelColor(ii, fIt & 0x1 ? 0xc040a0 : 0x0c0318);
fIt >>= 1;
}
}
// 5x5 in the middle of eight +1 x, +1 y
void stabIt5X5() {
const byte XPIXELS = 25;
byte asX, asY;
// hardcode ... 5x5 inset on 8x8 x+1 y+2 ??
unsigned long long fIt = it;
for (byte ii = 0; ii < XPIXELS; ii++) {
asX = ii / 5;
asY = ii % 5;
int pixel = (asX + 1) * 8 + asY + 1;
stab.setPixelColor(pixel, fIt & 0x1 ? 0x804060 : 0x240014);
fIt >>= 1;
}
}
// (2x3)^ 2 pattern from map
// (2 + 3)^2
const byte map2X3[] = {
9, 10, 12, 13, 14,
17, 18, 20, 21, 22,
33, 34, 36, 37, 38,
41, 42, 44, 45, 46,
49, 50, 52, 53, 54
};
const byte altMap[] = {
9, 10, 17, 18, 12, 13, 14, 20, 21, 22,
33, 34, 41, 42, 49, 50,
36, 37, 38, 44, 45, 46, 52, 53, 54,
};
const byte XPIXELS = sizeof map2X3 / sizeof *map2X3;
void stabIt2X3() {
byte asX, asY;
// hardcode ... 5x5 inset on 8x8 x+1 y+2 ??
unsigned long long fIt = it;
for (byte ii = 0; ii < XPIXELS; ii++) {
// int pixel = map2X3[ii];
int pixel = altMap[ii];
stab.setPixelColor(pixel, fIt & 0x1 ? 0x804060 : 0x243014);
fIt >>= 1;
}
}
// feed in the XOR of the feedback bits here 2^15 and 2^14
void advance0()
{
it <<= 1;
if (it & 0x8000)
if (it & 0x4000); else it |= 1; // <--
else if (it & 0x4000) it |= 1;
}
void advance()
{
unsigned long long itt = it;
advanceA();
unsigned long long itA = it;
it = itt;
advanceB();
unsigned long long itB = it;
}
// *it* is unsigned and either 32 or 64 bits.
// so far all LFSR have been 16 or fewer. displays from 2x2 to 8x8
void advanceA()
{
it <<= 1;
if (it & (1ul << 15)) // 0x8000ul, gack! chain reaction interesting affect
if (it & (1 << 14)); else it |= 1; // <--
else if (it & (1 << 14)) it |= 1;
if (1) {
static int counter;
Serial.print(counter); Serial.print(" ");
counter++;
unsigned int the = it & 0xffff;
Serial.println(the, HEX);
}
}
void advanceB()
{
bool msb = it & (1 << 14);
it <<= 1;
if (msb)
it ^= 0x3;
if (1) {
static int counter;
Serial.print(counter + 1000); Serial.print(" ");
counter++;
unsigned int the = it & 0xffff;
Serial.println(the, HEX);
}
}
void advance16_2()
{
bool msb = it & (1ul << 15);
it <<= 1;
if (msb)
it ^= 0x002Du;
}
/*
void advanceG16()
{
bool msb = it & 0x8000ul;
it <<= 1;
if (msb)
it ^= 0x002Du;
}
*/
# define lamp it
//void advanceLikeOldways()
void xAdvance()
{
lamp >>= 1;
// return; /* to find why neopixels 0 and 1 get turned on */
if (digitalRead(3) == HIGH) {
if (lamp & 1)
if (lamp & 2) lamp &= 0x7fff;
else lamp |= 0x8000;
else
if (lamp & 2) lamp |= 0x8000;
else lamp &= 0x7fff;
/*
if (lamp & 2)
if (lamp & 4) nextBit = 0;
else nextBit = 1;
else
if (lamp & 4) nextBit = 1;
else nextBit = 0;
*/
}
else {
if (lamp & 0x4000)
if (lamp & 1) lamp &= 0x7fff;
else lamp |= 0x8000;
else
if (lamp & 1) lamp |= 0x8000;
else lamp &= 0x7fff;
}
}
void mobe15()
{
if (digitalRead(3) == HIGH) it = advanceK15(it);
else it = reverseK15(it);
}
unsigned int advanceK15(unsigned int it)
{
unsigned int bits = it & 0x6000;
bool parity = false;
while (bits) {
bits &= bits - 1;
parity = !parity;
}
it <<= 1;
if (parity) it |= 0x1;
return it;
}
unsigned int reverseK15(unsigned int it)
{
unsigned int bits = it & 0x8002;
bool parity = false;
while (bits) {
bits &= bits - 1;
parity = !parity;
}
it >>= 1;
if (parity) it |= 0x8000;
return it;
}
void mobe16()
{
if (digitalRead(3) == HIGH) it = advanceK16(it);
else it = reverseK16(it);
}
unsigned int advanceK16(unsigned int it)
{
unsigned int bits = it & 0xb400;
bool parity = false;
while (bits) {
bits &= bits - 1;
parity = !parity;
}
it <<= 1;
if (parity) it |= 0x1;
return it;
}
unsigned int reverseK16(unsigned int it)
{
unsigned int bits = it & 0x5a1;
bool parity = false;
while (bits) {
bits &= bits - 1;
parity = !parity;
}
it >>= 1;
if (parity) it |= 0x8000;
return it;
}