На занятии мы разобрали код из предыдущего примера, содержащего описание класса 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();
}
}
}
Программа не очень интересная, т.к. светодиоды работают синхронно. Как будет работать программа при изменении входных значений, мы рассмотрим на следующих занятиях.