diff options
-rw-r--r-- | kicad/glutte-coulombcounter.sch | 2 | ||||
-rw-r--r-- | sw/Makefile | 2 | ||||
-rw-r--r-- | sw/main.cpp | 40 | ||||
-rw-r--r-- | sw/pins.h | 54 |
4 files changed, 70 insertions, 28 deletions
diff --git a/kicad/glutte-coulombcounter.sch b/kicad/glutte-coulombcounter.sch index 850d73a..e550376 100644 --- a/kicad/glutte-coulombcounter.sch +++ b/kicad/glutte-coulombcounter.sch @@ -1496,4 +1496,6 @@ $EndComp Wire Wire Line 8250 5250 8000 5250 Connection ~ 8250 5250 +Text Notes 3050 1800 0 31 ~ 0 +Vout - 2.5V = 20 * Ishunt * Rshunt\nSee AD8210 datasheet\n"Splitting an external reference" $EndSCHEMATC diff --git a/sw/Makefile b/sw/Makefile index e8057b2..6b49420 100644 --- a/sw/Makefile +++ b/sw/Makefile @@ -57,7 +57,7 @@ vpath %.hex ./$(BUILD_DIR) # GCC flags DEFINES=-DUART_RX0_BUFFER_SIZE=64 -DUART_TX0_BUFFER_SIZE=64 -DARDUINO=180 -FLAGS=-g -mmcu=$(PART) -Os -Wall -Wextra -Werror -DF_CPU=$(F_CPU) $(DEFINES) -ffunction-sections -fdata-sections -MMD -flto -fno-fat-lto-objects +FLAGS=-g -mmcu=$(PART) -Os -Wall -Wextra -DF_CPU=$(F_CPU) $(DEFINES) -ffunction-sections -fdata-sections -MMD -flto -fno-fat-lto-objects CFLAGS=$(FLAGS) -std=c99 CXXFLAGS=$(FLAGS) -std=c++11 -fno-exceptions -fno-threadsafe-statics INCLUDES=-I. -I$(LIB_DIR) diff --git a/sw/main.cpp b/sw/main.cpp index c68ba33..9c9a436 100644 --- a/sw/main.cpp +++ b/sw/main.cpp @@ -25,6 +25,7 @@ #include <stdlib.h> #include <stdint.h> #include <stdio.h> +#include <math.h> #include <avr/pgmspace.h> #include <avr/io.h> @@ -43,6 +44,9 @@ extern "C" { // UART endline is usually CR LF #define ENDL "\r\n" +constexpr double R_SHUNT = 5e-3; +constexpr int TICKS_PER_SECOND = 10; + struct timer_t { uint32_t seconds = 0; /* Timer in seconds */ uint8_t ticks = 0; /* Timer in 100ms steps */ @@ -70,6 +74,8 @@ struct timer_t { this->ticks -= 10; } } + + static constexpr int ms_to_ticks(int ms) { return ms / 100; } }; /* Storage of battery capacity in mC. @@ -198,18 +204,23 @@ int main() wdt_reset(); wdt_enable(WDTO_4S); + current_capacity = 0; +#warning "Initialise current_capacity properly" + /* Setup GPIO */ // Active-low outputs must be high // PINB_SPI_SCK must be low (See ltc2400.h) - PORTB = PINB_STATUSn | PINB_SPI_LTC_CSn; - PORTC = 0; - PORTD = 0; + PORTB = PINB_INIT; + PORTC = PINC_INIT; + PORTD = PIND_INIT; // Enable output DDRB = PINB_OUTPUTS; DDRC = PINC_OUTPUTS; DDRD = PIND_OUTPUTS; + pins_set_status(true); + // Initialise SPI and LTC2400 ltc2400_init(); @@ -247,10 +258,10 @@ int main() */ system_timer.seconds = 0; system_timer.ticks = 0; - TCCR0B |= (1 << WGM02); // Set timer mode to CTC (datasheet 15.7.2) - TIMSK0 |= (1 << TOIE0); // enable overflow interrupt + TCCR0B |= _BV(WGM02); // Set timer mode to CTC (datasheet 15.7.2) + TIMSK0 |= _BV(TOIE0); // enable overflow interrupt OCR0A = (uint8_t)(F_CPU / 1024 / 10); // Overflow at 99.84 ms - TCCR0B |= (1 << CS02) | (1 << CS00); // Start timer at Fcpu/1024 + TCCR0B |= _BV(CS02) | _BV(CS00); // Start timer at Fcpu/1024 /* Load capacity stored in EEPROM */ load_capacity_from_eeprom(); @@ -259,23 +270,27 @@ int main() /* Enable interrupts */ sei(); + double accum = 0.0; + /* Put the CPU to sleep */ set_sleep_mode(SLEEP_MODE_IDLE); while (true) { sleep_mode(); + pins_set_status(system_timer.ticks == 0); + if (last_store_time + 3600 * 5 >= system_timer.seconds) { store_capacity_to_eeprom(); } - if (last_ltc2400_measure + 100 > system_timer) { - last_ltc2400_measure += 100; + constexpr auto ltc2400_measure_interval = timer_t::ms_to_ticks(100); + if (last_ltc2400_measure + ltc2400_measure_interval > system_timer) { + last_ltc2400_measure += ltc2400_measure_interval; if (ltc2400_conversion_ready()) { bool dmy_fault = false; bool exr_fault = false; - float adc_voltage = ltc2400_get_conversion_result(dmy_fault, exr_fault); -#error "convert to mAh and integrate" + const float adc_voltage = ltc2400_get_conversion_result(dmy_fault, exr_fault); if (dmy_fault) { flag_error(error_type_t::LTC2400_DMY_BIT_FAULT); @@ -284,6 +299,11 @@ int main() if (exr_fault) { flag_error(error_type_t::LTC2400_EXTENDED_RANGE_ERROR); } + + /* Vout - 2.5V = Ishunt * Rshunt * 20 */ + const double i_shunt = (adc_voltage - 2.5) / (20.0 * R_SHUNT); + accum += i_shunt / TICKS_PER_SECOND; + current_capacity = lrint(accum); } } } @@ -26,9 +26,10 @@ #include <stdlib.h> #include <stdint.h> +#include <avr/io.h> +#include <avr/interrupt.h> // Definitions allocation pin -#define PIN(x) (1 << x) /* All relay signals PINx_Kx have external pulldown. * All pins whose name ends in 'n' are active low */ @@ -37,38 +38,57 @@ // lib/pins_arduino.h // PORT B -constexpr uint8_t PINB_STATUSn = PIN(0); +constexpr uint8_t PINB_STATUSn = _BV(0); // Pins 2,3,4,5 = SPI -constexpr uint8_t PINB_SPI_LTC_CSn = PIN(2); // with external pullup -constexpr uint8_t PINB_SPI_MOSI = PIN(3); -constexpr uint8_t PINB_SPI_MISO = PIN(4); -constexpr uint8_t PINB_SPI_SCK = PIN(5); +constexpr uint8_t PINB_SPI_LTC_CSn = _BV(2); // with external pullup +constexpr uint8_t PINB_SPI_MOSI = _BV(3); +constexpr uint8_t PINB_SPI_MISO = _BV(4); +constexpr uint8_t PINB_SPI_SCK = _BV(5); constexpr uint8_t PINB_OUTPUTS = PINB_STATUSn | PINB_SPI_SCK | PINB_SPI_MOSI | PINB_SPI_LTC_CSn; +constexpr uint8_t PINB_INIT = + PINB_STATUSn | PINB_SPI_LTC_CSn; + // PORT C -constexpr uint8_t PINC_ADC0 = PIN(0); -constexpr uint8_t PINC_ADC1 = PIN(1); -constexpr uint8_t PINC_K3_RESET = PIN(2); -constexpr uint8_t PINC_K3_SET = PIN(3); -constexpr uint8_t PINC_K2_RESET = PIN(4); -constexpr uint8_t PINC_K2_SET = PIN(5); +constexpr uint8_t PINC_ADC0 = _BV(0); +constexpr uint8_t PINC_ADC1 = _BV(1); +constexpr uint8_t PINC_K3_RESET = _BV(2); +constexpr uint8_t PINC_K3_SET = _BV(3); +constexpr uint8_t PINC_K2_RESET = _BV(4); +constexpr uint8_t PINC_K2_SET = _BV(5); constexpr uint8_t PINC_OUTPUTS = PINC_K3_RESET | PINC_K3_SET | PINC_K2_RESET | PINC_K2_SET; +constexpr uint8_t PINC_INIT = 0; + // PORT D // Pins 0,1 = UART RX,TX -constexpr uint8_t PIND_UART_RX = PIN(0); -constexpr uint8_t PIND_UART_TX = PIN(1); +constexpr uint8_t PIND_UART_RX = _BV(0); +constexpr uint8_t PIND_UART_TX = _BV(1); -constexpr uint8_t PIND_ONEWIRE = PIN(4); // with exteral pullup +constexpr uint8_t PIND_ONEWIRE = _BV(4); // with exteral pullup -constexpr uint8_t PIND_K1_RESET = PIN(5); -constexpr uint8_t PIND_K1_SET = PIN(6); +constexpr uint8_t PIND_K1_RESET = _BV(5); +constexpr uint8_t PIND_K1_SET = _BV(6); constexpr uint8_t PIND_OUTPUTS = PIND_UART_TX | PIND_K1_RESET | PIND_K1_SET; + +constexpr uint8_t PIND_INIT = 0; + +inline void pins_set_status(bool enable) +{ + cli(); + if (enable) { + PORTB &= ~PINB_STATUSn; + } + else { + PORTB |= PINB_STATUSn; + } + sei(); +} |