Example #1
0
void goto_sleep(void)
{
     // Disable the watchdog timer's interrupt vector, WDIE

     // On the Arduino (ATmega328p at least), it suffices to
     // just set WDTCSR = 0.  So what follows may be overkill
     // on some AVRs
     asm("cli");
     asm("wdr");

     // Make sure that the watchdog interrupt is not renewed by the
     // watchdog interrupt
     sleeping = 1;

     MCUSR = 0;
     WDTCSR |= (1 << WDCE) | (1 << WDE);
     WDTCSR = 0;

     // Again, enable the pull up resistor on the input port
     BUTTON_PORT = (1 << BUTTON_BIT);

     // Shut down the LEDs
     leds_on     = 0;
     old_leds_on = 0;
     LED_PORT &= ~(LED_1 | LED_2 | LED_3 | LED_4 | LED_5 | LED_6 | LED_7);

     // Set the sleep mode
     set_sleep_mode(SLEEP_MODE_PWR_DOWN);

     // Use INT0 and run the INT0 interrupt routine when pin 2 goes LOW
     // When the external interrupt INT0 is enabled, we will
     // trigger when the pin goes to a logical low
     INTERRUPT_CONT &= ~((1 << ISC00) | (1 <<ISC01));
     INTERRUPT_MASK = (1 << INT0);
 
     // Enable the sleep bit in MCUCR register
     sleep_enable();

     // And now go to sleep
     asm("sei");
     sleep_mode();

     // We will resume here when awoken...

     // Disable sleep...
     sleep_disable();

     // Disable INT0 thus preventing the INT0 interrupt from being
     // executed during normal operation
     INTERRUPT_MASK &= ~(1 << INT0);

     // Allow the watchdog interrupt to renew itself
     sleeping = 0;

     // Re-enable the watchdog timer's interrupt vector
     // The following is overkill on some AVRs.  For instance, on the
     // ATmege328p, just doing "WDTCSR = 1 << WDIE" is sufficient.
     WDTCSR = (1 << WDCE) | (1 << WDE);
     WDTCSR = (1 << WDE) | (1 << WDIE);

     // Run throught the LED test
     led_test();
}
int main(void)
{
	uint16_t	adcPVoltages[BUFSIZE] = {0UL};
	uint16_t	adcNVoltages[BUFSIZE] = {0UL};
	uint16_t	adcCurrents[BUFSIZE] = {0UL};
	uint16_t	adcGNDs[BUFSIZE] = {0UL};

	uint16_t	adcValue;
	int16_t	gndValue;
	int16_t	mVoltage, mCurrent;
	uint8_t	idx;
	float	fv, fa;
		
	// ポートの初期化
	DDRD = _BV(2);			 // RSTピンを出力に
	PORTC = _BV(4) | _BV(5); // SCL, SDA内蔵プルアップを有効
	
	
	// デバイスの初期化
	i2c_init();				 // AVR内蔵I2Cモジュールの初期化
	wait_ms(500);
	
	PORTD &= ~_BV(2);		 // RSTをLにします。リセット
	wait_ms(1);
	PORTD |= _BV(2);		 // RSTをHにします。リセット解除
	wait_ms(10);
	
	lcdInit();
	
	//LCD初期表示
	lcdSetPos(0, 0);	lcdPutStr("Volt + / Current");
	lcdSetPos(0, 1);	lcdPutStr("Volt - / GND");
	wait_sec(3);
	
	//消費電力削減のためADC使用ピンをデジタル入力禁止にする(ADC入力(アナログ)専用となる)
	DIDR0 |= (1 << ADC0D) | (1 << ADC1D) | (1 << ADC2D) | (1 << ADC3D);	//PC0,PC1,PC2,PC3
	
	//ADC動作設定
	ADCSRA = 0b10000110		//bit2-0: 110 = 64分周	8MHz/64=125kHz (50k〜200kHzであること)
		| (1 << ADIE);		//割り込み許可(スリープ対応)
	
	//ADCの基準電圧(AVCC)と入力ピンを設定する
	ADMUX =	(1 << REFS0) | ADC_SET_PVOLTAGE;

	
	//A/D変換ノイズ低減のスリープモードを設定する
	set_sleep_mode(SLEEP_MODE_ADC);
	sei();			//割り込み許可
	sleep_mode();	//A/Dコンバータ初期化として初回変換開始…変換中…変換完了
	adcValue = ADC;	//値の読み捨て

	idx = 0;
	
    while(1)
    {
		//===== GND電圧を測定する ===================================================
		//
		ADMUX =	ADC_SET_GND;
		wait_ms(10);	//安定待ち
		sleep_mode();	//スリープモード突入…変換中…変換完了
		
		adcGNDs[idx] = ADC;
		adcValue = total(adcGNDs);
		gndValue = (float)adcValue / BUFSIZE;
		fv = gndValue * F_VCC * 1000 / 1024;	// mV単位
		
		//電圧を表示する
		mVoltage = (int16_t)fv;
		lcdPutVoltage(mVoltage, 1, 1);
		
        //===== 正電圧を測定する ===================================================
		//
		ADMUX =	ADC_SET_PVOLTAGE;
		wait_ms(10);	//安定待ち
		sleep_mode();	//スリープモード突入…変換中…変換完了
		
		adcPVoltages[idx] = ADC;
		adcValue = total(adcPVoltages);
			
		//A/D変換値から電圧を求める
		fv = (((float)adcValue / BUFSIZE) - gndValue) * F_VCC * 1000 / (1024 * F_POSITIVE_V_RATE); // mV単位
			
		//電圧を表示する
		mVoltage = (int16_t)fv;
		lcdPutVoltage(mVoltage, 0, 0);
					
		//===== 負電圧を測定する ===================================================
		//
		ADMUX =	ADC_SET_NVOLTAGE;
		wait_ms(10);	//安定待ち
		sleep_mode();	//スリープモード突入…変換中…変換完了
			
		adcNVoltages[idx] = ADC;
		adcValue = total(adcNVoltages);
			
		//A/D変換値から電圧を求める
		fv = (((float)adcValue / BUFSIZE) - gndValue) * F_VCC * 1000 / (1024 * F_NEGATIVE_V_RATE); // mV単位
					
		//電圧を表示する
		mVoltage = (int16_t)fv;
		lcdPutVoltage(mVoltage, 0, 1);
			
		//===== 電流を測定する ====================================================
		//
		ADMUX =	ADC_SET_CURRENT;
		wait_ms(10);	//安定待ち
		sleep_mode();	//スリープモード突入…変換中…変換完了
			
		adcCurrents[idx] = ADC;
		adcValue = total(adcCurrents);

		// ADCの読み取り値が1000以上の場合測定不可とする
		if ((float)adcValue / BUFSIZE < 1000) {
	
			//A/D変換値から電圧を求め、電流を算出する
			fv = (((float)adcValue / BUFSIZE) - gndValue) * F_VCC * 1000 / (1024 * F_CURRENT_AMP); // mV単位
			fa = fv / F_SHUNT_R;	//mA単位
				
			//電流を表示する
			mCurrent = (int16_t)(fa * 10.0);	//0.1mA単位
			lcdPutCurrent(mCurrent, 1, 0);
		}
		else {		
			lcdLineClear(1, 0);
			lcdSetPos(8, 0);
			lcdPutStr("  OVER");
		}
		
		//次のループの準備
		if (++idx == BUFSIZE) idx = 0;
    }
	
	return 0;
}
Example #3
0
int main(void) {
   int seq[SEQMAX];
   word adc1val, sinceTriggered;
   int dumax = 0;
   byte q = 0;
   boolean listening = false;
   
   
   init();
   
   sei();
   music(0);
   
   for (;;){
	
	adc1val = 0;
	//
	set_sleep_mode(0);
	sleep_mode();
	
	if ( ! bitRead(ADCSRA, ADSC) ) // adc completed.
	{
	   adc1val = ADCL + (ADCH<<8);
	   if ( adc1val > 10 ) {
		sinceTriggered = t0compa_cnt;
	   }
	}
	
	if ( adc1val > 10 && (sinceTriggered > 48)) {
	   if ( listening ) {
		seq[q++] = t0compa_cnt;
		seq[q] = 0;
		dumax = max(dumax, t0compa_cnt);
		t0compa_cnt = 0;
	   } else {
		listening = true;
		q = 0;
		seq[q] = 0;
		dumax = 0;
		t0compa_cnt = 0;
	   }
	}
	
	if (listening ) {
	   if (q >= SEQMAX) {
		listening = false;
	   } else 
		if ( (dumax != 0) && (t0compa_cnt > dumax*4) ) {
		   listening = false;
		} else 
		   if ( t0compa_cnt > 400 ) {
			listening = false;
		   }
	}
	
	if ( (!listening) && q > 0 ) {
	   analyzeSeq(seq);
	   q = 0;
	} else {
	   bitClear(PORTB, PB3);
	}
   }
   return 0;               /* never reached */
}
Example #4
0
int main(void)
{
    // All ports default to input, but turn pull-up resistors on for the stars
    // (not the ADC input!  Made that mistake already)
    // (stars not used)
    //PORTB = (1 << STAR2_PIN) | (1 << STAR3_PIN) | (1 << STAR4_PIN);

    // Set PWM pin to output
    DDRB = (1 << PWM_PIN);

    // Turn features on or off as needed
    #ifdef VOLTAGE_MON
    ADC_on();
    #else
    ADC_off();
    #endif
    ACSR   |=  (1<<7); //AC off

    // Enable sleep mode set to Idle that will be triggered by the sleep_mode() command.
    // Will allow us to go idle between WDT interrupts (which we're not using anyway)
    set_sleep_mode(SLEEP_MODE_IDLE);

    // Determine what mode we should fire up
    // Read the last mode that was saved
    if (noinit_decay) // not short press, forget mode
    {
        noinit_mode = 0;
        mode_idx = 0;
    } else { // short press, advance to next mode
        mode_idx = noinit_mode;
        next_mode();
        noinit_mode = mode_idx;
    }
    // set noinit data for next boot
    noinit_decay = 0;

    // set PWM mode
    if (modes[mode_idx] < FAST_PWM_START) {
        // Set timer to do PWM for correct output pin and set prescaler timing
        TCCR0A = 0x21; // phase corrected PWM is 0x21 for PB1, fast-PWM is 0x23
    } else {
        // Set timer to do PWM for correct output pin and set prescaler timing
        TCCR0A = 0x23; // phase corrected PWM is 0x21 for PB1, fast-PWM is 0x23
    }
    TCCR0B = 0x01; // pre-scaler for timer (1 => 1, 2 => 8, 3 => 64...)

    // Now just fire up the mode
    PWM_LVL = modes[mode_idx];

    uint8_t i = 0;
    uint8_t j = 0;
    uint8_t strobe_len = 0;
#ifdef VOLTAGE_MON
    uint8_t lowbatt_cnt = 0;
    uint8_t voltage;
#endif
    while(1) {
        if(mode_idx < SOLID_MODES) { // Just stay on at a given brightness
            sleep_mode();
        } else if (mode_idx < BATT_CHECK_MODE) {
            PWM_LVL = 0;
            get_voltage();  _delay_ms(200);  // the first reading is junk
#ifdef BATTCHECK_VpT
            uint8_t result = battcheck();
            blink(result >> 5, BLINK_SPEED/8);
            _delay_ms(BLINK_SPEED);
            blink(1,5);
            _delay_ms(BLINK_SPEED*3/2);
            blink(result & 0b00011111, BLINK_SPEED/8);
#else
            blink(battcheck());
#endif  // BATTCHECK_VpT
            _delay_ms(2000);  // wait at least 2 seconds between readouts
        } else if (mode_idx < SINGLE_BEACON_MODES) { // heartbeat flasher
Example #5
0
/* deepSleep(time2wake, offset, mode) - sets the microcontroller to the lowest consumption sleep mode
 *
 * It sets the microcontroller to the lowest consumption sleep mode. It enables RTC interruption to be able to
 * wake up the microcontroller when the RTC alarm is launched.
 *
 * 'time2wake' --> it specifies the time at which the RTC alarm will activate. It must follow the next format:
 *	"DD:HH:MM:SS"
 * 'offset' --> it specifies if 'time2wake' is added to the actual time or if this time is set as the alarm
 * 'mode' --> it specifies the mode for RTC alarm
 *
 * It uses Alarm1 on the RTC due to this Alarm has more precision than Alarm2
 * 
 * It switches off all the switches on the Waspmote board.
 *
 * It returns nothing.
 */
void WaspPWR::deepSleep(	const char* time2wake, 
							uint8_t offset, 
							uint8_t mode, 
							uint8_t option	)
{	
	uint8_t retries=0;
	
	// Switch off both multiplexers in UART_0 and UART_1
	Utils.muxOFF();
	
	// set the XBee monitorization pin to zero
	pinMode(XBEE_MON,OUTPUT);
	digitalWrite(XBEE_MON,LOW);
	
	// switches off depending on the option selected  
	switchesOFF(option);
	
	// mandatory delay to wait for MUX_RX stabilization 
	// after switching off the sensor boards 
	delay(100);	
	
	// make sure interruption pin is LOW before entering a low power state
	// if not the interruption will never come
	while(digitalRead(MUX_RX)==HIGH)
	{	
		// clear all detected interruption signals
		delay(1);
		PWR.clearInterruptionPin();
		retries++;
		if(retries>10)
		{
			return (void)0;
		}
	}
	
	// RTC ON
	RTC.ON();
	// set Alarm
	RTC.setAlarm1(time2wake,offset,mode); 
	// get backup of selected Alarm	
	uint8_t day_aux = RTC.day_alarm1; 
	uint8_t hour_aux = RTC.hour_alarm1; 
	uint8_t minute_aux = RTC.minute_alarm1; 
	uint8_t second_aux = RTC.second_alarm1; 
	// get Alarm
	RTC.getAlarm1();
	// check Alarm was correctly set	
	if(	( day_aux != RTC.day_alarm1 ) 
	||	( hour_aux != RTC.hour_alarm1 )
	||	( minute_aux != RTC.minute_alarm1 )
	||	( second_aux != RTC.second_alarm1 ) )
	{
		RTC.disableAlarm1();
		RTC.OFF();
		return (void)0;
	}
    RTC.OFF();	
	
	// set sleep mode
	set_sleep_mode(SLEEP_MODE_PWR_DOWN);
	sleep_enable();
	sleep_mode();
	sleep_disable();
		
	// in the case SENS_OFF was an option is mandatory to turn on the
	// sensor boards before setting up the I2C bus
	switchesON(option);
	
	// Switch on the RTC and clear the alarm signals	
	// Disable RTC interruption after waking up 
	RTC.ON();
	RTC.disableAlarm1();
	RTC.clearAlarmFlag();
	RTC.OFF();
	
	// Keep sensor supply powered down if selected
	if( option & SENS_OFF )
	{
		pinMode(SENS_PW_3V3,OUTPUT);
		digitalWrite(SENS_PW_3V3,LOW);	
		pinMode(SENS_PW_5V,OUTPUT);
		digitalWrite(SENS_PW_5V,LOW);
	}
}
void enterSleepMode() {
	set_sleep_mode(SLEEP_MODE_IDLE);
	sleep_mode()
	;
}
Example #7
0
void sleep_if_no_traffic(void)
{
	if (serial_available()) return;
	sleep_mode();
}
Example #8
0
File: lma.c Project: shimniok/lma
int main()
{
	cli();
	disableWatchdog();

	slowClock();
	initBuzzer();
	initSwitch();
	initADC();
	
#ifdef DEBUG
	uint16_t v = getVoltage();
	uint16_t i;

	for (i = 0x8000; i != 0; i >>= 1) {
		if (v & i) {
			dit();
		} else {
			dah();
		}
		_delay_ms(1000);
	}
#endif
	
	// Retrieve the current warning timeout from eeprom
	uint8_t warn_min = eeprom_read_byte(&cfg_warn_min);
	if (switchPressed()) {
		number(warn_min);
		// pause between increments
		_delay_ms(3000);
	}

	// If switch is depressed (at power up), begin increasing
	// warning time, in 5-minute increments, max 30 minutes
	// SOS time is 2 x warning time.
	//
	while (switchPressed()) {	
	
		if (switchPressed()) {
			// Increment warning time by 5 minutes
			warn_min += 5;

			// Maximum warning time is 30 minutes
			if (warn_min > 30) warn_min = 5;

			// Save the new warning time
			eeprom_update_byte(&cfg_warn_min, warn_min);
		}
		number(warn_min);

		// pause between increments
		_delay_ms(3000);		
	}

	// Compute the number of seconds for warning and SOS
	warn_sec = warn_min * 60;
	sos_sec = warn_sec * 2;

	if (checkVoltage()) {
		ok();
	} else {
		sos();
	}

	enableWatchdog();
 	sei();

	while (1) {
		set_sleep_mode(SLEEP_MODE_PWR_DOWN);
		sleep_mode();
	}
}
Example #9
0
// Add a new linear movement to the buffer. x, y and z is the signed, absolute target position in 
// millimaters. Feed rate specifies the speed of the motion. If feed rate is inverted, the feed
// rate is taken to mean "frequency" and would complete the operation in 1/feed_rate minutes.
//void plan_buffer_line(double x, double y, double z, double feed_rate, uint8_t invert_feed_rate)
void plan_buffer_line (tActionRequest *pAction)
{
  double x;
  double y;
  double z;
  double feed_rate;
  uint8_t invert_feed_rate;
  bool e_only = false;
  double speed_x, speed_y, speed_z, speed_e; // Nominal mm/minute for each axis

  
  x = pAction->target.x;
  y = pAction->target.y;
  z = pAction->target.z;
  feed_rate = pAction->target.feed_rate;
  invert_feed_rate = pAction->target.invert_feed_rate;
  
  // Calculate target position in absolute steps
  int32_t target[NUM_AXES];
  target[X_AXIS] = lround(x*(double)config.steps_per_mm_x);
  target[Y_AXIS] = lround(y*(double)config.steps_per_mm_y);
  target[Z_AXIS] = lround(z*(double)config.steps_per_mm_z);     
  target[E_AXIS] = lround(pAction->target.e*(double)config.steps_per_mm_e);     
  
  // Calculate the buffer head after we push this byte
  int next_buffer_head = next_block_index( block_buffer_head );	
  
  // If the buffer is full: good! That means we are well ahead of the robot. 
  // Rest here until there is room in the buffer.
  while(block_buffer_tail == next_buffer_head) { sleep_mode(); }
  
  // Prepare to set up new block
  block_t *block = &block_buffer[block_buffer_head];

  block->action_type = AT_MOVE;
  
  // Compute direction bits for this block
  block->direction_bits = 0;
  if (target[X_AXIS] < position[X_AXIS]) { block->direction_bits |= X_DIR_BIT; }
  if (target[Y_AXIS] < position[Y_AXIS]) { block->direction_bits |= Y_DIR_BIT; }
  if (target[Z_AXIS] < position[Z_AXIS]) { block->direction_bits |= Z_DIR_BIT; }
  if (target[E_AXIS] < position[E_AXIS]) { block->direction_bits |= E_DIR_BIT; }
  
  // Number of steps for each axis
  block->steps_x = labs(target[X_AXIS]-position[X_AXIS]);
  block->steps_y = labs(target[Y_AXIS]-position[Y_AXIS]);
  block->steps_z = labs(target[Z_AXIS]-position[Z_AXIS]);
  block->steps_e = labs(target[E_AXIS]-position[E_AXIS]);
  block->step_event_count = max(block->steps_x, max(block->steps_y, block->steps_z));
  block->step_event_count = max(block->step_event_count, block->steps_e);

  // Bail if this is a zero-length block
  if (block->step_event_count == 0) { return; };
  
  // Compute path vector in terms of absolute step target and current positions
  double delta_mm[NUM_AXES];
  delta_mm[X_AXIS] = (target[X_AXIS]-position[X_AXIS])/(double)config.steps_per_mm_x;
  delta_mm[Y_AXIS] = (target[Y_AXIS]-position[Y_AXIS])/(double)config.steps_per_mm_y;
  delta_mm[Z_AXIS] = (target[Z_AXIS]-position[Z_AXIS])/(double)config.steps_per_mm_z;
  delta_mm[E_AXIS] = (target[E_AXIS]-position[E_AXIS])/(double)config.steps_per_mm_e;
  block->millimeters = sqrt(square(delta_mm[X_AXIS]) + square(delta_mm[Y_AXIS]) + 
                            square(delta_mm[Z_AXIS]));
  if (block->millimeters == 0)
  {
    e_only = true;
    block->millimeters = fabs(delta_mm[E_AXIS]);
  }
  double inverse_millimeters = 1.0/block->millimeters;  // Inverse millimeters to remove multiple divides	
  
//
// Speed limit code from Marlin firmware
//
//TODO: handle invert_feed_rate
  double microseconds;
  //if(feedrate<minimumfeedrate)
  //  feedrate=minimumfeedrate;
  microseconds = lround((block->millimeters/feed_rate*60.0)*1000000.0);

  // Calculate speed in mm/minute for each axis
  double multiplier = 60.0*1000000.0/(double)microseconds;
  speed_x = delta_mm[X_AXIS] * multiplier;
  speed_y = delta_mm[Y_AXIS] * multiplier;
  speed_z = delta_mm[Z_AXIS] * multiplier;
  speed_e = delta_mm[E_AXIS] * multiplier;

  // Limit speed per axis
  double speed_factor = 1; //factor <=1 do decrease speed
  if(fabs(speed_x) > config.maximum_feedrate_x) 
  {
    speed_factor = (double)config.maximum_feedrate_x / fabs(speed_x);
  }
  if(fabs(speed_y) > config.maximum_feedrate_y)
  {
    double tmp_speed_factor = (double)config.maximum_feedrate_y / fabs(speed_y);
    if(speed_factor > tmp_speed_factor) speed_factor = tmp_speed_factor;
  }
  if(fabs(speed_z) > config.maximum_feedrate_z)
  {
    double tmp_speed_factor = (double)config.maximum_feedrate_z / fabs(speed_z);
    if(speed_factor > tmp_speed_factor) speed_factor = tmp_speed_factor;
  }
  if(fabs(speed_e) > config.maximum_feedrate_e)
  {
    double tmp_speed_factor = (double)config.maximum_feedrate_e / fabs(speed_e);
    if(speed_factor > tmp_speed_factor) speed_factor = tmp_speed_factor;
  }

  multiplier = multiplier * speed_factor;
  speed_x = delta_mm[X_AXIS] * multiplier;
  speed_y = delta_mm[Y_AXIS] * multiplier;
  speed_z = delta_mm[Z_AXIS] * multiplier;
  speed_e = delta_mm[E_AXIS] * multiplier;
  block->nominal_speed = block->millimeters * multiplier;    // mm per min
  block->nominal_rate = ceil(block->step_event_count * multiplier);   // steps per minute

//---  
#if 0
  // Calculate speed in mm/minute for each axis. No divide by zero due to previous checks.
  // NOTE: Minimum stepper speed is limited by MINIMUM_STEPS_PER_MINUTE in stepper.c
  double inverse_minute;
  if (!invert_feed_rate) {
    inverse_minute = feed_rate * inverse_millimeters;
  } else {
    inverse_minute = 1.0 / feed_rate;
  }
  block->nominal_speed = block->millimeters * inverse_minute; // (mm/min) Always > 0
  block->nominal_rate = ceil(block->step_event_count * inverse_minute); // (step/min) Always > 0
#endif
  
#if 0
  double axis_speed;
  axis_speed = delta_mm[Z_AXIS] * inverse_minute;
  if (axis_speed > config.maximum_feedrate_z)
  {
    inverse_millimeters = 1.0 / delta_mm[Z_AXIS];
    inverse_minute = calc_inverse_minute (false, config.maximum_feedrate_z, inverse_millimeters);
    
    block->nominal_speed = delta_mm[Z_AXIS] * inverse_minute; // (mm/min) Always > 0
    block->nominal_rate = ceil(block->step_event_count * inverse_minute); // (step/min) Always > 0
  }
#endif
  
  // Compute the acceleration rate for the trapezoid generator. Depending on the slope of the line
  // average travel per step event changes. For a line along one axis the travel per step event
  // is equal to the travel/step in the particular axis. For a 45 degree line the steppers of both
  // axes might step for every step event. Travel per step event is then sqrt(travel_x^2+travel_y^2).
  // To generate trapezoids with contant acceleration between blocks the rate_delta must be computed 
  // specifically for each line to compensate for this phenomenon:
  // Convert universal acceleration for direction-dependent stepper rate change parameter
  block->rate_delta = ceil( block->step_event_count*inverse_millimeters *  
        config.acceleration*60.0 / ACCELERATION_TICKS_PER_SECOND ); // (step/min/acceleration_tick)

#if 0
  double rate_calc;
  if (delta_mm[Z_AXIS] > 0)
  {
    rate_calc = ceil( block->step_event_count / delta_mm[Z_AXIS] *  
          50*60.0 / ACCELERATION_TICKS_PER_SECOND ); // (step/min/acceleration_tick)
    
    if (rate_calc < block->rate_delta)
      block->rate_delta = rate_calc;
  }
#endif    
  // Perform planner-enabled calculations
  if (acceleration_manager_enabled /*&& !e_only*/ ) {  
  
    // Compute path unit vector                            
    double unit_vec[NUM_AXES];

    unit_vec[X_AXIS] = delta_mm[X_AXIS]*inverse_millimeters;
    unit_vec[Y_AXIS] = delta_mm[Y_AXIS]*inverse_millimeters;
    unit_vec[Z_AXIS] = delta_mm[Z_AXIS]*inverse_millimeters;  
  
    // Compute maximum allowable entry speed at junction by centripetal acceleration approximation.
    // Let a circle be tangent to both previous and current path line segments, where the junction 
    // deviation is defined as the distance from the junction to the closest edge of the circle, 
    // colinear with the circle center. The circular segment joining the two paths represents the 
    // path of centripetal acceleration. Solve for max velocity based on max acceleration about the
    // radius of the circle, defined indirectly by junction deviation. This may be also viewed as 
    // path width or max_jerk in the previous grbl version. This approach does not actually deviate 
    // from path, but used as a robust way to compute cornering speeds, as it takes into account the
    // nonlinearities of both the junction angle and junction velocity.
    double vmax_junction = MINIMUM_PLANNER_SPEED; // Set default max junction speed

    // Skip first block or when previous_nominal_speed is used as a flag for homing and offset cycles.
    if ((block_buffer_head != block_buffer_tail) && (previous_nominal_speed > 0.0)) {
      // Compute cosine of angle between previous and current path. (prev_unit_vec is negative)
      // NOTE: Max junction velocity is computed without sin() or acos() by trig half angle identity.
      double cos_theta = - previous_unit_vec[X_AXIS] * unit_vec[X_AXIS] 
                         - previous_unit_vec[Y_AXIS] * unit_vec[Y_AXIS] 
                         - previous_unit_vec[Z_AXIS] * unit_vec[Z_AXIS] ;
                           
      // Skip and use default max junction speed for 0 degree acute junction.
      if (cos_theta < 0.95) {
        vmax_junction = min(previous_nominal_speed,block->nominal_speed);
        // Skip and avoid divide by zero for straight junctions at 180 degrees. Limit to min() of nominal speeds.
        if (cos_theta > -0.95) {
          // Compute maximum junction velocity based on maximum acceleration and junction deviation
          double sin_theta_d2 = sqrt(0.5*(1.0-cos_theta)); // Trig half angle identity. Always positive.
          vmax_junction = min(vmax_junction,
            sqrt(config.acceleration*60*60 * config.junction_deviation * sin_theta_d2/(1.0-sin_theta_d2)) );
        }
      }
    }
    block->max_entry_speed = vmax_junction;
    
    // Initialize block entry speed. Compute based on deceleration to user-defined MINIMUM_PLANNER_SPEED.
    double v_allowable = max_allowable_speed(-config.acceleration,MINIMUM_PLANNER_SPEED,block->millimeters);
    block->entry_speed = min(vmax_junction, v_allowable);

    // Initialize planner efficiency flags
    // Set flag if block will always reach maximum junction speed regardless of entry/exit speeds.
    // If a block can de/ac-celerate from nominal speed to zero within the length of the block, then
    // the current block and next block junction speeds are guaranteed to always be at their maximum
    // junction speeds in deceleration and acceleration, respectively. This is due to how the current
    // block nominal speed limits both the current and next maximum junction speeds. Hence, in both
    // the reverse and forward planners, the corresponding block junction speed will always be at the
    // the maximum junction speed and may always be ignored for any speed reduction checks.
    if (block->nominal_speed <= v_allowable) { block->nominal_length_flag = true; }
    else { block->nominal_length_flag = false; }
    block->recalculate_flag = true; // Always calculate trapezoid for new block
  
    // Update previous path unit_vector and nominal speed
    memcpy(previous_unit_vec, unit_vec, sizeof(unit_vec)); // previous_unit_vec[] = unit_vec[]
    previous_nominal_speed = block->nominal_speed;

  } else {
    // Acceleration planner disabled. Set minimum that is required.
  //  block->entry_speed = block->nominal_speed;
    
    block->initial_rate = block->nominal_rate;
    block->final_rate = block->nominal_rate;
    block->accelerate_until = 0;
    block->decelerate_after = block->step_event_count;
    block->rate_delta = 0;
  }
  
  if (pAction->ActionType == AT_MOVE)
    block->check_endstops = false;
  else
    block->check_endstops = true;
  pAction->ActionType = AT_MOVE;
  
  // Move buffer head
  block_buffer_head = next_buffer_head;     
  // Update position
  memcpy(position, target, sizeof(target)); // position[] = target[]

  startpoint = pAction->target;
  
  if (acceleration_manager_enabled) { planner_recalculate(); }  
  st_wake_up();
}
Example #10
0
void sleep_if_no_traffic(void)
{
	if (zcl_receiver_has_data()) return;
	sleep_mode();
}
Example #11
0
/*this mode turns off everything not needed during the time in which only the main counter is running
 The only things needed during simple sleep are the operation of basic pins and the timer1 interrupt
 */
void Radian_power_saver::EnterSimpleSleep(unsigned int IdlePWM ){
    
  /*  
    
    //Disable ADC and internal Vref
    POWER_OFF;
    ADMUX &= ~( (1<<REFS1) | (1<<REFS0));
    ADCSRA &= ~( (1<<ADEN) );
    //Disable AnalogComparator
    ACSR |= (1<<ACD); 
    
    
    
    SMCR = 1; //go into idle mode
    sleep_mode();
    POWER_ON;
   
    set_sleep_mode(SLEEP_MODE_PWR_DOWN);  
    sleep_enable();
    interrupts();
 //   attachInterrupt(0,sleepHandler, FALLING);
    sleep_mode();  //sleep now
    //--------------- ZZZZZZ sleeping here
    sleep_disable(); //fully awake now
    POWER_ON; //turn the power back on
   
  */
    
    
    if(DEBUG) Serial.println("Entering simple Sleep Mode");
    if(IdlePWM == 0) SetIdlePins(PAN);
    else SetIdlePins(TILT);
//    power_all_disable(); //turn off all modules
    
    //turn necessary idle ports back on
    power_usart0_enable();
    power_timer1_enable();
 //   power_timer4_enable(); //leave PWM module on, should make something smarter for future
    
    set_sleep_mode(SLEEP_MODE_IDLE);  
    sleep_enable();
    //  interrupts();
    //  attachInterrupt(0,sleepHandler, FALLING);
    
    sleep_mode();  //sleep now
    //--------------- ZZZZZZ sleeping here
    sleep_disable(); //fully awake now
   // Serial.println("Woke up");
    POWER_ON;
    power_all_enable();
    if(IdlePWM == 0) WakeUpPins(PAN);
    else WakeUpPins(TILT);

    
    /*power_adc_enable();
    power_timer0_enable();
    power_usart1_enable();
    power_useart0_enable();
     
     */
    
}
Example #12
0
void sleep_after_exit() {
    cli();
    sleep_mode();
}
Example #13
0
int main(void)
{
    LCD_Initalize();
    LCD_GoTo(0, 0);                     // Set cursor to first char in first line
    LCD_WriteText("-= LCD READY =-");   // Display sample text

#ifdef HEART_BEAT
    SET_BIT(DDRB, PB0);
    SET_BIT(PORTB, PB0);
#endif

//    g_clock.handle_milisec = milisec_handler;
    g_clock.handle_second = second_handler;
    init_clock();
    init_keypad();
    sei();

    msg_t* msg = 0;
    int screen = DEFAULT_SCREEN;
    char screen_changed = 1;

    while(1) {
        while((msg = get_msg())) {
            switch(msg->type) {
            case MSG_INPUT:
                if (msg->size == BTN_0) {
                    if (screen == SETUP_TIME_SCREEN) {
                        set_clock(g_time_screen.hour, g_time_screen.minute);
                    }
                    ++screen;
                    screen %= SCREEN_COUNT;
                    screen_changed = 1;
                }
                break;

            default:
                break;
            }
            if (screen_changed) {
                clear_screen();
            }
            switch (screen) {
            case 0:
                show_default_screen(msg);
                break;

            case 1:
                show_setup_time_screen(screen_changed, msg);
                break;

            case -1:
                show_setup_diameter_screen();
                break;

            default:
            break;
            }
            screen_changed = 0;
            free_msg(&msg);
        }
        sleep_mode();
    }
    return 0;
}
Example #14
0
int main(void)
{
    { // Set up timers, sleep and such
        cli();
        set_sleep_mode(SLEEP_MODE_IDLE);
        PRR = ((1 << PRTIM1) | (1 << PRUSI) | (1 << PRADC));
        // TIMER0
        TCCR0A = (1 << WGM01);
        TCCR0B = ((1 << CS01) | (1 << CS00));
        OCR0A = 61;
        OCR0B = 0;
        TIMSK = (1 << OCIE0A);
        // INT0
        MCUCR |= (1 << ISC01);
        GIMSK = (1 << INT0);
        PORTB = PORTB_NULL;
        counter = leds = 0;
        counter_max = MAXIMUM;
        piezo = 0;
        stopped = 1;
        sei();
    }
    { // Set up the counter and start
        while (stopped < 3)
        {
            leds = counter_max;
            sleep_mode();
        }
        leds = LED_ON;
    }
    { // Prepare for the timer
        cli();
        GIMSK = 0; // Stop INT0
        stopped = 0;
        TCNT0 = 0; // Clear TIMER0
        sei();
    }
    { // Display the timer while it's running
        while (counter < counter_max)
        {
            leds = counter | LED_ON;
            sleep_mode();
        }
        stopped = 4;
        leds = counter;
    }
    { // Yell!
        cli();
        GIMSK = (1 << INT0); // Start INT0
        sei();
        while (stopped == 4) // Sleep!
            sleep_mode();
        GIMSK = 0; // Stop INT0
        TCCR0A &= ~((1 << COM0B1) | (1 << COM0B0)); // Stop yelling!
    }
    { // Timer finished, sleep forever!
        cli();
        TIMSK = 0;
        PORTB = 0; // Everything off
        set_sleep_mode(SLEEP_MODE_PWR_DOWN);
        sleep_mode();
    }
    return 0;
}
int main(void)
{	
	// All ports default to input, but turn pull-up resistors on for the stars (not the ADC input!  Made that mistake already)
	PORTB = (1 << STAR2_PIN) | (1 << STAR3_PIN) | (1 << STAR4_PIN);
	
    // Set PWM pin to output
    DDRB = (1 << PWM_PIN);

    // Set timer to do PWM for correct output pin and set prescaler timing
    TCCR0A = 0x23; // phase corrected PWM is 0x21 for PB1, fast-PWM is 0x23
    TCCR0B = 0x01; // pre-scaler for timer (1 => 1, 2 => 8, 3 => 64...)
	
	// Turn features on or off as needed
	#ifdef ENABLE_VOLTAGE_MONITORING
	ADC_on();
	#else
	ADC_off();
	#endif
	ACSR   |=  (1<<7); //AC off
	
#ifdef ENABLE_TURNING_OFF_MEMORY
	// Soldering Star 4 disables memory
#ifdef MEMORY_ON_BY_DEFAULT
	memory_enabled = ((PINB & (1 << STAR4_PIN)) > 0) ? 1 : 0;
#else
	memory_enabled = ((PINB & (1 << STAR4_PIN)) == 0) ? 1 : 0;
#endif
#endif

#ifdef ENABLE_TURNING_OFF_TURBO_TIMER
	turbo_timer_enabled = ((PINB & (1 << STAR2_PIN)) > 0) ? 1 : 0;
#endif

#ifdef ENABLE_SINGLE_MODE
	if((PINB & (1 << STAR2_PIN)) == 0)
	{
			modes[0] = modes[1] = 
#ifdef FOUR_MODES
			modes[2] = 
#endif
			MODE_TURBO;

			// Last basic mode is already MODE_TURBO - no need to waste bytes changing that
	}		
#endif

#ifdef ENABLE_TACTICAL_MODE
#ifdef TACTICAL_MODE_ON_BY_DEFAULT
	if((PINB & (1 << STAR2_PIN)) > 0)
#else
	if((PINB & (1 << STAR2_PIN)) == 0)
#endif
	{
#ifdef ENABLE_TURNING_OFF_MEMORY
		if(memory_enabled) // Single mode
		{
			modes[0] = modes[1] = 
#ifdef FOUR_MODES
			modes[2] = 
#endif
			MODE_TURBO;

			// Last basic mode is already MODE_TURBO - no need to waste bytes changing that
		}
		else
#endif
		{
			modes[0] = MODE_STROBE;
			modes[1] = MODE_TURBO;
			modes[2] = MODE_LOW;
#ifdef FOUR_MODES
			modes[3] = MODE_LOWLOW;
#endif
			wdt_timeout = 1;
		}
	}
#endif


#ifdef ENABLE_HIGH_TO_LOW
#ifdef HIGH_TO_LOW_ON_BY_DEFAULT
	if((PINB & (1 << STAR3_PIN)) > 0)
#else
	if((PINB & (1 << STAR3_PIN)) == 0)
#endif
		revert_modes();
#endif
	
	// Enable sleep mode set to Idle that will be triggered by the sleep_mode() command.
	// Will allow us to go idle between WDT interrupts
	set_sleep_mode(SLEEP_MODE_IDLE);
	
	// Mode memory handling block
	{
		uint8_t short_clicks = 0;

		// Determine what mode we should fire up
		// Read the last mode that was saved
		mode_idx = read_stored_idx();

		// Handle short press indicator
		short_clicks = (mode_idx & 0xf0);
		mode_idx &= 0x0f;
		
		if(short_clicks) // One or more short clicks
		{
			// Indicates we did a short press last time, go to the next mode
			next_mode(short_clicks); // Will handle wrap arounds
		} 
		// else: Didn't have a short press, keep the same mode, nothing to do
	
		// Store mode with short press indicator
		store_mode_idx(mode_idx | ((short_clicks < HIDDEN_MODE_THRESHOLD) ? short_clicks+0x10 : short_clicks));
	}		
	
	// Start watchdog timer (used for storing the mode after delay, turbo timer, and voltage monitoring)
	WDT_on();
	
	// Now just fire up the mode
	selected_pwm = modes[mode_idx]; // Note: Actual PWM can be less than selected PWM (e.g. in case of low voltage)
	
	if(selected_pwm < PWM_MIN) // Hidden blinky modes
		adjusted_pwm = PWM_MAX; // All blinky modes initially with full power
	else
		adjusted_pwm = selected_pwm;

	// block for main loop
	{
		uint8_t ii = 0; // Loop counter, used by multiple branches
#ifdef ENABLE_BEACONS
		uint8_t beacon_background = PWM_OFF;
#endif
	
		while(1)
		{
#ifdef ENABLE_VOLTAGE_MONITORING
			if(adjusted_pwm == PWM_OFF) // Voltage monitoring signaled us to turn off the light -> break out of the main loop
				break;
#endif

			PWM_LVL = adjusted_pwm; // must be set inside loop, is volatile & might have changed because of voltage monitoring

			switch(selected_pwm)
			{
			case MODE_STROBE: // Disorienting alternating strobe
#ifdef NORMAL_STROBE
				_delay_ms(20);
				PWM_LVL = 0;
				_delay_ms(40);
#endif
#ifdef ALTERNATING_STROBE
				_delay_ms(20);
				PWM_LVL = 0;
				if(ii < 22) // 60ms = ~16.7Hz, ~33% DC
					_delay_ms(40);
				else if(ii < 36) // 111ms = ~9Hz, ~18% DC
					_delay_ms(90);
				else
					ii = 255;
#endif
#ifdef RANDOM_STROBE 
				{   // 77ms = 13Hz, 51ms = 19.5Hz / 40-60% DC
					ii = (5 * ii) + 128;
					_delay_ms(31);
					PWM_LVL = 0;
					_delay_ms(ii > 127 ? 46 : 20);
				}					
#endif
				break;
			case MODE_MOTION_STOPPING_STROBE: // 10Hz, 2% DC
				_delay_ms(2);
				PWM_LVL = 0;
				_delay_ms(98);
				break;
#ifdef ENABLE_SOS
			case MODE_SOS:
				if(ii / 3 == 1)
					_delay_ms(600);  // Dash for 'O' (3xDot)
				else
					_delay_ms(200);  // Dot for 'S'

				PWM_LVL = 0;

				switch(ii)
				{
				default:
					_delay_ms(200);  // Pause inside a letter (1xDot)
					break;
				case 2:
				case 5:
					_delay_ms(600); // Pause between letters (3xDot)
					break;
				case 8:
					_delay_ms(2500); // Pause between "words" (should be 7xDot, but I like it longer)
					ii = 255;
					break;
				}
				break;
#endif
#ifdef ENABLE_BEACONS
			case MODE_BEACON_WITH_BACKGROUND:
			case MODE_SLOW_BEACON_WITH_BACKGROUND:
#ifdef FOUR_MODES
				beacon_background = PWM_SLOW_BEACON_BACKGROUND;
#else
				switch(selected_pwm)
				{
				case MODE_BEACON_WITH_BACKGROUND:
					beacon_background = PWM_BEACON_BACKGROUND;
					break;
				case MODE_SLOW_BEACON_WITH_BACKGROUND:
					beacon_background = PWM_SLOW_BEACON_BACKGROUND;
					break;
				}
#endif
				// no break - fall through to beacon code
			case MODE_BEACON:
			case MODE_ALPINE_DISTRESS_BEACON:
				_delay_ms(50);
				PWM_LVL = beacon_background;

				_delay_ms(950);
				if(selected_pwm == MODE_ALPINE_DISTRESS_BEACON)
				{
					if(ii > 5)
					{
						_delay_ms(59000);
						ii = 255;
					}
					else
						_delay_ms(9000);
				}
				else if(selected_pwm == MODE_SLOW_BEACON_WITH_BACKGROUND)
					_delay_ms(1500);
#endif
				break;
			default:
				sleep_mode();
				break;
			}

			ii++; // Loop counter, used by multiple branches
		}
	}

#ifdef ENABLE_VOLTAGE_MONITORING
	//
	// Critically low voltage -> Turn off the light
	// 
		
	// Disable WDT so it doesn't wake us up from sleep
	WDT_off();

	// Would be nice to blink a couple of times with lowest brightness to notify the user, but not implemented due space restrictions

	// Turn the light off
	PWM_LVL = 0;

	// Disable ADC so it doesn't consume power
	ADC_off();

	// Power down as many components as possible
	set_sleep_mode(SLEEP_MODE_PWR_DOWN);

	// Deep sleep until powered off - consumes ~110uA during the deep sleep
	while(1)
		sleep_mode();
#endif

    return 0; // Standard Return Code -> would return to idle loop with interrupts disabled.
}
Example #16
0
int main(void)
{
	SetSystemClockPrescaler(0);
	init();
	sei();

	led_blink(3);

     while (1)
     {
    	if(SW_ACTIVE())
    	{
    		// SW pressed
    		uint8_t pressCnt = 100;

    		// wait until released
    		do
    		{
				// long term press detected?
    			if(pressCnt>0 && --pressCnt==0)
    				LED_ON();

    			_delay_ms(10);
    		} while(SW_ACTIVE());


    		// SW released
    		LED_OFF();
    		if(pressCnt>0)
    			handleSensor(1); // force transmit
    		else
    		{
    			// program mode
        		LED_ON();
        		fs20_resetbuffer();
        		fs20_rxon();
        		fstelegram_t t;
        		t.type = 'U'; // undefined
        		pressCnt = 100;

        		// wait for next telegram
        		// exit if button pressed or timeout occured
        		while(!fs20_readFS20Telegram(&t) && --pressCnt>0 && !SW_ACTIVE())
        			_delay_ms(100);

        		fs20_idle();
        		LED_OFF();

        		// save the result
        		if(t.type=='F')
        		{
        			saveConfig(t.housecode, t.button);
        			led_blink(2); // confirm save of config
        			handleSensor(1); // force transmit
        		}

        		// wait until sw releases
        		while(SW_ACTIVE());
    		}
    	}

		// check long term timer
		if(longTimerCnt >= LONGTIMER_VAL)
			handleSensor(1);

		// finaly check if sensor value changed
		// this will only be the case if the current sensor value haven't been sent
		// during this cycle
		handleSensor(0);

		// sleep well
		LED_OFF();
		SENS_ACTIVATE(0);
		set_sleep_mode(SLEEP_MODE_PWR_DOWN);
		sleep_mode();
     }
}
Example #17
0
 void powerdown_avr(){
   set_sleep_mode(SLEEP_MODE_PWR_DOWN  ); // sleep mode is set here
   sleep_enable();
   sleep_mode();                        // System sleeps here
 }
Example #18
0
// **************** main() ***********************************************
int main(void) {

	DDRD  |= (1<<PD5)|(1<<PD4)|(1<<PD0)|(1<<PD1);			// ustaw piny PWM1 (OC1A) oraz PWM2 (OC1B) jako wyjœcia WA¯NE !!!
	
	DDRB |= (1<<PB0);				// wyjœcie do sterowania zasilaniem karty SD
	PORTB = 0b00000001;					// podci¹gniêcie PORTB do VCC ??
	
	set_sleep_mode(SLEEP_MODE_PWR_DOWN);  //Wybranie trybu uœpienia mikrokontrolera
	
	
	// init SPI
	DDRB |= (1<<CS)|(1<<MOSI)|(1<<SCK)|(1<<CS);
	PORTB |= (1<<CS);
	SPCR |= (1<<SPE)|(1<<MSTR);		
	SPSR |= (1<<SPI2X);				// masymalny zegar SCK

	// konfiguracja PWM (Timer1)
	TCCR1A = (1<<WGM10)|(1<<COM1A1)|(0<<COM1A0)|(1<<COM1B1);//|(1<<COM1B0);
	TCCR1B = (1<<CS10);

	// konfiguracja Timer0 (samplowanie)
	TCCR0 = (1<<WGM01);		// tryb CTC
	TIMSK = (1<<OCIE0);		// zezwolenie na przerwanie CompareMatch

	sei();		// globalne zezwolenie na przerwania
	
	OCR0 = (uint8_t)44;						//bo F_CPU/8/samplerate	
	
	
	// **************** akcelerometr **********************************
	
	ADCSRA |= 1<<ADPS2 | 1<<ADPS1 | 1<<ADPS0;	//ustawienie preskalera
	ADMUX |= 1<<REFS0 | 1<<REFS1;				//ustawienie napiêcia referencyjnego
	ADCSRA |= 1<<ADIE;							//w³¹czenie przerwania
	ADCSRA |= 1<<ADEN;							//w³¹czenie modu³u konwersji
	
	// **************** pêtla g³ówna **********************************
	while(1) {
		
		if (pf_mount(&Fs)) continue;		//inicjalizacja FS

		for (;;) {

		if (pf_opendir(&Dir, "")) break;	//otwarcie g³ównego folderu karty
			
		if (startup==1)						//odtworzenie dŸwiêku w³¹czania 
		{
			if (play("startup.wav")) break;
			startup=0;
			PORTD |= (1<<PIND0);
		}
		
	// ********************* zdarzenie SWING  ****************
		if (hitpriority==1)				
		{
			swingnumber=swing[swingcounter];
			if (swingnumber==1)
			{
				play("swing.wav");
			}
			if (swingnumber==2)
			{
				play("swing.wav");
			}
			if (swingnumber==3)
			{
				play("swing.wav");
			}
			hitpriority=0;
			breakdisablehigh=0;
			breakdisablelow=0;
			swingcounter++;
			if (swingcounter==9)
			{
				swingcounter=0;
			}
		}
		
	// ******************** zdarzenie HIT ***********
		if (hitpriority==2)	
		{
			hitnumber=hit[hitcounter];
			PORTD |= (1<<PIND1);				//W³¹czenie dodatkowej diody
			ledoff=1;
			if (hitnumber==1)
			{
				play("clash.wav");
			}
			if (hitnumber==2)
			{
				play("clash.wav");
			}
			if (hitnumber==3)
			{
				play("clash.wav");
			}
			hitpriority=0;
			breakdisablehigh=0;	
			hitcounter++;
			if (hitcounter==9)
			{
				hitcounter=0;
			}
		}
		
	// ********************** sekwencja POWER DOWN  ******************	
		if (shutdown==1)
		{
			play("startup.wav");
			GENERAL_MAJOR_SHUTDOWN_PROCEDURE;
			sleep_mode();
		}
		
	// ********************** tryb ja³owy  ******************	
		else
		{
			if (play("hum.wav")) break;	
		}
		}

	}
}
Example #19
0
int st_buffer_block(int32_t steps_x, int32_t steps_y, int32_t steps_z,
					int32_t pos_x,   int32_t pos_y,   int32_t pos_z,
					uint32_t microseconds, 
					int16_t line_number) {
  uint8_t 		direction_bits = 0;
  uint8_t 		changed_dir;
  struct Block 	*block;
  struct Block 	*comp_block=NULL;
  uint32_t		maximum_steps;
  
  maximum_steps = max(labs(steps_x), max(labs(steps_y), labs(steps_z)));
  // Don't process empty blocks 
  if (maximum_steps==0) {return 0;}
  
  // Determine direction bits					
  if (steps_x < 0) { direction_bits |= (1<<X_DIRECTION_BIT); }
  if (steps_y < 0) { direction_bits |= (1<<Y_DIRECTION_BIT); }
  if (steps_z < 0) { direction_bits |= (1<<Z_DIRECTION_BIT); }
	
  while (st_buffer_full()) { sleep_mode();}  // makes sure there are two
                                             // slots left on buffer
                                            
  // If direction has changed, then put a backlash instruction				
  // on the queue:
  if (direction_bits!=old_direction_bits){
  	comp_block = &block_buffer[block_buffer_head];

	comp_block->backlash = 1;
  	comp_block->direction_bits = direction_bits;
  	comp_block->line_number = line_number;
	
    comp_block->steps_x = 0;
    comp_block->steps_y = 0;
    comp_block->steps_z = 0;  
    
    comp_block->pos_x = pos_x;
    comp_block->pos_y = pos_y;
    comp_block->pos_z = pos_z;  

	changed_dir = direction_bits^old_direction_bits;

  	old_direction_bits = direction_bits;

	if (changed_dir & (1<<X_DIRECTION_BIT)) comp_block->steps_x=settings.backlash_x_count;
	if (changed_dir & (1<<Y_DIRECTION_BIT)) comp_block->steps_y=settings.backlash_y_count;
	if (changed_dir & (1<<Z_DIRECTION_BIT)) comp_block->steps_z=settings.backlash_z_count;
	  
	// Use same rate for backlash compensation as for the block itself:
  	comp_block->rate = microseconds/maximum_steps;
  	comp_block->mode = SM_RUN;

  	comp_block->maximum_steps = max(comp_block->steps_x, max(comp_block->steps_y, comp_block->steps_z));
  // If compensation is not empty, advance the end of the queue 
  	if (comp_block->maximum_steps > 0) {
	  	block_buffer_head = (block_buffer_head + 1) % BLOCK_BUFFER_SIZE;
	}
  }

  // Setup block record
  block = &block_buffer[block_buffer_head];
  block->backlash=0;
  block->line_number = line_number;
  
  block->steps_x = labs(steps_x);
  block->steps_y = labs(steps_y);
  block->steps_z = labs(steps_z);  
    
  block->pos_x = pos_x;
  block->pos_y = pos_y;
  block->pos_z = pos_z;  
  
  block->maximum_steps = maximum_steps;

  block->rate = microseconds/block->maximum_steps;
  block->mode = SM_RUN;
  // Compute direction bits for this block
  block->direction_bits = direction_bits;
  
  // Move buffer head
  block_buffer_head = (block_buffer_head + 1) % BLOCK_BUFFER_SIZE;	//next_buffer_head;
  
  // Ensure that blocks will be processed by enabling The Stepper Driver Interrupt
  ENABLE_STEPPER_DRIVER_INTERRUPT();
    return 1;
}
Example #20
0
void ALWBase::idle() {
  set_sleep_mode(SLEEP_MODE_IDLE);
  sleep_mode();
}
Example #21
0
/* deepSleep(time2wake, offset, mode) - sets the microcontroller to the lowest consumption sleep mode
 *
 * It sets the microcontroller to the lowest consumption sleep mode. It enables RTC interruption to be able to
 * wake up the microcontroller when the RTC alarm is launched.
 *
 * 'time2wake' --> it specifies the time at which the RTC alarm will activate. It must follow the next format:
 *	"DD:HH:MM:SS"
 * 'offset' --> it specifies if 'time2wake' is added to the actual time or if this time is set as the alarm
 * 'mode' --> it specifies the mode for RTC alarm
 *
 * It uses Alarm1 on the RTC due to this Alarm has more precision than Alarm2
 * 
 * It switches off all the switches on the MakeSuremote board.
 *
 * It returns nothing.
 */
void MakeSurePWR::deepSleep(	const char* time2wake, 
							uint8_t offset, 
							uint8_t mode, 
							uint8_t option	)
{	
	uint8_t retries=0;
		
	// set the monitorization pin to zero
	pinMode(XBEE_MON,INPUT);
	digitalWrite(XBEE_MON,LOW);
	
	// Switch off both multiplexers in UART_0 and UART_1 when 
	// no interruption is expected through the UART1
   	if( !(option & UART1_OFF) )
	{	
		// keep multiplexer on
	}
	else
	{
		Utils.muxOFF();
	}
	delay(100);
	
	// Set RTC alarm to wake up from Sleep Power Down Mode
	RTC.ON();
	RTC.setAlarm1(time2wake,offset,mode);
	RTC.close();  
    RTC.OFF();
	
    pinMode(I2C_SDA,OUTPUT);
	digitalWrite(I2C_SDA,LOW);
	pinMode(I2C_SCL,OUTPUT);
	digitalWrite(I2C_SCL,LOW);    
	
	switchesOFF(option);
	
	// make sure interruption pin is LOW before entering a low power state
	// if not the interruption will never come
	while(digitalRead(MUX_RX)==HIGH)
	{
		// clear all detected interruption signals
		delay(1);
		PWR.clearInt();
		retries++;
		if(retries>10)
		{
			return (void)0;
		}
	}
	set_sleep_mode(SLEEP_MODE_PWR_DOWN);
	sleep_enable();
	sleep_mode();
	sleep_disable();
	
	switchesON(option);
	RTC.ON();
	RTC.clearAlarmFlag();
	if( option & RTC_OFF ) RTC.OFF();
	if( option & SENS_OFF )
	{
		pinMode(SENS_PW_3V3,OUTPUT);
		digitalWrite(SENS_PW_3V3,LOW);	
		pinMode(SENS_PW_5V,OUTPUT);
		digitalWrite(SENS_PW_5V,LOW);
	}
}
Example #22
0
// Add a new linear movement to the buffer. steps_x, _y and _z is the absolute position in 
// mm. Microseconds specify how many microseconds the move should take to perform. To aid acceleration
// calculation the caller must also provide the physical length of the line in millimeters.
void plan_buffer_line(double x, double y, double z, double feed_rate, int invert_feed_rate) {
  // The target position of the tool in absolute steps
  
  // Calculate target position in absolute steps
  int32_t target[3];
  target[X_AXIS] = lround(x*settings.steps_per_mm[X_AXIS]);
  target[Y_AXIS] = lround(y*settings.steps_per_mm[Y_AXIS]);
  target[Z_AXIS] = lround(z*settings.steps_per_mm[Z_AXIS]);     
  
  // Calculate the buffer head after we push this byte
	uint8_t next_buffer_head = (block_buffer_head + 1);
	next_buffer_head = next_buffer_head % BLOCK_BUFFER_SIZE;	
	// If the buffer is full: good! That means we are well ahead of the robot. 
	// Rest here until there is room in the buffer.
	uint8_t bufferWasFull = block_buffer_tail == next_buffer_head;
	if( bufferWasFull)
	{
		//printPgmString(PSTR("::buf_full::\r\n"));
	}
	while(block_buffer_tail == next_buffer_head) { 
		st_pause_wait_resume();
		sleep_mode(); 
	}
	if(bufferWasFull)
	{
		//printPgmString(PSTR("::not_full::\r\n"));
	}
  // Prepare to set up new block
  block_t *block = &block_buffer[block_buffer_head];
  // Number of steps for each axis
  block->steps_x = labs(target[X_AXIS]-position[X_AXIS]);
  block->steps_y = labs(target[Y_AXIS]-position[Y_AXIS]);
  block->steps_z = labs(target[Z_AXIS]-position[Z_AXIS]);
  block->step_event_count = max(block->steps_x, max(block->steps_y, block->steps_z));
  // Bail if this is a zero-length block
  if (block->step_event_count == 0) { return; };
  
  double delta_x_mm = (target[X_AXIS]-position[X_AXIS])/settings.steps_per_mm[X_AXIS];
  double delta_y_mm = (target[Y_AXIS]-position[Y_AXIS])/settings.steps_per_mm[Y_AXIS];
  double delta_z_mm = (target[Z_AXIS]-position[Z_AXIS])/settings.steps_per_mm[Z_AXIS];
  block->millimeters = sqrt(square(delta_x_mm) + square(delta_y_mm) + square(delta_z_mm));
	
  
  uint32_t microseconds;
  if (!invert_feed_rate) {
    microseconds = lround((block->millimeters/feed_rate)*1000000);
  } else {
    microseconds = lround(ONE_MINUTE_OF_MICROSECONDS/feed_rate);
  }
  
  // Calculate speed in mm/minute for each axis
  double multiplier = 60.0*1000000.0/microseconds;
  block->speed_x = delta_x_mm * multiplier;
  block->speed_y = delta_y_mm * multiplier;
  block->speed_z = delta_z_mm * multiplier; 
  block->nominal_speed = block->millimeters * multiplier;
  block->nominal_rate = ceil(block->step_event_count * multiplier);  
  block->entry_factor = 0.0;
  
  // Compute the acceleration rate for the trapezoid generator. Depending on the slope of the line
  // average travel per step event changes. For a line along one axis the travel per step event
  // is equal to the travel/step in the particular axis. For a 45 degree line the steppers of both
  // axes might step for every step event. Travel per step event is then sqrt(travel_x^2+travel_y^2).
  // To generate trapezoids with contant acceleration between blocks the rate_delta must be computed 
  // specifically for each line to compensate for this phenomenon:
  double travel_per_step = block->millimeters/block->step_event_count;
  block->rate_delta = ceil(
    ((settings.acceleration*60.0)/(ACCELERATION_TICKS_PER_SECOND))/ // acceleration mm/sec/sec per acceleration_tick
    travel_per_step);                                               // convert to: acceleration steps/min/acceleration_tick    
  if (acceleration_manager_enabled) {
    // compute a preliminary conservative acceleration trapezoid
    double safe_speed_factor = factor_for_safe_speed(block);
    calculate_trapezoid_for_block(block, safe_speed_factor, safe_speed_factor); 
  } else {
    block->initial_rate = block->nominal_rate;
    block->final_rate = block->nominal_rate;
    block->accelerate_until = 0;
    block->decelerate_after = block->step_event_count;
    block->rate_delta = 0;
  }
  
  // Compute direction bits for this block
  block->direction_bits = 0;
  if (target[X_AXIS] < position[X_AXIS]) { block->direction_bits |= (1<<X_DIRECTION_BIT); }
  if (target[Y_AXIS] < position[Y_AXIS]) { block->direction_bits |= (1<<Y_DIRECTION_BIT); }
  if (target[Z_AXIS] < position[Z_AXIS]) { block->direction_bits |= (1<<Z_DIRECTION_BIT); }
  
  // Move buffer head
  block_buffer_head = next_buffer_head;     
  // Update position 
  memcpy(position, target, sizeof(target)); // position[] = target[]
  
  if (acceleration_manager_enabled) { planner_recalculate(); }  
  st_wake_up();
}
int main(void) {

  uint8_t numSensors = 0, i;
  // unsigned long nextflash = 0;

  // Configure all pins as inputs with pullups initially
  DDRA = 0x00;
  PORTA = 0xff;
  DDRB = 0x00;
  PORTB = 0xff;

  // Serial output line
  DDRB |= _BV(PINB0);
  PORTB |= _BV(PINB0);

  // LED
  // DDRA |= _BV(PINA0);

  // Radio power is PA1
  PORTA &= ~_BV(PINA1);
  DDRA |= _BV(PINA1);

  // Onewire power is PA2
  PORTA &= ~_BV(PINA2);
  DDRA |= _BV(PINA2);

  myPutStr("Hello world\r\n");

  // Various power-saving things

  // Disable BOD while sleeping. I hope.
  MCUCR |= (_BV(BODS) | _BV(BODSE));
  MCUCR &= ~_BV(BODSE);
  MCUCR |= (_BV(BODS));
 
  // Disable the ADC
  ADCSRA &= ~_BV(ADEN);

  // Disable the Analog Comparator
  ACSR |= _BV(ACD);

  // Disable clocking of timer1 and ADC
  PRR |= (_BV(PRTIM1)|_BV(PRADC));

  timerInit();
  wdtInit();
  initInterrupts();


  // Power up the Onewire bus
  PORTA |= _BV(PINA2);
  while(numSensors == 0) {
    myPutStr("Scanning for sensors\r\n");
    numSensors = search_sensors();
    myPutStr("Found ");
    myPutUint8(numSensors);
    myPutStr(" sensors\r\n");

    for (i=0;i<numSensors;i++) {
      uint8_t j;
      myPutStr("Sensor ");
      myPutUint8(i);
      myPutStr(" address ");
      for (j=0;j<OW_ROMCODE_SIZE;j++) {
	myPutUint8(gSensorIDs[i][j]);
      }
      if (gSensorIDs[i][0] == DS18S20_FAMILY_CODE ) {
	myPutStr(" DS18S20/DS1820");
      } else if ( gSensorIDs[i][0] == DS1822_FAMILY_CODE ) {
	myPutStr(" DS1822");
      } else {
	myPutStr(" DS18B20");
      }
      if ( DS18X20_get_power_status( &gSensorIDs[i][0] ) == DS18X20_POWER_PARASITE ) {
	myPutStr(" parasite\r\n");
      } else {
	myPutStr(" external\r\n");
      }

      // Enable 12 bit mode (won't do anything on DS18S20)
      DS18X20_write_scratchpad(&gSensorIDs[i][0], 0, 0, DS18B20_12_BIT);
      DS18X20_scratchpad_to_eeprom(DS18X20_get_power_status( &gSensorIDs[i][0] ),&gSensorIDs[i][0]);
	
    }
      

  }
  while(1) {
    unsigned long wakepoint;
    myRadioBuf_t radiobuf;
    //char debugbuf[10];

    // if ((signed long)now - (signed long)nextflash >= 0) {
    //   debugLedToggle(0);
    //   nextflash = now + 1000;
    // }

    // Power up the Onewire bus
    PORTA |= _BV(PINA2);
    // Let is stabilize for a few ms
    wakepoint = getMillis() + 15;
    numSensors = search_sensors();
    while (! ((signed long)getMillis() - (signed long)wakepoint >= 0)) {
      set_sleep_mode(SLEEP_MODE_IDLE);
      sleep_mode();
    }
    if ( DS18X20_start_meas( DS18X20_POWER_PARASITE, NULL ) == DS18X20_OK) {
      wakepoint = getMillis() + DS18B20_TCONV_12BIT;
      while (! ((signed long)getMillis() - (signed long)wakepoint >= 0)) {
	set_sleep_mode(SLEEP_MODE_IDLE);
	sleep_mode();
      }
      // Power the radio up
      PORTA |= _BV(PINA1);
      // Wakepoint set to now +100ms to allow radio to wake
      wakepoint = getMillis() + 100;

      for ( i = 0; i < numSensors; i++ ) {
        radiobuf.tenthousandths = -9999999L;
	if (DS18X20_read_maxres( &gSensorIDs[i][0], &(radiobuf.tenthousandths) ) != DS18X20_OK) {
	  radiobuf.tenthousandths = -9999999L;
	}

	//myPutStr("Sensor ");
	uint8_t j;
	for (j=0;j<OW_ROMCODE_SIZE;j++) {
            radiobuf.sensid[j] = gSensorIDs[i][j];
	    //myPutUint8(gSensorIDs[i][j]);
        }
	//myPutStr(" = ");
	//sprintf(debugbuf, "%d.%d\r\n", (int)(radiobuf.tenthousandths/10000), (int)(radiobuf.tenthousandths % 10000));
	//myPutStr(debugbuf);
        if (0 == i) {
	  // First time around, radio not initialized
	  while (! ((signed long)getMillis() - (signed long)wakepoint >= 0)) {
            set_sleep_mode(SLEEP_MODE_IDLE);
            sleep_mode();
          }
	  radioInit();
	  // No auto ack
	  radioSetAutoAck(0);
	  radioOpenWritingPipe(pipe);
        }
	radiobuf.tstamp = getMillis();
	//myPutStr("about to radioWrite, i=");
	//myPutUint8(i);
	//myPutStr("...");
	radioWrite(&radiobuf,sizeof(radiobuf));
	//myPutStr("Done\r\n");
      }
      // Power the radio down
      PORTA &= ~_BV(PINA1);
      // Plus the CE and CSN pins
      PORTA &= ~_BV(PINA7);
      PORTB &= ~_BV(PINB2);
      // And the onewire bus
      PORTA &= ~_BV(PINA2);
    } else {
      myPutStr("Error measuring sensors\n");
    }
    //tmp = getMillis();
    //radioWrite(&tmp , sizeof(unsigned long) );
    // Sleep hard until WDT fires
    set_sleep_mode(SLEEP_MODE_PWR_DOWN);
    sleep_mode();
  }
}
Example #24
0
int main() {
	cli();

	wdt_disable(); // To make sure nothing weird happens
	init_tlc5940();
	init_spi();
	init_ps();

	init_blank_timer();
	init_effect_timer();
	
	init_playlist();
	
	initUSART();
	sei();

	hcsr04_start_continuous_meas();
	adc_start();

	serial_elo_init();
	
	// Select correct startup mode
	pick_startup_mode();

	while(1) {
		if(serial_available()) {
			uint8_t cmd = serial_read();
#if defined AVR_ZCL
			serial_zcl_process(cmd);
#elif defined AVR_ELO
			serial_elo_process(cmd);
#elif defined SIMU
			// Do nothing
#else
#error Unsupported serial communication type
#endif
		}

		switch (mode) {
		case MODE_SLEEP:
			// Fall through to MODE_IDLE
		case MODE_IDLE:
			// No operation
			sleep_mode();
			break;
		case MODE_PLAYLIST:
			ticks = centisecs();
			if (ticks > effect_length) {
				next_effect();
				init_current_effect();
			}

			// no need to break!
			// fall to MODE_EFFECT on purpose
		case MODE_EFFECT:
			// If a buffer is not yet flipped
			if (flags.may_flip) break;

			// Update clock and sensor values
			ticks = centisecs();
			sensors.distance1 = hcsr04_get_distance_in_cm();
			sensors.distance2 = hcsr04_get_distance_in_cm(); //TODO: use separate sensor
			sensors.ambient_light = adc_get(0) >> 2;
			sensors.sound_pressure_level = adc_get(1) >> 2;

			// Do the actual drawing
			draw_t draw = (draw_t)pgm_get(effect->draw,word);
			if (draw != NULL) {
				draw();
				allow_flipping(true);
			}

			// Slow down drawing if FPS is going to be too high
			uint16_t target_ticks =
				ticks + pgm_get(effect->minimum_ticks,byte);
			while (centisecs() < target_ticks ) {
				sleep_mode();
			}

			break;
		}
	}

	return 0;
}
Example #25
0
void systemSleep() {
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);  // Sleep mode is set here
  sleep_enable();
  sleep_mode();                         // System actually sleeps here
  sleep_disable();                      // System continues execution here when watchdog timed out
}
Example #26
0
void micro_sleep(uint8_t howlong)
{
    uint8_t saved_sreg = SREG, saved_howlong = howlong;
#if AVR_CONF_USE32KCRYSTAL
/* Save TIMER2 configuration if clock.c is using it */
    uint8_t savedTCNT2=TCNT2, savedTCCR2A=TCCR2A, savedTCCR2B = TCCR2B, savedOCR2A = OCR2A;
#endif

//    if (howlong==0) {
//        set_sleep_mode(SLEEP_MODE_PWR_DOWN);  // UART can't wake from powerdown
//     } else {
        set_sleep_mode(SLEEP_MODE_PWR_SAVE);    // Sleep for howlong seconds
        if (howlong==0) howlong=3;              // 3*32/(32768/1024) = 3 second sleep cycle if not specified
        cli();                                  // Disable interrupts for the present
        ASSR |= (1 << AS2);                     // Set TIMER2 asyncronous from external crystal
        TCCR2A =(1<<WGM21);                     // CTC mode
        TCCR2B =((1<<CS22)|(1<<CS21)|(1<<CS20));// Prescale by 1024 = 32 ticks/sec
//      while(ASSR & (1 << TCR2BUB));           // Wait for TCNT2 write to finish.
        OCR2A = howlong*32;                     // Set TIMER2 output compare register
//      while(ASSR & (1 << OCR2AUB));           // Wait for OCR2 write to finish.
        SREG = saved_sreg;                      // Restore interrupt state.
//      UCSR(USART,B)&= ~(1<<RXCIE(USART))      // Disable the RX Complete interrupt;
//      UCSR0B|=(1<<RXCIE0);                    // Enable UART0 RX complete interrupt
//      UCSR1B|=(1<<RXCIE1);                    // Enable UART1 RX complete interrupt 
//      TCNT2 = 0;                              // Reset TIMER2 timer counter value.
//      while(ASSR & (1 << TCN2UB));            // Wait for TCNT2 write to finish before entering sleep.
//      TIMSK2 |= (1 << OCIE2A);                // Enable TIMER2 output compare interrupt.
//    }

    TCNT2 = 0;                                  // Reset timer
    watchdog_stop();                            // Silence annoying distractions
    while(ASSR & (1 << TCN2UB));                // Wait for TCNT2 write to (which assures TCCR2x and OCR2A are finished!)
    TIMSK2 |= (1 << OCIE2A);                    // Enable TIMER2 output compare interrupt
    SMCR |= (1 <<  SE);                         // Enable sleep mode.
    while (1) {
//    TCNT2 = 0;                                // Cleared automatically in CTC mode
//     while(ASSR & (1 << TCN2UB));             // Wait for TCNT2 write to finish before entering sleep.
       serial_char_received=0;                  // Set when chars received by UART
       sleep_mode();                            // Sleep

       /* Adjust clock.c for the time spent sleeping */
       extern void clock_adjust_seconds(uint8_t howmany);
       clock_adjust_seconds(howlong);

//     if (TIMSK2&(1<<OCIE2A)) break;           // Exit sleep if not awakened by TIMER2
       PRINTF(".");
       if (saved_howlong) break;                // Exit sleep if nonzero time specified
//     PRINTF("%d",serial_char_received);
       if (serial_char_received) break;
   }

    SMCR  &= ~(1 << SE);                        //Disable sleep mode after wakeup

#if AVR_CONF_USE32KCRYSTAL
/* Restore clock.c configuration */
//  OCRSetup();
    cli();
    TCCR2A = savedTCCR2A;
    TCCR2B = savedTCCR2B;
    OCR2A  = savedOCR2A;
    TCNT2  = savedTCNT2;
    sei();
#else
    TIMSK2 &= ~(1 << OCIE2A);                   //Disable TIMER2 interrupt
#endif

    watchdog_start();
}
Example #27
0
int main(void)
{
	unsigned char i;
	char * _ptr;
	const char * _ptr1;

	//Initialize display buffer with StartUp strings
	strcpy_P(&str_array[vga_symbols_per_row*18],&str1[0]); 	
	strcpy_P(&str_array[vga_symbols_per_row*19],&str2[0]); 	
	strcpy_P(&str_array[vga_symbols_per_row*0],&str3[0]); 	
	strcpy_P(&str_array[vga_symbols_per_row*5],&str4[0]); 	
	strcpy_P(&str_array[vga_symbols_per_row*10],&str5[0]); 	
    avr_init();
	for(;;)
    {

		//Wait compare interrupt signal from Timer1
		sleep_mode();
		
		
		//Check visible field
		if(video_enable_flg)
		{
		//OK, visible
		//Main render routine
				//Set pointer for render line (display bufffer)
				_ptr = &str_array[raw_render * vga_symbols_per_row];

				//Set pointer for render line (character generator)
				_ptr1 = &symbol[0][y_line_render >> 1];
	
				//Cycle for render line 
				i = vga_symbols_per_row;
				while(i--)
				{
					SPDR = PRG_RDB(_ptr1 + (* _ptr++)*symbol_height/2);
				    video_on;
					//That's a great pity can't shift data faster (8Mhz at FOSC=16Mhz)!!
					NOP;
					NOP;
				}
				//Delay for draw last symbol
				NOP;
				NOP;
				NOP;
				NOP;
				NOP;
				NOP;
				video_off;

		}
		else
		{
		//Not visible
		//Can do something else..	
		//*****Users handlers example
					static unsigned int framecount, time;
					//Simplest task switcher (linecount<45 not visible)
					switch ( linecount )
					{
					  //Task for make ADC0 convertion
					  case  0:  
						//Enable conversion only at the begin of video line count
						//to avoid flickering at the top display
						ADCSRA |= 1<<ADSC;//start the single conversion 
						while(bit_is_set(ADCSRA, ADSC));
					  break;
					  
					  //Task for refresh ADC0 convertion result
					  case  3:
						_display_adc(196*ADCH);
					  break;

					  //Task for show and count time value
					  case  9: 
						//Count frame for time count
						framecount++;
						//Time count
						if (framecount==60)
						{
							framecount = 0;
							//Running timer only when PinC.1 = "0";
							if (bit_is_clear(PINC,1))
							{
							//Increment every second
							_display_time(++time);
							}
							else
							{
								time = 0;
							}
						}
					  break;

					  //Default task Check and show state of PINC.1
					  default: 
						if (bit_is_set(PINC,1))
							str_array[7] = '1';
						else
							str_array[7] = '0';
					}
		//*****Users handlers example
		}
		
    }//for(;;)