Eine elegante automatische Treppenbeleuchtung (Teil5) - AZ-Delivery

Bonjour et bienvenue dans le dernier de la partie de la série "éclairage d’escalier automatique élégant".

 

Aujourd’hui, nous complétons notre système de contrôle avec une option de configuration pratique pour tous les paramètres d’exploitation. Tous les paramètres de fonctionnement peuvent désormais être réglés facilement via l’interface série au repos (toutes les lumières d’escalier inactives) et sont stockées dans l’EEPROM interne de l’UC. Ainsi, tous les paramètres sont maintenus même en cas de redémarrage ou d’une panne de courant. Tous les paramètres réglables sont expliqués individuellement à la fin du document. Étant donné que la fonction est complètement réalisée dans le logiciel, la structure technique ne change pas par rapport à la partie 4 de la série. Néanmoins, pour des raisons d’exhaustivité, cela devrait être présenté à nouveau:

Photo de la partie 4

 

La liste des composantes du projet et tous les conseils des parties précédentes ne changent pas :

 

Nombre

Description

Note

2

Pir Module HC-SR501 PIR

Capteur de mouvement

jusqu’à 62

PCA9685 16 Channel 12 Bit PWM Driver

Nombre selon le nombre d’escaliers /16

1

Nano V3

 

1

Adaptateur d’alimentation MB102

Pour la configuration de la planche à pain

jusqu’à 992

Module de pilote IRF520 MOS 0-24V 5A

Nombre selon le nombre d’escaliers

1

Alimentation électrique pour LED/lampes pour les marches

Maximum 24 volts

1

10 KOhm Rematch

 

1

Ldr

Re-stand photo

 

Il peut être SANS ajustement préalable le code suivant peut être téléchargé sur l’Arduino :

 

 

#include <Fil.H (en)>
#include <Eeprom.H (en)>

#define PWM_Module_Base_Addr 0x40 1000000b Le dernier morceau de l’adresse byte définit l’opération à effectuer. Lorsqu’il est réglé à la logique 1 0x41 module 2 etc. Gamme d’adresses0x40 - 0x47 
sélectionne une opération de lecture tandis qu’un 0 logique sélectionne une opération d’écriture.
#define OE_Pin  8                 Pin pour l’activation de sortie 
#define CPU_LED_Pin 13            Interne Board LED to pin 13 (à des fins de débogage)
#define PIRA_Pin 2
#define PIRB_Pin 3
#define Num_Stages_per_Module 16
#define LDR_Pin A2                Épingle analogique pour mesurer la luminosité. (LDR Re-énergisme)
#define DEBUG
#define L_Sens_Scope 50
#define MaxInputBufferSize 5 maximum 255 caractères pour s’adapter à vlcdr


Struct WiFiEEPromData
{   Paramètres d’exploitation réglables (constantes)   Int Delay_ON_to_OFF = 10;          Temps d’attente minimum pour la séquence off en quelques secondes   Int Overall_Stages =  8;         nombre maximum d’étapes : 62 x 16 et 992   Int delay_per_Stage_in_ms = 100;   Int DayLight_Brightness_Border = 600; Brightness Limit Automatic - Valeur supérieure - Luminosité plus élevée   Octet Delay_Stages_ON = 20;   Octet Delay_Stages_OFF = 20;   Char Char ConfigValid[3]; Si Config est Vaild, tag "TK" est nécessaire"
};


Variables globales
Int Pwm_Channel = 0;
Int Pwm_Channel_Brightness = 0;
Bool Motion_Trigger_Down_to_Up = Faux;
Bool Motion_Trigger_Up_to_Down = Faux;
Bool On_Delay = Faux;
Bool DayLight_Status = Vrai;
Bool DLightCntrl = Vrai;
Octet PwMModules = 0;
Octet StagesLeft (en) = 0;
interrompre le contrôle
Volatile Octet A60telSecondes24 = 0;
Volatile Octet Seconds24;
Manipulation d’intrants en série
Char Char TBuffer (TBuffer);
Char Char Cbuffer (Cbuffer)[MaxInputBufferSize + 1];     Tampon d’entrée de code USB
String Sbuffer (Sbuffer) = "";                      Tampon d’entrée de chaîne USB
Int Valeur;                                Tampon d’entrée NUmmeric USB
Octet Ccount (Ccount) { 0 };                          Nombre reçu Chars
Octet Inptype (Inptype) = 0;
Boolean StrInput (En) = Faux;
Boolean Nombre d’autres = Faux;
Boolean DataInput (en) = Faux;
Boolean EntrezInput = Faux;
Octet MenueSelection = 0;
Octet MnuState (en) = 0;            Profondeur maximale du menu 255 icl Sub
WiFiEEPromData MyConfig (en);


Isr (Isr)(TIMER1_COMPA_vect)
{   A60telSecondes24++;   Si (A60telSecondes24 > 59)   {     A60telSecondes24 = 0;     Seconds24++;     Si (Seconds24 > 150)     {       Seconds24 = 0;     }   }
}

Vide ISR_PIR_A()
{   Bool PinState (En) = digitalRead (en)(PIRA_Pin);   Si (PinState (En))   {     Si (!(Motion_Trigger_Up_to_Down) Et !(Motion_Trigger_Down_to_Up))     {       digitalWrite (en)(CPU_LED_Pin, Haute);       Motion_Trigger_Down_to_Up = Vrai;     } PIR A déclenché   } Autre   {     digitalWrite (en)(CPU_LED_Pin, Faible);   }
}

Vide ISR_PIR_B()
{   Bool PinState (En) = digitalRead (en)(PIRB_Pin);   Si (PinState (En))   {     Si (!(Motion_Trigger_Down_to_Up) Et !(Motion_Trigger_Up_to_Down))     {       digitalWrite (en)(CPU_LED_Pin, Haute);       Motion_Trigger_Up_to_Down = Vrai;     } PIR B déclenché   } Autre   {     digitalWrite (en)(CPU_LED_Pin, Faible);   }
}

Vide Init_PWM_Module(Octet PWM_ModuleAddr)
{   digitalWrite (en)(OE_Pin, Haute); Épingle d’activation de sortie LOW active (OE).   Fil.commenceTransmission(PWM_ModuleAddr); Initier le transfert de données   Fil.Écrire(0x00);                       //   Fil.Écrire(0x06);                       Réinitialisation logicielle   Fil.endTransmission();                 Stop Communication - Envoyer Stop Bit   Retard(400);   Fil.commenceTransmission(PWM_ModuleAddr); Initier le transfert de données   Fil.Écrire(0x01 (en));                       Sélectionnez Mode 2 Registre (Registre de commande)   Fil.Écrire(0x04);                       Configurer Chip: 0x04: sortie de poteau mort 0x00: Sortie de vidange ouverte.   Fil.endTransmission();                 Stop Communication - Envoyer Stop Bit   Fil.commenceTransmission(PWM_ModuleAddr); Initier le transfert de données   Fil.Écrire(0x00);                      Sélectionnez Mode 1 Registre (Registre de commande)   Fil.Écrire(0x10);                      Configurer SleepMode   Fil.endTransmission();                Stop Communication - Envoyer Stop Bit   Fil.commenceTransmission(PWM_ModuleAddr); Initier le transfert de données   Fil.Écrire(0xFE (en));                       Sélectionnez PRE_SCALE inscrivez-vous   Fil.Écrire(0x03);                       Réglez Prescaler. La fréquence maximale pwM est de 1526 Hz si le PRE_SCALEer l’opérateur est réglé à "0x03h". Standard: 200 Hz   Fil.endTransmission();                 Stop Communication - Envoyer Stop Bit   Fil.commenceTransmission(PWM_ModuleAddr); Initier le transfert de données   Fil.Écrire(0x00);                       Sélectionnez Mode 1 Registre (Registre de commande)   Fil.Écrire(0xA1 (en));                       Configurer Chip: ERrlaube All Call I2C adresses, utiliser l’horloge interne, / Autoriser la fonction d’incrément automatique   Fil.endTransmission();                 Stop Communication - Envoyer Stop Bit
}


Vide Init_PWM_Outputs(Octet PWM_ModuleAddr)
{   digitalWrite (en)(OE_Pin, Haute); Épingle d’activation de sortie LOW active (OE).   Pour ( Int Z = 0; Z < 16 + 1; Z++)   {     Fil.commenceTransmission(PWM_ModuleAddr);     Fil.Écrire(Z * 4 + 6);      Sélectionnez PWM_Channel_ON_L inscrivez-vous     Fil.Écrire(0x00);                     Valeur pour le registre ci-dessus     Fil.endTransmission();     Fil.commenceTransmission(PWM_ModuleAddr);     Fil.Écrire(Z * 4 + 7);      Sélectionnez PWM_Channel_ON_H inscrivez-vous     Fil.Écrire(0x00);                     Valeur pour le registre ci-dessus     Fil.endTransmission();     Fil.commenceTransmission(PWM_ModuleAddr);     Fil.Écrire(Z * 4 + 8);   Sélectionnez PWM_Channel_OFF_L inscrivez-vous     Fil.Écrire(0x00);        Valeur pour le registre ci-dessus     Fil.endTransmission();     Fil.commenceTransmission(PWM_ModuleAddr);     Fil.Écrire(Z * 4 + 9);  Sélectionnez PWM_Channel_OFF_H inscrivez-vous     Fil.Écrire(0x00);             Valeur pour le registre ci-dessus     Fil.endTransmission();   }   digitalWrite (en)(OE_Pin, Faible); Épingle d’activation de sortie LOW active (OE).
}

