Implement heater control

This change controls a GPIO on the expansion connector depending on the
surrounding temperature. If external temperature is too low for
charging, the GPIO is set high, else it is set low.

In combination with the new LNSC-2420-Addon board this allows to switch
on a high-power heater connected directly to the solar panels whenever
the temperature is too low to charge the battery. Once the temperature
becomes high enough again, the heater is switched off and the battery is
charged instead.
This commit is contained in:
Thomas Kolb 2023-04-22 20:02:16 +02:00
parent 1153da6fc2
commit 2cedcb712a
4 changed files with 66 additions and 0 deletions

35
src/addon_io.c Normal file
View file

@ -0,0 +1,35 @@
#include <libopencm3/stm32/gpio.h>
#include "pinout.h"
#include "addon_io.h"
static const uint32_t OUTPUT_LIST[2] = {ADDON_ISO_IO_OUT1, ADDON_ISO_IO_OUT2};
void addon_io_init(void)
{
// Isolated outputs configuration: output, initially low = off
gpio_clear(ADDON_ISO_IO_PORT, ADDON_ISO_IO_OUT1 | ADDON_ISO_IO_OUT2);
gpio_mode_setup(ADDON_ISO_IO_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, ADDON_ISO_IO_OUT1 | ADDON_ISO_IO_OUT2);
// Isolated inputs configuration: input, no pull resistors
gpio_mode_setup(ADDON_ISO_IO_PORT, GPIO_MODE_INPUT, GPIO_PUPD_NONE, ADDON_ISO_IO_IN);
}
void addon_io_iso_out_on(uint8_t idx)
{
gpio_set(ADDON_ISO_IO_PORT, OUTPUT_LIST[idx]);
}
void addon_io_iso_out_off(uint8_t idx)
{
gpio_clear(ADDON_ISO_IO_PORT, OUTPUT_LIST[idx]);
}
bool addon_io_read_iso_in(void)
{
return gpio_get(ADDON_ISO_IO_PORT, ADDON_ISO_IO_IN) != 0;
}

14
src/addon_io.h Normal file
View file

@ -0,0 +1,14 @@
#ifndef ADDON_IO_H
#define ADDON_IO_H
#include <stdint.h>
#include <stdbool.h>
void addon_io_init(void);
void addon_io_iso_out_on(uint8_t idx);
void addon_io_iso_out_off(uint8_t idx);
bool addon_io_read_iso_in(void);
#endif // ADDON_IO_H

View file

@ -8,6 +8,7 @@
#include "charge_pump.h" #include "charge_pump.h"
#include "rs485.h" #include "rs485.h"
#include "flash_config.h" #include "flash_config.h"
#include "addon_io.h"
#include "charge_control.h" #include "charge_control.h"
@ -243,12 +244,18 @@ static void solar_fsm_update(uint64_t uptime_ms, struct MeasurementResult *meas)
case CHARGE_LOW_EXTERNAL_TEMPERATURE: case CHARGE_LOW_EXTERNAL_TEMPERATURE:
if(charge_state_entered) { if(charge_state_entered) {
power_switch_solar_off(); power_switch_solar_off();
// switch on the heater via the isolated I/O addon board
addon_io_iso_out_on(0);
} }
// this state can only be entered if the BMP280 measurement is valid, so // this state can only be entered if the BMP280 measurement is valid, so
// no need to check it again here. // no need to check it again here.
if(bmp280_get_temperature() > external_temperature_recovery) { if(bmp280_get_temperature() > external_temperature_recovery) {
charge_state = CHARGE_WAIT_CHARGEPUMP; charge_state = CHARGE_WAIT_CHARGEPUMP;
// switch the heater off again when this state is left
addon_io_iso_out_off(0);
break; break;
} }
break; break;

View file

@ -43,6 +43,8 @@
#define RS485_TX_PIN GPIO6 #define RS485_TX_PIN GPIO6
#define RS485_RX_PIN GPIO7 #define RS485_RX_PIN GPIO7
/*** Expansion connector signals ***/
/* BMP280 I²C */ /* BMP280 I²C */
#define BMP280_I2C_PORT GPIOA #define BMP280_I2C_PORT GPIOA
@ -50,4 +52,12 @@
#define BMP280_I2C_SCL GPIO9 #define BMP280_I2C_SCL GPIO9
#define BMP280_I2C_SDA GPIO10 #define BMP280_I2C_SDA GPIO10
/* Isolated inputs and outputs on I/O addon board */
#define ADDON_ISO_IO_PORT GPIOA
#define ADDON_ISO_IO_OUT1 GPIO5
#define ADDON_ISO_IO_OUT2 GPIO6
#define ADDON_ISO_IO_IN GPIO7
#endif // PINOUT_H #endif // PINOUT_H