Visualizza un messaggio singolo
Vecchio 16-07-2013, 13:59   #2
Niko79
Guppy
 
Registrato: Nov 2009
Città: Augusta
Acquariofilo: Marino
Messaggi: 273
Foto: 0 Albums: 0
Post "Grazie" / "Mi Piace"
Grazie (Dati):
Grazie (Ricev.):
Mi piace (Dati):
Mi piace (Ricev.):
Mentioned: 0 Post(s)
Feedback 0/0%

Annunci Mercatino: 0
Libreria "base" gestione plafoniera aggiornata al 19/07/2013

Ho buttato giù due righe di codice creando la libreria per gestire la plafoniera che sto costruendo.

La libreria fornisce le funzioni "essenziali" che potrete facilmente estendere in base alle vostre necessità.
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)
codice:
//  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)
codice:
//  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:
codice:
#include "Plafo.h"

Plafo plafo;

void setup(void) {
  //Channel,startHour,startMinute,endHour,endMinute,fadeLen,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 libreria vi possa essere di aiuto, naturalmente sono ben accetti consigli o segnalazioni di bug.

--------------AGGIORNAMENTI
19/07/2013 - i canali venivano ricreati ogni qualvolta venivano configurati
__________________
IO USERO' ACQUA DEL NOSTRO MARE
IO USERO' SABBIA DEL NOSTRO MARE

Ultima modifica di Niko79; 21-09-2013 alle ore 11:24. Motivo: Aggiunto commento su esempio
Niko79 non è in linea   Rispondi quotando
 
Page generated in 0,17294 seconds with 13 queries