summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/system.cc54
-rw-r--r--src/system.h38
2 files changed, 74 insertions, 18 deletions
diff --git a/src/system.cc b/src/system.cc
index b7d17e6..5eb3f77 100644
--- a/src/system.cc
+++ b/src/system.cc
@@ -74,6 +74,20 @@ uint8_t const hsbtable[42] PROGMEM = {
0, 0
};
+uint8_t const energytable[12] PROGMEM = {
+ 2, // WARMWHITE
+ 3, // SLOWRGB
+ 9, // SUN
+ 3, // RED
+ 2, // GREEN
+ 2, // BLUE
+ 5, // YELLOW
+ 5, // MAGENTA
+ 4, // CYAN
+ 3, // FASTRGB
+ 1, // SLOWRGB2
+ 1 // FASTRGB2
+};
void System::initialize()
{
@@ -133,14 +147,21 @@ void System::loop()
TCCR1A = _BV(COM1A1) | _BV(COM1B1) | _BV(WGM10);
TCCR1B = _BV(WGM12) | _BV(CS00);
- // interrupt on Timer 0 overflow
+ // interrupt on Timer 0 overflow (31.25 kHz)
TIMSK = _BV(TOIE0);
- } else {
+ } else if (mode == OFF) {
TCCR0A = 0;
TCCR0B = 0;
TCCR1A = 0;
TCCR1B = 0;
TIMSK = 0;
+ } else {
+ TCCR0A = _BV(WGM01) | _BV(WGM00);
+ TCCR0B = _BV(CS00);
+ TCCR1A = 0;
+ TCCR1B = 0;
+ // interrupt on Timer 0 overflow (31.25 kHz)
+ TIMSK = _BV(TOIE0);
}
switch (mode) {
case OFF:
@@ -236,6 +257,20 @@ void System::loop()
if (mode == OFF) {
sleep();
} else {
+ if (tick_18s) {
+ tick_18s = 0;
+ energy_j -= pgm_read_byte(&energytable[mode - 1]);
+ }
+ if (energy_j < 0) {
+ mode_changed = 1;
+ energy_j = -1;
+
+ PORTD &= ~BIT_WW;
+ PORTB = BIT_RED;
+ _delay_ms(50);
+
+ mode = OFF;
+ }
idle();
}
}
@@ -277,14 +312,26 @@ ISR(WDT_OVERFLOW_vect)
ISR(TIMER0_OVF_vect)
{
static uint8_t slowdown = 0;
+ static uint8_t slowdown2 = 0;
+ static uint8_t slowdown3 = 0;
if (++slowdown == 10) {
+ slowdown = 0;
+ // 3.125 kHz
if (++blinkencat.anim_step_fine == HSBTABLE_MAX) {
blinkencat.anim_step_fine = 0;
if (++blinkencat.anim_step_coarse == HSBTABLE_MAX) {
blinkencat.anim_step_coarse = 0;
}
}
- slowdown = 0;
+ if (++slowdown2 == 255) {
+ slowdown2 = 0;
+ // 12.25 Hz
+ if (++slowdown3 == 221) {
+ slowdown3 = 0;
+ // ~55.5 mHz == (1/18) Hz
+ blinkencat.tick_18s = 1;
+ }
+ }
}
}
@@ -295,6 +342,7 @@ ISR(PCINT2_vect)
}
if (PIND & _BV(PD3)) {
blinkencat.is_charging = 1;
+ blinkencat.setEnergyFull();
PORTD |= _BV(PD1);
} else {
blinkencat.is_charging = 0;
diff --git a/src/system.h b/src/system.h
index 10a2f73..12c5e0c 100644
--- a/src/system.h
+++ b/src/system.h
@@ -14,6 +14,10 @@ class System {
uint8_t blue;
uint8_t mode_changed;
+ // 1 Ah @ 3.7V = 13 kJ
+ int16_t const energy_full = 13000;
+ int16_t energy_j;
+
public:
uint8_t anim_step_fine;
@@ -21,23 +25,25 @@ class System {
void initialize(void);
void loop(void);
-
uint8_t is_charging;
+ uint8_t tick_18s;
+ // Battery: 1000 mAh @ 3.7V -> ~13 kJ / 13000 J
+ // 15 mA * 3.7 V * 18s -> 1 J
enum BCMode : uint8_t {
- OFF = 0,
- WARMWHITE,
- SLOWRGB,
- SUN,
- RED,
- GREEN,
- BLUE,
- YELLOW,
- MAGENTA,
- CYAN,
- FASTRGB,
- SLOWRGB2,
- FASTRGB2,
+ OFF = 0, // 0 mA
+ WARMWHITE, // 32 mA @ 4 V : 2 J per 18 s
+ SLOWRGB, // ~45 mA @ 4 V : 3
+ SUN, // 134 mA @ 4 V : 9
+ RED, // 45 mA @ 4 V : 3
+ GREEN, // 29 mA @ 4 V : 2
+ BLUE, // 30 mA @ 4 V : 2
+ YELLOW, // 74 mA @ 4 V : 5
+ MAGENTA, // 76 mA @ 4 V : 5
+ CYAN, // 59 mA @ 4 V : 4
+ FASTRGB, // ~45 mA @ 4 V : 3
+ SLOWRGB2, // ~17 mA @ 4 V : 1
+ FASTRGB2, // ~17 mA @ 4 V : 1
MODE_ENUM_MAX,
};
@@ -49,7 +55,9 @@ class System {
void debounce_start(void);
- System() { btn_debounce = 0; mode = OFF; is_charging = 0; mode_changed = 0; };
+ inline void setEnergyFull(void) { energy_j = energy_full; }
+
+ System() : btn_debounce(0), mode_changed(0), energy_j(energy_full), is_charging(0), tick_18s(0), mode(OFF) {}
};
extern System blinkencat;