Benvenuti nella seconda parte della nostra serie "controllo della luce elegante scala". Come sempre nella serie di progetti, le parti seguenti riguardano il miglioramento o l'estensione della funzione. Nella parte di oggi, stiamo migliorando la funzione prima.
Fondamentalmente, le nostre scale vanno lentamente dal basso verso l'alto, se lo inserisci dall'alto verso il basso o viceversa, dal basso verso l'alto. Tuttavia, sarebbe più bello se le nostre scale si accese esattamente nella direzione come una luce di corsa, in cui entriamo le scale e poi lentamente spegnere di nuovo.
Questo è esattamente ciò che questo allargamento è di circa nella parte di oggi della serie. La luce delle scale segue i nostri passi non appena entriamo nelle scale, indipendentemente dalla direzione.
I parametri e il circuito possono essere dalla prima parte della serie essere preso in consegna. Si tratta di un'estensione software pura.
#define Num_Stages 15
Delay_Stages #define 10
#define Delay_ON_to_OFF 5
Num_Stages |
Definisce il numero di scale da illuminare (massimo 16, contando da 0 all'inizio. Valore massimo: 15) |
Delay_Stages |
Periodo di dissolvenza per ogni passo scala -> minore è il valore maggiore, più lento. |
Delay_ON_to_OFF |
Periodo che passa lasciando le scale nello stato "on". |
Dopo che i valori sono stati personalizzati in base alle proprie preferenze, il codice esteso può essere caricato su Arduino:
2019 Tobias Kuch GPL 3.0 Includono <Filo.H> # define PWM_Module_Base_Addr 0x40 (in questo 0x40) 10000000b L'ultimo bit del byte dell'indirizzo definisce l'operazione da eseguire. Se impostato su logico 1 0x41 modulo 2 seleziona un'operazione di lettura mentre uno 0 logico seleziona un'operazione di scrittura. # define OE_Pin 8 Perno per l'abilitazione dell'uscita # define CPU_LED_Pin 13 # define PIRA_Pin 2 # define PIRB_Pin 3 # define Num_Stages 15 # define Delay_Stages 5 # define Delay_ON_to_OFF 30 Delay_ON_to_OFF minimo in secondi # define delay_per_Stage_in_ms 200 Int Pwm_Channel = 0; Int Pwm_Channel_Brightness = 0; Bool Motion_Trigger_Down_to_Up = False; Bool Motion_Trigger_Up_to_Down = False; Bool On_Delay = False; controllo interrupt Byte A60telSeconds24 = 0; Byte Secondi24; Pvr(TIMER1_COMPA_vect) { A60telSeconds24++; Se (A60telSeconds24 > 59) { A60telSeconds24 = 0; Secondi24++; Se (Secondi24 > 150) { Secondi24 = 0; } } } Vuoto ISR_PIR_A() { Bool PinState = digitalRead (Lettura digitale)(PIRA_Pin); Se (PinState) { Se (!(Motion_Trigger_Up_to_Down) E !(Motion_Trigger_Down_to_Up)) { digitalWrite (Scrittura digitale)(CPU_LED_Pin, alto); Motion_Trigger_Down_to_Up = Vero; } PIR A attivato } Altro { digitalWrite (Scrittura digitale)(CPU_LED_Pin, Basso); } } Vuoto ISR_PIR_B() { Bool PinState = digitalRead (Lettura digitale)(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) { PinMode (Modalità pin)(OE_Pin, Output); PinMode (Modalità pin)(CPU_LED_Pin, Output); 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); // Configura SleepMode filo.trasmissione finale(); // Arresta comunicazione - invia bit di stop filo.iniziare la trasmissione(PWM_ModuleAddr); // Avvia il trasferimento di dati filo.write(0xFE); // Scegli il registro PRE_SCALE (Registro comandi) filo.write(0x03); // Imposta prescaler. La frequenza PWM massima è 1526 Hz se PRE_SCALEer Regsiter è impostato su "0x03h". Standard: 200 Hz filo.trasmissione finale(); // Arresta comunicazione - invia bit di stop filo.iniziare la trasmissione(PWM_ModuleAddr); // Avvia il trasferimento di dati filo.write(0x00); // Seleziona il registro modalità 1 (Registro comandi) filo.write(0xA1); // Configura chip: consenti tutti gli indirizzi I2C di chiamata, utilizza l'orologio interno, // Consenti funzione di incremento automatico filo.trasmissione finale(); // Arresta comunicazione - invia bit di stop } vuoto Init_PWM_Outputs(byte PWM_ModuleAddr) { digitalWrite(OE_Pin, ALTA); // Pin di attivazione dell'uscita LOW (OE) attivo. per ( int z = 0; z < 16 + 1; z++) { filo.iniziare la trasmissione(PWM_ModuleAddr); filo.write(z * 4 + 6); // Scegli il registro PWM_Channel_ON_L filo.write(0x00); // valore per quanto sopra registro filo.trasmissione finale(); filo.iniziare la trasmissione(PWM_ModuleAddr); filo.write(z * 4 + 7); // Scegli il registro PWM_Channel_ON_H filo.write(0x00); // valore per quanto sopra registro filo.trasmissione finale(); filo.iniziare la trasmissione(PWM_ModuleAddr); filo.write(z * 4 + 8); // Scegli il registro PWM_Channel_OFF_L filo.write(0x00); // valore per quanto sopra registro filo.trasmissione finale(); filo.iniziare la trasmissione(PWM_ModuleAddr); filo.write(z * 4 + 9); // Scegli il registro PWM_Channel_OFF_H filo.write(0x00); // valore per quanto sopra registro filo.trasmissione finale(); } digitalWrite(OE_Pin, LOW); // Pin di attivazione dell'uscita LOW (OE) attivo. } vuoto configurazione() { // inizializzazione serial.iniziare(9600); pinMode(PIRA_Pin, INGRESSO); pinMode(PIRB_Pin, INGRESSO); serial.iniziare(9600); filo.iniziare(); // Inizializza bus I2C A4 (SDA), A5 (SCL) Init_PWM_Module(PWM_Module_Base_Addr); Init_PWM_Outputs(PWM_Module_Base_Addr); noInterrupts(); attachInterrupt(0, ISR_PIR_A, CAMBIO); attachInterrupt(1, ISR_PIR_B, CAMBIO); TCCR1A = 0x00; TCCR1B = 0x02; TCNT1 = 0; // inizializza il registro con 0 OCR1A = 33353; // preassegna il registro di confronto delle uscite TIMSK1 |= (1 << OCIE1A); // Attiva l'interruzione del confronto timer interrupt(); } vuoto Down_to_Up_ON() { Pwm_Channel = 0; Pwm_Channel_Brightness = 0; mentre (Pwm_Channel < Num_Stages + 1) { filo.iniziare la trasmissione( PWM_Module_Base_Addr); filo.write(Pwm_Channel * 4 + 8); // Scegli il registro PWM_Channel_0_OFF_L filo.write((byte)Pwm_Channel_Brightness & 0xFF); // valore per quanto sopra registro filo.trasmissione finale(); filo.iniziare la trasmissione( PWM_Module_Base_Addr); filo.write(Pwm_Channel * 4 + 9); // Scegli il registro PWM_Channel_0_OFF_H filo.write((Pwm_Channel_Brightness >> 8)); // valore per quanto sopra registro filo.trasmissione finale(); se (Pwm_Channel_Brightness < 4095) { Pwm_Channel_Brightness = Pwm_Channel_Brightness + Delay_Stages; se (Pwm_Channel_Brightness > 4095) { Pwm_Channel_Brightness = 4095; } } altro se ( Pwm_Channel < Num_Stages + 1) { Pwm_Channel_Brightness = 0; ritardo(delay_per_Stage_in_ms); Pwm_Channel++; } } } vuoto Down_to_Up_OFF() { Pwm_Channel = 0; Pwm_Channel_Brightness = 4095; mentre (Pwm_Channel < Num_Stages + 1) { filo.iniziare la trasmissione( PWM_Module_Base_Addr); filo.write(Pwm_Channel * 4 + 8); // Scegli il registro PWM_Channel_0_OFF_L filo.write((byte)Pwm_Channel_Brightness & 0xFF); // valore per quanto sopra registro filo.trasmissione finale(); filo.iniziare la trasmissione(PWM_Module_Base_Addr); filo.write(Pwm_Channel * 4 + 9); // Scegli il registro PWM_Channel_0_OFF_H filo.write((Pwm_Channel_Brightness >> 8)); // valore per quanto sopra registro filo.trasmissione finale(); se (Pwm_Channel_Brightness > 0) { Pwm_Channel_Brightness = Pwm_Channel_Brightness - Delay_Stages; Se (Pwm_Channel_Brightness < 0) { Pwm_Channel_Brightness = 0; } } altro Se ( Pwm_Channel < Num_Stages + 1) { Pwm_Channel_Brightness = 4095; ritardo(delay_per_Stage_in_ms); Pwm_Channel++; } } } vuoto Up_to_DOWN_ON() { Pwm_Channel = Num_Stages; Pwm_Channel_Brightness = 0; mentre (Pwm_Channel > -1) { Filo.beginTransmission( PWM_Module_Base_Addr); Filo.Scrivi(Pwm_Channel * 4 + 8); // Registro Wähle PWM_Channel_0_OFF_L Filo.Scrivi((byte)Pwm_Channel_Brightness & 0xFF); // Wert für o.g. Registrati Filo.endTransmission(); Filo.beginTransmission(PWM_Module_Base_Addr); Filo.Scrivi(Pwm_Channel * 4 + 9); // Registro Wähle PWM_Channel_0_OFF_H Filo.Scrivi((Pwm_Channel_Brightness >> 8)); // Wert für o.g. Registrati Filo.endTransmission(); Se (Pwm_Channel_Brightness < 4095) { Pwm_Channel_Brightness = Pwm_Channel_Brightness + Delay_Stages; 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; rompere; } } } } vuoto Up_to_DOWN_OFF() { Pwm_Channel = Num_Stages; Pwm_Channel_Brightness = 4095; mentre (Pwm_Channel > -1) { Filo.beginTransmission(PWM_Module_Base_Addr); Filo.Scrivi(Pwm_Channel * 4 + 8); // Registro Wähle PWM_Channel_0_OFF_L Filo.Scrivi((byte)Pwm_Channel_Brightness & 0xFF); // Wert für o.g. Registrati Filo.endTransmission(); Filo.beginTransmission(PWM_Module_Base_Addr); Filo.Scrivi(Pwm_Channel * 4 + 9); // Registro Wähle PWM_Channel_0_OFF_H Filo.Scrivi((Pwm_Channel_Brightness >> 8)); // Wert für o.g. Registrati Filo.endTransmission(); Se (Pwm_Channel_Brightness > 0) { Pwm_Channel_Brightness = Pwm_Channel_Brightness - Delay_Stages; 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; rompere; } } } } vuoto ciclo continuo() { Se ((Motion_Trigger_Down_to_Up) e !(In ritardo) ) { Seconds24 = 0; In ritardo = vero; Down_to_Up_ON(); } Se ((In ritardo) e (Seconds24 > Delay_ON_to_OFF) e (Motion_Trigger_Down_to_Up) ) { Down_to_Up_OFF(); Motion_Trigger_Down_to_Up = falso; In ritardo = falso; Seconds24 = 0; } Se ((Motion_Trigger_Up_to_Down) e !(In ritardo) ) { Seconds24 = 0; In ritardo = vero; Up_to_DOWN_ON(); } Se ((In ritardo) e (Seconds24 > Delay_ON_to_OFF) e (Motion_Trigger_Up_to_Down)) { Up_to_DOWN_OFF(); Motion_Trigger_Up_to_Down = falso; In ritardo = falso; Seconds24 = 0; } }
Ich wünsche viel Spaß beim Nachbauen diees Projektes und bis zum nächsten Teil.
6 commenti
Peter Wenk
Hallo Freunde im Blog,
ich habe mir die Treppenbeleuchtung auf dem Steckbrett nachgebaut und es funktioniert wunderbar.
Jetzt würde ich gern die helligkeit aller leds reduzieren. Es müsste doch über die PWM Taktung funktionieren also nicht mit 100% sondern nach wunsch nur 50% Taktung.
Kann mir einer helfen wie ich den Skretch umschreiben muss?
Würde mich über Hilfe freuen.
LG
Peter
Maik
@Thomas
Realisiere das doch mit einer separaten Steuerung, dann kannst Du dir den Flur nach deinen Wünschen ausleuchten.
Strotty
Hallo,
ich bekomme bei ISR folgende Fehlermeldung:
exit status 1
expected unqualified-id before string constant
kann mir jemand einen Tipp geben?
Thomas
Das Treppenlicht ist eine wirklich tolle Idee, mit der ich schon viele Jahre liebäugele. Aber wie es immer so ist, das, was man sucht, findet man dann doch in der Form nicht und sich zu kompletter Eigenentwicklung aufzuraffen bleibt bei mir meist auf der Strecke. Ich habe nun auch mit dem Kommentar bis zum 2. Teil gewartet, da mir im 1. Teil die Beschränkung auf die eine „Einschaltrichtung“ auffiel und die erwartungsgemäß nun ergänzt wurde. Jetzt würde ich gerne meine Idee anbringen, die mit dem Rettungsdienst-Kommentar von Wolfgang konform geht:
Unser Flur im 1. OG ist nachts erbärmlich dunkel und auf dem Weg durch den Flur auch ohne Treppenbenutzung wäre es super, wenn eben am oberen Ende der Treppe die Beleuchtung der obersten Stufe mit einem zusätzlichen (dritten) Sensor verbunden wäre, der eben nur die eine Stufe schaltet, wenn sich jemand oben im Flur bewegt. Damit hat man dann nachts ausreichend Orientierung im Flur und es ist als Funktion abgegrenzt von der Treppenbenutzung. Aber die Stufe sollte trotzdem wie in der beschriebenen Lösung integriert bleiben.
Ein Ausschalten am Ende des „Treppenganges“ wäre für mich nicht sinnvoll, da es wegen mehrerer Bewohner und Hund zwangsläufig zu Situation kommen wird, wo jemand dann im Dunklen auf der Treppe steht.
Markus
Was ist wenn ich mir auf der hälfte der Treppe einfällt ich muss noch mal runter ?
Wolfgang Hauf
Hi,
du hast in der ersten Zeile die “#” vergessen !!