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:
Per la nostra parte di oggi del progetto abbiamo bisogno:
Numero |
Descrizione |
Osservazione |
2 |
Sensore di movimento |
|
a 62 |
Numero secondo numero/16 di gradino |
|
1 |
|
|
1 |
Per Breadboardaufbau |
|
a 992 |
Numero secondo numero di gradino |
|
1 |
Parte netta per CONDOTTE/LAMPADE per i passi |
24 volt massimi |
1 |
10 KOhm riaffermano |
|
1 |
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:
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
1 commento
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