Elegancia de las escaleras automáticas.

Hola y bienvenidos a la última parte de la serie "iluminación automática de escalera elegante".

 

Hoy en día, completamos nuestro sistema de control con una opción de configuración conveniente para todos los parámetros de funcionamiento. Todos los parámetros de funcionamiento ahora se pueden configurar convenientemente a través de la interfaz serie en reposo (todas las luces de escalera inactivas) y se almacenan en el EEPROM interno de los uC. Por lo tanto, todos los ajustes se mantienen incluso en caso de un reinicio o un fallo de alimentación. Todos los parámetros ajustables se explican individualmente al final del documento. Dado que la función se realiza completamente en software, la estructura técnica no cambia en comparación con la parte 4 de la serie. Sin embargo, en aras de la exhaustividad, esto debe ser presentado de nuevo:

Imagen de la Parte 4

 

La lista de componentes para el proyecto y todos los consejos de las partes anteriores no cambiar:

 

Número

Descripción

Nota

2

Pir Módulo HC-SR501 PIR

Sensor de movimiento

hasta 62

PCA9685 16 Canal 12 Bit PWM Driver

Número dependiendo del número de escaleras /16

1

Nano V3

 

1

Mb102 Adaptador de fuente de alimentación

Para la configuración de la placa de pan

hasta 992

Módulo de controlador IRF520 MOS 0-24V 5A

Número dependiendo del número de escaleras

1

Fuente de alimentación para LED/lámparas para los pasos

Máximo 24 voltios

1

10 KOhm Revancha

 

1

Ldr

Re-stand fotográfico

 

Puede ser SIN ajuste previo el siguiente código se puede cargar en el Arduino:

 

 

#include <Alambre.H>
#include <Eeprom.H>

#define PWM_Module_Base_Addr 0x40 10000000b El último bit del byte de dirección define la operación que se va a realizar. Cuando se establece en lógico 1 0x41 módulo 2 etc. Rango de direcciones0x40 - 0x47 
selecciona una operación de lectura mientras que un 0 lógico selecciona una operación de escritura.
#define OE_Pin  8                 Pin para el activador de salida 
#define CPU_LED_Pin 13            LED de placa interna al pin 13 (para fines de depuración)
#define PIRA_Pin 2
#define PIRB_Pin 3
#define Num_Stages_per_Module 16
#define LDR_Pin A2                Pin analógico para medir el brillo. (Reenergización LDR)
#DEFINE DEBUG
#define L_Sens_Scope 50
#define MaxInputBufferSize 5 máximo 255 caracteres para adaptarse a vlcdr


Estructura WiFieePromData
{   Parámetros de funcionamiento ajustables (constantes)   Int Delay_ON_to_OFF = 10;          Tiempo de espera mínimo a la "Secuencia desactivada" en segundos   Int Overall_Stages =  8;         número máximo de pasos: 62 x 16 x 992   Int delay_per_Stage_in_ms = 100;   Int DayLight_Brightness_Border = 600; Límite de brillo automático - Valor más alto - Brillo más alto   Byte Delay_Stages_ON = 20;   Byte Delay_Stages_OFF = 20;   Char ConfigValid[3]; Si Config es Vaild, se requiere la etiqueta "TK""
};


Variables globales
Int Pwm_Channel = 0;
Int 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 = Verdad;
Bool DLightCntrl = Verdad;
Byte PWMModules = 0;
Byte StagesLeft = 0;
interrumpir el control
Volátil Byte A60telSeconds24 = 0;
Volátil Byte Seconds24;
Manejo de entradas serie
Char TBuffer;
Char Cbuffer[MaxInputBufferSize + 1];     Búfer de entrada de código USB
Cadena Sbuffer = "";                      Búfer de entrada de cadena USB
Int Valor;                                Búfer de entrada Nummeric USB
Byte Ccount { 0 };                          Número recibido Chars
Byte Inptype = 0;
Booleana StrInput = Falso;
Booleana NumberInput = Falso;
Booleana DataInput = Falso;
Booleana EnterInput = Falso;
Byte MenueSelection = 0;
Byte MnuState = 0;            Profundidad máxima del menú 255 icl Sub
WiFieePromData MyConfig;


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

Vacío ISR_PIR_A()
{   Bool PinState = digitalRead(PIRA_Pin);   Si (PinState)   {     Si (!(Motion_Trigger_Up_to_Down) Y !(Motion_Trigger_Down_to_Up))     {       digitalWrite(CPU_LED_Pin, Alto);       Motion_Trigger_Down_to_Up = Verdad;     } PIR A activado   } Más   {     digitalWrite(CPU_LED_Pin, Bajo);   }
}

Vacío ISR_PIR_B()
{   Bool PinState = digitalRead(PIRB_Pin);   Si (PinState)   {     Si (!(Motion_Trigger_Down_to_Up) Y !(Motion_Trigger_Up_to_Down))     {       digitalWrite(CPU_LED_Pin, Alto);       Motion_Trigger_Up_to_Down = Verdad;     } PIR B activado   } Más   {     digitalWrite(CPU_LED_Pin, Bajo);   }
}

Vacío Init_PWM_Module(Byte PWM_ModuleAddr)
{   digitalWrite(OE_Pin, Alto); Pin de activación de salida BAJO activo (OE).   Alambre.beginTransmisión(PWM_ModuleAddr); Iniciar la transferencia de datos   Alambre.Escribir(0x00);                       //   Alambre.Escribir(0x06);                       Restablecimiento de software   Alambre.endTransmission();                 Detener comunicación - Enviar bit de parada   Retraso(400);   Alambre.beginTransmisión(PWM_ModuleAddr); Iniciar la transferencia de datos   Alambre.Escribir(0x01);                       Seleccionar el registro del modo 2 (registro de comandos)   Alambre.Escribir(0x04);                       Configurar chip: 0x04: salida de polo muerto 0x00: Salida de drenaje abierta.   Alambre.endTransmission();                 Detener comunicación - Enviar bit de parada   Alambre.beginTransmisión(PWM_ModuleAddr); Iniciar la transferencia de datos   Alambre.Escribir(0x00);                      Seleccionar el registro del modo 1 (registro de comandos)   Alambre.Escribir(0x10);                      Configurar SleepMode   Alambre.endTransmission();                Detener comunicación - Enviar bit de parada   Alambre.beginTransmisión(PWM_ModuleAddr); Iniciar la transferencia de datos   Alambre.Escribir(0xFE);                       Seleccione PRE_SCALE registrarse   Alambre.Escribir(0x03);                       Establezca Prescaler. La frecuencia máxima de PWM es de 1526 Hz si el PRE_SCALEer el operador se establece en "0x03h". Estándar: 200 Hz   Alambre.endTransmission();                 Detener comunicación - Enviar bit de parada   Alambre.beginTransmisión(PWM_ModuleAddr); Iniciar la transferencia de datos   Alambre.Escribir(0x00);                       Seleccionar el registro del modo 1 (registro de comandos)   Alambre.Escribir(0xA1);                       Configurar chip: ERrlaube Todas las direcciones I2C de la llamada, utilice el reloj interno, / permita la característica del incremento automático   Alambre.endTransmission();                 Detener comunicación - Enviar bit de parada
}


Vacío Init_PWM_Outputs(Byte PWM_ModuleAddr)
{   digitalWrite(OE_Pin, Alto); Pin de activación de salida BAJO activo (OE).   Para ( Int Z = 0; Z < 16 + 1; Z++)   {     Alambre.beginTransmisión(PWM_ModuleAddr);     Alambre.Escribir(Z * 4 + 6);      Seleccione PWM_Channel_ON_L registrarse     Alambre.Escribir(0x00);                     Valor para el registro anterior     Alambre.endTransmission();     Alambre.beginTransmisión(PWM_ModuleAddr);     Alambre.Escribir(Z * 4 + 7);      Seleccione PWM_Channel_ON_H registrarse     Alambre.Escribir(0x00);                     Valor para el registro anterior     Alambre.endTransmission();     Alambre.beginTransmisión(PWM_ModuleAddr);     Alambre.Escribir(Z * 4 + 8);   Seleccione PWM_Channel_OFF_L registrar     Alambre.Escribir(0x00);        Valor para el registro anterior     Alambre.endTransmission();     Alambre.beginTransmisión(PWM_ModuleAddr);     Alambre.Escribir(Z * 4 + 9);  Seleccione PWM_Channel_OFF_H registrarse     Alambre.Escribir(0x00);             Valor para el registro anterior     Alambre.endTransmission();   }   digitalWrite(OE_Pin, Bajo); Pin de activación de salida BAJO activo (OE).
}

