Elegante automatische trapverlichting (deel 4)

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:

Circuit met fotoresistor

 

Voor ons huidige deel van het project hebben we:

Nummer

Beschrijving

Opmerking

2

Pir Module HC-SR501 PIR

Bewegingssensor

maximaal 62

PCA9685 16 Kanaal12-bits PWM-stuurprogramma

Aantal afhankelijk van het aantal trappen /16

1

Nano V3

 

1

MB102-voedingsadapter

Voor breadboard setup

tot 992

IRF520 MOS Driver Module 0-24V 5A

Aantal afhankelijk van het aantal trappen

1

Voeding voor LED/lampen voor de stappen

Maximaal 24 volt

1

10 KOhm Rematch

 

1

Ldr

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:

Uitvoer op de seriële monitor

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

 

 

Für arduinoProjekte für fortgeschritteneSensoren

1 Kommentar

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

Einen Kommentar hinterlassen

Alle Kommentare werden vor der Veröffentlichung moderiert

Aanbevolen blog berichten

  1. Installeer ESP32 nu van de raad van bestuur
  2. Lüftersteuerung Raspberry Pi
  3. Arduino IDE - Programmieren für Einsteiger - Teil 1
  4. ESP32 - das Multitalent
  5. OTA - Over the Air - ESP Programmeren via Wi-Fi