#include <Arduino.h>
#include <Arduino_FreeRTOS.h>
#include <timers.h>
/* power of two, use indexes from 0-7
led(0) = 1, led(1) = 2, led(2) = 4, led(3) = 8, ..., led(7) = 128
to turn on some specific leds, e.g. to light led(1), led(3) & led(5)
just sum its values and use updateLED function
led(1)+led(3)+led(5) == 2+8+32 == 42, i.e. updateLED(42) will light up led1, led3, and led5.
... turning on all leds = SUM(led(0) to led(7)) == 255. */
#define led(x) (1 << (x))
#define ONE_SHOT_TIMER xTimer[0]
#define ONE_SHOT_COUNTER (int)pvTimerGetTimerID(ONE_SHOT_TIMER) // times oneshot been called
#define CURRENT_TIMER xTimer[ONE_SHOT_COUNTER%numbOfPatterns+1] // handle to next pattern
const size_t numberOfLeds = 8; // 0-7
const size_t numbOfPatterns = 4;
const size_t allLeds = 255;
// because im using a shift registor i have following constants data(4), clock(6) and latch(5).
int const data = 4;
int const clock = 6;
int const latch = 5;
int interruptPin = 2;
TimerHandle_t xTimer[numbOfPatterns+1]; // +1 is for the oneshot timer (index0), rest is patterns. 1-5
TimerHandle_t antiBouncerTimer;
void OneShotCallback(TimerHandle_t xTimer);
void ISRFunction();
int patternHandler(TimerHandle_t t, int maxValue);
void ledPattern1(TimerHandle_t t) ;
void ledPattern2(TimerHandle_t t);
void ledPattern3(TimerHandle_t t);
void ledPattern4(TimerHandle_t t);
void ledPattern5(TimerHandle_t t);
/* to get desired leds to light up use the led macro
e.g. to use lamp 3 and 5, use: updateLED(led(2)+led(4)) */
void updateLED(int led) {
digitalWrite(latch, LOW);
shiftOut(data, clock, MSBFIRST, led);
digitalWrite(latch, HIGH);
}
void ISRFunction(){
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
xTimerStopFromISR(CURRENT_TIMER, &xHigherPriorityTaskWoken);
xTimerStartFromISR(antiBouncerTimer, &xHigherPriorityTaskWoken);
}
void delayer(TimerHandle_t t){ xTimerStart(xTimer[0], 0); };
void setup() {
Serial.begin(9600);
pinMode(interruptPin, INPUT);
pinMode(data, OUTPUT);
pinMode(clock, OUTPUT);
pinMode(latch, OUTPUT);
attachInterrupt(digitalPinToInterrupt(interruptPin), ISRFunction, RISING);
xTimer[1] = xTimerCreate("Pattern1",pdMS_TO_TICKS(75),pdTRUE,
(void*)0,ledPattern1);
xTimer[2] = xTimerCreate("Pattern2",pdMS_TO_TICKS(50),pdTRUE,
(void*)0,ledPattern2);
xTimer[3] = xTimerCreate("Pattern3",pdMS_TO_TICKS(200),pdTRUE,
(void*)0,ledPattern3);
xTimer[4] = xTimerCreate("Pattern4",pdMS_TO_TICKS(200),pdTRUE,
(void*)0,ledPattern4);
antiBouncerTimer = xTimerCreate("bouncer",pdMS_TO_TICKS(100),pdFALSE,
(void*)0,delayer);
xTimer[0] = xTimerCreate( "OneShot",
pdMS_TO_TICKS(110),
pdFALSE,
(void*)0,
OneShotCallback);
xTimerStart(xTimer[1], 0);
} void loop() {}
void OneShotCallback(TimerHandle_t t){
vTimerSetTimerID(ONE_SHOT_TIMER, (void*) (ONE_SHOT_COUNTER+1));
xTimerStart(CURRENT_TIMER, 0);
}
/* Led patterns */
void ledPattern1(TimerHandle_t t) {
updateLED(led(patternHandler(t, numberOfLeds)));
}
void ledPattern2(TimerHandle_t t) {
int on = patternHandler(t, numberOfLeds);
updateLED((led((on - 1) % numberOfLeds) + led(on % numberOfLeds) + led((on +
1) % numberOfLeds)));
}
void ledPattern3(TimerHandle_t t) { //RANDOM
updateLED(rand()%256);
}
void ledPattern4(TimerHandle_t t) { // BINARY COUNT
updateLED(patternHandler(t, allLeds));
}
int patternHandler(TimerHandle_t t, int maxValue){
int current = (int)pvTimerGetTimerID(t);
(current==maxValue) ? (vTimerSetTimerID(t,(void*)0)) :
(vTimerSetTimerID(t,(void*)(current+1)));
return (int)pvTimerGetTimerID(t);
}