Sunday, 8 March 2009

sequel 2 to slave concepts

3.handling button actions:

To capture a button state change you have two option or you take a poll approach or you do it by interrupt. As I'm an interrupt lover I took the second option. On my AVR development board the EXT0 pin was used for connecting a button or switch. If you use the EXT0 you have the possibility to trigger on positive or negative edge or both. In my case I triggered the positive edge. This depends a bit on how you connect your button pulled up or not. The code of course to do that is more than simple:

ISR(INT0_vect)
{
interrupt0=SIGNALED;
}

The
interrupt0 flag I used is treated in the idle main loop. ( so a little polling anyway ) It's very important that you test the signal on any glitches or faults. The best thing you can do is bringing a delay loop in action as soon as you triggered a state change. If the signal is still stable and correct after the delay you can go ahead and treat the change as you wish. But let me copy in my code snippet here to make things clear it's sufficient self describing as you will notice reading it. Sorry for the layout , the indents are not correctly put, but it has only two levels and is not of much importance for the concept. ( HTML don't like tabs either ;-)

void TriacStep ( void )
{
if ( interrupt0 == SIGNALED )
{
// turn off INT after neg edge
DISABLEINT0;

// poll pin on remain clear
// in case of glitch abort while loop
while ( bit_is_clear(PINB, PB6) )
{
_delay_ms(PUSHDELAYPOLL);
pushtime++;
}

//***if glitch pushtime still zero here !

// check push time
if (pushtime > TRESHOLDOFF)
{
///***long hold means goto power down***
/// turn off zerocross INT
/// for NO wackup from powerdown
DISABLEPCINT;

/// no triac pulse needed
UNMASKTRIAC;

/// INT0 back on
/// for wackup from powerdown
ENABLEINT0;

/// powerdown initiated
sleep_mode();

/// zerocross back on
ENABLEPCINT;

/// triac puls back on
MASKTRIAC;

}
else if (pushtime != ZEROTIME)
{
///***normal hold for triac step***

/// increase one step
triaclevel--;

/// get pre calculated values
TC1H = tc1high[triaclevel];
OCR1A = tc1low [triaclevel];

/// when max goto min
if (triaclevel==TRIACMAX)
triaclevel= TRIACLEVELS;
}

/// toggle INT flag atomic
ATOMIC_BLOCK(ATOMIC_FORCEON)
{
interrupt0 = NOTSIGNALED;
}

/// reset pushtime
pushtime = ZEROTIME;

/// save to trigger again on edge
ENABLEINT0;
}
}

As you can see I work with some threshold value to keep track how long the button has been pressed. This is done to diversify a simple push or a long push which in my case puts the AVR to sleep and put off the lamp completely. This concept works great. Ok I bring you up to the next slave sequel then.




No comments: