Hallo en welkom bij het voorlaatste deel van de serie "elegante automatische trapverlichting".
Vandaag breiden we ons besturingssysteem uit met een lichtgevoelige weerstand die fungeert als helderheidssensor. Beginnend met een helderheidswaarde die in de code kan worden ingesteld met de parameter "DayLight_Brightness_Border", waarbij een hoger getal een hogere helderheid symboliseert, wordt de automatische trap gedeactiveerd van deze waarde, zodat alleen wanneer het donker is de trap wordt verlicht. Door het gebruik van een LDR in plaats van een I2C sensor, het hele ding wordt een beetje ongevoeliger voor externe interferentie.
Als een verdere kleine verbetering, in deze versie, de vervagende tijd tussen twee niveaus op de aan- en uitte kan nu afzonderlijk worden ingesteld door de parameters "Delay_Stages_ON" en "Delay_Stages_OFF". Respectabele resultaten kunnen worden bereikt, bijvoorbeeld door de parameter te selecteren voor het uitschakelen van de afzonderlijke stappen die groter zijn dan die voor de inschakelschakelaar.
In de volgende afbeelding is duidelijk hoe de LDR en de pre-stand moeten worden aangesloten:
Voor ons huidige deel van het project hebben we:
Nummer |
Beschrijving |
Opmerking |
2 |
Bewegingssensor |
|
maximaal 62 |
Aantal afhankelijk van het aantal trappen /16 |
|
1 |
|
|
1 |
Voor breadboard setup |
|
tot 992 |
Aantal afhankelijk van het aantal trappen |
|
1 |
Voeding voor LED/lampen voor de stappen |
Maximaal 24 volt |
1 |
10 KOhm Rematch |
|
1 |
Foto-re-stand |
Alle nota's uit de vorige delen zijn ook van toepassing in het deel van vandaag.
Na het aanpassen en toevoegen van de LDR's kan de code worden geüpload:
#include <Draad.H> #define PWM_Module_Base_Addr 0x40 10000000b Het laatste stukje van de adresbyte definieert de bewerking die moet worden uitgevoerd. Wanneer ingesteld op logische 1 0x41 module 2 etc.. Adresbereik0x40 - 0x47 selecteert een leesbewerking terwijl een logische 0 een schrijfbewerking selecteert. #define OE_Pin 8 Vastmaken voor uitvoer inschakelen #define CPU_LED_Pin 13 Intern board LED naar pin 13 (voor foutopsporingsdoeleinden) #define PIRA_Pin 2 #define PIRB_Pin 3 #define Num_Stages_per_Module 16 #define LDR_Pin A2 Analoge pin om de helderheid te meten. (LDR Re-energisme) #define Debug #define L_Sens_Scope 50 Instelbare bedrijfsparameters (constanten) Int Delay_ON_to_OFF = 10; Minimale wachttijd voor de "Off Sequence" in seconden Int Overall_Stages = 8; maximum aantal stappen: 62 x 16 = 992 Int delay_per_Stage_in_ms = 100; Int DayLight_Brightness_Border = 600; Helderheidslimiet automatisch - hogere waarde - Hogere helderheid Byte Delay_Stages_ON = 20; Byte Delay_Stages_OFF = 20; Globale variabelen Int Pwm_Channel = 0; Int Pwm_Channel_Brightness = 0; Bool Motion_Trigger_Down_to_Up = Valse; Bool Motion_Trigger_Up_to_Down = Valse; Bool On_Delay = Valse; Bool DayLight_Status = Waar; Bool DLightCntrl DLightCntrl = Waar; Byte PWMModules = 0; Byte StadiaLinks = 0; Besturingselement onderbreken Volatile Byte A60telSeconds24 = 0; Volatile Byte Seconden24; Isr(TIMER1_COMPA_vect) { A60telSeconds24++; Als (A60telSeconds24 > 59) { A60telSeconds24 = 0; Seconden24++; Als (Seconden24 > 150) { Seconden24 = 0; } } } Void ISR_PIR_A() { Bool PinState = digitaalLezen(PIRA_Pin); Als (PinState) { Als (!(Motion_Trigger_Up_to_Down) En !(Motion_Trigger_Down_to_Up)) { digitalWrite(CPU_LED_Pin, Hoge); Motion_Trigger_Down_to_Up = Waar; } PIR A geactiveerd } Anders { digitalWrite(CPU_LED_Pin, Lage); } } Void ISR_PIR_B() { Bool PinState = digitaalLezen(PIRB_Pin); Als (PinState) { Als (!(Motion_Trigger_Down_to_Up) En !(Motion_Trigger_Up_to_Down)) { digitalWrite(CPU_LED_Pin, Hoge); Motion_Trigger_Up_to_Down = Waar; } PIR B geactiveerd } Anders { digitalWrite(CPU_LED_Pin, Lage); } } Void Init_PWM_Module(Byte PWM_ModuleAddr) { digitalWrite(OE_Pin, Hoge); Actieve pincode voor activering van lage uitvoer (OE). Draad.beginTransmissie(PWM_ModuleAddr); Gegevensoverdracht starten Draad.Schrijven(0x00); // Draad.Schrijven(0x06); Software opnieuw instellen Draad.eindTransmissie(); Communicatie stoppen - Stop bit verzenden Vertraging(400); Draad.beginTransmissie(PWM_ModuleAddr); Gegevensoverdracht starten Draad.Schrijven(0x01); Modus 2 Registreren selecteren (opdrachtregister) Draad.Schrijven(0x04); Configureer Chip: 0x04: dead pole output 0x00: Open drain output. Draad.eindTransmissie(); Communicatie stoppen - Stop bit verzenden Draad.beginTransmissie(PWM_ModuleAddr); Gegevensoverdracht starten Draad.Schrijven(0x00); Modus 1 Registreren selecteren (opdrachtregister) Draad.Schrijven(0x10); Slaapmodus configureren Draad.eindTransmissie(); Communicatie stoppen - Stop bit verzenden Draad.beginTransmissie(PWM_ModuleAddr); Gegevensoverdracht starten Draad.Schrijven(0xFE); Selecteer PRE_SCALE registreren Draad.Schrijven(0x03); Stel Prescaler in. De maximale PWM-frequentie is 1526 Hz als de PRE_SCALEer de operator is ingesteld op "0x03h". Standaard: 200 Hz Draad.eindTransmissie(); Communicatie stoppen - Stop bit verzenden Draad.beginTransmissie(PWM_ModuleAddr); Gegevensoverdracht starten Draad.Schrijven(0x00); Modus 1 Registreren selecteren (opdrachtregister) Draad.Schrijven(0xA1); Chip configureren: ERrlaube All Call I2C-adressen, interne klok gebruiken, / Functie Automatisch stappen toestaan Draad.eindTransmissie(); Communicatie stoppen - Stop bit verzenden } Void Init_PWM_Outputs(Byte PWM_ModuleAddr) { digitalWrite(OE_Pin, Hoge); Actieve pincode voor activering van lage uitvoer (OE). Voor ( Int Z = 0; Z < 16 + 1; Z++) { Draad.beginTransmissie(PWM_ModuleAddr); Draad.Schrijven(Z * 4 + 6); Selecteer PWM_Channel_ON_L register Draad.Schrijven(0x00); Waarde voor bovenstaand register Draad.eindTransmissie(); Draad.beginTransmissie(PWM_ModuleAddr); Draad.Schrijven(Z * 4 + 7); Selecteer PWM_Channel_ON_H register Draad.Schrijven(0x00); Waarde voor bovenstaand register Draad.eindTransmissie(); Draad.beginTransmissie(PWM_ModuleAddr); Draad.Schrijven(Z * 4 + 8); Selecteer PWM_Channel_OFF_L register Draad.Schrijven(0x00); Waarde voor bovenstaand register Draad.eindTransmissie(); Draad.beginTransmissie(PWM_ModuleAddr); Draad.Schrijven(Z * 4 + 9); Selecteer PWM_Channel_OFF_H register Draad.Schrijven(0x00); Waarde voor bovenstaand register Draad.eindTransmissie(); } digitalWrite(OE_Pin, Lage); Actieve pincode voor activering van lage uitvoer (OE). } Void Setup() { Initalisatie Seriële.Beginnen(9600); pinMode(PIRA_Pin, Input); pinMode(PIRB_Pin, Input); pinMode(OE_Pin, Output); pinMode(CPU_LED_Pin, Output); pinMode(LDR_Pin, Input); PWMModules = Overall_Stages / 16; StadiaLinks = (Overall_Stages % 16) - 1; Als (StadiaLinks >= 1) { PWMModules++; } Draad.Beginnen(); Initalisia I2C Bus A4 (SDA), A5 (SCL) Voor (Byte Aantal modules = 0; Aantal modules < PWMModules; Aantal modules++) { Init_PWM_Module(PWM_Module_Base_Addr + Aantal modules); Init_PWM_Outputs(PWM_Module_Base_Addr + Aantal modules); } noInterrupts(); attachInterrupt(0, ISR_PIR_A, Wijzigen); attachInterrupt(1, ISR_PIR_B, Wijzigen); TCCR1A = 0x00; TCCR1B = 0x02; TCNT1 = 0; Inschrijving met 0 initialiseren OCR1A = 33353; Pre-documenten Uitvoervergelijkregister TIMSK1 TIMSK1 |= (1 << OCIE1A); Timer vergelijken onderbreken inschakelen Interrupts(); Seriële.println(V("Init_Complete")); } Bool DayLightStatus () { Int Sensorwaarde = 0; Bool Returnvalue = Waar; Sensorwaarde = analoogLezen(LDR_Pin); #ifdef Debug Seriële.Afdrukken(V("DayLightStatus: ")); Seriële.Afdrukken(Sensorwaarde); #endif Als (Sensorwaarde > DayLight_Brightness_Border) { Als ((DayLight_Status) En (Sensorwaarde > DayLight_Brightness_Border + L_Sens_Scope)) { Returnvalue = Valse; DayLight_Status = Valse; } Anders Als (!(DayLight_Status)) { Returnvalue = Valse; DayLight_Status = Valse; } #ifdef Debug Seriële.println(F("UIT")); #endif } Anders { Als ((DayLight_Status) En (Sensorwaarde > DayLight_Brightness_Border - L_Sens_Scope)) { Returnvalue = Waar; DayLight_Status = Waar; } Anders Als (!(DayLight_Status)) { Returnvalue = Waar; DayLight_Status = Waar; } #ifdef Debug Seriële.println(F(" OP")); #endif } Terug Returnvalue; } Void Down_to_Up_ON() { #ifdef Debug Seriële.println(F("Down_to_Up_ON")); #endif Byte Calc_Num_Stages_per_Module = Num_Stages_per_Module; Voor (Byte Aantal modules = 0; Aantal modules < PWMModules; Aantal modules++) { Pwm_Channel = 0; Pwm_Channel_Brightness = 4095; Als ((StadiaLinks >= 1) En (Aantal modules == PWMModules - 1)) { Calc_Num_Stages_per_Module = StadiaLinks; } Anders { Calc_Num_Stages_per_Module = Num_Stages_per_Module; } Pwm_Channel = 0; Pwm_Channel_Brightness = 0; Terwijl (Pwm_Channel < Calc_Num_Stages_per_Module + 1) { Draad.beginTransmissie( PWM_Module_Base_Addr + Aantal modules); Draad.Schrijven(Pwm_Channel * 4 + 8); Wähle PWM_Channel_0_OFF_L register Draad.Schrijven((Byte)Pwm_Channel_Brightness & 0xFF); Wert für o.g. Register Draad.eindTransmissie(); Draad.beginTransmissie( PWM_Module_Base_Addr + Aantal modules); Draad.Schrijven(Pwm_Channel * 4 + 9); Wähle PWM_Channel_0_OFF_H register Draad.Schrijven((Pwm_Channel_Brightness >> 8)); Wert für o.g. Register Draad.eindTransmissie(); Als (Pwm_Channel_Brightness < 4095) { Pwm_Channel_Brightness = Pwm_Channel_Brightness + Delay_Stages_ON; Als (Pwm_Channel_Brightness > 4095) { Pwm_Channel_Brightness = 4095; } } Anders Als ( Pwm_Channel < Num_Stages_per_Module + 1) { Pwm_Channel_Brightness = 0; Vertraging(delay_per_Stage_in_ms); Pwm_Channel++; } } } } Void Up_to_DOWN_ON() { #ifdef Debug Seriële.println(F("Up_to_DOWN_ON ")); #endif Byte Calc_Num_Stages_per_Module = Num_Stages_per_Module; Int Aantal modules = PWMModules - 1; Terwijl (Aantal modules >= 0) { Pwm_Channel_Brightness = 0; Als ((StadiaLinks >= 1) En (Aantal modules == PWMModules - 1)) { Calc_Num_Stages_per_Module = StadiaLinks; } Anders { Calc_Num_Stages_per_Module = Num_Stages_per_Module; } Pwm_Channel = Calc_Num_Stages_per_Module; Terwijl (Pwm_Channel > -1) { Draad.beginTransmissie( PWM_Module_Base_Addr + Aantal modules); Draad.Schrijven(Pwm_Channel * 4 + 8); Wähle PWM_Channel_0_OFF_L register Draad.Schrijven((Byte)Pwm_Channel_Brightness & 0xFF); Wert für o.g. Register Draad.eindTransmissie(); Draad.beginTransmissie(PWM_Module_Base_Addr + Aantal modules); Draad.Schrijven(Pwm_Channel * 4 + 9); Wähle PWM_Channel_0_OFF_H register Draad.Schrijven((Pwm_Channel_Brightness >> 8)); Wert für o.g. Register Draad.eindTransmissie(); Als (Pwm_Channel_Brightness < 4095) { Pwm_Channel_Brightness = Pwm_Channel_Brightness + Delay_Stages_ON; Als (Pwm_Channel_Brightness > 4095) { Pwm_Channel_Brightness = 4095; } } Anders Als ( Pwm_Channel >= 0) { Pwm_Channel_Brightness = 0; Vertraging(delay_per_Stage_in_ms); Pwm_Channel--; Als ( Pwm_Channel < 0) { Pwm_Channel = 0; Breken; } } } Aantal modules = Aantal modules - 1; } } Void Down_to_Up_OFF() { #ifdef Debug Seriële.println(F("Down_to_Up_OFF")); #endif Byte Calc_Num_Stages_per_Module = Num_Stages_per_Module; Voor (Byte Aantal modules = 0; Aantal modules < PWMModules; Aantal modules++) { Pwm_Channel = 0; Pwm_Channel_Brightness = 4095; Als ((StadiaLinks >= 1) En (Aantal modules == PWMModules - 1)) { Calc_Num_Stages_per_Module = StadiaLinks; } Anders { Calc_Num_Stages_per_Module = Num_Stages_per_Module; } Terwijl (Pwm_Channel < Calc_Num_Stages_per_Module + 1) { Draad.beginTransmissie( PWM_Module_Base_Addr + Aantal modules); Draad.Schrijven(Pwm_Channel * 4 + 8); Selecteer PWM_Channel_0_OFF_L register Draad.Schrijven((Byte)Pwm_Channel_Brightness & 0xff); Waarde voor bovenstaand register Draad.eindTransmissie(); Draad.beginTransmissie(PWM_Module_Base_Addr + Aantal modules); Draad.Schrijven(Pwm_Channel * 4 + 9); Selecteer PWM_Channel_0_OFF_H register Draad.Schrijven((Pwm_Channel_Brightness >> 8)); Waarde voor bovenstaand register Draad.eindTransmissie(); Als (Pwm_Channel_Brightness > 0) { Pwm_Channel_Brightness = Pwm_Channel_Brightness - Delay_Stages_OFF; Als (Pwm_Channel_Brightness < 0) { Pwm_Channel_Brightness = 0; } } Anders Als ( Pwm_Channel < Num_Stages_per_Module + 1) { Pwm_Channel_Brightness = 4095; Vertraging(delay_per_Stage_in_ms); Pwm_Channel++; } } } } Void Up_to_DOWN_OFF() { #ifdef Debug Seriële.println(V("Up_to_DOWN_OFF")); #endif Byte Calc_Num_Stages_per_Module = Num_Stages_per_Module; Int Aantal modules = PWMModules - 1; Terwijl (Aantal modules >= 0) { Pwm_Channel_Brightness = 4095; Als ((StadiaLinks >= 1) En (Aantal modules == PWMModules - 1)) { Calc_Num_Stages_per_Module = StadiaLinks; } Anders { Calc_Num_Stages_per_Module = Num_Stages_per_Module; } Pwm_Channel = Calc_Num_Stages_per_Module; Terwijl (Pwm_Channel > -1) { Draad.beginTransmissie(PWM_Module_Base_Addr + Aantal modules); Draad.Schrijven(Pwm_Channel * 4 + 8); Selecteer PWM_Channel_0_OFF_L register Draad.Schrijven((Byte)Pwm_Channel_Brightness & 0xff); Waarde voor bovenstaand register Draad.eindTransmissie(); Draad.beginTransmissie(PWM_Module_Base_Addr + Aantal modules); Draad.Schrijven(Pwm_Channel * 4 + 9); Selecteer PWM_Channel_0_OFF_H register Draad.Schrijven((Pwm_Channel_Brightness >> 8)); Waarde voor bovenstaand register Draad.eindTransmissie(); Als (Pwm_Channel_Brightness > 0) { Pwm_Channel_Brightness = Pwm_Channel_Brightness - Delay_Stages_OFF; Als (Pwm_Channel_Brightness < 0) { Pwm_Channel_Brightness = 0; } } Anders Als ( Pwm_Channel >= 0) { Pwm_Channel_Brightness = 4095; Vertraging(delay_per_Stage_in_ms); Pwm_Channel--; Als ( Pwm_Channel < 0) { Pwm_Channel = 0; Breken; } } } Aantal modules = Aantal modules - 1; } } Void Stages_Light_Control () { Als ((Motion_Trigger_Down_to_Up) En !(On_Delay)) { DLightCntrl DLightCntrl = DayLightStatus(); Als (DLightCntrl DLightCntrl) { Seconden24 = 0; On_Delay = Waar; Down_to_Up_ON(); } Anders { Motion_Trigger_Down_to_Up = Valse; } } Als ((On_Delay) En (Seconden24 > Delay_ON_to_OFF) En (Motion_Trigger_Down_to_Up) ) { Down_to_Up_OFF(); Motion_Trigger_Down_to_Up = Valse; On_Delay = Valse; Seconden24 = 0; } Als ((Motion_Trigger_Up_to_Down) En !(On_Delay)) { DLightCntrl DLightCntrl = DayLightStatus(); Als (DLightCntrl DLightCntrl) { Seconden24 = 0; On_Delay = Waar; Up_to_DOWN_ON(); } Anders { Motion_Trigger_Up_to_Down = Valse; } } Als ((On_Delay) En (Seconden24 > Delay_ON_to_OFF) En (Motion_Trigger_Up_to_Down)) { Up_to_DOWN_OFF(); Motion_Trigger_Up_to_Down = Valse; On_Delay = Valse; Seconden24 = 0; } } Void Lus() { Stages_Light_Control (); }
Voor foutdiagnose is een seriële interface met 9600 baud beschikbaar, waarbij enige informatie over de huidige status uitvoer is:
Ik wens u veel plezier met de replica en tot het laatste deel van de serie.
Zoals altijd vindt u alle eerdere projecten onder de GitHub-pagina https://github.com/kuchto
1 Reactie
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