Vide Configuration()
{   Initalisation   Série.Commencer(9600);   pinMode(PIRA_Pin, Entrée);   pinMode(PIRB_Pin, Entrée);   pinMode(OE_Pin, Sortie);   pinMode(CPU_LED_Pin, Sortie);   pinMode(LDR_Pin, Entrée);   PwMModules = MyConfig (en).Overall_Stages / 16;   StagesLeft (en) = ( MyConfig (en).Overall_Stages % 16) - 1;   Si (StagesLeft (en) >= 1) {     PwMModules++;   }   Fil.Commencer(); Initalisia I2C Bus A4 (SDA), A5 (SCL)   Pour (Octet ModuleCompte = 0; ModuleCompte < PwMModules; ModuleCompte++)   {     Init_PWM_Module(PWM_Module_Base_Addr + ModuleCompte);     Init_PWM_Outputs(PWM_Module_Base_Addr + ModuleCompte);   }   Si (!(loadEEPROM_Config())) Chargement des infiltrations de l’EEPROM   {     Série.println(Q(" Paramètres standard EEPROM enregistrés."));     MyConfig (en).Delay_ON_to_OFF = 10;          Minimum Wartezeit bis zur "Aus Sequenz" à Sekunden     MyConfig (en).Overall_Stages =  8;         maximum Stufenanzahl: 62 x 16 - 992     MyConfig (en).delay_per_Stage_in_ms = 100;     MyConfig (en).DayLight_Brightness_Border = 600; Helligkeitsgrenze Automatik - Hôherer Wert - Helligkeit     MyConfig (en).Delay_Stages_ON = 20;     saveEEPROM_Config();   }   noInterrupts();   attacherInterrupt(0, ISR_PIR_A, changement);   attacherInterrupt(1, ISR_PIR_B, changement);   TCCR1A (EN) = 0x00;   TCCR1B (EN) = 0x02;   TCNT1 (en) = 0;      Enregistrer mit 0 initialisieren   OCR1A =  33353;      Sortie Comparer le vorbelegen de registre   TIMSK1 (en) |= (1 << OCIE1A);  Timer Comparer Interrupt aktivieren   Interrompt();   Série.println(F("Init_Complete"));
}

Sauver Config à l’EEPROM /

Bool loadEEPROM_Config()
{   Bool RetValue;   Eeprom.Avoir(0, MyConfig (en));   Eeprom.Fin();   Si (String(MyConfig (en).ConfigValid) = String("TK"))   {     RetValue = Vrai;   } Autre   {     RetValue = Faux; Paramètres non trouvés.   }   Retour RetValue;
}

Magasinez Config à eEPROM /
Bool saveEEPROM_Config()
{   strncpy( MyConfig (en).ConfigValid , "TK", Sizeof(MyConfig (en).ConfigValid) );   Eeprom.Mettre(0, MyConfig (en));   Eeprom.Fin();   Retour Vrai;
}

Bool DayLightStatus ()
{   Int SensorValue = 0;   Bool Returnvalue = Vrai;   SensorValue = analogRead (en)(LDR_Pin);
#ifdef Debug   Série.Imprimer(F("DayLightStatus: "));   Série.Imprimer(SensorValue);
#endif   Si (SensorValue > MyConfig (en).DayLight_Brightness_Border)   {     Si ((DayLight_Status) Et (SensorValue > MyConfig (en).DayLight_Brightness_Border + L_Sens_Scope))     {       Returnvalue = Faux;       DayLight_Status = Faux;     } Autre Si (!(DayLight_Status))     {       Returnvalue = Faux;       DayLight_Status = Faux;     }
#ifdef Debug     Série.println(F("OFF"));
#endif   } Autre   {     Si ((DayLight_Status) Et (SensorValue > MyConfig (en).DayLight_Brightness_Border - L_Sens_Scope))     {       Returnvalue = Vrai;       DayLight_Status = Vrai;     } Autre Si (!(DayLight_Status))     {       Returnvalue = Vrai;       DayLight_Status = Vrai;     }
#ifdef Debug     Série.println(F("SUR"));
#endif   }   Retour Returnvalue;
}

Vide Down_to_Up_ON()
{
#ifdef Debug   Série.println(F("Down_to_Up_ON"));
#endif   Octet Calc_Num_Stages_per_Module = Num_Stages_per_Module;   Pour (Octet ModuleCompte = 0; ModuleCompte < PwMModules; ModuleCompte++)   {     Pwm_Channel = 0;     Pwm_Channel_Brightness = 4095;     Si ((StagesLeft (en) >= 1) Et (ModuleCompte == PwMModules - 1))     {       Calc_Num_Stages_per_Module = StagesLeft (en);     }     Autre     {       Calc_Num_Stages_per_Module = Num_Stages_per_Module;     }     Pwm_Channel = 0;     Pwm_Channel_Brightness = 0;     Tandis que (Pwm_Channel < Calc_Num_Stages_per_Module + 1)     {       Fil.commenceTransmission( PWM_Module_Base_Addr + ModuleCompte);       Fil.Écrire(Pwm_Channel * 4 + 8);   Registre PWM_Channel_0_OFF_L de Wôhle       Fil.Écrire((Octet)Pwm_Channel_Brightness & 0xff);        Wert f’r o.g. Registre       Fil.endTransmission();       Fil.commenceTransmission( PWM_Module_Base_Addr + ModuleCompte);       Fil.Écrire(Pwm_Channel * 4 + 9);  Registre PWM_Channel_0_OFF_H de Wôhle       Fil.Écrire((Pwm_Channel_Brightness >> 8));             Wert f’r o.g. Registre       Fil.endTransmission();       Si (Pwm_Channel_Brightness < 4095)       {         Pwm_Channel_Brightness = Pwm_Channel_Brightness + MyConfig (en).Delay_Stages_ON;         Si (Pwm_Channel_Brightness > 4095) {           Pwm_Channel_Brightness = 4095;         }       } Autre Si ( Pwm_Channel < Num_Stages_per_Module + 1)       {         Pwm_Channel_Brightness = 0;         Retard(MyConfig (en).delay_per_Stage_in_ms);         Pwm_Channel++;       }     }   }
}

Vide Up_to_DOWN_ON()
{
#ifdef Debug   Série.println(F("Up_to_DOWN_ON"));
#endif   Octet Calc_Num_Stages_per_Module = Num_Stages_per_Module;   Int ModuleCompte = PwMModules - 1;   Tandis que (ModuleCompte >= 0)   {     Pwm_Channel_Brightness = 0;     Si ((StagesLeft (en) >= 1) Et (ModuleCompte == PwMModules - 1))     {       Calc_Num_Stages_per_Module =  StagesLeft (en);     }     Autre     {       Calc_Num_Stages_per_Module = Num_Stages_per_Module;     }     Pwm_Channel = Calc_Num_Stages_per_Module;     Tandis que (Pwm_Channel > -1)     {       Fil.commenceTransmission( PWM_Module_Base_Addr + ModuleCompte);       Câble.écrire(Pwm_Channel * 4 + 8);   // Wähle PWM_Channel_0_OFF_L registre       Câble.écrire((octet)Pwm_Channel_Brightness & 0xFF);        // Wert für o.g. S'inscrire       Câble.endTransmission();       Câble.beginTransmission(PWM_Module_Base_Addr + ModuleCount);       Câble.écrire(Pwm_Channel * 4 + 9);  // Wähle PWM_Channel_0_OFF_H registre       Câble.écrire((Pwm_Channel_Brightness >> 8));             // Wert für o.g. S'inscrire       Câble.endTransmission();       si (Pwm_Channel_Brightness < 4095)       {         Pwm_Channel_Brightness = Pwm_Channel_Brightness + MyConfig.Delay_Stages_ON;         si (Pwm_Channel_Brightness > 4095) {           Pwm_Channel_Brightness = 4095;         }       } autre si ( Pwm_Channel >= 0)       {         Pwm_Channel_Brightness = 0;         retard(MyConfig.delay_per_Stage_in_ms);         Pwm_Channel--;         si ( Pwm_Channel < 0)         {           Pwm_Channel = 0;           Pause;         }       }     }     ModuleCount = ModuleCount - 1;   }
}

néant Down_to_Up_OFF()
{
#ifdef DÉBOGUER   En série.println(F("Down_to_Up_OFF"));
#fin si   octet Calc_Num_Stages_per_Module = Num_Stages_per_Module;   pour (octet ModuleCount = 0; ModuleCount < PWMModules; ModuleCount++)   {     Pwm_Channel = 0;     Pwm_Channel_Brightness = 4095;     si ((StagesLeft >= 1) et (ModuleCount == PWMModules - 1))     {       Calc_Num_Stages_per_Module = StagesLeft;     }     autre     {       Calc_Num_Stages_per_Module = Num_Stages_per_Module;     }     tandis que (Pwm_Channel < Calc_Num_Stages_per_Module + 1)     {       Câble.beginTransmission( PWM_Module_Base_Addr + ModuleCount);       Câble.écrire(Pwm_Channel * 4 + 8);   // Wähle PWM_Channel_0_OFF_L registre       Câble.écrire((octet)Pwm_Channel_Brightness & 0xFF);        // Wert für o.g. S'inscrire       Câble.endTransmission();       Câble.beginTransmission(PWM_Module_Base_Addr + ModuleCount);       Câble.écrire(Pwm_Channel * 4 + 9);  // Wähle PWM_Channel_0_OFF_H registre       Câble.écrire((Pwm_Channel_Brightness >> 8));             // Wert für o.g. S'inscrire       Câble.endTransmission();       si (Pwm_Channel_Brightness > 0)       {         Pwm_Channel_Brightness = Pwm_Channel_Brightness - MyConfig.Delay_Stages_OFF;         si (Pwm_Channel_Brightness < 0) {           Pwm_Channel_Brightness = 0;         }       } autre si ( Pwm_Channel < Num_Stages_per_Module + 1)       {         Pwm_Channel_Brightness = 4095;         retard(MyConfig.delay_per_Stage_in_ms);         Pwm_Channel++;       }     }   }
}

néant Up_to_DOWN_OFF()
{
#ifdef DÉBOGUER   En série.println(F("Up_to_DOWN_OFF"));
#fin si   octet Calc_Num_Stages_per_Module = Num_Stages_per_Module;   int ModuleCount = PWMModules - 1;   tandis que (ModuleCount >= 0)   {     Pwm_Channel_Brightness = 4095;     si ((StagesLeft >= 1) et (ModuleCount == PWMModules - 1))     {       Calc_Num_Stages_per_Module = StagesLeft;     }     autre     {       Calc_Num_Stages_per_Module = Num_Stages_per_Module;     }     Pwm_Channel = Calc_Num_Stages_per_Module;     tandis que (Pwm_Channel > -1)     {       Câble.beginTransmission(PWM_Module_Base_Addr + ModuleCount);       Câble.écrire(Pwm_Channel * 4 + 8);   // Wähle PWM_Channel_0_OFF_L registre       Câble.écrire((octet)Pwm_Channel_Brightness & 0xFF);        // Wert für o.g. S'inscrire       Câble.endTransmission();       Câble.beginTransmission(PWM_Module_Base_Addr + ModuleCount);       Câble.écrire(Pwm_Channel * 4 + 9);  // Wähle PWM_Channel_0_OFF_H registre       Câble.écrire((Pwm_Channel_Brightness >> 8));             // Wert für o.g. S'inscrire       Câble.endTransmission();       si (Pwm_Channel_Brightness > 0)       {         Pwm_Channel_Brightness = Pwm_Channel_Brightness - MyConfig.Delay_Stages_OFF;         si (Pwm_Channel_Brightness < 0) {           Pwm_Channel_Brightness = 0;         }       } autre si ( Pwm_Channel >= 0)       {         Pwm_Channel_Brightness =  4095;         retard(MyConfig.delay_per_Stage_in_ms);         Pwm_Channel--;         si ( Pwm_Channel < 0)         {           Pwm_Channel = 0;           Pause;         }       }     }     ModuleCount = ModuleCount - 1;   }
}

