/*
17 buttons for 17 steps in a staircase.
One addressable leds strip all along.
You can change the color and the fading resolution.
Play with the loop micro delay to make fading slower or faster.
*/
#include <FastLED.h>
//****************************
#define NUM_LEDS 60 /*the number of leds that will light. */
#define DATA_PIN 13
//#define LED_TYPE WS2811
#define LED_TYPE NEOPIXEL //Wokwi device for tests purpose...
#define NUM_STEPS 17 /*the number of steps we need to light up */
//Input Registry
const int dataPin = 9; /* Q7 */
const int latchPin = 10; /* PL */
const int clockPin = 11; /* CP */
const int numBits = 24; /* Set to 8 * number of shift registers */
CRGB leds[NUM_LEDS]; // sets number of pixels that will light on the strip.
//*****************************************************
void setup() {
delay(1500); // prevents the MCU to fall into a "brownout reset" loop
Serial.begin(11520);
pinMode(dataPin, INPUT);
pinMode(latchPin, OUTPUT);
pinMode(clockPin, OUTPUT);
FastLED.addLeds<LED_TYPE, DATA_PIN>(leds, NUM_LEDS);
//set all leds to black.
for (byte i = 0; i < NUM_LEDS; i++) {
leds[i] = CRGB::Black;
FastLED.show();
}
}
//********************************************************
void loop() {
delay(60); // Makes fading slower or faster
// Step 1: Sample
digitalWrite(latchPin, LOW);
digitalWrite(latchPin, HIGH);
// Step 2: Shift
for (int i = numBits; i > 0 ; i--) {
int bit = digitalRead(dataPin);
if (bit == HIGH) {
//Serial.print(i);
//Serial.print(":1;");
} else {
//Serial.print(i);
//Serial.print(":0;");
if (i < (NUM_STEPS+1)) {
lightStep(i);
Serial.print("L;");
FastLED.show();
}
}
digitalWrite(clockPin, HIGH); // Shift out the next bit
digitalWrite(clockPin, LOW);
}
// fade all existing pixels toward bgColor by "5" (out of 255)
CRGB bgColor( 0, 0, 0); // pine green ?
fadeTowardColor( leds, NUM_LEDS, bgColor, 10); // Last parameter deals with fading resolution.
FastLED.show();
}
void lightStep(int stepNumber) {
int minLed = floor( stepNumber * NUM_LEDS / (NUM_STEPS+1) ) - 4;
int maxLed = ceil( stepNumber * NUM_LEDS / (NUM_STEPS+1) ) + 4;
if (minLed < 0) minLed = 0 ;
Serial.print("Step:");
Serial.print(stepNumber);
Serial.print("-");
Serial.print(minLed);
Serial.print("/");
Serial.print(maxLed);
for (byte i = minLed; i < maxLed; i++) {
//Change color here. Few commented examples.
//leds[i] = CRGB(random(50,200), random(50,200), random(50,200));
//leds[i] = CRGB(51, 255, 0);
leds[i] = CRGB(0, 252, 252);
}
}
//FADER FUNCTIONS - START
//https://gist.github.com/kriegsman/d0a5ed3c8f38c64adcb4837dafb6e690
// Helper function that blends one uint8_t toward another by a given amount
void nblendU8TowardU8( uint8_t& cur, const uint8_t target, uint8_t amount)
{
if ( cur == target) return;
if ( cur < target ) {
uint8_t delta = target - cur;
delta = scale8_video( delta, amount);
cur += delta;
} else {
uint8_t delta = cur - target;
delta = scale8_video( delta, amount);
cur -= delta;
}
}
// Blend one CRGB color toward another CRGB color by a given amount.
// Blending is linear, and done in the RGB color space.
// This function modifies 'cur' in place.
CRGB fadeTowardColorLed( CRGB& cur, const CRGB& target, uint8_t amount)
{
nblendU8TowardU8( cur.red, target.red, amount);
nblendU8TowardU8( cur.green, target.green, amount);
nblendU8TowardU8( cur.blue, target.blue, amount);
return cur;
}
// Fade an entire array of CRGBs toward a given background color by a given amount
// This function modifies the pixel array in place.
void fadeTowardColor( CRGB* L, uint16_t N, const CRGB& bgColor, uint8_t fadeAmount)
{
for ( uint16_t i = 0; i < N; i++) {
fadeTowardColorLed( L[i], bgColor, fadeAmount);
}
}
//FADER FUNCTIONS - END
//Binary to Decimal converter
int readBinaryString(char *s) {
int result = 0;
while (*s) {
result <<= 1;
if (*s++ == '1') result |= 1;
}
return result;
}