Eine elegante automatische Treppenbeleuchtung (Teil4) - AZ-Delivery

Ciao, e dia il benvenuto nella parte penultima della fila „all'illuminazione di gradino automatica elegante “.

 

Oggi estendiamo il nostro controllo da un'opposizione fotosensibile che deve agire come un sensore di splendore. Da uno nel codice con il parametro «DayLight_Brightness_Border» il valore di splendore variabile e un numero più alto simboleggiano uno splendore più alto il gradino automatico da questo valore è disattivato, in modo che solo se è scuro che è illuminato il gradino. Tramite un LDRs invece di un I2C di sensore, diventa intero un un po' più insensibilmente contro disordini esterni.

Come poi piccolo in miglioramento può esser messo in questa versione, il tempo sbiadente tra due passi con uno e spegnere dai parametri «Delay_Stages_ON» e «Delay_Stages_OFF» adesso separatamente dell'un l'altro. I risultati rispettabili sono realizzabili, per esempio, con ciò, mentre il parametro è scelto per spegnere i passi di scala soli più grandi che per questo accendono.


Sotto quadro è riconoscibile come il LDR e preriaffermare rivestito di pannelli deve diventare:

Giro con fotoresistore

 

Per la nostra parte di oggi del progetto abbiamo bisogno:

Numero

Descrizione

Osservazione

2

PIR Modulo HC-SR501 PIR

Sensore di movimento

a 62

Canale PCA9685 16 Guidatore di PWM di 12 pezzettini

Numero secondo numero/16 di gradino

1

Nano V3

 

1

Adattatore di parte di Rete di MB102

Per Breadboardaufbau

a 992

Guidatore di IRF520 MOS di modulo 0-24V 5A

Numero secondo numero di gradino

1

Parte netta per CONDOTTE/LAMPADE per i passi

24 volt massimi

1

10 KOhm riaffermano

 

1

LDR

Fotowiederstand

 

Tutte le punte dalle parti precedenti sono anche valide nella parte di oggi.

Dopo propri adattamenti e i Hinzufügen del LDR's il codice può diventare molto carico:

 

#include <Filo.H>

#define PWM_Module_Base_Addr 0x40 //10000000B L'ultimo pezzettino del byte d'indirizzo definisce l'operazione esecutiva. Con installazione su logicamente 1 modulo 0x41 2 eccetera Adressbereich0x40 - 0x47 
//se diventa un processo di lettura sceglie, mentre 0 logico sceglie un'operazione di scrittura.
#define OE_Pin  8                 //Lo spillo per uscita Permette 
#define CPU_LED_Pin 13            //Asse interna CONDOTTA in spillo 13 (a Debuggingzwecken)
#define PIRA_Pin 2
#define PIRB_Pin 3
#define Num_Stages_per_Module 16
#define LDR_Pin A2                //Analogamente lo Spillo su cui lo splendore deve esser misurato. (LDR riaffermano)
#define MESSA A PUNTO
#define L_Sens_Scope 50

//Parametri di società adattabili (costanti)

intervallo Delay_ON_to_OFF = 10;          //Periodo di attesa minimo fino a «da successione» in secondi
intervallo Overall_Stages =  8;         //numero di passo massimo: 62 x 16 = 992
intervallo delay_per_Stage_in_ms = 100;
intervallo DayLight_Brightness_Border = 600; //Confine di splendore automatico - valore più alto - splendore più alto
byte Delay_Stages_ON = 20;
byte Delay_Stages_OFF = 20;


//Variabili globali
intervallo Pwm_Channel = 0;
intervallo Pwm_Channel_Brightness = 0;
bool Motion_Trigger_Down_to_Up = falso;
bool Motion_Trigger_Up_to_Down = falso;
bool On_Delay = falso;
bool DayLight_Status = vero;
bool DLightCntrl = vero;
byte PWMModules = 0;
byte StagesLeft = 0;
//Controllo d'interruzione
volatile byte A60telSeconds24 = 0;
volatile byte Seconds24;

