Filter overtemp signals
authorJoseph Coffland <joseph@cauldrondevelopment.com>
Fri, 16 Feb 2018 03:29:58 +0000 (19:29 -0800)
committerJoseph Coffland <joseph@cauldrondevelopment.com>
Fri, 16 Feb 2018 03:29:58 +0000 (19:29 -0800)
src/pwr/config.h
src/pwr/main.c

index 149451431a350e9bc09aaa422fa8b29def4b363b..f7a90a7760db4d359068db1e89a1192ab2f77d98 100644 (file)
@@ -80,9 +80,11 @@ enum {
 #define VOLTAGE_MIN 11
 #define VOLTAGE_MAX 39
 #define CURRENT_MAX 25
-#define LOAD_CURRENT_MAX 10.5
-#define CURRENT_OVERTEMP 19 // Should read ~21A but over 11.86A is faulty
+#define LOAD_CURRENT_MAX 8
+#define CURRENT_OVERTEMP 16 // Should read ~21A but over 11.86A is faulty
 #define LOAD_LIMIT_TICKS 10
+#define LOAD_SHUTDOWN_THRESH 10
+#define MOTOR_SHUTDOWN_THRESH 10
 #define VOLTAGE_SETTLE_COUNT 5
 #define VOLTAGE_SETTLE_PERIOD 20 // ms
 #define VOLTAGE_SETTLE_TOLERANCE 0.01
index 9ab2509b85e7edfe9ee315829d3f0ff764c8565a..8c94efa5dcc0be8f7386ad9798b970fd1acadc8c 100644 (file)
 
 
 typedef struct {
-  regs_t reg;
-  uint8_t pin;
-  uint8_t limit;
-  uint8_t count;
-  bool shutdown;
+  const regs_t reg;
+  const uint8_t pin;
+  volatile uint8_t limit;
+  volatile uint8_t count;
+  volatile uint8_t shutdown;
 } load_t;
 
+
 load_t loads[2] = {
-  {LOAD1_REG, LOAD1_PIN, 0, 0, false},
-  {LOAD2_REG, LOAD2_PIN, 0, 0, false},
+  {LOAD1_REG, LOAD1_PIN, 0, 0, 0},
+  {LOAD2_REG, LOAD2_PIN, 0, 0, 0},
 };
 
 
@@ -63,7 +64,7 @@ static const uint8_t ch_schedule[] = {
 
 static volatile uint16_t regs[NUM_REGS] = {0};
 static volatile uint64_t time = 0; // ms
-static volatile bool motor_overload = false;
+static volatile uint8_t motor_overload = 0;
 static volatile bool shunt_overload = false;
 static volatile float shunt_ms_power = 0;
 static volatile float vnom = 0;
@@ -115,6 +116,15 @@ ISR(TWI_SLAVE_vect) {
 }
 
 
+static bool limited_counter(volatile uint8_t *counter, bool up, uint8_t max) {
+  if (up) {
+    if (*counter < max) (*counter)++;
+  } else if (0 < *counter) (*counter)--;
+
+  return *counter == max;
+}
+
+
 static float get_total_current() {
   cli();
   float current =
@@ -177,24 +187,23 @@ static void measure_nominal_voltage() {
 
 
 static void check_load(load_t *load) {
-  if (load->shutdown) return;
+  if (LOAD_SHUTDOWN_THRESH <= load->shutdown) return;
 
   // Check overtemp
-  if (CURRENT_OVERTEMP * 100 < regs[load->reg]) {
+  bool overtemp = CURRENT_OVERTEMP * 100 < regs[load->reg];
+  if (limited_counter(&load->shutdown, overtemp, LOAD_SHUTDOWN_THRESH)) {
     IO_PORT_CLR(load->pin); // Lo
     IO_DDR_SET(load->pin);  // Output
-    load->shutdown = true;
   }
 
   // Check and adjust limit
-  if (LOAD_CURRENT_MAX * 100 < regs[load->reg]) {
-    if (load->limit < LOAD_LIMIT_TICKS) load->limit++;
-  } else if (load->limit) load->limit--;
+  bool overcurrent = LOAD_CURRENT_MAX * 100 < regs[load->reg];
+  limited_counter(&load->limit, overcurrent, LOAD_LIMIT_TICKS);
 }
 
 
 void limit_load(load_t *load) {
-  if (load->shutdown) return;
+  if (LOAD_SHUTDOWN_THRESH <= load->shutdown) return;
 
   // Limit
   if (load->count < load->limit) {
@@ -249,10 +258,12 @@ static void read_conversion(uint8_t ch) {
   case VIN_ADC:  regs[VIN_REG]  = convert_voltage(data); break;
   case VOUT_ADC: regs[VOUT_REG] = convert_voltage(data); break;
 
-  case CS1_ADC:
+  case CS1_ADC: {
     regs[MOTOR_REG] = convert_current(data);
-    if (CURRENT_OVERTEMP * 100 < regs[MOTOR_REG]) motor_overload = true;
+    bool overtemp = CURRENT_OVERTEMP * 100 < regs[MOTOR_REG];
+    limited_counter(&motor_overload, overtemp, MOTOR_SHUTDOWN_THRESH);
     break;
+  }
 
   case CS2_ADC: regs[VDD_REG] = convert_current(data); break;
 
@@ -429,9 +440,9 @@ int main() {
     if (VOLTAGE_MAX < vin || VOLTAGE_MAX < vout) flags |= OVER_VOLTAGE_FLAG;
     if (CURRENT_MAX < get_total_current()) flags |= OVER_CURRENT_FLAG;
     if (shunt_overload) flags |= SHUNT_OVERLOAD_FLAG;
-    if (motor_overload) flags |= MOTOR_OVERLOAD_FLAG;
-    if (loads[0].shutdown) flags |= LOAD1_OVERTEMP_FLAG;
-    if (loads[1].shutdown) flags |= LOAD2_OVERTEMP_FLAG;
+    if (MOTOR_SHUTDOWN_THRESH <= motor_overload) flags |= MOTOR_OVERLOAD_FLAG;
+    if (LOAD_SHUTDOWN_THRESH <= loads[0].shutdown) flags |= LOAD1_OVERTEMP_FLAG;
+    if (LOAD_SHUTDOWN_THRESH <= loads[1].shutdown) flags |= LOAD2_OVERTEMP_FLAG;
     if (loads[0].limit) flags |= LOAD1_LIMITING_FLAG;
     if (loads[1].limit) flags |= LOAD2_LIMITING_FLAG;