inline void hexbright::adjust_leds() { // turn off led if it's expired #if (DEBUG==DEBUG_LED) if(led_on_time[GLED]>=0) { Serial.print("green on countdown: "); Serial.println(led_on_time[GLED]*update_delay); } else if (led_on_time[GLED]<0 && led_wait_time[GLED]>=0) { Serial.print("green wait countdown: "); Serial.println((led_wait_time[GLED])*update_delay); } if(led_on_time[RLED]>=0) { Serial.print("red on countdown: "); Serial.println(led_on_time[RLED]*update_delay); } else if (led_on_time[RLED]<0 && led_wait_time[RLED]>=0) { Serial.print("red wait countdown: "); Serial.println((led_wait_time[RLED])*update_delay); } #endif int i=0; for(i=0; i<2; i++) { if(led_on_time[i]>0) { _led_on(i); led_on_time[i]--; } else if(led_on_time[i]==0) { _led_off(i); led_on_time[i]--; } else if (led_wait_time[i]>=0) { led_wait_time[i]--; } } }
void _led_set(unsigned char led,unsigned char val) { if(val==1) _led_on(led); else _led_off(led); }
void hexbright::update() { unsigned long now; #if (DEBUG==DEBUG_LOOP) unsigned long start_time=micros(); #endif #ifdef STROBE while (true) { do { now = micros(); } while (next_strobe > now && // not ready for strobe continue_time > now); // not ready for update if (next_strobe <= now) { if (now - next_strobe <26) { digitalWriteFast(DPIN_DRV_EN, HIGH); delayMicroseconds(strobe_duration); digitalWriteFast(DPIN_DRV_EN, LOW); } next_strobe += strobe_delay; } if(continue_time <= now) { if(strobe_delay>update_delay && // we strobe less than once every 8333 microseconds next_strobe-continue_time < 4000) // and the next strobe is within 4000 microseconds (may occur before we return) continue; else break; } } // do nothing... (will short circuit once every 70 minutes (micros maxint)) #else do { now = micros(); } while (continue_time > now); // not ready for update #endif // if we're in debug mode, let us know if our loops are too large #if (DEBUG!=DEBUG_OFF && DEBUG!=DEBUG_PRINT) static int i=0; #if (DEBUG==DEBUG_LOOP) static unsigned long last_time = 0; if(!i) { Serial.print("Time used: "); Serial.print(start_time-last_time); Serial.println("/8333"); } last_time = now; #endif if(now-continue_time>5000 && !i) { // This may be caused by too much processing for our update_delay, or by too many print statements) // If you're triggering this, your button and light will react more slowly, and some accelerometer // data is being missed. Serial.println("WARNING: code is too slow"); } if (!i) i=1000/update_delay; // display loop output every second else i--; #endif // power saving modes described here: http://www.atmel.com/Images/2545s.pdf //run overheat protection, time display, track battery usage #ifdef LED // regardless of desired led state, turn it off so we can read the button _led_off(RLED); delayMicroseconds(50); // let the light stabilize... read_button(); // turn on (or off) the leds, if appropriate adjust_leds(); #ifdef PRINT_NUMBER update_number(); #endif #else read_button(); #endif read_thermal_sensor(); // takes about .2 ms to execute (fairly long, relative to the other steps) read_charge_state(); read_avr_voltage(); #ifdef ACCELEROMETER read_accelerometer(); find_down(); #endif detect_overheating(); detect_low_battery(); apply_max_light_level(); // change light levels as requested adjust_light(); // advance time at the same rate as values are changed in the accelerometer. // advance continue_time here, so the first run through short-circuits, // meaning we will read hardware immediately after power on. continue_time = continue_time+(1000*update_delay); }
void hexbright::update() { // advance time at the same rate as values are changed in the accelerometer. continue_time = continue_time+(1000*update_delay); unsigned long now; while (true) { do { now = micros(); } while (next_strobe > now && // not ready for strobe continue_time > now); // not ready for update if (next_strobe <= now) { if (now - next_strobe <26) { digitalWrite(DPIN_DRV_EN, HIGH); delayMicroseconds(strobe_duration); digitalWrite(DPIN_DRV_EN, LOW); } next_strobe += strobe_delay; } if(continue_time <= now) { if(strobe_delay>update_delay && // we strobe less than once every 8333 microseconds next_strobe-continue_time < 4000) // and the next strobe is within 4000 microseconds (may occur before we return) continue; else break; } } // do nothing... (will short circuit once every 70 minutes (micros maxint)) // if we're in debug mode, let us know if our loops are too large #if (DEBUG!=DEBUG_OFF) static int i=0; static float avg_loop_time = 0; static float last_time = 0; avg_loop_time = (avg_loop_time*29 + continue_time-last_time)/30; #if (DEBUG==DEBUG_LOOP) if(!i) { Serial.print("Average loop time: "); Serial.println(avg_loop_time/1000); } #endif if(avg_loop_time/1000>update_delay+1 && !i) { // This may be caused by too much processing for our update_delay, or by too many print statements (each one takes a few ms) Serial.print("WARNING: loop time: "); Serial.println(avg_loop_time/1000); } if (!i) i=1000/update_delay; // display loop output every second else i--; last_time = continue_time; #endif // power saving modes described here: http://www.atmel.com/Images/2545s.pdf //run overheat protection, time display, track battery usage #ifdef LED // regardless of desired led state, turn it off so we can read the button _led_off(RLED); delayMicroseconds(50); // let the light stabilize... read_button(); // turn on (or off) the leds, if appropriate adjust_leds(); #ifdef PRINT_NUMBER update_number(); #endif #else read_button(); #endif read_thermal_sensor(); // takes about .2 ms to execute (fairly long, relative to the other steps) #ifdef ACCELEROMETER read_accelerometer(); find_down(); #endif overheat_protection(); // change light levels as requested adjust_light(); }
/****************************************************************************** Led manager callback ******************************************************************************* Must be called at regular intervals. Typicalls from an interrupt vector at about 10Hz. ******************************************************************************/ void led_callback_10hz(void) { // Process the 2 leds for(unsigned char l=0; l<2; l++) { switch(_led_mode[l]) { // Case 0: LED in static mode. case 0: break; // Case 1: LED in blink sequence mode case 1: //printf_P(PSTR("LED %d\r"),l); //printf_P(PSTR("B dotrans %d istate %d ctr %d rctr %d inf %d\r"),_led_istatedotrans[l],_led_istate[l],_led_istate_ctr[l],_led_istate_rctr[l],_led_inf[l]); // Transient code (entering a state) if(_led_istatedotrans[l]) { _led_istatedotrans[l]=0; switch(_led_istate[l]) { // Reset transition case 0: _led_istate[l]=1; // First state after reset // Reset initialization _led_istate_rctr[l]=0; // No break on purpose to ensure initialization, and entering in the first state upon power up. // Transition to LED on case 1: _led_on(l); _led_istate_ctr[l]=0; break; // Transition to LED off case 2: _led_off(l); _led_istate_ctr[l]=0; break; // Transition to wait case 3: _led_istate_ctr[l]=0; _led_istate_rctr[l]=0; break; // Transition to end of sequence repetition case 4: _led_idone[l]=1; } } // State code (in a state) switch(_led_istate[l]) { // State LED on case 1: INCREMENT_WRAP(_led_istate_ctr[l],_led_ton[l]); if(!_led_istate_ctr[l]) // Time elapsed { _led_istate[l]=2; _led_istatedotrans[l]=1; } break; // State LED off case 2: INCREMENT_WRAP(_led_istate_ctr[l],_led_toff[l]); if(!_led_istate_ctr[l]) // Time elapsed { // Go to wait, or repeat? INCREMENT_WRAP(_led_istate_rctr[l],_led_rep[l]); // We blink on again if: the sequence is not complete, or the sequence is complete but we should not wait at the end of the sequence, and we want infinite blinks if(_led_istate_rctr[l] || (_led_w[l]==0 && _led_inf[l]==1)) { _led_istate[l]=1; _led_istatedotrans[l]=1; } else { if(_led_inf[l]==0 && _led_w[l]==0) // no need to wait and no infinite loop -> end { _led_istate[l]=4; _led_istatedotrans[l]=1; } else // need to wait, state 3: wait { _led_istate[l]=3; _led_istatedotrans[l]=1; } } } break; // State wait case 3: INCREMENT_WRAP(_led_istate_ctr[l],_led_w[l]); if(!_led_istate_ctr[l]) // Time elapsed { // wait is done if(_led_inf[l]==1) // infinite blinks: state1 { _led_istate[l]=1; _led_istatedotrans[l]=1; } else { _led_istate[l]=4; _led_istatedotrans[l]=1; } } break; } //printf_P(PSTR("B t%d s%d c%d r %d\r\r"),_led_istate0dotrans,_led_istate0,_led_istate0_ctr,_led_istate0_rctr); break; } } }