aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias P. Braendli <matthias.braendli@mpb.li>2019-10-26 23:29:22 +0200
committerMatthias P. Braendli <matthias.braendli@mpb.li>2019-10-26 23:29:22 +0200
commit66cdf851a8e945adf702088d9f78f850c8b8932c (patch)
treebbeb6b4f30bfc08e2064a375c27fae4f88411559
parentf6c2c762afc1d527cf40f8925ecf22b8b5845b43 (diff)
downloadglutte-batteries-66cdf851a8e945adf702088d9f78f850c8b8932c.tar.gz
glutte-batteries-66cdf851a8e945adf702088d9f78f850c8b8932c.tar.bz2
glutte-batteries-66cdf851a8e945adf702088d9f78f850c8b8932c.zip
Add preliminary mAh accumulator
-rw-r--r--kicad/glutte-coulombcounter.sch2
-rw-r--r--sw/Makefile2
-rw-r--r--sw/main.cpp40
-rw-r--r--sw/pins.h54
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);
}
}
}
diff --git a/sw/pins.h b/sw/pins.h
index 6dc75bc..c69870d 100644
--- a/sw/pins.h
+++ b/sw/pins.h
@@ -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();
+}