Дополнение к классу softLed

На занятии мы разобрали код из предыдущего примера, содержащего описание класса softLed и выполняющего плавное включение светодиода. Я просил вас переделать программу так, что бы можно было подключить произвольное кол-во светодиодов. Опустим ограничения контроллера.

В итоге у нас получилось 2 класса:

#ifndef MYLIBRARY_H
#define MYLIBRARY_H

//class timer;
class timer {
  private:
     unsigned long ulTimer;
  public:
     timer(unsigned long dT);
     timer();
     //*****************************       установка времени задержки таймера
     bool setTimer(unsigned long dT);
     //***************************** запрос состояния таймера. Возвращает true, если включен.
     bool getTimer();

};
#endif

Файл timer.cpp

#include  "Arduino.h"
#include "timer.h"

timer::timer(unsigned long dT){ulTimer = dT;}
timer::timer(){ulTimer = 0;}
//***********************************************************************
bool timer::setTimer(unsigned long dT){
bool bActive = false;
  if(ulTimer == 0){           //если таймер не включен
      bActive = true;
      ulTimer = millis() + dT;  //задаем значение - сумма текущего времени
  }                               //и заданного времни ожидания
  return bActive;
}
//***************************** запрос состояния таймера. Возвращает true, если включен.
bool timer::getTimer(){
  if(ulTimer <= millis()){   //проверяем состояние таймера
      ulTimer = 0;            //если время истекло, сбрасываем заданное значение, выключаем таймер.
  }
  return ulTimer != 0;       //возвращаем логическое состояние таймера, если включен - true
}

Файл softLed.h

#ifndef SOFTLED_H
#define SOFTLED_H
#include "timer.h"
/*
класс softLed обеспечивает плавное включение и выключение светодиода,
выполняя, при этом, функции триггера состояния.
Состояние изменяется на противоположное при каждом вызове функции ledOn().
После выполнения последней итерации включения (выключения) светодиода, вызывается виртуальная функция action().
*/
class softLed{
  private:
    int n;        //текущая итерация
    int pin;
  protected:
    int steps;    //число шагов
    int stat;     //состояние светодиода
    unsigned long dt; //длительность задержки
    timer *Timer;
  public:
    softLed(int pin, int steps = 30, bool stat = true, unsigned long dt = 50);    //конструктор
    ~softLed();   //деструктор
    bool ledOn(); //включение
    bool cycle();   //цикл в цепи
    virtual bool action();
};
#endif

Файл softLed.cpp

#include "Arduino.h"
#include "softLed.h"
#include "timer.h"

//***********************
softLed::softLed(int pin, int steps, bool stat, unsigned long dt){
  this->pin = pin;
  this->n = 0;
  this->steps = steps;
  this->stat = stat;
  this -> dt = dt;
  Timer = new timer();
  pinMode(pin, OUTPUT);
  digitalWrite(pin, stat);
}
//***********************
softLed::~softLed(){
  delete Timer;
}
//***********************
int softLed::getPin(){
  return pin;
}
//***********************
bool softLed::ledOn(){
  n = steps;
  stat = !stat;
  return n > 0;
}
//***********************
bool softLed::action(){
  return false;
}
//***********************
bool softLed::cycle(){
  if(n && !Timer->getTimer()){
      Timer->setTimer(dt); //запускаем таймер на следующий период
      int levelLight = map(n-1, 0, steps-1, 0, 255); 
      levelLight = stat? 255 - levelLight: levelLight;
      analogWrite(pin, levelLight);
      n--;
      if(!n)action(); 
  } else 
  return n > 0;
}

В итоге, код программы сильно упростился:

#include "timer.h"
#include "softLed.h"

static const int arPins[] = {9, 10, 11};
int nLeds = 0; //число подключаемых светодиодов
softLed **arLeds;
timer *Tm;
//***********************
void setup() {
  nLeds = sizeof(arPins)/sizeof(int);  //вычисление числа подключенных светодиодов по числу объявленных портов
  arLeds = new softLed*[nLeds];
  for(int i= 0; i < nLeds; ++i){
    arLeds[i] = new softLed((int)arPins[i]);
    arLeds[i]-> ledOn();
  }
  Tm = new timer();
}

//***********************
void loop() {
  for(int i= 0; i < nLeds; ++i){
    arLeds[i] -> cycle();
  }
  if(!Tm -> getTimer()){
    Tm -> setTimer(3000);
    for(int i= 0; i < nLeds; ++i){
      arLeds[i] -> ledOn();
    }
  }
}

Программа не очень интересная, т.к. светодиоды работают синхронно. Как будет работать программа при изменении входных значений, мы рассмотрим на следующих занятиях.