Exemplo n.º 1
0
Arquivo: main.c Projeto: aravind2/mwtp
int main(void)
{
  init_other_hw(); /* Must call this first */
  init_timer();
  init_audio();
  init_turnled();
  init_inputs();

  enable_task(TURNLED_TASK);
  enable_task(AUDIO_TASK);
  enable_task(INPUTS_TASK);
  enable_task(COUNTDOWN_TASK);
   
  /* initialize display, cursor off */
  lcd_init(LCD_DISP_ON);

  init_clock();

  /* Enable interrupts */
  sei();

  for (;;) {                           /* loop forever */
    poll_inputs();
    poll_clock();
    sleep_until_interrupt();
  } /* end loop forever */
}
Exemplo n.º 2
0
int main(void)
{
		
	setup();
	uint16_t increment = 0;	
	
	//DDRD &= ~(1<<PD4);	no longer needed
	//PORTD |= (1<<PD4);
		
    while(1)
    {
		
		/* measure supply voltage and warn user if voltage drops too low */
			if(ISR_flag.check_supply)	//measure supply voltage every 10ms
			{	
				check_supply_voltage();
				ISR_flag.check_supply = 0;	//clear flag	
			}

		/* poll the inputs and look for any falling edges indicating button presses or other input signals */
			if(ISR_flag.check_inputs)
			{
				poll_inputs();
				ISR_flag.check_inputs = 0;	//clear flag	
				
			/* Detect a long button press by incrementing a variable every ms the button is pressed
			 * This is necessary to avoid false triggering due to EMI from the motor lines.
			 */	
				if(!(DOOR_BUTTON_PINREG & (1<<DOOR_BUTTON_PIN)))
				{
					increment++;
				}else{
					increment = 0;	// reset the count if the button is released.
				}
			}
			
		/* check for a 1000ms long button press 
		 * Again, this is necessary to avoid false triggering due to motor interference 
		 */
			if(increment >= 1000)
			{
				increment = 0;				
				command.delayed_lock = 1;	//activate the delayed lock sequence
				delayed_lock_tick = 0;		//reset the timer for the delayed lock sequence
			}
		
		
		/* check, if status is unknown or a reference command has been issued
		 * If that is the case, ignore any other commands and find the reference point first!
		 *
		 * Note, that command.reference is not implemented yet. There was no need for this until now (10/Aug/15)
		 */
			if( ((!status.locked) && (!status.unlocked)) || (command.reference) )
			{
				if((command.lock)||(command.unlock)||(command.reference))
				{	
					if(input_status_current[6])	//find out, if gear magnet is already near the reed contact
					{
						find_reference(0,500,2000);	
					}else{
						find_reference(1,500,2000);
					}	
					command.lock = 0;
					command.unlock = 0;
					command.reference = 0;	
					command.delayed_lock = 0;			
				}
			}else
			
			{ 	
			/* open the door */
				if (command.unlock && !command.block_unlock && !command.reference)
				{
					command.block_lock = 1;	//prevent any other lock commands while this is active
					enable_stepper(1);

					if(!status.open)		//Door is not open yet, move to "open" position
					{
						if(move_to_position(OPEN)==1)	//set status.open once at "open" position 
						{
							status.open = 1;
						}
						ms_100_tick = 0;	//reset the 100ms tick until at "open" position 
						
					}else if(ms_100_tick<=35)
					{
						//wait 3.5s at "open" position before turning back to "neutral". This lets the user open the door by pushing it
					}

					if((ms_100_tick>35)&&(status.open))	//Door is "open" and we waited for 3.5s
					{
						
						if(move_to_position(NEUTRAL)==1)	//move back to "neutral" position and reset all status and command bits.
						{
							command.unlock = 0;
							command.block_lock = 0;
							status.open = 0;
							status.locked = 0;
							status.unlocked = 1;
							status.error = 0;
							status.reached_endstop = 0;
							command.delayed_lock = 0;

							enable_stepper(0);
						}
					}
				} else

			/* lock the door */	
				if (command.lock && !command.block_lock && !command.reference)
				{
					/* locking is the same as a reference turn, so we use every lock command to re-reference our position
					 * to account for stupid users turning the gear by hand
					 */
						enable_stepper(1);	
						command.block_unlock = 1;		//block any other actions while locking the door
						
						if(!status.reached_endstop && (position > (-2000)))		//turn CCW until either endstop is reached or 2000 steps have passed
						{
							move_to_position(-2000);
							ms_100_tick = 0;	
							
						} 
						else if (position <= (-2000))		//2000 steps have passed without reaching the endstop -> something went wrong
						{
							command.lock = 0;
							command.block_unlock = 0;
							status.locked = 0;
							status.unlocked = 0;
							status.error = 1;
							command.delayed_lock = 0;
							
							enable_stepper(0);
						}
						else if(ms_100_tick<=1){		//endstop reached, reset the position to 0 while waiting a bit 
							position = 0;
						} 
						
						if((ms_100_tick>3)&&(status.reached_endstop))	//return to "neutral" position after 300ms
						{
							if(move_to_position(NEUTRAL)==1)	//reset status and command bits after coming back to the "neutral" position
							{
								command.lock = 0;
								command.block_unlock = 0;
								status.reached_endstop = 0;
								status.locked = 1;
								status.unlocked = 0;
								status.error = 0;
								enable_stepper(0);
								command.delayed_lock = 0;
							}
	
						}							
				} 
				else
				
			/* someone locked the door by hand and triggered the endstop. Set status to "locked" */
				if (!command.lock && !command.unlock && !command.reference)
				{
					if(status.reached_endstop)
					{
						status.open = 0;
						status.unlocked = 0;
						status.locked = 1;
					}
				}
					
			}	
			
			
			
			
		/* delayed lock has been triggered. Start the countdown */
			if (command.delayed_lock && status.unlocked && !status.open && !command.block_unlock && !command.block_lock && !command.lock && !command.unlock)
			{
				if(delayed_lock_tick < 150)		//wait for 15s and set "status.delayed_lock". This triggers the flashing yellow LED 
				{
					status.delayed_lock = 1;
					switch_LED(0,'B');			
				}else
				{
					status.delayed_lock = 0;
					command.delayed_lock = 0;
					command.lock = 1;			//15s have passed, give the "lock" command to lock the door
				}
			}
			
		/* Switch LEDs according to the status bits.
		 *
		 * This needs to be streamlined, it is way to complicated
		 */	
			if(status.delayed_lock)		//Override any other LED configurations while "status.delayed_lock" is active
			{
				flash_LED(25,(180-delayed_lock_tick),'Y');
				switch_LED(0,'B');
			}else
			{

				if(status.error || ( (!status.unlocked)&&(!status.locked)))
				{
					flash_LED(10,20,'Y');
					flash_LED(10,20,'B');
					set_status('E');
				}
				if(status.open)
				{
					flash_LED(25,40,'B');
					switch_LED(0,'Y');
					set_status('U');
				}
				if(status.unlocked && !status.open)
				{
					switch_LED(0,'Y');
					switch_LED(1,'B');
					set_status('U');
				}
				if(status.locked && !status.open)
				{
					switch_LED(0,'B');
					switch_LED(1,'Y');
					set_status('L');
				}
			
			}	
    }
}