StateMachine

Dependencies:   mbed

main.cpp

Committer:
p0ckin3d
Date:
2014-10-28
Revision:
0:965e1122fba3

File content as of revision 0:965e1122fba3:

#include "mbed.h"

/* Modulname:   SM_FahrradLeuchte1.c      Version:1.0   */
/* Funktion:    State-Machine-Programm                  */
/* Erstellt von: p0ckin3d              am: 2014-10-28         */
/* Beschreibung:                                        */
// Fahrradrückleuchte mit 4 roten LEDs am PORTC
// -----------------------------------
// Zum Schalten: 1 Taster PINA PA0
// 1. Funktion
// Start-Taste 1x betätigen: 
// Dauerlicht aller 4 LEDs
// 2. Funktion
// Start-Taste ein 2.mal betätigen:
// LEDs blinken im ca. 400 Millisekunden-Takt; 200 msec Ein, 200 msec Aus
// Ausschalten des Rücklichts
// Die Start-Taste ein 3.mal betätigen:
// Alle LEDs aus.


//volatile uint8_t count;
volatile unsigned int count;
volatile unsigned int newEvent =0; 
volatile unsigned int event=0, state=0;

Ticker timer0;
BusOut myleds(LED1, LED2, LED3, LED4);
DigitalIn center(p14);

/* Prototypen der Funktionen */
int no_fu();
int ledsEin();
int msec300TimerOn();
int ledsAusTimerOff();
int ledsTogglen();
int nightRiderTest();
int nightRider();

bool doNightRider = false;
bool upwards = true;
int ledCounter = 1;

/****************************************************/
/* Tabelle fuer die naechsten Zustaende bei Eingabe */
/****************************************************/
unsigned char nextstate_tab[3][4]=
//present state 0  1  2  3
//------------------------
/* event 0 */{{ 1, 2, 3, 0 },  // next
/* event 1 */ { 0, 1, 2, 3 }, // state
/* event 2 */ { 0, 1, 2, 3 }}; // state
// state=nextstate_tab[event][state]; // gehe auf naechsten Zustand

/*************************************************************/
/* Tabelle fuer Aktionsroutinen fuer die Zustaende bei Input */ 
/*************************************************************/
//                           p r e s e n t    s t a t e  
int(*action[3][4])()= //  0             1              2               3
/* event 0 */       {{ ledsEin, msec300TimerOn, nightRiderTest, ledsAusTimerOff },        
/* event 1 */        {  no_fu,       no_fu,   ledsTogglen,     no_fu },
/* event 2 */        {  no_fu,       no_fu,   no_fu,     nightRider  }}; 
// (*action[event][state])(); // suche in Tabelle nach Funktion


/* Aktionsroutinen, functions */
int no_fu()         // keine function - tue nichts
{
  return(0);
}

int nightRiderTest()
{
    doNightRider = true;  
    return(2); 
}

int nightRider()
{
    myleds = ledCounter;
    
    if(ledCounter == 8)
        upwards = false;
    else if(ledCounter == 1)
        upwards = true;
    
    if(upwards)
        ledCounter*=2;
    else
        ledCounter/=2;
        
    return 4;
}

// interrupt SR
void timer0_int()
{
    //Increment our variable
    count++;
    if(count==10)
    {
        count=0;
        
        if(doNightRider)
            event=2;
        else
            event=1;
            
        newEvent = 1;
    }
}

int msec300TimerOn()       
{
    timer0.attach(&timer0_int, 0.032);
    doNightRider = false;
    return(1);
}

int ledsAusTimerOff()        
{ 
    timer0.detach();
    myleds = 0;
    doNightRider = false;
    return(3);
}

int ledsTogglen()   
{ 
    myleds = ~myleds;
    return(3);
}

int ledsEin()   
{ 
    myleds = 0x0F;
    return(4);
}

// functions
void initTimer0()
{
    count=0;
}

// Diese Funktion ist zum Entprellen von Tastern geeignet: 
// Durch den zusätzlichen Code kann eine Entprellzeit von durchschnittlich 1,5-4ms
// (mindestens 8*150us = 1,2ms) erreicht werden. 
// Grundsätzlich prüft die Funktion den Pegel der Pins auf einem bestimmten Port. 
// Wenn die/der Pegel 8 Mal konstant war, wird die Schleife verlassen. 
// Diese Funktion kann sehr gut eingesetzt werden, um in einer Endlosschleife Taster anzufragen, 
// da sie, wie erwähnt, eine kurze Wartezeit hat.
unsigned char debounce(PinName name, unsigned char samples)
{
    DigitalIn joystick(name);
    
    unsigned char i = 0; 
    
    for(unsigned char j=0; j < samples; j++)
    {
        if(joystick == 1)
            j++;    
        else
        {
            j = 0;
            i++;
        }
            
        if(j == samples)
            break;
            
        if(i == samples)
            break;
            
        wait(0.001);
    }
    return joystick;
}


int main()
{
    unsigned char released = 0;

    myleds = 0;
    initTimer0();
    
    newEvent = 0;
    state=0; 
    event=0;

    while(1)
    {
        //debounce(p14, 6);
        if(debounce(P0_10, 6))           // jetzt stabilen Wert einlesen
        {
            if (released == 1)
            {
                event =0;
                newEvent =1;
                released =0;
            }
        }
        else
        {
            released =1;
        }

        if (newEvent)
        {
            timer0.detach();
            newEvent =0;
            (*action[event][state])(); // suche in Tabelle nach Funktion
            state=nextstate_tab[event][state]; // gehe auf naechsten Zustand
            timer0.attach(&timer0_int, 0.032);
        }
    }
}