néant Stages_Light_Control ()
{   si ((Motion_Trigger_Down_to_Up) et !(On_Delay))   {     DLightCntrl = DayLightStatus();     si (DLightCntrl)     {       Secondes24 = 0;       On_Delay = vrai;       Down_to_Up_ON();     } autre {       Motion_Trigger_Down_to_Up = faux;     }   }   si ((On_Delay) et (Secondes24 > MyConfig.Delay_ON_to_OFF) et (Motion_Trigger_Down_to_Up) )   {     Down_to_Up_OFF();     Motion_Trigger_Down_to_Up = faux;     On_Delay = faux;     Secondes24 = 0;   }   si ((Motion_Trigger_Up_to_Down) et !(On_Delay))   {     DLightCntrl = DayLightStatus();     si (DLightCntrl)     {       Secondes24 = 0;       On_Delay = Vrai;       Up_to_DOWN_ON();     } Autre {       Motion_Trigger_Up_to_Down = Faux;     }   }   Si ((On_Delay) Et (Seconds24 > MyConfig (en).Delay_ON_to_OFF) Et (Motion_Trigger_Up_to_Down))   {     Up_to_DOWN_OFF();     Motion_Trigger_Up_to_Down = Faux;     On_Delay = Faux;     Seconds24 = 0;   }
}

Fonctions d’interprète de commandement en série -------------------------------

Vide ClearCBuffer (en) ()
{   Pour (Octet Un = 0; MaxInputBufferSize - 1; Un++)     Cbuffer (Cbuffer)[Un] = 0;
}

Boolean CheckforserialEvent()
{   Tandis que (Série.Disponible()) {     obtenir le nouveau byte:     TBuffer (TBuffer) = Série.Lire();     Si (TBuffer (TBuffer) > 9 && TBuffer (TBuffer) < 14)     {       Cbuffer (Cbuffer)[Ccount (Ccount)] = 0;       TBuffer (TBuffer) = 0;       Série.Imprimer(char(13));       Série.Rincer();       Série.println("");       Sbuffer (Sbuffer) = "";       Valeur = 0;       EntrezInput = Vrai;       Retour Vrai;     } Autre Si (TBuffer (TBuffer) > 47 && TBuffer (TBuffer) < 58 )     {       Si ( Ccount (Ccount) < MaxInputBufferSize)       {         Cbuffer (Cbuffer)[Ccount (Ccount)] = TBuffer (TBuffer);         Ccount (Ccount)++;       } Autre {         Série.Imprimer("#");       }       Entrée de nombre détectée       Nombre d’autres = Vrai;     }     Autre Si (TBuffer (TBuffer) > 64 && TBuffer (TBuffer) < 123 )     {       Si ( Ccount (Ccount) < MaxInputBufferSize)       {         Cbuffer (Cbuffer)[Ccount (Ccount)] = TBuffer (TBuffer);         Ccount (Ccount)++;         Série.Imprimer(char(TBuffer (TBuffer)));         Série.Rincer();       }       Entrée de char de caractère détectée       StrInput (En) = Vrai;     }     Autre Si ( (TBuffer (TBuffer) == 127 )  |  (TBuffer (TBuffer) == 8 ) )     {       Si ( Ccount (Ccount) > 0)       {         Ccount (Ccount)--;         Cbuffer (Cbuffer)[Ccount (Ccount)] = 0;         Série.Imprimer("-");         Série.Rincer();       }     }     Autre     {       Si ( Ccount (Ccount) < MaxInputBufferSize)       {         Cbuffer (Cbuffer)[Ccount (Ccount)] = TBuffer (TBuffer);         Ccount (Ccount)++;         Série.Imprimer(char(TBuffer (TBuffer)));         Série.Rincer();         Entrée de données détectée         DataInput (en) = Vrai;       }       Retour Faux;     }     Retour Faux;   }
}

