Commit 4e819bfa authored by Daniel Friesel's avatar Daniel Friesel
Browse files

Add energy accounting

parent 6e13ff47
Loading
Loading
Loading
Loading
+51 −3
Original line number Diff line number Diff line
@@ -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;
+23 −15
Original line number Diff line number Diff line
@@ -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;