Vacío Configuración()
{   Initalización   Serial.Comenzar(9600);   pinMode(PIRA_Pin, Entrada);   pinMode(PIRB_Pin, Entrada);   pinMode(OE_Pin, Salida);   pinMode(CPU_LED_Pin, Salida);   pinMode(LDR_Pin, Entrada);   PWMModules = MyConfig.Overall_Stages / 16;   StagesLeft = ( MyConfig.Overall_Stages % 16) - 1;   Si (StagesLeft >= 1) {     PWMModules++;   }   Alambre.Comenzar(); Initalisia I2C Bus A4 (SDA), A5 (SCL)   Para (Byte ModuleCount = 0; ModuleCount < PWMModules; ModuleCount++)   {     Init_PWM_Module(PWM_Module_Base_Addr + ModuleCount);     Init_PWM_Outputs(PWM_Module_Base_Addr + ModuleCount);   }   Si (!(loadEEPROM_Config())) Cargar filtraciones de EEPROM   {     Serial.println(Q("Configuración estándar de EEPROM guardada."));     MyConfig.Delay_ON_to_OFF = 10;          Mínimo Wartezeit bis zur "Aus Sequenz" en Sekunden     MyConfig.Overall_Stages =  8;         maximale Stufenanzahl: 62 x 16 x 992     MyConfig.delay_per_Stage_in_ms = 100;     MyConfig.DayLight_Brightness_Border = 600; Helligkeitsgrenze Automatik - Heherer Wert - Hehere Helligkeit     MyConfig.Delay_Stages_ON = 20;     saveEEPROM_Config();   }   noInterrupts();   adjuntarInterrupt(0, ISR_PIR_A, cambio);   adjuntarInterrupt(1, ISR_PIR_B, cambio);   TCCR1A = 0x00;   TCCR1B = 0x02;   TCNT1 = 0;      Registrar mit 0 initialisieren   OCR1A =  33353;      Salida Comparar Registro vorbelegen   TIMSK1 |= (1 << OCIE1A);  Timer Compare Interrupt aktivieren   Interrumpe();   Serial.println(F("Init_Complete"));
}

/** Guardar configuración en EEPROM */

Bool loadEEPROM_Config()
{   Bool RetValue;   Eeprom.Obtener(0, MyConfig);   Eeprom.Final();   Si (Cadena(MyConfig.ConfigValid) = Cadena("Tk"))   {     RetValue = Verdad;   } Más   {     RetValue = Falso; No se han encontrado los ajustes.   }   devolución RetValue;
}

/** Almacenar configuración a EEPROM */
Bool saveEEPROM_Config()
{   strncpy( MyConfig.ConfigValid , "Tk", Sizeof(MyConfig.ConfigValid) );   Eeprom.Poner(0, MyConfig);   Eeprom.Final();   devolución Verdad;
}

Bool DayLightStatus ()
{   Int SensorValue = 0;   Bool ReturnValue = Verdad;   SensorValue = analogRead(LDR_Pin);
#ifdef Depuración   Serial.Impresión(F("DayLightStatus: "));   Serial.Impresión(SensorValue);
#endif   Si (SensorValue > MyConfig.DayLight_Brightness_Border)   {     Si ((DayLight_Status) Y (SensorValue > MyConfig.DayLight_Brightness_Border + L_Sens_Scope))     {       ReturnValue = Falso;       DayLight_Status = Falso;     } Más Si (!(DayLight_Status))     {       ReturnValue = Falso;       DayLight_Status = Falso;     }
#ifdef Depuración     Serial.println(F("Off"));
#endif   } Más   {     Si ((DayLight_Status) Y (SensorValue > MyConfig.DayLight_Brightness_Border - L_Sens_Scope))     {       ReturnValue = Verdad;       DayLight_Status = Verdad;     } Más Si (!(DayLight_Status))     {       ReturnValue = Verdad;       DayLight_Status = Verdad;     }
#ifdef Depuración     Serial.println(F("ON"));
#endif   }   devolución ReturnValue;
}

