Niko
01-10-2014, 15:02
Ciao ragazzi, ho notato che sul forum c'è molto interesse verso questo bel microcontroller.
Vi posto la classe che ho creato per gestire la mia plafoniera a led.
La classe fornisce le funzioni "essenziali" che potrete facilmente estendere in base alle vostre necessità.
La funzione "delay" NON è assolutamente utilizzata cosi potete integrare la classe sul vostro progetto che magari fa anche "qualcos'altro".
L'effetto alba e tramonto, qualora sia impostato, viene automaticamente regolato proporzionalmente ai secondi trascorsi in relazione all'ora di accensione e spegnimento del canale.
Per ogni canale basta impostare l'ora di accensione e spegnimento, eventuali minuti iniziali/finali di durata effetto alba/tramonto, il valore massimo pwm e il pin del canale.
Interfaccia (scheda denominata Plafo.h)
// Created by Niko Furioso on 15/07/13.
#ifndef __PLAFO_H__
#define __PLAFO_H__
#include <arduino.h>
enum Channels{
blue=0,
white=1,
uv=2,
moon=3
};
const byte channelsCount=4;
class Plafo {
public:
//Costruttore
Plafo();
void setChannel(const int channel,const byte startHour,const byte startMinute,const byte endHour,const byte endMinute,const unsigned int fadeLen,const byte maxPWM,const byte pin);
void perform(const byte nowHour,const byte nowMinute,const byte nowSecond);
private:
void performChannel(void* channel,const byte nowHour,const byte nowMinute,const byte nowSecond);
unsigned long elapsedTimeToSecond(const byte startHour,const byte startMinute,const byte startSecond,const byte endHour,const byte endMinute,const byte endSecond);
};
#endif
Implementazione (scheda denominata Plafo.cpp)
// Created by Niko Furioso on 15/07/13.
#include "Plafo.h"
struct Channel{
byte startHour,startMinute,maxPWM,lastPWM,pin;
unsigned long lightLen,fadeLen;
};
Channel *channels[channelsCount];
byte lastSecond;
//Costruttore
Plafo::Plafo(){
//Creazione canali
for (byte idx=0;idx<channelsCount;idx++){
channels[idx]= new Channel();
}
lastSecond=60;
}
//Metodi publici
void Plafo::setChannel(const int channel,const byte startHour,const byte startMinute,const byte endHour,const byte endMinute,const unsigned int fadeLen,const byte maxPWM,const byte pin){
//Configurazione canale
channels[channel]->startHour=startHour;
channels[channel]->startMinute=startMinute;
channels[channel]->lightLen=elapsedTimeToSecond(startHour,startMinute ,0,endHour,endMinute,0);
channels[channel]->fadeLen=(unsigned long)fadeLen*60;
channels[channel]->maxPWM=maxPWM;
channels[channel]->pin=pin;
//Impostazione pin canale in uscita
pinMode(channels[channel]->pin,OUTPUT);
}
void Plafo::perform(const byte nowHour,const byte nowMinute,const byte nowSecond){
//Aggiornamento stato plafoniera
if (lastSecond!=nowSecond){
lastSecond=nowSecond;
for (byte idx=0;idx<channelsCount;idx++){
performChannel(channels[idx],nowHour,nowMinute,nowSecond);
}
}
}
//Metodi privati
void Plafo::performChannel(void* channel,const byte nowHour,const byte nowMinute,const byte nowSecond){
Channel *workCnl=(Channel*)channel;
//In base al valore massimo del canale determina se il pin è pwm o digitale
boolean isDigitalPin=workCnl->maxPWM==HIGH;
//Calcolo secondi trascorsi tra l'ora di accensione del canale e l'ora attuale
unsigned long elapsedSecond=elapsedTimeToSecond(workCnl->startHour,workCnl->startMinute,0,nowHour,nowMinute,nowSecond);
byte pwmValue=(isDigitalPin) ? LOW : 0;
//Verifica se il canale è acceso
if (elapsedSecond<=workCnl->lightLen){
//Verifica se alba
if (elapsedSecond<workCnl->fadeLen){
//Calcolo valore PWM in relazione ai secondi trascorsi dall'ora di inizio
pwmValue=(elapsedSecond*workCnl->maxPWM)/workCnl->fadeLen;
}//Verifica se tramonto
else if (elapsedSecond>workCnl->lightLen-workCnl->fadeLen){
//Calcolo valore PWM in relazione ai secondi mancanti all'ora di fine
pwmValue=((workCnl->lightLen-elapsedSecond)*workCnl->maxPWM)/workCnl->fadeLen;
}//Luce piena
else{
pwmValue=workCnl->maxPWM;
}
}
//Aggiorna lo stato del pin solo se il valore è effettivamente cambiato
if (workCnl->lastPWM!=pwmValue){
workCnl->lastPWM=pwmValue;
if (isDigitalPin){
digitalWrite(workCnl->pin,pwmValue);
}
else{
analogWrite(workCnl->pin,pwmValue);
}
}
}
unsigned long Plafo::elapsedTimeToSecond(const byte startHour,const byte startMinute,const byte startSecond,const byte endHour,const byte endMinute,const byte endSecond){
//Calcolo secondi tra ora di inizio e ora di fine
int elapsedHour;
elapsedHour=endHour-startHour;
if (elapsedHour<0)elapsedHour=24-startHour+endHour;
unsigned int elapsedMinute;
elapsedMinute=(unsigned int)elapsedHour*60 + endMinute-startMinute;
return (unsigned long)elapsedMinute*60 + endSecond-startSecond;
}
Per utilizzarla non resta che importarla nel vostro progetto, ad esempio:
#include "Plafo.h"
Plafo plafo;
void setup(void) {
//Channel,startHour,startMinute,endHour,endMinute,fa deLen,maxPWM,pin
plafo.setChannel(blue,18,0,4,0,30,180,7);//Dalle 18.00 alle 4.00, alba/tramonto 30 minuti, pwm massimo 180, pin 7
plafo.setChannel(white,18,15,3,45,75,180,5);//Dalle 18.15 alle 3.45, alba/tramonto 75 minuti
plafo.setChannel(uv,19,30,2,30,0,HIGH,22);//Dalle 19.30 alle 2.30, accensione immediata, pin 22 (digitale)
plafo.setChannel(moon,4,10,7,0,0,HIGH,23);//Dalle 4.10 alle 7.00
}
void loop(void) {
//Sostituire "hour","minute", "second" con le variabili dichiarate sul vostro progetto, che contengono rispettivamente l'ora, i minuti e i secondi correnti.
plafo.perform(hour,minute,second);
}
Per modificare, eliminare o aggiugere nuovi canali basta modificare "enum Channels" e la costante "channelsCount" presenti sull'interfaccia.
Spero che questa classe vi possa essere di aiuto, naturalmente sono ben accetti consigli o segnalazioni di bug.
:114-45:
Vi posto la classe che ho creato per gestire la mia plafoniera a led.
La classe fornisce le funzioni "essenziali" che potrete facilmente estendere in base alle vostre necessità.
La funzione "delay" NON è assolutamente utilizzata cosi potete integrare la classe sul vostro progetto che magari fa anche "qualcos'altro".
L'effetto alba e tramonto, qualora sia impostato, viene automaticamente regolato proporzionalmente ai secondi trascorsi in relazione all'ora di accensione e spegnimento del canale.
Per ogni canale basta impostare l'ora di accensione e spegnimento, eventuali minuti iniziali/finali di durata effetto alba/tramonto, il valore massimo pwm e il pin del canale.
Interfaccia (scheda denominata Plafo.h)
// Created by Niko Furioso on 15/07/13.
#ifndef __PLAFO_H__
#define __PLAFO_H__
#include <arduino.h>
enum Channels{
blue=0,
white=1,
uv=2,
moon=3
};
const byte channelsCount=4;
class Plafo {
public:
//Costruttore
Plafo();
void setChannel(const int channel,const byte startHour,const byte startMinute,const byte endHour,const byte endMinute,const unsigned int fadeLen,const byte maxPWM,const byte pin);
void perform(const byte nowHour,const byte nowMinute,const byte nowSecond);
private:
void performChannel(void* channel,const byte nowHour,const byte nowMinute,const byte nowSecond);
unsigned long elapsedTimeToSecond(const byte startHour,const byte startMinute,const byte startSecond,const byte endHour,const byte endMinute,const byte endSecond);
};
#endif
Implementazione (scheda denominata Plafo.cpp)
// Created by Niko Furioso on 15/07/13.
#include "Plafo.h"
struct Channel{
byte startHour,startMinute,maxPWM,lastPWM,pin;
unsigned long lightLen,fadeLen;
};
Channel *channels[channelsCount];
byte lastSecond;
//Costruttore
Plafo::Plafo(){
//Creazione canali
for (byte idx=0;idx<channelsCount;idx++){
channels[idx]= new Channel();
}
lastSecond=60;
}
//Metodi publici
void Plafo::setChannel(const int channel,const byte startHour,const byte startMinute,const byte endHour,const byte endMinute,const unsigned int fadeLen,const byte maxPWM,const byte pin){
//Configurazione canale
channels[channel]->startHour=startHour;
channels[channel]->startMinute=startMinute;
channels[channel]->lightLen=elapsedTimeToSecond(startHour,startMinute ,0,endHour,endMinute,0);
channels[channel]->fadeLen=(unsigned long)fadeLen*60;
channels[channel]->maxPWM=maxPWM;
channels[channel]->pin=pin;
//Impostazione pin canale in uscita
pinMode(channels[channel]->pin,OUTPUT);
}
void Plafo::perform(const byte nowHour,const byte nowMinute,const byte nowSecond){
//Aggiornamento stato plafoniera
if (lastSecond!=nowSecond){
lastSecond=nowSecond;
for (byte idx=0;idx<channelsCount;idx++){
performChannel(channels[idx],nowHour,nowMinute,nowSecond);
}
}
}
//Metodi privati
void Plafo::performChannel(void* channel,const byte nowHour,const byte nowMinute,const byte nowSecond){
Channel *workCnl=(Channel*)channel;
//In base al valore massimo del canale determina se il pin è pwm o digitale
boolean isDigitalPin=workCnl->maxPWM==HIGH;
//Calcolo secondi trascorsi tra l'ora di accensione del canale e l'ora attuale
unsigned long elapsedSecond=elapsedTimeToSecond(workCnl->startHour,workCnl->startMinute,0,nowHour,nowMinute,nowSecond);
byte pwmValue=(isDigitalPin) ? LOW : 0;
//Verifica se il canale è acceso
if (elapsedSecond<=workCnl->lightLen){
//Verifica se alba
if (elapsedSecond<workCnl->fadeLen){
//Calcolo valore PWM in relazione ai secondi trascorsi dall'ora di inizio
pwmValue=(elapsedSecond*workCnl->maxPWM)/workCnl->fadeLen;
}//Verifica se tramonto
else if (elapsedSecond>workCnl->lightLen-workCnl->fadeLen){
//Calcolo valore PWM in relazione ai secondi mancanti all'ora di fine
pwmValue=((workCnl->lightLen-elapsedSecond)*workCnl->maxPWM)/workCnl->fadeLen;
}//Luce piena
else{
pwmValue=workCnl->maxPWM;
}
}
//Aggiorna lo stato del pin solo se il valore è effettivamente cambiato
if (workCnl->lastPWM!=pwmValue){
workCnl->lastPWM=pwmValue;
if (isDigitalPin){
digitalWrite(workCnl->pin,pwmValue);
}
else{
analogWrite(workCnl->pin,pwmValue);
}
}
}
unsigned long Plafo::elapsedTimeToSecond(const byte startHour,const byte startMinute,const byte startSecond,const byte endHour,const byte endMinute,const byte endSecond){
//Calcolo secondi tra ora di inizio e ora di fine
int elapsedHour;
elapsedHour=endHour-startHour;
if (elapsedHour<0)elapsedHour=24-startHour+endHour;
unsigned int elapsedMinute;
elapsedMinute=(unsigned int)elapsedHour*60 + endMinute-startMinute;
return (unsigned long)elapsedMinute*60 + endSecond-startSecond;
}
Per utilizzarla non resta che importarla nel vostro progetto, ad esempio:
#include "Plafo.h"
Plafo plafo;
void setup(void) {
//Channel,startHour,startMinute,endHour,endMinute,fa deLen,maxPWM,pin
plafo.setChannel(blue,18,0,4,0,30,180,7);//Dalle 18.00 alle 4.00, alba/tramonto 30 minuti, pwm massimo 180, pin 7
plafo.setChannel(white,18,15,3,45,75,180,5);//Dalle 18.15 alle 3.45, alba/tramonto 75 minuti
plafo.setChannel(uv,19,30,2,30,0,HIGH,22);//Dalle 19.30 alle 2.30, accensione immediata, pin 22 (digitale)
plafo.setChannel(moon,4,10,7,0,0,HIGH,23);//Dalle 4.10 alle 7.00
}
void loop(void) {
//Sostituire "hour","minute", "second" con le variabili dichiarate sul vostro progetto, che contengono rispettivamente l'ora, i minuti e i secondi correnti.
plafo.perform(hour,minute,second);
}
Per modificare, eliminare o aggiugere nuovi canali basta modificare "enum Channels" e la costante "channelsCount" presenti sull'interfaccia.
Spero che questa classe vi possa essere di aiuto, naturalmente sono ben accetti consigli o segnalazioni di bug.
:114-45: