Attiny-state machine

Go To Last Post
4 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello,

I work on my simple small project, which is realised on Attiny 45 MCU.

I use one push button for switch between different states.

I switch different state of LED diodes when I count button press, but I have two problem.

 

First problem:

 

When I long press button, so I switch very fast all states. I want use short press for switch between states.

 

Second problem:

 

I want state for LED blink, but when I use do-while or one while cycle so I can not escape from this cycle with new press button count.

 

Thank you for help!

Teodor

 

 

#define F_CPU 8000000UL
#include <util/delay.h>
#include <avr/io.h>

#define BUTTON_PRESS (!(PINB&(1<<PB2)))

#define LED_1_ON PORTB |= (1<<PB0)
#define LED_2_ON PORTB |= (1<<PB1)
#define LED_3_ON PORTB |= (1<<PB4)

#define LED_1_OFF PORTB &= ~(1<<PB0)
#define LED_2_OFF PORTB &= ~(1<<PB1)
#define LED_3_OFF PORTB &= ~(1<<PB4)

#define  LED_1_TOGGLE PORTB ^= (1<<PB0)
#define  LED_2_TOGGLE PORTB ^= (1<<PB1)
#define  LED_3_TOGGLE PORTB ^= (1<<PB4)

volatile uint8_t count;
volatile uint8_t stavTlacitka;

void setup_MCU(){
	DDRB |= (1<<PB0)|(1<<PB1)|(1<<PB4); //nastaveni vystupu
	DDRB &= ~(1<<PB2); //nastaveni vstupu
	PORTB |= (1<<PB2); //nastaveni pull-up pro vstup
	TCCR0A = 0x00;
	TCCR0B = 0x00;
	TCCR0B |= (1<<CS00)|(1<<CS02);
	TCCR0A |= (1<<WGM01);
	OCR0A = 94;
	TCNT0 = 0;		
}

void debounce_delay(){
	uint8_t i = 0;
	
	while(i <=1){
		while ((TIFR & (1<<OCF0A)) == 0);
		TIFR |= (1<<OCF0A);
		i++;
	}
}

int main(void){
	
	setup_MCU();
	
	while (1)
	{				
		if(BUTTON_PRESS){
			debounce_delay();
			if(BUTTON_PRESS){
				count++;	
				
				if (count == 1)
				{				
					LED_1_ON;
					LED_2_OFF;
					LED_3_OFF;					
					
					}
					
					if(count == 2){
					
					LED_1_OFF;
					LED_2_ON;
					LED_3_OFF;				
					
					}
					
					if(count == 3){
					
					LED_1_OFF;
					LED_2_OFF;
					LED_3_ON;				
					
					}
					
					if(count == 4){
					
					LED_1_OFF;
					LED_2_OFF;
					LED_3_OFF;					
					
					}
					
					if(count == 5){
					
					LED_1_ON;
					LED_2_ON;
					LED_3_ON;
																				
					}
					
					if(count == 6){
						
						LED_1_OFF;
						LED_2_OFF;
						LED_3_OFF;
						//count = 0;
					}
					
					if(count == 7){
						while(count >=7){						
						LED_1_ON;
						LED_2_ON;
						LED_3_ON;
						_delay_ms(150);
						LED_1_OFF;
						LED_2_OFF;
						LED_3_OFF;
						_delay_ms(150);
						}
						
					}
					
					if(count == 9){
						
						LED_1_OFF;
						LED_2_OFF;
						LED_3_OFF;
						count = 0;
					}
			}
		}
	}
	
}

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You could change the line

while (count >= 7) {

to

while (count >= 7 && (! BUTTON_PRESS)) {

in order to check for a button press in the flash loop. 

Good luck!

 

Jarrod 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You never detect when the button is released

 

Make one state machine that tells when there is a new debounced button cycle (from released state to debounced pushed state) ...this machine can do the debouncing.

 

A different state machine will advance to the next leds state only when the first one says a new button cycle has occurred & reset the first machine back to the non-pushed state.

 

An even easier way is when the first machine enters the debounced push state, it calls for an update to the led state machine,  This call will only happen every fresh button cycle (entering the debounced push state), so  no special resetting is needed from the second machine.

 

See, they can work together.  

 

 

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Can you give me any example or can you re-write my code with one press for example?

thx!