PDA

Visualizza Versione Completa : Arduino: classe gestione plafoniera



Niko
01-10-2014, 14: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:

billykid591
01-10-2014, 15:29
Sbaglio o l'avevi già presentata su altro forum?........ comunque funziona bene...anche se nel mio caso dovendo utilizzare la versione 023 dell'IDE che non supporta le classi l'ho dovuta trasformare in una serie di funzioni da richiamare nel listato principale.....

Niko
01-10-2014, 16:19
Si è la stessa che ho presentato nell'altro forum.
E' un peccato che non puoi utilizzare le classi. A parte la comodità del facile riutilizzo, ti permettono di strutturare il progetto in modo più chiaro e pulito focalizzando le funzioni di ogni dispositivo su una classe specifica.
Perché non puoi aggiornare l'IDE ?

billykid591
01-10-2014, 16:25
Si è la stessa che ho presentato nell'altro forum.
E' un peccato che non puoi utilizzare le classi. A parte la comodità del facile riutilizzo, ti permettono di strutturare il progetto in modo più chiaro e pulito focalizzando le funzioni di ogni dispositivo su una classe specifica.
Perché non puoi aggiornare l'IDE ?

non è che non posso aggiornare l'IDE infatti lo sto usando per altri progetti..è che avevo già realizzato un controller per plafo LED (su base arduino ma usando solo il micro su cs fatto ad hoc) che usa delle librerie per la gestione dei menu e dei bottoni non più compatibili con il nuovo IDE.....e modificarle tutte mi rompeva...

iz1yqy
05-11-2015, 07:21
Ciao Niko,
ho provato a caricare il tuo sketch, chiaramente creando le tre pagine .ino,.h e .cpp, caricato su arduino UNO , ma mi da un problema:
all'avvio si accendono istantaneamente i due canali blu e bianco, mentre gli altri non fanno nulla,
ho provato anche a variare ora accensione e accorciare i dempi di alba-tramonto da poter visualizzare il tutto in poco tempo, ma nulla da fare,
hai qualche consiglio, ah dimenticavo, ho anche impostato ora minuti e secondi come da tue istruzioni.
Grazie in anticipo sia per il lavoro fatto che per i consigli che mi potrai dare

Niko
05-11-2015, 14:08
Ciao Niko,
ho provato a caricare il tuo sketch, chiaramente creando le tre pagine .ino,.h e .cpp, caricato su arduino UNO , ma mi da un problema:
all'avvio si accendono istantaneamente i due canali blu e bianco, mentre gli altri non fanno nulla,
ho provato anche a variare ora accensione e accorciare i dempi di alba-tramonto da poter visualizzare il tutto in poco tempo, ma nulla da fare,
hai qualche consiglio, ah dimenticavo, ho anche impostato ora minuti e secondi come da tue istruzioni.
Grazie in anticipo sia per il lavoro fatto che per i consigli che mi potrai dare

Ciao, se si accendono istantaneamente potrebbe essere che non stai utilizzando i pin pwm che per arduino UNO sono 3, 5, 6, 9, 10, 11.

iz1yqy
05-11-2015, 17:20
Sono collegati tra 9-10-11-12, ma resta acceso anche fuori dagli orari programmati

Inviato dal mio SM-G388F utilizzando Tapatalk

billykid591
05-11-2015, 17:47
Sono collegati tra 9-10-11-12, ma resta acceso anche fuori dagli orari programmati

Inviato dal mio SM-G388F utilizzando Tapatalk

posta il listato del programma così vediamo se ci sono errori

marco8181
05-11-2015, 18:16
inquino un attimo il topic per chiedere un informazione:
avete usato mai schede arduino con modulì rele già montati? vi fidate? qualche consiglio su marche/etc ?

grazie!

billykid591
05-11-2015, 18:21
inquino un attimo il topic per chiedere un informazione:
avete usato mai schede arduino con modulì rele già montati? vi fidate? qualche consiglio su marche/etc ?

grazie!

schede con rele' pilotabili da Arduino ce ne sono tante...... nella maggioranza dei casi non sono dei shield da poter inserire sopra la scheda arduino ma schede più grandi esterne (i relè anche se piccoli occupano posto)..... dipende quanti te ne servono e cosa devi pilotarci (da questo dipende il tipo di relè occorrente), per comprarli ci sono molti siti (dove trovi arduino) preferibilmente Italiani (anche se sono fatte tutte in Cina)....

marco8181
05-11-2015, 18:30
mettiamo il solito esempio del timer per le luci, quindi 2 relè che pilotano una plafoniera: in uno 312 w e nel secondo 78 w ( una 10 x 39 t5 )

perché il mio dubbio è proprio quello che hai detto: trovo un sacco di schede con relè 10a 250v ma quali di queste sono affidabili? se hai qualche link incolla pure

billykid591
05-11-2015, 18:41
un buon sito è il seguente:

http://www.robot-italy.com/

ma ce ne sono altri basta che fai una ricerca su google

iz1yqy
05-11-2015, 18:45
Io veramente ho fatto copia e incolla dalle tue oagine

Inviato dal mio SM-G388F utilizzando Tapatalk

Niko
05-11-2015, 23:10
Io veramente ho fatto copia e incolla dalle tue oagine

Inviato dal mio SM-G388F utilizzando Tapatalk


Se hai semplicemente copiato il codice allora il problema sta nei collegamenti.
Apri un topic tutto tuo dove spieghi che led, driver, ecc stai utilizzando.
Posta anche lo schema di collegamento allegando qualche foto.
Tralasciando la classe, prova a settare i pin collegati ai led variandone l'intensità manualmente.

marco8181
06-11-2015, 13:24
grazie!
ma giusto per curiosità ne hai già usate tu di queste schede con relay già montate?

billykid591
06-11-2015, 15:22
grazie!
ma giusto per curiosità ne hai già usate tu di queste schede con relay già montate?

no ma le più semplici (non quelle con porta USB incorporata) da collegare ad Arduino non dovrebbero dare problemi in fondo sono solo relè cablati su un circuito stampato e o transistor di pilotaggio o una interfaccia ic2........

iz1yqy
07-11-2015, 17:44
Per niko, ho verificato il tutto è ho trovato il problema, ma mi serve un aiuto, le lampade si accendono come da programma se l'ora attuale é nel range di lavoro delle lampade, sembra che Arduino non vada avanti con il tempo, devo implementare un modulo rtc?
Grazie

Inviato dal mio SM-G388F utilizzando Tapatalk

Niko
07-11-2015, 20:53
L'RTC è fondamentale.
Ti serve proprio per gestire le ore che passerai continuamente all'oggetto "plafo" tramite il metodo perform sul ciclo loop.

iz1yqy
07-11-2015, 20:56
Ok, allora avevo capito il problema, grazie ancora appena monto il tutto posto qualche foto del progetto finito... striscia led bianco freddo e rgb

Inviato dal mio SM-G388F utilizzando Tapatalk

iz1yqy
10-12-2015, 22:06
Ok, allora avevo capito il problema, grazie ancora appena monto il tutto posto qualche foto del progetto finito... striscia led bianco freddo e rgb

Inviato dal mio SM-G388F utilizzando Tapatalk
18973

Inviato dal mio SM-G388F utilizzando Tapatalk