Vacío Down_to_Up_ON()
{
#ifdef Depuración   Serial.println(F("Down_to_Up_ON"));
#endif   Byte Calc_Num_Stages_per_Module = Num_Stages_per_Module;   Para (Byte ModuleCount = 0; ModuleCount < PWMModules; ModuleCount++)   {     Pwm_Channel = 0;     Pwm_Channel_Brightness = 4095;     Si ((StagesLeft >= 1) Y (ModuleCount == PWMModules - 1))     {       Calc_Num_Stages_per_Module = StagesLeft;     }     Más     {       Calc_Num_Stages_per_Module = Num_Stages_per_Module;     }     Pwm_Channel = 0;     Pwm_Channel_Brightness = 0;     Mientras (Pwm_Channel < Calc_Num_Stages_per_Module + 1)     {       Alambre.beginTransmisión( PWM_Module_Base_Addr + ModuleCount);       Alambre.Escribir(Pwm_Channel * 4 + 8);   Registro de PWM_Channel_0_OFF_L de Wuhle       Alambre.Escribir((Byte)Pwm_Channel_Brightness & 0xFF);        Registro de registros       Alambre.endTransmission();       Alambre.beginTransmisión( PWM_Module_Base_Addr + ModuleCount);       Alambre.Escribir(Pwm_Channel * 4 + 9);  Registro de PWM_Channel_0_OFF_H de Wuhle       Alambre.Escribir((Pwm_Channel_Brightness >> 8));             Registro de registros       Alambre.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;         }       } Más Si ( Pwm_Channel < Num_Stages_per_Module + 1)       {         Pwm_Channel_Brightness = 0;         Retraso(MyConfig.delay_per_Stage_in_ms);         Pwm_Channel++;       }     }   }
}

Vacío Up_to_DOWN_ON()
{
#ifdef Depuración   Serial.println(F("Up_to_DOWN_ON"));
#endif   Byte Calc_Num_Stages_per_Module = Num_Stages_per_Module;   Int ModuleCount = PWMModules - 1;   Mientras (ModuleCount >= 0)   {     Pwm_Channel_Brightness = 0;     Si ((StagesLeft >= 1) Y (ModuleCount == PWMModules - 1))     {       Calc_Num_Stages_per_Module =  StagesLeft;     }     Más     {       Calc_Num_Stages_per_Module = Num_Stages_per_Module;     }     Pwm_Channel = Calc_Num_Stages_per_Module;     Mientras (Pwm_Channel > -1)     {       Alambre.beginTransmisión( PWM_Module_Base_Addr + ModuleCount);       Alambre.Escribir(Pwm_Channel * 4 + 8);   Registro de PWM_Channel_0_OFF_L de Wuhle       Alambre.Escribir((Byte)Pwm_Channel_Brightness & 0xFF);        Registro de registros       Alambre.endTransmission();       Alambre.beginTransmisión(PWM_Module_Base_Addr + ModuleCount);       Alambre.Escribir(Pwm_Channel * 4 + 9);  Registro de PWM_Channel_0_OFF_H de Wuhle       Alambre.Escribir((Pwm_Channel_Brightness >> 8));             Registro de registros       Alambre.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;         }       } Más Si ( Pwm_Channel >= 0)       {         Pwm_Channel_Brightness = 0;         Retraso(MyConfig.delay_per_Stage_in_ms);         Pwm_Channel--;         Si ( Pwm_Channel < 0)         {           Pwm_Channel = 0;           Romper;         }       }     }     ModuleCount = ModuleCount - 1;   }
}

