Display Steuerung für Lampen per Relais. https://www.youtube.com/watch?v=_CupBMcZ8Xc

Dependencies:   BSP_DISCO_F746NG F746_GUI LCD_DISCO_F746NG TS_DISCO_F746NG mbed

lightAutomatic.cpp

Committer:
hexfactory
Date:
2017-04-23
Revision:
1:f316de154ff7

File content as of revision 1:f316de154ff7:

/*=============================================================================================
        section 1 - includes
 ==============================================================================================*/
/* imported libs */
#include "mbed.h"
#include "F746_GUI.hpp"

/* project files */
#include "lightAutomatic.h"
#include "flash.h"
#include "relay.h"

/*=============================================================================================
        section 2 - private defines / enumerations
 ==============================================================================================*/
/* debgug switch */
#define DEBUG_MODULE 1 /* DEBUG_MODULE 1 => ON, 0 => OFF */

/* GPIO Eingangswerter für Türkontaktsensor */
#define DOOR_OPEN       1 /* high */
#define DOOR_CLOSED     0 /* low */
 
/* GPIO Eingangswerter für Helligkeitssensor */
#define LIGHT_DARK      1 /* high */
#define LIGHT_BRIGHT    0 /* low */

enum E_FSM {INACTIVE, ACTIVE_WAITING, ACTIVE_LIGHT_ON};
enum E_STATE {OFF = 0, ON};

/*=============================================================================================
        section 3 - private typedefs
 ==============================================================================================*/
typedef E_STATE t_lightAutomaticState;
typedef E_STATE t_lighState;

/*=============================================================================================
        section 4 - private macros
 ==============================================================================================*/
 
/*=============================================================================================
        section 5 - public constants definition
 ==============================================================================================*/

/*=============================================================================================
        section 6 - public variables/pointers definition
 ==============================================================================================*/

/*=============================================================================================
        section 7 - private constants definition
 ==============================================================================================*/

/*=============================================================================================
        section 8 - private variables/objects/pointers definition
 ==============================================================================================*/
/* light automatic state pro Lampe */
static t_lightAutomaticState lightAutomatic1State = OFF;
static t_lightAutomaticState lightAutomatic2State = OFF;

/* speichert ein button pressed event, 1 == pressed */ 
static uint8_t stayActivePressed = 0; 

/* Zustandsautomat */                                      
static E_FSM fsmLightAutomatic;

 /* gui */
static Label  *pLabelAutomatic1Text;
static Button *pBtnLight1Automatic;
static Label  *pLabelAutomatic1State;
static Label  *pLabelAutomatic2Text;
static Button *pBtnLight2Automatic; 
static Label  *pLabelAutomatic2State;
static Button *pBtnStayActive; 

/* gui - debug */
#if (DEBUG_MODULE == 1)
static uint8_t doorStatusOld;
static uint8_t doorStatusNew;
static uint8_t lightStatusOld;
static uint8_t lightStatusNew;

static Label  *pLabelDebugFsm;
static Label  *pLabelDebugTimer;
static Label  *pLabelDebugDoorSensor;
static Label  *pLabelDebugLightSensor;
#endif

/*=============================================================================================
        section 9 - private functions - declaration
 ==============================================================================================*/
static void _buttonSubTask(void);
static void _fsmSubTask(void);

/* debug */
#if (DEBUG_MODULE == 1)
static void _debugInit(void);
static void _debugSubTask(void);
#endif

/*=============================================================================================
        section 10 - private functions - implementation (definition)
 ==============================================================================================*/
static void _buttonSubTask(void) 
{
    /* Objekte nicht initialisiert => Fehler */
    if ((pLabelAutomatic1State == NULL) ||
        (pBtnLight1Automatic == NULL) ||
        (pLabelAutomatic2State == NULL) ||
        (pBtnLight2Automatic == NULL)) 
    {
        return;        
    }
    
    /* prüfe ob button gedrückt */
    if (pBtnLight1Automatic->Touched()) 
    {
        if (OFF == lightAutomatic1State) 
        { /* automatic an */
            lightAutomatic1State = ON;
            pLabelAutomatic1State->Draw("on");
            wait(0.5);
            pBtnLight1Automatic->Draw();
        } 
        else { /* automatic aus */
            lightAutomatic1State = OFF;
            pLabelAutomatic1State->Draw("off");
            wait(0.5);
            pBtnLight1Automatic->Draw();
        }
    }
    
    /* prüfe ob button gedrückt */
    if (pBtnLight2Automatic->Touched()) 
    {
        if (OFF == lightAutomatic2State) 
        { /* automatic an */
            lightAutomatic2State = ON;
            pLabelAutomatic2State->Draw("on");
            wait(0.5);
            pBtnLight2Automatic->Draw();
        } 
        else 
        { /* automatic aus */
            lightAutomatic2State = OFF;
            pLabelAutomatic2State->Draw("off");
            wait(0.5);
            pBtnLight2Automatic->Draw();
        }
    }
    
    /* button ist nur aktiv im Zustand ACTIVE_LIGHT_ON */
    if (fsmLightAutomatic == ACTIVE_LIGHT_ON) {
        /* prüfe ob button gedrückt */
        if (pBtnStayActive->Touched())
        {
            stayActivePressed = 1;
        }
    }    
    
    /* sichere light state im flash */
    flash_write(FLASH_LIGHT_AUTOMATIC1, lightAutomatic1State);
    flash_write(FLASH_LIGHT_AUTOMATIC2, lightAutomatic2State);    
}