ISR(TIMER1_COMPA_vect)
{   A60telSeconds24++;   se (A60telSeconds24 > 59)   {     A60telSeconds24 = 0;     Seconds24++;     se (Seconds24 > 150)     {       Seconds24 = 0;     }   }
}

vuoto ISR_PIR_A()
{   bool PinState = digitalRead(PIRA_Pin);   se (PinState)   {     se (!(Motion_Trigger_Up_to_Down) e !(Motion_Trigger_Down_to_Up))     {       digitalWrite(CPU_LED_Pin, IN ALTO);       Motion_Trigger_Down_to_Up = vero;     } //PIR Un rilasciato   } altro   {     digitalWrite(CPU_LED_Pin, IN BASSO);   }
}

vuoto ISR_PIR_B()
{   bool PinState = digitalRead(PIRB_Pin);   se (PinState)   {     se (!(Motion_Trigger_Down_to_Up) e !(Motion_Trigger_Up_to_Down))     {       digitalWrite (Scrittura digitale)(CPU_LED_Pin, alto);       Motion_Trigger_Up_to_Down = Vero;     } PIR B attivato   } Altro   {     digitalWrite (Scrittura digitale)(CPU_LED_Pin, Basso);   }
}

Vuoto Init_PWM_Module(Byte PWM_ModuleAddr)
{   digitalWrite (Scrittura digitale)(OE_Pin, alto); Pin di attivazione dell'uscita LOW attivo (OE).   Filo.beginTransmission(PWM_ModuleAddr); Avviare il trasferimento dei dati   Filo.Scrivere(0x00 (in questo 0x00));                       //   Filo.Scrivere(0x06 (in inglese));                       Ripristino del software   Filo.endTransmission();                 Interrompi comunicazione - Invia bit di arresto   Ritardo(400);   Filo.beginTransmission(PWM_ModuleAddr); Avviare il trasferimento dei dati   Filo.Scrivere(0x01 (in tissuta (in ti);                       Selezionare la modalità 2 Registro (Registro comandi)   Filo.Scrivere(0x04 (in tissuta 0x0);                       Chip di configurazione: 0x04: uscita palo morto 0x00: Uscita di scarico aperta.   Filo.endTransmission();                 Interrompi comunicazione - Invia bit di arresto   Filo.beginTransmission(PWM_ModuleAddr); Avviare il trasferimento dei dati   Filo.Scrivere(0x00 (in questo 0x00));                      Selezionare Modalità 1 Registro (Registro comandi)   Filo.Scrivere(0x10 (in modo 0x10));                      Configurare SleepMode   Filo.endTransmission();                Interrompi comunicazione - Invia bit di arresto   Filo.beginTransmission(PWM_ModuleAddr); Avviare il trasferimento dei dati   Filo.Scrivere(0xFE (in modo 0xFE));                       Seleziona PRE_SCALE registro   Filo.Scrivere(0x03 (in tissuta (in ti);                       Impostare Prescaler. La frequenza PWM massima è 1526 Hz se il PRE_SCALEer l'operatore è impostato su "0x03h". Standard: 200 Hz   Filo.endTransmission();                 Interrompi comunicazione - Invia bit di arresto   Filo.beginTransmission(PWM_ModuleAddr); Avviare il trasferimento dei dati   Filo.Scrivere(0x00 (in questo 0x00));                       Selezionare Modalità 1 Registro (Registro comandi)   Filo.Scrivere(0xA1 (in modo 0xA1));                       Configura chip: ERrlaube Tutti gli indirizzi I2C chiamata, utilizzare l'orologio interno, / Consenti funzione di incremento automatico   Filo.endTransmission();                 Interrompi comunicazione - Invia bit di arresto
}


Vuoto Init_PWM_Outputs(Byte PWM_ModuleAddr)
{   digitalWrite (Scrittura digitale)(OE_Pin, alto); Pin di attivazione dell'uscita LOW attivo (OE).   Per ( Int Z = 0; Z < 16 + 1; Z++)   {     Filo.beginTransmission(PWM_ModuleAddr);     Filo.Scrivere(Z * 4 + 6);      Seleziona PWM_Channel_ON_L registro     Filo.Scrivere(0x00 (in questo 0x00));                     Valore per il registro sopra     Filo.endTransmission();     Filo.beginTransmission(PWM_ModuleAddr);     Filo.Scrivere(Z * 4 + 7);      Seleziona PWM_Channel_ON_H registratore di cassa     Filo.Scrivere(0x00 (in questo 0x00));                     Valore per il registro sopra     Filo.endTransmission();     Filo.beginTransmission(PWM_ModuleAddr);     Filo.Scrivere(Z * 4 + 8);   Seleziona PWM_Channel_OFF_L registrato     Filo.Scrivere(0x00 (in questo 0x00));        Valore per il registro sopra     Filo.endTransmission();     Filo.beginTransmission(PWM_ModuleAddr);     Filo.Scrivere(Z * 4 + 9);  Seleziona PWM_Channel_OFF_H registro     Filo.Scrivere(0x00 (in questo 0x00));             Valore per il registro sopra     Filo.endTransmission();   }   digitalWrite (Scrittura digitale)(OE_Pin, Basso); Pin di attivazione dell'uscita LOW attivo (OE).
}

Vuoto Installazione()
{   Inializzazione   Seriale.Iniziare(9600);   PinMode (Modalità pin)(PIRA_Pin, Input);   PinMode (Modalità pin)(PIRB_Pin, Input);   PinMode (Modalità pin)(OE_Pin, Output);   PinMode (Modalità pin)(CPU_LED_Pin, Output);   PinMode (Modalità pin)(LDR_Pin, Input);   PWMModules = Overall_Stages / 16;   Fasi sinistra = (Overall_Stages % 16) - 1;   Se (Fasi sinistra >= 1) {     PWMModules++;   }   Filo.Iniziare(); Initalisia I2C Bus A4 (SDA), A5 (SCL)   Per (Byte ModuleCount (Conteggio moduli) = 0; ModuleCount (Conteggio moduli) < PWMModules; ModuleCount (Conteggio moduli)++)   {     Init_PWM_Module(PWM_Module_Base_Addr + ModuleCount (Conteggio moduli));     Init_PWM_Outputs(PWM_Module_Base_Addr + ModuleCount (Conteggio moduli));   }   noInterruzioni();   attachInterrupt (attachInterrupt)(0, ISR_PIR_A, Cambiare);   attachInterrupt (attachInterrupt)(1, ISR_PIR_B, Cambiare);   TCCR1A = 0x00 (in questo 0x00);   TCCR1B = 0x02 (in tissuta 0x0;   TCNT1 (in questo stato in stato di = 0;      Inizializzare il registro con 0   OCR1A =  33353;      Registro di confronto di output pre-documenti   TIMSK1 |= (1 << CIE1A);  Abilita interruzione confronto timer   Interrompe();   Seriale.println(D("Init_Complete"));
}

Bool Stato di DayLight ()
{   Int SensorValue (Valore sensore) = 0;   Bool Returnvalue = Vero;   SensorValue (Valore sensore) = analogicOLettura(LDR_Pin);
#ifdef Eseguire il debug   Seriale.Stampare(D("DayLightStatus: "));   Seriale.Stampare(SensorValue (Valore sensore));
#endif   Se (SensorValue (Valore sensore) > DayLight_Brightness_Border)   {     Se ((DayLight_Status) E (SensorValue (Valore sensore) > DayLight_Brightness_Border + L_Sens_Scope))     {       Returnvalue = False;       DayLight_Status = False;     } Altro Se (!(DayLight_Status))     {       Returnvalue = False;       DayLight_Status = False;     }
#ifdef DEBUG     Seriale.println(F("OFF"));
#endif   } Altro   {     Se ((DayLight_Status) E (SensorValue (Valore sensore) > DayLight_Brightness_Border - L_Sens_Scope))     {       Returnvalue = Vero;       DayLight_Status = Vero;     } Altro Se (!(DayLight_Status))     {       Returnvalue = Vero;       DayLight_Status = Vero;     }
#ifdef DEBUG     Seriale.println(F("ON"));
#endif   }   Ritorno Returnvalue;
}

Vuoto Down_to_Up_ON()
{
#ifdef DEBUG   Seriale.println(F("Down_to_Up_ON"));
#endif   byte Calc_Num_Stages_per_Module = Num_Stages_per_Module;   Per (byte ModuleCount (Conteggio moduli) = 0; ModuleCount (Conteggio moduli) < PWMModules; ModuleCount (Conteggio moduli)++)   {     Pwm_Channel = 0;     Pwm_Channel_Brightness = 4095;     Se ((Fasi sinistra >= 1) E (ModuleCount (Conteggio moduli) == PWMModules - 1))     {       Calc_Num_Stages_per_Module = Fasi sinistra;     }     Altro     {       Calc_Num_Stages_per_Module = Num_Stages_per_Module;     }     Pwm_Channel = 0;     Pwm_Channel_Brightness = 0;     Mentre (Pwm_Channel < Calc_Num_Stages_per_Module + 1)     {       Filo.beginTransmission( PWM_Module_Base_Addr + ModuleCount (Conteggio moduli));       Filo.Scrivere(Pwm_Channel * 4 + 8);   Registro PWM_Channel_0_OFF_L di W'hle       Filo.Scrivere((byte)Pwm_Channel_Brightness & 0xff);        Registro Wert f'r o.g.       Filo.endTransmission();       Filo.beginTransmission( PWM_Module_Base_Addr + ModuleCount (Conteggio moduli));       Filo.Scrivere(Pwm_Channel * 4 + 9);  Registro PWM_Channel_0_OFF_H W'hle       Filo.Scrivere((Pwm_Channel_Brightness >> 8));             Registro Wert f'r o.g.       Filo.endTransmission();       Se (Pwm_Channel_Brightness < 4095)       {         Pwm_Channel_Brightness = Pwm_Channel_Brightness + Delay_Stages_ON;         Se (Pwm_Channel_Brightness > 4095) {           Pwm_Channel_Brightness = 4095;         }       } Altro Se ( Pwm_Channel < Num_Stages_per_Module + 1)       {         Pwm_Channel_Brightness = 0;         Ritardo(delay_per_Stage_in_ms);         Pwm_Channel++;       }     }   }
}

Vuoto Up_to_DOWN_ON()
{
#ifdef DEBUG   Seriale.println(F("Up_to_DOWN_ON"));
#endif   byte Calc_Num_Stages_per_Module = Num_Stages_per_Module;   Int ModuleCount (Conteggio moduli) = PWMModules - 1;   Mentre (ModuleCount (Conteggio moduli) >= 0)   {     Pwm_Channel_Brightness = 0;     Se ((Fasi sinistra >= 1) E (ModuleCount (Conteggio moduli) == PWMModules - 1))     {       Calc_Num_Stages_per_Module =  Fasi sinistra;     }     Altro     {       Calc_Num_Stages_per_Module = Num_Stages_per_Module;     }     Pwm_Channel = Calc_Num_Stages_per_Module;     Mentre (Pwm_Channel > -1)     {       Filo.beginTransmission( PWM_Module_Base_Addr + ModuleCount (Conteggio moduli));       Filo.Scrivere(Pwm_Channel * 4 + 8);   Registro PWM_Channel_0_OFF_L di W'hle       Filo.Scrivere((byte)Pwm_Channel_Brightness & 0xff);        Registro Wert f'r o.g.       Filo.endTransmission();       Filo.beginTransmission(PWM_Module_Base_Addr + ModuleCount (Conteggio moduli));       Filo.Scrivere(Pwm_Channel * 4 + 9);  Registro PWM_Channel_0_OFF_H W'hle       Filo.Scrivere((Pwm_Channel_Brightness >> 8));             Registro Wert f'r o.g.       Filo.endTransmission();       Se (Pwm_Channel_Brightness < 4095)       {         Pwm_Channel_Brightness = Pwm_Channel_Brightness + Delay_Stages_ON;         Se (Pwm_Channel_Brightness > 4095) {           Pwm_Channel_Brightness = 4095;         }       } Altro Se ( Pwm_Channel >= 0)       {         Pwm_Channel_Brightness = 0;         Ritardo(delay_per_Stage_in_ms);         Pwm_Channel--;         Se ( Pwm_Channel < 0)         {           Pwm_Channel = 0;           Pausa;         }       }     }     ModuleCount (Conteggio moduli) = ModuleCount (Conteggio moduli) - 1;   }
}


Vuoto Down_to_Up_OFF()
{
#ifdef DEBUG   Seriale.println(F("Down_to_Up_OFF"));
#endif   byte Calc_Num_Stages_per_Module = Num_Stages_per_Module;   Per (byte ModuleCount (Conteggio moduli) = 0; ModuleCount (Conteggio moduli) < PWMModules; ModuleCount (Conteggio moduli)++)   {     Pwm_Channel = 0;     Pwm_Channel_Brightness = 4095;     Se ((Fasi sinistra >= 1) E (ModuleCount (Conteggio moduli) == PWMModules - 1))     {       Calc_Num_Stages_per_Module = Fasi sinistra;     }     Altro     {       Calc_Num_Stages_per_Module = Num_Stages_per_Module;     }     Mentre (Pwm_Channel < Calc_Num_Stages_per_Module + 1)     {       Filo.beginTransmission( PWM_Module_Base_Addr + ModuleCount (Conteggio moduli));       Filo.Scrivere(Pwm_Channel * 4 + 8);   Seleziona PWM_Channel_0_OFF_L registro       Filo.Scrivere((Byte)Pwm_Channel_Brightness & 0xff);        Valore per il registro sopra       Filo.endTransmission();       Filo.beginTransmission(PWM_Module_Base_Addr + ModuleCount (Conteggio moduli));       Filo.Scrivere(Pwm_Channel * 4 + 9);  Seleziona PWM_Channel_0_OFF_H registro       Filo.Scrivere((Pwm_Channel_Brightness >> 8));             Valore per il registro sopra       Filo.endTransmission();       Se (Pwm_Channel_Brightness > 0)       {         Pwm_Channel_Brightness = Pwm_Channel_Brightness - Delay_Stages_OFF;         Se (Pwm_Channel_Brightness < 0) {           Pwm_Channel_Brightness = 0;         }       } Altro Se ( Pwm_Channel < Num_Stages_per_Module + 1)       {         Pwm_Channel_Brightness = 4095;         Ritardo(delay_per_Stage_in_ms);         Pwm_Channel++;       }     }   }
}


Vuoto Up_to_DOWN_OFF()
{
#ifdef Eseguire il debug   Seriale.println(D("Up_to_DOWN_OFF"));
#endif   Byte Calc_Num_Stages_per_Module = Num_Stages_per_Module;   Int ModuleCount (Conteggio moduli) = PWMModules - 1;   Mentre (ModuleCount (Conteggio moduli) >= 0)   {     Pwm_Channel_Brightness = 4095;     Se ((Fasi sinistra >= 1) E (ModuleCount (Conteggio moduli) == PWMModules - 1))     {       Calc_Num_Stages_per_Module = Fasi sinistra;     }     Altro     {       Calc_Num_Stages_per_Module = Num_Stages_per_Module;     }     Pwm_Channel = Calc_Num_Stages_per_Module;     Mentre (Pwm_Channel > -1)     {       Filo.beginTransmission(PWM_Module_Base_Addr + ModuleCount (Conteggio moduli));       Filo.Scrivere(Pwm_Channel * 4 + 8);   Seleziona PWM_Channel_0_OFF_L registro       Filo.Scrivere((Byte)Pwm_Channel_Brightness & 0xff);        Valore per il registro sopra       Filo.endTransmission();       Filo.beginTransmission(PWM_Module_Base_Addr + ModuleCount (Conteggio moduli));       Filo.Scrivere(Pwm_Channel * 4 + 9);  Seleziona PWM_Channel_0_OFF_H registro       Filo.Scrivere((Pwm_Channel_Brightness >> 8));             Valore per il registro sopra       Filo.endTransmission();       Se (Pwm_Channel_Brightness > 0)       {         Pwm_Channel_Brightness = Pwm_Channel_Brightness - Delay_Stages_OFF;         Se (Pwm_Channel_Brightness < 0) {           Pwm_Channel_Brightness = 0;         }       } Altro Se ( Pwm_Channel >= 0)       {         Pwm_Channel_Brightness =  4095;         Ritardo(delay_per_Stage_in_ms);         Pwm_Channel--;         Se ( Pwm_Channel < 0)         {           Pwm_Channel = 0;           Pausa;         }       }     }     ModuleCount (Conteggio moduli) = ModuleCount (Conteggio moduli) - 1;   }
}

Vuoto Stages_Light_Control ()
{   Se ((Motion_Trigger_Down_to_Up) E !(On_Delay))   {     DLightCntrl = Stato di DayLight();     Se (DLightCntrl)     {       Secondi24 = 0;       On_Delay = Vero;       Down_to_Up_ON();     } Altro {       Motion_Trigger_Down_to_Up = False;     }   }   Se ((On_Delay) E (Secondi24 > Delay_ON_to_OFF) E (Motion_Trigger_Down_to_Up) )   {     Down_to_Up_OFF();     Motion_Trigger_Down_to_Up = False;     On_Delay = False;     Secondi24 = 0;   }   Se ((Motion_Trigger_Up_to_Down) E !(On_Delay))   {     DLightCntrl = Stato di DayLight();     Se (DLightCntrl)     {       Secondi24 = 0;       On_Delay = Vero;       Up_to_DOWN_ON();     } Altro {       Motion_Trigger_Up_to_Down = False;     }   }   Se ((On_Delay) E (Secondi24 > Delay_ON_to_OFF) E (Motion_Trigger_Up_to_Down))   {     Up_to_DOWN_OFF();     Motion_Trigger_Up_to_Down = False;     On_Delay = False;     Secondi24 = 0;   }
}

Vuoto Ciclo()
{   Stages_Light_Control ();

}

 

Per la diagnosi degli errori, è disponibile un'interfaccia seriale con 9600 baud, in cui vengono emesse alcune informazioni sullo stato corrente:

Problema sul monitor seriale

Vi auguro un sacco di divertimento con la replica e fino all'ultima parte della serie.

Come sempre, puoi trovare tutti i progetti precedenti nella pagina GitHub https://github.com/kuchto

 

 

Für arduinoProjekte für fortgeschritteneSensoren

1 commento

Arnie

Arnie

Servus an alle Treppenbeleuchter,
wer den neuen Code so übernimmt:
- auf 8 Stufen eingestellt
- Ausschaltzeit beträgt 10 sec
- die Überblendungen sind sehr flott
- ich habe einen LDR von 3,9 kohm eingesetzt

Lascia un commento

Tutti i commenti vengono moderati prima della pubblicazione