Vacío Down_to_Up_OFF()
{
#ifdef Depuración   Serial.println(F("Down_to_Up_OFF"));
#endif   Byte Calc_Num_Stages_per_Module = Num_Stages_per_Module;   Para (Byte ModuleCount = 0; ModuleCount < PWMModules; ModuleCount++)   {     Pwm_Channel = 0;     Pwm_Channel_Brightness = 4095;     Si ((StagesLeft >= 1) Y (ModuleCount == PWMModules - 1))     {       Calc_Num_Stages_per_Module = StagesLeft;     }     Más     {       Calc_Num_Stages_per_Module = Num_Stages_per_Module;     }     Mientras (Pwm_Channel < Calc_Num_Stages_per_Module + 1)     {       Alambre.beginTransmisión( PWM_Module_Base_Addr + ModuleCount);       Alambre.Escribir(Pwm_Channel * 4 + 8);   Registro de PWM_Channel_0_OFF_L de Wuhle       Alambre.Escribir((Byte)Pwm_Channel_Brightness & 0xFF);        Registro de registros       Alambre.endTransmission();       Alambre.beginTransmisión(PWM_Module_Base_Addr + ModuleCount);       Alambre.Escribir(Pwm_Channel * 4 + 9);  Registro de PWM_Channel_0_OFF_H de Wuhle       Alambre.Escribir((Pwm_Channel_Brightness >> 8));             Registro de registros       Alambre.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;         }       } Más Si ( Pwm_Channel < Num_Stages_per_Module + 1)       {         Pwm_Channel_Brightness = 4095;         Retraso(MyConfig.delay_per_Stage_in_ms);         Pwm_Channel++;       }     }   }
}

Vacío Up_to_DOWN_OFF()
{
#ifdef Depuración   Serial.println(F("Up_to_DOWN_OFF"));
#endif   Byte Calc_Num_Stages_per_Module = Num_Stages_per_Module;   Int ModuleCount = PWMModules - 1;   Mientras (ModuleCount >= 0)   {     Pwm_Channel_Brightness = 4095;     Si ((StagesLeft >= 1) Y (ModuleCount == PWMModules - 1))     {       Calc_Num_Stages_per_Module = StagesLeft;     }     Más     {       Calc_Num_Stages_per_Module = Num_Stages_per_Module;     }     Pwm_Channel = Calc_Num_Stages_per_Module;     Mientras (Pwm_Channel > -1)     {       Alambre.beginTransmisión(PWM_Module_Base_Addr + ModuleCount);       Alambre.Escribir(Pwm_Channel * 4 + 8);   Registro de PWM_Channel_0_OFF_L de Wuhle       Alambre.Escribir((Byte)Pwm_Channel_Brightness & 0xFF);        Registro de registros       Alambre.endTransmission();       Alambre.beginTransmisión(PWM_Module_Base_Addr + ModuleCount);       Alambre.Escribir(Pwm_Channel * 4 + 9);  Registro de PWM_Channel_0_OFF_H de Wuhle       Alambre.Escribir((Pwm_Channel_Brightness >> 8));             Registro de registros       Alambre.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;         }       } Más Si ( Pwm_Channel >= 0)       {         Pwm_Channel_Brightness =  4095;         Retraso(MyConfig.delay_per_Stage_in_ms);         Pwm_Channel--;         Si ( Pwm_Channel < 0)         {           Pwm_Channel = 0;           Romper;         }       }     }     ModuleCount = ModuleCount - 1;   }
}

Vacío Stages_Light_Control ()
{   Si ((Motion_Trigger_Down_to_Up) Y !(On_Delay))   {     DLightCntrl = DayLightStatus();     Si (DLightCntrl)     {       Seconds24 = 0;       On_Delay = Verdad;       Down_to_Up_ON();     } Más {       Motion_Trigger_Down_to_Up = Falso;     }   }   Si ((On_Delay) Y (Seconds24 > MyConfig.Delay_ON_to_OFF) Y (Motion_Trigger_Down_to_Up) )   {     Down_to_Up_OFF();     Motion_Trigger_Down_to_Up = Falso;     On_Delay = Falso;     Seconds24 = 0;   }   Si ((Motion_Trigger_Up_to_Down) Y !(On_Delay))   {     DLightCntrl = DayLightStatus();     Si (DLightCntrl)     {       Seconds24 = 0;       On_Delay = Verdad;       Up_to_DOWN_ON();     } Más {       Motion_Trigger_Up_to_Down = Falso;     }   }   Si ((On_Delay) Y (Seconds24 > MyConfig.Delay_ON_to_OFF) Y (Motion_Trigger_Up_to_Down))   {     Up_to_DOWN_OFF();     Motion_Trigger_Up_to_Down = Falso;     On_Delay = Falso;     Seconds24 = 0;   }
}

