Задание 4.12.20

1) Создаем динамический массив из 4 светодиодов.

Базовые классы: Timer, Indicator

const int arPins[MAX_LED]{3, 5, 6, 9};
Indicator** ar;
    ar = new Indicator * [MAX_LED];

    for (int i{}; i < MAX_LED; ++i) {
        ar[i] = new Indicator(arPins[i], 8);
    }

//********************************************************* Timer
#pragma once
#include<Arduino.h>
class Timer
{
	unsigned long t{ 0 };
	unsigned long dT{ 50 };	//время задержки
public:
	Timer() {}
	Timer(unsigned long dt):dT(dt) {}
	bool getTimer() { return t < millis(); }
	void setTimer(unsigned long dt = 0) {t = millis() + (dt == 0 ? dT : dt);}
	void setDt(unsigned long dt) { dT = dt; }
};
//******************************************************** Indicator
#pragma once
#include<Arduino.h>
#include "timer.h"
const int MAX_LIGHT {255};

class Indicator :public Timer
{
    unsigned short pin{ };
    int bright{ 0 };
    int value{ 0 };
public:
    Indicator(unsigned short p, int s_dt):Timer(s_dt), pin( p ) { pinMode(pin, OUTPUT); };
    void setBright(int bright_d) { bright = bright_d; };
	void on(){bright = MAX_LIGHT;}
	void off(){bright = 0;}
    int cycle();
};
//***************************************** Indicator.cpp
#include "indicator.h"
#include <Arduino.h>
//**
int Indicator::cycle() {
    if (getTimer()) {
        setTimer();
        if (value != bright) {
            value += value < bright ? 1 : -1;
        }
    }
    analogWrite(pin, value);
}
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

2) Программируем ручной режим работы.

Кнопка подключена ко 2-му порту и должна обрабатываться прерыванием.

Режим изменяется нажатием на кнопку.

//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
bool auto = true;

auto = !auto;


//***********************************
void press_button()
{
	static unsigned long millis_prev;
	if (millis() - 100 > millis_prev)
		flag = 1;
	millis_prev = millis();
}
//***************************************
void setup(){
	attachInterrupt(digitalPinToInterrupt(2), press_button, LOW);
}

//***************************************************************
void loop() {
	if (flag) {	//в цикле проверяем флаг и если флаг установлен сбрасываем его и производим действия
		flag = 0;
		//наши действия ......
		
	}
}
//**************************************************************

Ручные режимы – последовательно переключить все каналы нажатием на кнопку.

int nLed = 0;

При нажатии на кнопку увеличиваем номер индикатора и управляем включением / выключения каждого.
Ниже пример простейшего цикла.

for(int i{}; i < MAX_LED; ++i){
	if(i == nLed)
		ar[i]->on();
	else
		ar[i]->off();
}

nLed++;
if( nLed == MAX_LED) nLed = 0; //сбрасываем если переполнение