static void _fsmSubTask(void) 
{
    static Timer timer1;
    static float startTime;
    static t_lighState tmpLight1 = OFF;
    static t_lighState tmpLight2 = OFF;
#if (DEBUG_MODULE == 1)  
    char debugBuffer[30];
#endif 
    
    /* debug */
    /* Objekte nicht initialisiert => Fehler */
#if (DEBUG_MODULE == 1)    
    if ((pLabelDebugFsm == NULL) ||
        (pLabelDebugTimer == NULL)) 
    {
        return;        
    }
#endif
    
    /* fsm */
    switch(fsmLightAutomatic) 
    {
        case INACTIVE:        
            /* debug */
#if (DEBUG_MODULE == 1)
            pLabelDebugFsm->Draw("FSM:        INACTIVE");
#endif
            
            /* next state */
            if ((ON == lightAutomatic1State) ||
                (ON == lightAutomatic2State)) 
            {
                fsmLightAutomatic = ACTIVE_WAITING;
            }
            break; 
        case ACTIVE_WAITING:        
            /*debug */
#if (DEBUG_MODULE == 1)
            pLabelDebugFsm->Draw("FSM:        ACTIVE_WAITING");
#endif          
            /* next state */
            /* INACTIVE */
            if ((OFF == lightAutomatic1State) &&
                (OFF == lightAutomatic2State)) 
            {
                fsmLightAutomatic = INACTIVE;
            }
            /* ACTIVE_LIGHT_ON */
            else if ((DOOR_OPEN == g_doorSensor) &&
                     (LIGHT_DARK == g_lightSensor))
            {
                fsmLightAutomatic = ACTIVE_LIGHT_ON;
                timer1.reset();
                timer1.start();
                startTime = timer1.read();
                pBtnStayActive->Draw(); /* show button */
                if (ON == lightAutomatic1State){
                   relay_switch(RELAY_LIGHT1); 
                   tmpLight1 = ON;
                }
                if (ON == lightAutomatic2State){
                   relay_switch(RELAY_LIGHT2); 
                   tmpLight2 = ON;
                }
            }            
            break; 
        case ACTIVE_LIGHT_ON:        
            /* debug */
#if (DEBUG_MODULE == 1)            
            pLabelDebugFsm->Draw("FSM:        ACTIVE_LIGHT_ON");
            snprintf(debugBuffer, 30, "Timer:      %f", timer1.read());
            pLabelDebugTimer->Draw(debugBuffer);
#endif
            
            /* next state */
            if (stayActivePressed == 1) {
                timer1.stop();
                fsmLightAutomatic = ACTIVE_WAITING;
                pBtnStayActive->Erase(); /* hide button */  
                stayActivePressed = 0; 
            } 
            else if ((timer1.read() - startTime) >= 30) 
            {
                timer1.stop();
                fsmLightAutomatic = ACTIVE_WAITING;
                pBtnStayActive->Erase(); /* hide button */   
                if (ON == tmpLight1){
                   relay_switch(RELAY_LIGHT1); 
                   tmpLight1 = OFF;
                }
                if (ON == tmpLight2){
                   relay_switch(RELAY_LIGHT2); 
                   tmpLight2 = OFF;
                }
            }
            break; 
    }  
}

#if (DEBUG_MODULE == 1)
static void _debugInit(void) 
{
    /* gui labels*/
    pLabelDebugDoorSensor  = new Label(10, 200, "Tuer:       KEINE DATEN", Label::LEFT, Font16);
    pLabelDebugLightSensor = new Label(10, 220, "Helligkeit: KEINE DATEN", Label::LEFT, Font16);  
    pLabelDebugFsm         = new Label(10, 240, "FSM:        KEINE DATEN", Label::LEFT, Font16);
    pLabelDebugTimer       = new Label(10, 260, "Timer:      KEINE DATEN", Label::LEFT, Font16);
    
    /* door sensor */
    doorStatusNew = g_doorSensor;
    doorStatusOld = doorStatusNew;
    if (doorStatusNew == DOOR_OPEN) 
    {
        pLabelDebugDoorSensor->Draw("Tuer:       offen");
    } 
    else 
    {
        pLabelDebugDoorSensor->Draw("Tuer:       geschlossen");
    } 
    
    /* light sensor */
    lightStatusNew = g_lightSensor;
    lightStatusOld = lightStatusNew;
    if (lightStatusNew == LIGHT_DARK) 
    {
        pLabelDebugLightSensor->Draw("Helligkeit: dunkel");
    } 
    else 
    {
        pLabelDebugLightSensor->Draw("Helligkeit: hell");
    }  
}
#endif /* #if (DEBUG_MODULE == 1) */

#if (DEBUG_MODULE == 1)
static void _debugSubTask(void) {
    /* Objekte nicht initialisiert => Fehler */
    if ((pLabelDebugDoorSensor == NULL) ||
        (pLabelDebugLightSensor == NULL)) 
    {
        return;        
    }
    
    /* zeige tür offen oder zu*/
    doorStatusNew = g_doorSensor;
    if (doorStatusOld != doorStatusNew) 
    {        
        doorStatusOld = doorStatusNew;
        if (doorStatusNew == DOOR_OPEN)
        {
            pLabelDebugDoorSensor->Draw("Tuer:       offen");
        } 
        else 
        {
            pLabelDebugDoorSensor->Draw("Tuer:       geschlossen");
        }    
    } 
    
    /* zeige ob hell oder dunkel */
    lightStatusNew = g_lightSensor;
    if (lightStatusOld != lightStatusNew) 
    {
        lightStatusOld = lightStatusNew;
        if (lightStatusNew == LIGHT_DARK) {
            pLabelDebugLightSensor->Draw("Helligkeit: dunkel");
        } 
        else 
        {
            pLabelDebugLightSensor->Draw("Helligkeit: hell");
        }  
    }  
}
#endif /* #if (DEBUG_MODULE == 1) */

/*=============================================================================================
        section 11 - public functions - implementation (definition)
 ==============================================================================================*/
void lightAutomatic_init(void) 
{
    fsmLightAutomatic = INACTIVE;
    stayActivePressed = 0;
  
    /* light automatic status */
    lightAutomatic1State = (t_lightAutomaticState) flash_read(FLASH_LIGHT_AUTOMATIC1);
    lightAutomatic2State = (t_lightAutomaticState) flash_read(FLASH_LIGHT_AUTOMATIC2);
    
    /* gui - automatic for light 1 */
    pLabelAutomatic1Text  = new Label( 200, 40 + 12,  "Automatik:", Label::LEFT, Font16);
    pBtnLight1Automatic   = new Button(310, 40,      70, 40, "schalten");
    pLabelAutomatic1State = new Label( 390, 40 + 12,  "off", Label::LEFT, Font16);
    if (OFF == lightAutomatic1State) 
    {
        pLabelAutomatic1State->Draw("off");
    }
    else
    {
        pLabelAutomatic1State->Draw("on");
    }
    
    /* gui - automatic for light 2 */
    pLabelAutomatic2Text  = new Label( 200, 90 + 12, "Automatik:", Label::LEFT, Font16);
    pBtnLight2Automatic   = new Button(310, 90,      70, 40, "schalten");
    pLabelAutomatic2State = new Label( 390, 90 + 12,  "off", Label::LEFT, Font16);
    if (OFF == lightAutomatic2State)
    {
        pLabelAutomatic2State->Draw("off");
    }
    else
    {
        pLabelAutomatic2State->Draw("on");
    }
    
    /* gui - button für Licht-Automatik im Zustand ACTIVE_LIGHT_ON */
    pBtnStayActive = new Button(290, 160,      150, 60, "anlassen", Font24);
    pBtnStayActive->Erase(); /* hide button */
    
    /* debug */
#if (DEBUG_MODULE == 1)
    _debugInit();
#endif
}   
 
void lightAutomatic_task(void) 
{    
#if (DEBUG_MODULE == 1)
    /* debug */
    _debugSubTask();
#endif
    
    /* check button touched */
    _buttonSubTask();   
    
    /* check fsm state */
    _fsmSubTask();     
}  

/*=============================================================================================
        section 12 - interrupt service routines (ISRs)
 ==============================================================================================*/

/*=============================================================================================
        end of file
 ==============================================================================================*/