Funciones del intérprete de comandos -------------------------------

Vacío ClearCBuffer ()
{   Para (Byte Un = 0; MaxInputBufferSize - 1; Un++)     Cbuffer[Un] = 0;
}

Booleana CheckforserialEvent()
{   Mientras (Serial.Disponible()) {     obtener el nuevo byte:     TBuffer = Serial.Leer();     Si (TBuffer > 9 && TBuffer < 14)     {       Cbuffer[Ccount] = 0;       TBuffer = 0;       Serial.Impresión(Char(13));       Serial.rubor();       Serial.println("");       Sbuffer = "";       Valor = 0;       EnterInput = Verdad;       devolución Verdad;     } Más Si (TBuffer > 47 && TBuffer < 58 )     {       Si ( Ccount < MaxInputBufferSize)       {         Cbuffer[Ccount] = TBuffer;         Ccount++;       } Más {         Serial.Impresión("#");       }       Número Entrada detectada       NumberInput = Verdad;     }     Más Si (TBuffer > 64 && TBuffer < 123 )     {       Si ( Ccount < MaxInputBufferSize)       {         Cbuffer[Ccount] = TBuffer;         Ccount++;         Serial.Impresión(Char(TBuffer));         Serial.rubor();       }       Entrada de carácter Char detectada       StrInput = Verdad;     }     Más Si ( (TBuffer == 127 )  |  (TBuffer == 8 ) )     {       Si ( Ccount > 0)       {         Ccount--;         Cbuffer[Ccount] = 0;         Serial.Impresión("-");         Serial.rubor();       }     }     Más     {       Si ( Ccount < MaxInputBufferSize)       {         Cbuffer[Ccount] = TBuffer;         Ccount++;         Serial.Impresión(Char(TBuffer));         Serial.rubor();         Entrada de datos detectada         DataInput = Verdad;       }       devolución Falso;     }     devolución Falso;   }
}

Byte SerInputHandler()
{   Byte Resultado = 0;   Int C;   Int D;   Int Un;   Int B;   Resultado = 0;   Si (CheckforserialEvent())   {     Si ((NumberInput) Y No (DataInput) Y No (StrInput))    Sólo números     {       Sbuffer = "";       Valor = 0;       StrInput = Falso;       NumberInput = Falso;       DataInput = Falso;       EnterInput = Falso;       Un = 0;       B = 0;       C = 0;       D = 0;       Sbuffer = Cbuffer; Zahl wird AUCH ! en SBUFFER-bernommen, cae bentigt.       Si (Ccount == 1) {         Valor  = Cbuffer[0] - 48 ;       }       Si (Ccount == 2) {         Un = Cbuffer[0] - 48 ;         Un = Un * 10;         B = Cbuffer[1] - 48 ;         Valor = Un + B;       }       Si (Ccount == 3) {         Un = Cbuffer[0] - 48 ;         Un = Un * 100;         B = Cbuffer[1] - 48 ;         B = B * 10;         C = Cbuffer[2] - 48 ;         Valor = Un + B + C;       }       Si (Ccount == 4) {         Un = Cbuffer[0] - 48 ;         Un = Un * 1000;         B = Cbuffer[1] - 48 ;         B = B * 100;         C = Cbuffer[2] - 48 ;         C = C * 10;         D = Cbuffer[3] - 48 ;         Valor = Un + B + C + D;       }       Si (Ccount >= 5)       {         Sbuffer = "";         Valor = 0;         Sbuffer = Cbuffer;         ClearCBuffer;         Resultado = 2;       } Más       {         ClearCBuffer;         Ccount = 0;         Resultado = 1;                                                Código de devolución del número         NumberInput = Falso;         StrInput = Falso;         DataInput = Falso;         EnterInput = Falso;         Ccount = 0;         devolución Resultado;       }     }     Si ((StrInput) Y No (DataInput))                          Sólo entrada de cadena     {       Sbuffer = "";       Sbuffer = Cbuffer;       Valor = 0;       StrInput = Falso;       NumberInput = Falso;       DataInput = Falso;       EnterInput = Falso;       Ccount = 0;       ClearCBuffer;       Resultado = 2;                                                 Código de devolución del número     }     Si (DataInput) {       Sbuffer = "";       Sbuffer = Cbuffer;       Valor = 0;       StrInput = Falso;       NumberInput = Falso;       DataInput = Falso;       EnterInput = Falso;       Ccount = 0;       ClearCBuffer;       Resultado = 3;                                               Código de devolución del número     }     Si ((EnterInput) Y No (StrInput) Y No (NumberInput) Y No (DataInput))     {       Sbuffer = "";       Valor = 0;       Ccount = 0;       ClearCBuffer;       Resultado = 4;                                               Código de devolución del número     }     NumberInput = Falso;     StrInput = Falso;     DataInput = Falso;     EnterInput = Falso;     Ccount = 0;     devolución Resultado;   }   devolución Resultado;   Fin de CheckforSerialEvent
}

