aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias P. Braendli <matthias.braendli@mpb.li>2019-11-03 19:13:00 +0100
committerMatthias P. Braendli <matthias.braendli@mpb.li>2019-11-03 19:13:00 +0100
commit4193ec1618230f7bbc927e1d2280976a9d5dd464 (patch)
treed4d9efedfd928d2ca365ecab46d94dc9040bf749
parent48ac857cc3082aee3300a4d39834e109bd909f82 (diff)
downloadglutte-batteries-4193ec1618230f7bbc927e1d2280976a9d5dd464.tar.gz
glutte-batteries-4193ec1618230f7bbc927e1d2280976a9d5dd464.tar.bz2
glutte-batteries-4193ec1618230f7bbc927e1d2280976a9d5dd464.zip
Add relay toggle code
-rw-r--r--sw/Makefile1
-rw-r--r--sw/common.hpp12
-rw-r--r--sw/ltc2400.h2
-rw-r--r--sw/main.cpp46
-rw-r--r--sw/pins.hpp (renamed from sw/pins.h)6
-rw-r--r--sw/relays.cpp104
-rw-r--r--sw/relays.hpp7
7 files changed, 163 insertions, 15 deletions
diff --git a/sw/Makefile b/sw/Makefile
index bd9f6ff..0b76729 100644
--- a/sw/Makefile
+++ b/sw/Makefile
@@ -23,6 +23,7 @@ BUILD_DIR=build
APP_NAME = sw
HEADERS = \
+ pins.hpp \
common.hpp \
relays.hpp \
lib/Arduino.h \
diff --git a/sw/common.hpp b/sw/common.hpp
index 345f34b..fa0ee8e 100644
--- a/sw/common.hpp
+++ b/sw/common.hpp
@@ -26,6 +26,7 @@
#include <stdlib.h>
#include <stdint.h>
+#include <avr/interrupt.h>
struct timer_t {
uint32_t seconds_ = 0; /* Timer in seconds */
@@ -58,6 +59,11 @@ struct timer_t {
(seconds_ == rhs.seconds_ and ticks_ > rhs.ticks_);
}
+ bool operator<(const timer_t& rhs) const {
+ return (seconds_ < rhs.seconds_) or
+ (seconds_ == rhs.seconds_ and ticks_ < rhs.ticks_);
+ }
+
void normalise() {
while (ticks_ >= 10) {
seconds_++;
@@ -91,3 +97,9 @@ struct timer_t {
static constexpr int ms_to_ticks(int ms) { return ms / 100; }
};
+
+enum class relay_id_t {
+ K1,
+ K2,
+ K3,
+};
diff --git a/sw/ltc2400.h b/sw/ltc2400.h
index 9a046b2..ac99521 100644
--- a/sw/ltc2400.h
+++ b/sw/ltc2400.h
@@ -27,7 +27,7 @@
#include <stdlib.h>
#include <stdint.h>
-#include "pins.h"
+#include "pins.hpp"
void ltc2400_init();
diff --git a/sw/main.cpp b/sw/main.cpp
index f62fa27..fc61986 100644
--- a/sw/main.cpp
+++ b/sw/main.cpp
@@ -35,7 +35,8 @@
#include <avr/wdt.h>
#include "common.hpp"
-#include "pins.h"
+#include "pins.hpp"
+#include "relays.hpp"
#include "ltc2400.h"
extern "C" {
@@ -55,8 +56,19 @@ constexpr double R_SHUNT = 5e-3; // Ohm
constexpr double THRESHOLD_K1 = 1200.0 * 3600;
constexpr double THRESHOLD_K2 = 1000.0 * 3600;
constexpr double THRESHOLD_K3 = 600.0 * 3600;
+constexpr double THRESHOLD_HYSTERESIS = 10.0 * 3600;
+
+constexpr double THRESHOLD_K1_UP = 1200.0 * 3600 - THRESHOLD_HYSTERESIS;
+constexpr double THRESHOLD_K2_UP = 1000.0 * 3600 - THRESHOLD_HYSTERESIS;
+constexpr double THRESHOLD_K3_UP = 600.0 * 3600 - THRESHOLD_HYSTERESIS;
+
+constexpr double THRESHOLD_K1_DOWN = 1200.0 * 3600 + THRESHOLD_HYSTERESIS;
+constexpr double THRESHOLD_K2_DOWN = 1000.0 * 3600 + THRESHOLD_HYSTERESIS;
+constexpr double THRESHOLD_K3_DOWN = 600.0 * 3600 + THRESHOLD_HYSTERESIS;
+
constexpr double MAX_CAPACITY = 1500.0 * 3600;
-uint32_t current_capacity;
+static uint32_t current_capacity;
+static uint32_t previous_capacity;
/* Storage of battery capacity in mC.
* 3600 mC = 1mAh */
@@ -65,8 +77,9 @@ uint32_t current_capacity;
uint32_t EEMEM stored_capacity1;
uint32_t EEMEM stored_capacity2;
uint32_t EEMEM stored_capacity3;
-uint32_t last_store_time; /* In seconds */
+uint32_t last_store_time_seconds;
+uint32_t last_threshold_calculation_seconds;
timer_t last_ltc2400_measure;
timer_t last_ltc2400_print_time;
@@ -124,6 +137,8 @@ static void load_capacity_from_eeprom()
current_capacity = cap2; // arbitrary
#warning "Have a meaningful value for the very first startup value"
}
+
+ previous_capacity = current_capacity;
}
static void store_capacity_to_eeprom()
@@ -139,6 +154,11 @@ static void store_capacity_to_eeprom()
}
}
+static void handle_thresholds()
+{
+#warning "compare previous_capacity and current_capacity to thresholds and toggle relays accordingly"
+}
+
static char timestamp_buf[16];
static void send_message(const char *message)
{
@@ -201,6 +221,8 @@ int main()
pins_set_status(true);
+ relays_init();
+
// Initialise SPI and LTC2400
ltc2400_init();
@@ -247,8 +269,10 @@ int main()
/* Load capacity stored in EEPROM */
current_capacity = 0;
load_capacity_from_eeprom();
- last_ltc2400_print_time = last_ltc2400_measure = system_timer;
- last_store_time = system_timer.get_seconds_atomic();
+ last_ltc2400_print_time =
+ last_ltc2400_measure = system_timer;
+ last_store_time_seconds =
+ last_threshold_calculation_seconds = system_timer.get_seconds_atomic();
/* Enable interrupts */
sei();
@@ -265,7 +289,7 @@ int main()
pins_set_status(time_now.get_ticks_atomic() == 0);
- if (last_store_time + 3600 * 5 >= time_now.seconds_) {
+ if (last_store_time_seconds + 3600 * 5 >= time_now.seconds_) {
store_capacity_to_eeprom();
}
@@ -294,16 +318,22 @@ int main()
if (accum > MAX_CAPACITY) { accum = MAX_CAPACITY; }
current_capacity = lrint(accum);
-
-#warning "Handle thresholds for relays"
}
}
+ constexpr auto threshold_calculation_interval = 4;
+ if (last_threshold_calculation_seconds + threshold_calculation_interval > time_now.seconds_) {
+ last_threshold_calculation_seconds += threshold_calculation_interval;
+ handle_thresholds();
+ }
+
const auto ltc2400_print_interval = timer_t(10, 0);
if (last_ltc2400_print_time + ltc2400_print_interval > time_now) {
last_ltc2400_print_time += ltc2400_print_interval;
send_capacity(current_capacity);
}
+
+#warning "Add call to relays_handle"
}
return 0;
diff --git a/sw/pins.h b/sw/pins.hpp
index b22b2c9..7654819 100644
--- a/sw/pins.h
+++ b/sw/pins.hpp
@@ -91,9 +91,3 @@ inline void pins_set_status(bool enable)
}
}
-enum class relay_id_t {
- K1,
- K2,
- K3,
-};
-
diff --git a/sw/relays.cpp b/sw/relays.cpp
index 6604323..cb83626 100644
--- a/sw/relays.cpp
+++ b/sw/relays.cpp
@@ -23,5 +23,109 @@
*/
#include "relays.hpp"
+#include "pins.hpp"
#include <stdio.h>
#include <math.h>
+
+struct pending_event_t {
+ timer_t when;
+ relay_id_t relay;
+ bool set_not_reset;
+ bool level;
+ bool pending;
+};
+
+static constexpr int RELAY_SIGNAL_HOLD_TIME_MS = 400;
+
+static constexpr size_t PENDING_EVENTS_SIZE = 8;
+
+static pending_event_t pending_events[PENDING_EVENTS_SIZE];
+
+void relays_init()
+{
+ for (size_t i = 0; i < PENDING_EVENTS_SIZE; i++) {
+ pending_events[i].pending = false;
+ }
+}
+
+static void handle_event(pending_event_t& event)
+{
+ switch (event.relay) {
+ case relay_id_t::K1:
+ if (event.level) {
+ PORTD |= (event.set_not_reset ? PIND_K1_SET : PIND_K1_RESET);
+ }
+ else {
+ PORTD &= (event.set_not_reset ? ~PIND_K1_SET : ~PIND_K1_RESET);
+ }
+ break;
+ case relay_id_t::K2:
+ if (event.level) {
+ PORTC |= (event.set_not_reset ? PINC_K2_SET : PINC_K2_RESET);
+ }
+ else {
+ PORTC &= (event.set_not_reset ? ~PINC_K2_SET : ~PINC_K2_RESET);
+ }
+ break;
+ case relay_id_t::K3:
+ if (event.level) {
+ PORTC |= (event.set_not_reset ? PINC_K3_SET : PINC_K3_RESET);
+ }
+ else {
+ PORTC &= (event.set_not_reset ? ~PINC_K3_SET : ~PINC_K3_RESET);
+ }
+ break;
+ }
+
+ event.pending = false;
+}
+
+void relays_handle(const timer_t& time_now)
+{
+ for (size_t i = 0; i < PENDING_EVENTS_SIZE; i++) {
+ if (pending_events[i].pending and pending_events[i].when < time_now) {
+ handle_event(pending_events[i]);
+ }
+ }
+}
+
+bool relays_toggle(relay_id_t relay, bool set_not_reset, const timer_t& when)
+{
+ size_t num_free_events = 0;
+
+ for (size_t i = 0; i < PENDING_EVENTS_SIZE; i++) {
+ if (not pending_events[i].pending) {
+ num_free_events++;
+ }
+ }
+
+ if (num_free_events < 2) {
+ return false;
+ }
+
+ for (size_t i = 0; i < PENDING_EVENTS_SIZE; i++) {
+ if (not pending_events[i].pending) {
+ pending_events[i].pending = true;
+ pending_events[i].relay = relay;
+ pending_events[i].when = when;
+ pending_events[i].level = true;
+ pending_events[i].set_not_reset = set_not_reset;
+ break;
+ }
+ }
+
+ for (size_t i = 0; i < PENDING_EVENTS_SIZE; i++) {
+ if (not pending_events[i].pending) {
+ pending_events[i].pending = true;
+ pending_events[i].relay = relay;
+ pending_events[i].when = when +
+ timer_t{0, timer_t::ms_to_ticks(RELAY_SIGNAL_HOLD_TIME_MS)};
+
+ pending_events[i].level = false;
+ pending_events[i].set_not_reset = set_not_reset;
+ break;
+ }
+ }
+ return true;
+}
+
diff --git a/sw/relays.hpp b/sw/relays.hpp
index f6fc18b..8dd180e 100644
--- a/sw/relays.hpp
+++ b/sw/relays.hpp
@@ -26,4 +26,11 @@
#include <stdlib.h>
#include <stdint.h>
+#include "common.hpp"
+
+void relays_init();
+
+void relays_handle(const timer_t& time_now);
+
+bool relays_toggle(relay_id_t relay, bool set_not_reset, const timer_t& when);