/*
Использует порты с поддержкой ШИМ для управления светодиодами.
leds[] - массив светодиодов (объекты класса)
Функцию leds[0].goLed() необходимо использовать в цикле с задержкой 125 миллисекунд.
value - яркость светодиода от 0 до 255
stepValue - изменение яркости за цикл от 1 до 255
timeStep - время таймера от 0 до 4 294 967 295 с шагом 125 миллисекунд (указанных в цикле).
Примеры использования на одном светодиоде (объекте класса):
1. leds[0].GetValue(); // считывание текушей яркости
2. leds[0].SetValue(100); // установка яркости на 100 (яркость от 0 до 255)
3. led[0].GetTimeStop; // флаг окончания заданного ранее интервала времени
4. leds[0].goLed(0,0,0); // рандомный режим
5. leds[0].goLed(1,3,0); // растущая яркость c шагом 3 (шаг от 1 до 255)
6. leds[0].goLed(2,3,0); // убывающая яркость c шагом 3 (шаг от 1 до 255)
7. leds[0].goLed(3,0,900); // устанавливает таймер на гашение светодиода через 900 миллисекунд.
8. leds[0].goLed(4,0,900); // устанавливает таймер на зажигание светодиода через 900 миллисекунд.
*/
class LedBlink {
bool timeStop=1;
uint8_t pin, value=0, mode=0;
int16_t stepValue=0;
uint32_t timeStep=0, ms=0;
public:
LedBlink(uint8_t valPin) {
pin = valPin;
pinMode(pin, OUTPUT);
analogWrite(pin, value);
}
uint8_t GetValue() {return value;}
void SetValue(uint8_t value) {this -> value = value;}
bool GetTimeStop() {return timeStop;}
void goLed() {
analogWrite(pin, value);
}
void goLed(uint8_t mode, int16_t stepValue, uint32_t timeStep) {
this -> mode = mode;
this -> stepValue = stepValue;
if (timeStop) this -> timeStep = timeStep;
switch (mode) {
case 0: {
if (( millis() - ms) >= timeStep){
ms = millis();
timeStep = random(1000,3000);
stepValue = random(-10, 10);
}
if (((value + stepValue) >= 0) && ((value + stepValue) <= 255)) value = value + stepValue;
break;
}
case 1: {
if ((value + stepValue) <= 255) value = value + stepValue; else value = 0;
break;
}
case 2: {
if ((value - stepValue) >= 0) value = value - stepValue; else value = 255;
break;
}
case 3: {
if (( millis() - ms) >= timeStep){
ms = millis();
value = 20;
timeStop = 1;
} else timeStop=0;
break;
}
case 4: {
if (( millis() - ms) >= timeStep){
ms = millis();
value = 255;
timeStop = 1;
} else timeStop=0;
break;
}
}
goLed();
}
};
// Массив с портами с поддержкой ШИМ
static LedBlink leds[] = {3, 5, 6, 9, 10};
// Размер массива с портами поддерживаюшими ШИМ, т.е. колличество светодиодов
static constexpr uint8_t totalLeds = sizeof(leds) / sizeof(leds[0]);
void setup() {
uint32_t seed = 0;
for (uint8_t i = 0; i < 16; i++) {
seed *= 4UL;
seed += analogRead(A0) & 3;
}
randomSeed(seed);
}
// Далее пример использования класса
uint8_t loopMode=0, lLoopMode=0, loopValue=0, loopI=0;
int16_t loopStep=0;
uint32_t loopMs=0, loopTimeStep=0, loopStop=0;
void loop() {
if (( millis() - loopMs) >= loopTimeStep){
loopMs = millis();
lLoopMode = loopMode;
while (lLoopMode == loopMode) loopMode = random(0,7);
loopTimeStep = random(20000,60000);
if (loopMode == 1) {for (uint8_t i = 0; i < totalLeds; i++) leds[i].SetValue(0); loopStep = random(3,15);}
if (loopMode == 2) {for (uint8_t i = 0; i < totalLeds; i++) leds[i].SetValue(255); loopStep = random(3,15);}
if (loopMode == 3) {loopValue = random(100,255); loopStop = random(125,2000);}
if (loopMode == 4) for (uint8_t i = 0; i < totalLeds; i++) leds[i].SetValue(20);
if (loopMode == 5) {loopValue = random(0,20); loopStop = random(125,2000);}
if (loopMode == 6) for (uint8_t i = 0; i < totalLeds; i++) leds[i].SetValue(255);
}
switch (loopMode) {
case 0: {
for (uint8_t i = 0; i < totalLeds; i++) leds[i].goLed(0,0,0);
break;
}
case 1: {
for (uint8_t i = 0; i < totalLeds; i++) leds[i].goLed(1,loopStep,0);
break;
}
case 2: {
for (uint8_t i = 0; i < totalLeds; i++) leds[i].goLed(2,loopStep,0);
break;
}
case 3: {
for (uint8_t i = 0; i < totalLeds; i++) {
leds[i].goLed(3,0,loopStop);
if (leds[i].GetTimeStop()) leds[i].SetValue(loopValue);
}
break;
}
case 4: {
if (loopI < totalLeds) loopI++; else loopI = 0;
leds[loopI].SetValue(200); leds[loopI].goLed();
if (loopI > 0) {leds[loopI - 1].SetValue(20); leds[loopI - 1].goLed();}
else {leds[totalLeds - 1].SetValue(20); leds[totalLeds - 1].goLed();}
break;
}
case 5: {
for (uint8_t i = 0; i < totalLeds; i++) {
leds[i].goLed(4,0,loopStop);
if (leds[i].GetTimeStop()) leds[i].SetValue(loopValue);
}
break;
}
case 6: {
if (loopI < totalLeds) loopI++; else loopI = 0;
leds[loopI].SetValue(20); leds[loopI].goLed();
if (loopI > 0) {leds[loopI - 1].SetValue(255); leds[loopI - 1].goLed();}
else {leds[totalLeds - 1].SetValue(255); leds[totalLeds - 1].goLed();}
break;
}
}
delay(125);
}