Octet SerInputHandler()
{   Octet Résultat = 0;   Int C;   Int D;   Int Un;   Int B;   Résultat = 0;   Si (CheckforserialEvent())   {     Si ((Nombre d’autres) Et Pas (DataInput (en)) Et Pas (StrInput (En)))    Nombres seulement     {       Sbuffer (Sbuffer) = "";       Valeur = 0;       StrInput (En) = Faux;       Nombre d’autres = Faux;       DataInput (en) = Faux;       EntrezInput = Faux;       Un = 0;       B = 0;       C = 0;       D = 0;       Sbuffer (Sbuffer) = Cbuffer (Cbuffer); Zahl wird AUCH ! sBUFFER 'bernommen, falls ben’tigt.       Si (Ccount (Ccount) == 1) {         Valeur  = Cbuffer (Cbuffer)[0] - 48 ;       }       Si (Ccount (Ccount) == 2) {         Un = Cbuffer (Cbuffer)[0] - 48 ;         Un = Un * 10;         B = Cbuffer (Cbuffer)[1] - 48 ;         Valeur = Un + B;       }       Si (Ccount (Ccount) == 3) {         Un = Cbuffer (Cbuffer)[0] - 48 ;         Un = Un * 100;         B = Cbuffer (Cbuffer)[1] - 48 ;         B = B * 10;         C = Cbuffer (Cbuffer)[2] - 48 ;         Valeur = Un + B + C;       }       Si (Ccount (Ccount) == 4) {         Un = Cbuffer (Cbuffer)[0] - 48 ;         Un = Un * 1000;         B = Cbuffer (Cbuffer)[1] - 48 ;         B = B * 100;         C = Cbuffer (Cbuffer)[2] - 48 ;         C = C * 10;         D = Cbuffer (Cbuffer)[3] - 48 ;         Valeur = Un + B + C + D;       }       Si (Ccount (Ccount) >= 5)       {         Sbuffer (Sbuffer) = "";         Valeur = 0;         Sbuffer (Sbuffer) = Cbuffer (Cbuffer);         ClearCBuffer (en);         Résultat = 2;       } Autre       {         ClearCBuffer (en);         Ccount (Ccount) = 0;         Résultat = 1;                                                Code de retour de numéro         Nombre d’autres = Faux;         StrInput (En) = Faux;         DataInput (en) = Faux;         EntrezInput = Faux;         Ccount (Ccount) = 0;         Retour Résultat;       }     }     Si ((StrInput (En)) Et Pas (DataInput (en)))                          Entrée de chaîne seulement     {       Sbuffer (Sbuffer) = "";       Sbuffer (Sbuffer) = Cbuffer (Cbuffer);       Valeur = 0;       StrInput (En) = Faux;       Nombre d’autres = Faux;       DataInput (en) = Faux;       EntrezInput = Faux;       Ccount (Ccount) = 0;       ClearCBuffer (en);       Résultat = 2;                                                 Code de retour de numéro     }     Si (DataInput (en)) {       Sbuffer (Sbuffer) = "";       Sbuffer (Sbuffer) = Cbuffer (Cbuffer);       Valeur = 0;       StrInput (En) = Faux;       Nombre d’autres = Faux;       DataInput (en) = Faux;       EntrezInput = Faux;       Ccount (Ccount) = 0;       ClearCBuffer (en);       Résultat = 3;                                               Code de retour de numéro     }     Si ((EntrezInput) Et Pas (StrInput (En)) Et Pas (Nombre d’autres) Et Pas (DataInput (en)))     {       Sbuffer (Sbuffer) = "";       Valeur = 0;       Ccount (Ccount) = 0;       ClearCBuffer (en);       Résultat = 4;                                               Code de retour de numéro     }     Nombre d’autres = Faux;     StrInput (En) = Faux;     DataInput (en) = Faux;     EntrezInput = Faux;     Ccount (Ccount) = 0;     Retour Résultat;   }   Retour Résultat;   Fin CheckforSerialEvent
}

Vide SerialcommandProcesseur()
{   Int Un;   Inptype (Inptype) = 0;   Inptype (Inptype) = SerInputHandler();   0 keine R’ckgabe   1 Nummer   2 Chaîne   3 Données   Si (Inptype (Inptype) > 0)   {     MenueSelection = 0;     Si ((MnuState (en) < 2) && (Inptype (Inptype) == 2)) {       Sbuffer (Sbuffer).àUpperCase();  Pour faciliter les commandes     }     Si ((Sbuffer (Sbuffer) == "D") && (MnuState (en) == 0) && (Inptype (Inptype) == 2))   {       MenueSelection = 1;     }     Si ((Sbuffer (Sbuffer) == "O") && (MnuState (en) == 0) && (Inptype (Inptype) == 2))       {       MenueSelection = 2;     }     Si ((Sbuffer (Sbuffer) == "T") && (MnuState (en) == 0) && (Inptype (Inptype) == 2))       {       MenueSelection = 3;     }     Si ((Sbuffer (Sbuffer) == "B") && (MnuState (en) == 0) && (Inptype (Inptype) == 2))       {       MenueSelection = 4;     }     Si ((Sbuffer (Sbuffer) == "N") && (MnuState (en) == 0) && (Inptype (Inptype) == 2))   {       MenueSelection = 5;     }     Si ((Sbuffer == "F") && (MnuState == 0) && (Inptype == 2))       {       MenueSelection = 6;     }     si ((MnuState == 2) && (Inptype == 1))                          {       MenueSelection = 8;     }     si ((MnuState == 3) && (Inptype == 1))                          {       MenueSelection = 9;     }     si ((MnuState == 4) && (Inptype == 1))                          {       MenueSelection = 10;     }     si ((MnuState == 5) && (Inptype == 1))                          {       MenueSelection = 11;     }     si ((MnuState == 6) && (Inptype == 1))                          {       MenueSelection = 12;     }     si ((MnuState == 7) && (Inptype == 1))                          {       MenueSelection = 13;     }     si (MnuState == 10)                                              {       MenueSelection = 21; // Réglage de l'heure     }     si (MnuState == 11)                                              {       MenueSelection = 24; // Réglage de l'heure     }     si (MnuState == 12)                                              {       MenueSelection = 25; // Réglage de l'heure     }     si (MnuState == 13)                                              {       MenueSelection = 27; // Ensemble d'arrière-plan     }     si (MnuState == 14)                                              {       MenueSelection = 29; // ClockFace Set     }     commutateur (MenueSelection)     {       Cas 1:         {           En série.println("Délai ON à OFF: (1-65000)");           MnuState = 2;           valeur = 0;           Sbuffer = "";           Pause;         }       Cas 2:         {           En série.println("Étapes globales: (1-992)");           MnuState = 3;           valeur = 0;           Sbuffer = "";           Pause;         }       Cas 3:         {           En série.println("Délai par étape en ms: (1-65000)");           MnuState = 4;           valeur = 0;           Sbuffer = "";           Pause;         }       Cas 4:         {           En série.println("Bordure de luminosité DayLight: (0-65000)");           MnuState = 5;           valeur = 0;           Sbuffer = "";           Pause;         }       Cas 5:         {           En série.println("Delay Stages ON: (1-254)");           MnuState = 6;           valeur = 0;           Sbuffer = "";           Pause;         }       Cas 6:         {           En série.println("Delay Stages OFF: (1-254)");           MnuState = 7;           valeur = 0;           Sbuffer = "";           Pause;         }       Cas 8:         {           MyConfig.Delay_ON_to_OFF = valeur;           saveEEPROM_Config();           En série.impression(F("Delay_ON_to_OFF défini sur:"));           En série.println(MyConfig.Delay_ON_to_OFF);           MnuState = 0;           Sbuffer = "";           valeur = 0;           Pause;         }       Cas 9:         {           MyConfig.Global_Stages = valeur;           saveEEPROM_Config();           En série.impression(F("Etapes globales définies sur:"));           En série.println(MyConfig.Global_Stages);           MnuState = 0;           Sbuffer = "";           valeur = 0;           Pause;         }       Cas 10:         {           MyConfig.delay_per_Stage_in_ms = valeur;           saveEEPROM_Config();           En série.impression(F("Délai par étape en ms défini sur:"));           En série.println(MyConfig.delay_per_Stage_in_ms);           MnuState = 0;           Sbuffer = "";           valeur = 0;           Pause;         }       Cas 11:         {           MyConfig.DayLight_Brightness_Border = valeur;           saveEEPROM_Config();           En série.impression(F("Frontière de luminosité DayLight définie sur:"));           En série.println(MyConfig.DayLight_Brightness_Border);           MnuState = 0;           Sbuffer = "";           valeur = 0;           Pause;         }       Cas 12:         {           MyConfig.Delay_Stages_ON = valeur;           saveEEPROM_Config();           En série.impression(F("Delay Stages ON réglé sur:"));           En série.println(MyConfig.Delay_Stages_ON);           MnuState = 0;           Sbuffer = "";           valeur = 0;           Pause;         }       Cas 13:         {           MyConfig.Delay_Stages_OFF = valeur;           saveEEPROM_Config();           En série.impression(F("Delay Stages OFF réglé sur:"));           En série.println(MyConfig.Delay_Stages_OFF);           MnuState = 0;           Sbuffer = "";           valeur = 0;           Pause;         }       défaut:         {           MnuState = 0;           En série.println(F("-Treppenlichtsteuerung -"));           En série.impression(F("D - Délai ON à OFF / Valeur actuelle:"));           En série.println(MyConfig.Delay_ON_to_OFF);           En série.impression(F("O - Étapes globales / valeur actuelle:"));           En série.println(MyConfig.Global_Stages);           En série.impression(F("T - Délai par étape en ms / valeur actuelle:"));           En série.println(MyConfig.delay_per_Stage_in_ms);           En série.impression(F("B - Frontière de luminosité DayLight / Valeur actuelle:"));           En série.println(MyConfig.DayLight_Brightness_Border );           En série.impression(F("N - Delay Stages ON / Valeur actuelle:"));           En série.println(MyConfig.Delay_Stages_ON);           En série.impression(F("F - Delay Stages OFF / Current Value:"));           En série.println(MyConfig.Delay_Stages_OFF);           En série.println(F("Tapez Cmd et appuyez sur Entrée"));           En série.affleurer();           MnuState = 0;           valeur = 0;           Sbuffer = "";         }     }   } // Eingabe erkannt
}

néant boucle()
{   Stages_Light_Control();   SerialcommandProcessor();
}

 

Nachdem der Code hochgeladen wurde, können wir uns mit 9600 Baud auf die serielle Schnittstelle verbinden. Nach einem Enter (und inaktivem! Treppenlicht) erscheint folgendes Konfigurationsmenü:

 

Partie 5 - Menu Configuration

 

 

Paramenter

Erklärung

Délai ON à OFF

Zeit in SEKUNDEN, die die Treppenbeleuchtung vollständig eingeschaltet bleibt

Étapes globales

Nombre à la marche de l'escalier

Delay par Stage

Le temps dans des MILLISECONDES qui est attendu jusqu'à ce que le prochain escalier soit dirigé.

Daylight Brightness Border

La luminosité dans quoi l'éclairage d'escaliers devient inactif. Wertz plus haut -> luminosité plus haute

Delay Stages ON

rel. Temps de fading à la MISE SOUS COURANT des escaliers. Valeur plus haute - > temps plus petit

Delay Stages OFF

rel. Le temps de fading à ETEIGNENT des escaliers. Valeur plus haute - > temps plus petit

 

Je souhaite beaucoup de plaisir à l'imite. Comme toujours, vous trouvez aussi tous les projets préalables sous GitHub le côté https://github.com/kuchto

Für arduinoProjekte für fortgeschritteneSensoren

11 commentaires

Andreas Wolter

Andreas Wolter

@Jan: ich vermute, dass dafür die Variable Pwm_Channel_Brightness zuständig ist. Der Wert dafür ist hard codiert mit 4095. Man könnte dafür eine Variable einsetzen, um diesen Wert leichter einstellen zu können. Bitte testen Sie das mal aus.

Grüße,
Andreas Wolter
AZ-Delivery Blog

Jan

Jan

Habe das Projekt nachgebaut, funktioniert top!
Das einzige Problem das ich habe ist das meine gewählten LED-Stripes zu hell sind.
Gibt es eine Möglichkeit das ganze zu dimmen?

Im vorraus Danke für die Hilfe

Jan

Andreas Wolter

Andreas Wolter

@MBK: ich bin eben kurz über den Quellcode geflogen. Die Delays sind einstellbare Parameter. Haben Sie versucht, diese zu verändern?

Grüße,
Andreas Wolter
AZ-Delivery Blog

MBK

MBK

Danke für die Anleitung, gibt es die Möglichkeit Unterstützung für das Projekt zu bekommen?
Ich habe das ganze nachgebaut mit 7 beleuchteten Stufen ( zur Probe auf dem Steckbrett, auf dem Tisch), allerdings arbeitetn die Sensoren nicht sauber. Nach Abdunklung des Fotosensors, kommt es nur gelegentlich zur Auslösung der Treppenbeleuchtung, immer in der richtigen Reihenfolge ( von oben nach unten oder umgekehrt) aber danach gibt es eine wartezeit von ca 1,5 Minuten bis das System sich wieder auslösen lässt. Die rote Debug LED leuchtet während dieser Zeit. Ich habe die Sensoren schon getauscht um fehlerhafte Sensoren auszuschließen, das Ergebniss bleibt gleich.

Klaus-Peter Weidner

Klaus-Peter Weidner

Super interessantes Projekt.
Ich hätte nur zwei Anmerkungen / Wünsche.
1.) Im Menü die Anzeige der “aktuellen Daylight Brightness” um den Parameter besser zu bestimmen.
2.) Ein I2C-Shield mit LCD-Display und 5 Tasten, um die Einstellungen ohne PC o.ä. einzustellen.

Eugen

Eugen

Hallo nochmal! Melde mich, wie versprochen zurück. Habe alles soweit nachgebaut, und es funktioniert alles, bis auf zwei Sachen. Im seriellen Monitor lassen sich die Parameter zwar verändern, leider haben die Änderungen keinerlei Auswirkungen auf den Ablauf des Sketches.
Man kann ändern, was man will, aber das Programm läuft immer nur das eine Szenario ab. Selbst wenn man im Sketch die Variablen verändert, bleibt alles so, wie an Anfang. Mit einer Ausnahme, und zwar die Stufenanzahl lässt sich ändern. Ich weiß nicht, wo der Fehler sich versteckt, vielleicht habe ich etwas falsch gemacht.
Aber: wenn ich den Sketch aus dem Teil 4 hochlade, läuft alles prima und alle Parameter lassen sich wunderbar ändern. Schade, dass es mit dem Seriellen Monitor nicht klappt, aber das Programm aus dem Teil 4 läuft, habe alle Parameter so eingestellt, wie es mir passt.
Vielen Dank für die tolle Anleitung, meine Eltern sind total begeistert!
Viele Grüße

Eugen

Eugen

Hallo Tobias!
Das ist ein super Projekt! So simpel erklärt, so verständlich aufgebaut, einfach toll! Ich bin schon seit 3 Jahren auf der Suche nach einer Anleitung für so eine Treppenbeleuchtung. Eigentlich wollte ich selbständig versuchen, so ein Projekt zu entwickeln, leider fehlte mir immer die Zeit dafür. Jetzt bin ich überzeugt, dass ich es auf jeden Fall nachbauen werde. Die Bauteile sind schon bestellt, ich kann es kaum abwarten, loszulegen! Ich melde mich auf jeden Fall wieder, wenn ich es geschafft habe. Möchte mich aber jetzt schon herzlich bedanken!

Sebastian

Sebastian

Super interessantes Projekt. Ich hoffe dass das Thema W-lan und MQTT noch aufgegriffen wird und genau so genial erklärt wird, wie die anderen Projekte.

Helmut Tack

Helmut Tack

Bei dem Uno (Auslieferung vor 2018) gibt es Problem mit dem Hochladen.
Lösung hier https://forum.digikey.com/t/january-2018-arduino-nano-bootloader-update/1194

Wolfgang

Wolfgang

Super Projekt !!

Das ganze jetzt noch mit Wlan,
dann wäre es perfekt !!!!

LG
Wolfgang

stsc

stsc

Ein NodeMCU mit Steuerung per MQTT wäre auch interessant. Dann könnte man die Treppe in das Homesteuerungssystem einbinden.

Laisser un commentaire

Tous les commentaires sont modérés avant d'être publiés

Articles de blog recommandés

  1. ESP32 jetzt über den Boardverwalter installieren - AZ-Delivery
  2. Internet-Radio mit dem ESP32 - UPDATE - AZ-Delivery
  3. Arduino IDE - Programmieren für Einsteiger - Teil 1 - AZ-Delivery
  4. ESP32 - das Multitalent - AZ-Delivery