* Buttons:
* There are two buttons (+ and -). Any button can wake the system up from
* the power-down state.
- * TODO: When the system is woken up by the "-" button,
- * it starts with the minimum output power, when it is woken up by the "+"
- * button, it start with the maximum output power.
* When running, the "-" button is used for decreasing the output power,
* the "+" button is for increasing it.
- * When on the lowest power state, the "-" button switches the system off.
- * Long "-" button press switches the system off, long "+" button
- * press sets the output power to maximum.
+ * Any long button press switches the system off.
*
* Status LED:
* When powering up by a button press, the LED goes on to provide a visual
* feedback, and is switched off after the button is released.
- * After a button press, the # of blinks of the LED reflects the
- * chosen output power level for some time. Afterwards, it displays
- * the battery level.
+ * It displays the current power level and current battery voltage
+ * using # of blinks with different blinking lengths.
* When the battery is completely exhausted, the output power is switched
* off, the LED keeps blinking for some time, and then the whole system is
* switched off to avoid deep discharge of the battery.
#define WAKEUP_POLL 50 // msec
#define WAKEUP_LIMIT 5 // times WAKEUP_POLL
+// #define BUTTONS_REVERSE
+
+#ifdef BUTTONS_REVERSE
+# define BUTTON1 PB0
+# define BUTTON2 PB1
+#else
+# define BUTTON1 PB1
+# define BUTTON2 PB0
+#endif /* !BUTTONS_REVERSE */
+
/* which state (output on or output off) are we measuring now */
static volatile unsigned char adc_type, adc_drop;
#define ADC_RUNAVG_SHIFT 5 // running average shift on batt_on, batt_off
* (1024UL * (mV)) \
/ (6UL * ADC_1100MV_VALUE)) >> 8))
static unsigned char batt_levels[] = {
- MV_TO_ADC8(3350),
- MV_TO_ADC8(3700),
- MV_TO_ADC8(3900),
+ MV_TO_ADC8(3000), // below this, do not enable load, and switch off
+ MV_TO_ADC8(3150), // below this, switch off after some time
+ MV_TO_ADC8(3450), // battery low
+ MV_TO_ADC8(3800), // battery ok, above that almost full
};
#define BATT_N_LEVELS (sizeof(batt_levels) / sizeof(batt_levels[0]))
#define N_POWER_LEVELS (sizeof(power_levels) / sizeof(power_levels[0]))
static unsigned char power_level = 0; // selected power level
-static unsigned char power_level_changed; // for visual feedback
-#define LED_PWRCHANGE_COUNT 5
#define LED_BATTEMPTY_COUNT 60
/* timing by WDT */
static unsigned char buttons_pressed()
{
return (
- (PINB & _BV(PB0) ? 0 : 1)
+ (PINB & _BV(BUTTON1) ? 0 : 1)
|
- (PINB & _BV(PB1) ? 0 : 2)
+ (PINB & _BV(BUTTON2) ? 0 : 2)
);
}
static void status_led_next_pattern()
{
static unsigned char battery_exhausted;
+ static unsigned char display_power_level;
- if (power_level_changed) {
- power_level_changed--;
+ if (display_power_level) {
n_blinks = power_level + 1;
+ if (batt_on >> 8 == batt_off >> 8) { // load unplugged
+ n_blinks = 2 * n_blinks;
+ blink_on_time = 0;
+ blink_off_time = 0;
+ } else {
+ blink_on_time = 2;
+ blink_off_time = 2;
+ }
} else {
unsigned char b_level = battery_level();
- if (b_level) {
+ if (b_level > 1) {
battery_exhausted = 0;
} else if (battery_exhausted) {
if (!--battery_exhausted)
battery_exhausted = LED_BATTEMPTY_COUNT;
}
- n_blinks = b_level + 1;
+ n_blinks = b_level ? b_level : 1;
+ blink_on_time = b_level ? 4 : 2;
+ blink_off_time = 0;
}
- blink_on_time = 2;
- blink_off_time = 1;
- blink_counter = 10;
+ blink_counter = 12;
+ display_power_level = !display_power_level;
}
static void timer_blink()
static void button_pressed(unsigned char button, unsigned char long_press)
{
// ignore simlultaneous button 1 and 2 press
- // Note: we set power_level_changed after each button press,
- // even when the power is at maximum, to provide visual feedback
- // with status LED.
if (long_press) {
- if (button == 1) {
- power_down();
- return;
- } else if (button == 2) {
- power_level = N_POWER_LEVELS-1;
- }
+ power_down();
+ return;
} else { // short press
if (button == 1) {
if (power_level > 0) {
--power_level;
- } else {
- power_down();
- return;
}
} else if (button == 2) {
if (power_level < N_POWER_LEVELS-1) {
}
}
}
- power_level_changed = LED_PWRCHANGE_COUNT;
status_led_next_pattern();
}
log_byte(batt_on >> 8);
#endif
}
+ if (jiffies == 0) {
+ log_byte(batt_on >> 8);
+ log_byte(batt_off >> 8);
+ }
log_flush();
}
}