Vacío SerialcommandProcessor()
{   Int Un;   Inptype = 0;   Inptype = SerInputHandler();   0 keine Rackgabe   1 Nummer   2 Cuerdas   3 Datos   Si (Inptype > 0)   {     MenueSelection = 0;     Si ((MnuState < 2) && (Inptype == 2)) {       Sbuffer.toUpperCase();  Para facilitar la introducción de comandos     }     Si ((Sbuffer == "D") && (MnuState == 0) && (Inptype == 2))   {       MenueSelection = 1;     }     Si ((Sbuffer == "O") && (MnuState == 0) && (Inptype == 2))       {       MenueSelection = 2;     }     Si ((Sbuffer == "T") && (MnuState == 0) && (Inptype == 2))       {       MenueSelection = 3;     }     Si ((Sbuffer == "B") && (MnuState == 0) && (Inptype == 2))       {       MenueSelection = 4;     }     Si ((Sbuffer == "N") && (MnuState == 0) && (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; Conjunto de tiempo     }     Si (MnuState == 11)                                              {       MenueSelection = 24; Conjunto de tiempo     }     Si (MnuState == 12)                                              {       MenueSelection = 25; Conjunto de tiempo     }     Si (MnuState == 13)                                              {       MenueSelection = 27; Conjunto de fondo     }     Si (MnuState == 14)                                              {       MenueSelection = 29; Conjunto ClockFace     }     Interruptor (MenueSelection)     {       Caso 1:         {           Serial.println("Retraso on to OFF: (1-65000)");           MnuState = 2;           Valor = 0;           Sbuffer = "";           Romper;         }       Caso 2:         {           Serial.println("Etapas generales: (1-992)");           MnuState = 3;           Valor = 0;           Sbuffer = "";           Romper;         }       Caso 3:         {           Serial.println("Retraso por etapa en ms: (1-65000)");           MnuState = 4;           Valor = 0;           Sbuffer = "";           Romper;         }       Caso 4:         {           Serial.println("Borde de brillo de la luz diurna: (0-65000)");           MnuState = 5;           Valor = 0;           Sbuffer = "";           Romper;         }       Caso 5:         {           Serial.println("Etapas de retardo encendido: (1-254)");           MnuState = 6;           Valor = 0;           Sbuffer = "";           Romper;         }       Caso 6:         {           Serial.println("Etapas de retardo OFF: (1-254)");           MnuState = 7;           Valor = 0;           Sbuffer = "";           Romper;         }       Caso 8:         {           MyConfig.Delay_ON_to_OFF = Valor;           saveEEPROM_Config();           Serial.Impresión(Q("Delay_ON_to_OFF establece en:"));           Serial.println(MyConfig.Delay_ON_to_OFF);           MnuState = 0;           Sbuffer = "";           Valor = 0;           Romper;         }       Caso 9:         {           MyConfig.Overall_Stages = Valor;           saveEEPROM_Config();           Serial.Impresión(Q("Etapas generales establecidas en:"));           Serial.println(MyConfig.Overall_Stages);           MnuState = 0;           Sbuffer = "";           Valor = 0;           Romper;         }       Caso 10:         {           MyConfig.delay_per_Stage_in_ms = Valor;           saveEEPROM_Config();           Serial.Impresión(Q("Retraso por etapa en ms establecido en:"));           Serial.println(MyConfig.delay_per_Stage_in_ms);           MnuState = 0;           Sbuffer = "";           Valor = 0;           Romper;         }       Caso 11:         {           MyConfig.DayLight_Brightness_Border = Valor;           saveEEPROM_Config();           Serial.Impresión(Q("Borde de brillo de DayLight establecido en:"));           Serial.println(MyConfig.DayLight_Brightness_Border);           MnuState = 0;           Sbuffer = "";           Valor = 0;           Romper;         }       Caso 12:         {           MyConfig.Delay_Stages_ON = Valor;           saveEEPROM_Config();           Serial.Impresión(Q("Etapas de retardo on establecidaen en:"));           Serial.println(MyConfig.Delay_Stages_ON);           MnuState = 0;           Sbuffer = "";           Valor = 0;           Romper;         }       Caso 13:         {           MyConfig.Delay_Stages_OFF = Valor;           saveEEPROM_Config();           Serial.Impresión(Q("Etapas de retardo OFF establecidaen en:"));           Serial.println(MyConfig.Delay_Stages_OFF);           MnuState = 0;           Sbuffer = "";           Valor = 0;           Romper;         }       Predeterminado:         {           MnuState = 0;           Serial.println(Q("-Control de luz de escalera -"));           Serial.Impresión(Q("D - Retardo encendido a APAGADO / Valor actual:"));           Serial.println(MyConfig.Delay_ON_to_OFF);           Serial.Impresión(Q("O - Etapas generales / Valor actual:"));           Serial.println(MyConfig.Overall_Stages);           Serial.Impresión(Q("T - Retraso por etapa en ms / Valor actual:"));           Serial.println(MyConfig.delay_per_Stage_in_ms);           Serial.Impresión(Q("B - Borde de brillo de la luz diurna / Valor actual:"));           Serial.println(MyConfig.DayLight_Brightness_Border );           Serial.Impresión(Q("N - Etapas de retardo ON / Valor actual:"));           Serial.println(MyConfig.Delay_Stages_ON);           Serial.Impresión(Q("F - Etapas de retardo OFF / Valor actual:"));           Serial.println(MyConfig.Delay_Stages_OFF);           Serial.println(Q("Escriba Cmd y pulse Intro"));           Serial.rubor();           MnuState = 0;           Valor = 0;           Sbuffer = "";         }     }   } Entrada detectada
}

Vacío Bucle()
{   Stages_Light_Control();   SerialcommandProcessor();
}

 

Después de que el código ha sido cargado, podemos acceder al schni serial con 9600 baudiosTtPosición. Después de una entrada (e inactivo! Luz de escalera) aparece el siguiente menú de configuración:

 

Parte 5 - Menú de configuración

 

 

Paramenter

Declaración

Retardo ENCENDIDO a OFF

Tiempo en SEGUNDOS que mantiene la iluminación de la escalera completamente encendida

Etapas generales

Número de escaleras de las escaleras

Retraso por etapa

Tiempo en MILLISECONDS para esperar hasta que se acerca la siguiente escalera.

Borde de brillo de luz diurna

Brillo en el que la iluminación de la escalera se vuelve inactiva. Mayor valor -> mayor brillo

Etapas de retardo ACTIVADAs

Rel. Tiempo de desvanecimiento al cambiar las escaleras. Mayor valor - > menos tiempo

Etapas de retardo DESACTIVADAS

Rel. Tiempo de desvanecimiento al CAMBIAR las escaleras. Mayor valor - > menos tiempo

 

Te deseo mucha diversión con la réplica. Como siempre, puede encontrar todos los proyectos anteriores en la página de GitHub https://github.com/kuchto

Para arduinoProyectos para avanzados.Sensores

6 comentarios

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.

Deja un comentario

Todos los comentarios son moderados antes de ser publicados

Artículos de blog

  1. Ahora instalamos el esp32 a través de la administración.
  2. Lüftersteuerung Raspberry Pi
  3. Arduino IDE - Programmieren für Einsteiger - Teil 1
  4. ESP32 - das Multitalent
  5. Transporte Aéreo - programación de ESP mediante redes locales inalámbricas