주기적 배터리 저전압 및 고온 체크

- 온도 측정 추가
This commit is contained in:
2026-04-16 19:01:12 +09:00
parent 143e22c2d8
commit 24e5b2e205
3 changed files with 122 additions and 44 deletions

View File

@@ -3,8 +3,9 @@
* *
* Measures battery voltage via nRF52840 SAADC on AIN2: * Measures battery voltage via nRF52840 SAADC on AIN2:
* - 12-bit resolution, 4x oversampling * - 12-bit resolution, 4x oversampling
* - Periodic monitoring via battery_loop timer (60 s interval) * - Periodic safety check via battery_loop timer (60 s interval)
* - Auto power-off after 10 consecutive readings below 3500 mV * - Sequential: battery -> temperature measurement
* - Auto power-off after 5 consecutive readings below 3500 mV or above 40 C
* - In info4 mode (bulk sensor collection): stores to info_batt * - In info4 mode (bulk sensor collection): stores to info_batt
* *
* Voltage conversion: * Voltage conversion:
@@ -26,7 +27,8 @@
#include "app_timer.h" #include "app_timer.h"
#include "battery_saadc.h" #include "battery_saadc.h"
#include "main_timer.h" #include "main_timer.h"
#include "main.h" #include "tmp235_q1.h"
#include "dr_piezo.h"
#include "debug_print.h" #include "debug_print.h"
/* SAADC internal reference voltage (mV, float) */ /* SAADC internal reference voltage (mV, float) */
@@ -51,12 +53,25 @@ APP_TIMER_DEF(m_battery_loop_timer_id);
/* Battery monitoring interval (ms) */ /* Battery monitoring interval (ms) */
#define BATTERY_LOOP_INTERVAL 60000 #define BATTERY_LOOP_INTERVAL 60000
/* Safety check consecutive count threshold */
#define SAFETY_CHECK_COUNT 5
/* Low-battery check flag — set by battery_loop, consumed by handler */ /* Low-battery check flag — set by battery_loop, consumed by handler */
bool low_battery_check = false; bool low_battery_check = false;
/* Safety check mode flag — set by battery handler, consumed by tmp235 handler */
bool safety_check_mode = false;
/* SAADC callback completion flag — used by all_sensors() to wait */ /* SAADC callback completion flag — used by all_sensors() to wait */
volatile bool battery_saadc_done = false; volatile bool battery_saadc_done = false;
/* Safety check: cached battery voltage for use in safety_check_complete() */
static float safety_batt_mv = 0;
/* Safety check: consecutive counters */
static uint8_t low_battery_cnt = 0;
static uint8_t over_temp_cnt = 0;
/* info4: bulk sensor collection mode flag */ /* info4: bulk sensor collection mode flag */
extern bool info4; extern bool info4;
@@ -76,23 +91,73 @@ extern bool motion_raw_data_enabled ;
extern bool ble_got_new_data; extern bool ble_got_new_data;
extern bool motion_data_once; extern bool motion_data_once;
/*==============================================================================
* safety_check_complete - Called by tmp235 handler after temperature measurement
*
* Checks both battery voltage and temperature against thresholds.
* 5 consecutive readings exceeding either threshold triggers power OFF.
*============================================================================*/
void safety_check_complete(float temp_c)
{
DBG_PRINTF("[SAFETY] Batt=%d mV, Temp=%d.%d C\r\n",
(int)safety_batt_mv, (int)temp_c, ((int)(temp_c * 10)) % 10);
/* Battery check */
if (safety_batt_mv <= LOW_BATTERY_VOLTAGE)
{
low_battery_cnt++;
DBG_PRINTF("[SAFETY] Low batt cnt=%d\r\n", low_battery_cnt);
}
else
{
low_battery_cnt = 0;
}
/* Temperature check */
if (temp_c >= OVER_TEMPERATURE_THRESHOLD)
{
over_temp_cnt++;
DBG_PRINTF("[SAFETY] Over temp cnt=%d\r\n", over_temp_cnt);
}
else
{
over_temp_cnt = 0;
}
/* Power OFF if either threshold exceeded 5 consecutive times */
if (low_battery_cnt >= SAFETY_CHECK_COUNT)
{
low_battery_cnt = 0;
DBG_PRINTF("[SAFETY] Low battery -> Power OFF\r\n");
go_device_power_off = true;
main_timer_start();
}
else if (over_temp_cnt >= SAFETY_CHECK_COUNT)
{
over_temp_cnt = 0;
DBG_PRINTF("[SAFETY] Over temperature -> Power OFF\r\n");
go_device_power_off = true;
main_timer_start();
}
dr_piezo_power_off();
}
/*============================================================================== /*==============================================================================
* battery_event_handler - SAADC conversion complete callback * battery_event_handler - SAADC conversion complete callback
* *
* Converts the raw ADC value to battery voltage (mV) and then: * Converts the raw ADC value to battery voltage (mV) and then:
* - Low-battery check mode: if <= 3500 mV for 10 consecutive times -> power OFF * - Low-battery check mode: store voltage, chain temperature measurement
* - info4 mode: store to info_batt (no BLE send) * - info4 mode: store to info_batt (no BLE send)
* - Normal mode: send rsn: response over BLE or UART * - Normal mode: send rsn: response over BLE or UART
*============================================================================*/ *============================================================================*/
void battery_event_handler(nrf_drv_saadc_evt_t const * p_event) void battery_event_handler(nrf_drv_saadc_evt_t const * p_event)
{ {
static uint8_t low_battery_cnt = 0;
if (p_event->type == NRF_DRV_SAADC_EVT_DONE) if (p_event->type == NRF_DRV_SAADC_EVT_DONE)
{ {
nrf_saadc_value_t register_val = 0; nrf_saadc_value_t register_val = 0;
float batt_lvl_in_milli_volt_0 = 0; /* before divider correction */ float batt_lvl_in_milli_volt_0 = 0;
float batt_lvl_in_milli_volt_1 = 0; /* after divider correction */ float batt_lvl_in_milli_volt_1 = 0;
register_val = p_event->data.done.p_buffer[0]; register_val = p_event->data.done.p_buffer[0];
@@ -106,28 +171,21 @@ void battery_event_handler( nrf_drv_saadc_evt_t const * p_event )
batt_lvl_in_milli_volt_0 = BATTERY_RESULT_IN_MILLI_VOLTS(register_val); batt_lvl_in_milli_volt_0 = BATTERY_RESULT_IN_MILLI_VOLTS(register_val);
/* Resistor divider correction factor 1.42 */ /* Resistor divider correction factor 1.42 */
batt_lvl_in_milli_volt_1 = (batt_lvl_in_milli_volt_0) *1.42f; batt_lvl_in_milli_volt_1 = batt_lvl_in_milli_volt_0 * 1.42f;
/* --- Low-battery check mode (set by battery_loop timer) --- */ /* --- Safety check mode: store voltage, chain temperature measurement --- */
if (low_battery_check == true) if (low_battery_check == true)
{ {
low_battery_check = false; low_battery_check = false;
safety_batt_mv = batt_lvl_in_milli_volt_1;
safety_check_mode = true;
if(batt_lvl_in_milli_volt_1 <= LOW_BATTERY_VOLTAGE) /* TMP235 shares piezo TX/RX power rail */
if (!dr_piezo_is_power_on())
{ {
if(low_battery_cnt >= 10) dr_piezo_power_on();
{
low_battery_cnt = 0;
DBG_PRINTF("Save FDS parameters and then Power OFF\r\n");
go_device_power_off = true;
main_timer_start();
}
else
{
low_battery_cnt++;
DBG_PRINTF("WARNING!!! low_battery cnt = %d, Batt = %d(mV)\r\n", low_battery_cnt, (int)batt_lvl_in_milli_volt_1);
}
} }
tmp235_voltage_level_meas();
} }
/* --- info4 mode: store value for mbb? bulk response --- */ /* --- info4 mode: store value for mbb? bulk response --- */
@@ -165,7 +223,8 @@ static void battery_configure(void)
saadc_config.resolution = NRF_SAADC_RESOLUTION_12BIT; saadc_config.resolution = NRF_SAADC_RESOLUTION_12BIT;
saadc_config.oversample = NRF_SAADC_OVERSAMPLE_4X; saadc_config.oversample = NRF_SAADC_OVERSAMPLE_4X;
ret_code_t err_code = nrf_drv_saadc_init(&saadc_config, battery_event_handler); ret_code_t err_code = nrf_drv_saadc_init(&saadc_config, battery_event_handler);
if (err_code != NRF_SUCCESS) { if (err_code != NRF_SUCCESS)
{
return; /* SAADC busy — skip this cycle, retry next */ return; /* SAADC busy — skip this cycle, retry next */
} }
@@ -199,7 +258,7 @@ void battery_level_meas(void)
* battery_loop - Periodic battery monitoring timer callback * battery_loop - Periodic battery monitoring timer callback
* *
* Sets the low-battery check flag and starts a measurement. * Sets the low-battery check flag and starts a measurement.
* Skips if another sensor (IMU / info4) is already running (SAADC conflict). * Skips if info4 mode is active (SAADC conflict).
*============================================================================*/ *============================================================================*/
void battery_loop(void * p_context) void battery_loop(void * p_context)
{ {

View File

@@ -5,24 +5,35 @@
* *
* API: * API:
* battery_level_meas() : one-shot measurement (async, result via callback) * battery_level_meas() : one-shot measurement (async, result via callback)
* battery_timer_init/start/stop() : 5-second periodic monitoring timer * battery_timer_init/start/stop() : 60-second periodic monitoring timer
* *
* Auto power-off is triggered after 10 consecutive readings below * Periodic safety check (every 60 s):
* LOW_BATTERY_VOLTAGE (3500 mV). * Battery -> Temperature sequential measurement via SAADC.
* Auto power-off after 5 consecutive readings below LOW_BATTERY_VOLTAGE (3500 mV)
* or above OVER_TEMPERATURE_THRESHOLD (40 C).
*============================================================================*/ *============================================================================*/
#ifndef _BATTERY_SAADC_H_ #ifndef _BATTERY_SAADC_H_
#define _BATTERY_SAADC_H_ #define _BATTERY_SAADC_H_
/* Low-battery threshold (mV) — 10 consecutive readings below this -> power OFF */ /* Low-battery threshold (mV) — 5 consecutive readings below this -> power OFF */
#define LOW_BATTERY_VOLTAGE 3500 #define LOW_BATTERY_VOLTAGE 3500
/* Over-temperature threshold (deg C) — 5 consecutive readings above this -> power OFF */
#define OVER_TEMPERATURE_THRESHOLD 40.0f
/* SAADC callback completion flag (used by all_sensors() to wait) */ /* SAADC callback completion flag (used by all_sensors() to wait) */
extern volatile bool battery_saadc_done; extern volatile bool battery_saadc_done;
/* Safety check mode flag — set by battery_loop, consumed by tmp235 handler */
extern bool safety_check_mode;
/* Called by tmp235 handler when safety check temperature measurement completes */
void safety_check_complete(float temp_c);
/* Start a single async battery measurement. Result handled in callback. */ /* Start a single async battery measurement. Result handled in callback. */
void battery_level_meas(void); void battery_level_meas(void);
/* Start the 5-second periodic battery monitoring timer. */ /* Start the 60-second periodic battery monitoring timer. */
void battery_timer_start(void); void battery_timer_start(void);
/* Stop the battery monitoring timer. */ /* Stop the battery monitoring timer. */
void battery_timer_stop(void); void battery_timer_stop(void);

View File

@@ -24,6 +24,7 @@
#include "tmp235_q1.h" #include "tmp235_q1.h"
#include "main.h" #include "main.h"
#include "main_timer.h" #include "main_timer.h"
#include "battery_saadc.h"
#include "debug_print.h" #include "debug_print.h"
/* SAADC internal reference (mV) */ /* SAADC internal reference (mV) */
@@ -101,9 +102,16 @@ void tmp235_voltage_handler(nrf_drv_saadc_evt_t const * p_event)
DBG_PRINTF("ERR!!! Temperature is over 150c\r\n"); DBG_PRINTF("ERR!!! Temperature is over 150c\r\n");
} }
if (info4 == true) /* --- Safety check mode: pass temperature to battery module for judgment --- */
if (safety_check_mode == true)
{
safety_check_mode = false;
safety_check_complete(led_temp);
}
/* --- info4 mode: store value for mbb? bulk response --- */
else if (info4 == true)
{ {
/* Store as integer (e.g. 36.50 C -> 3650) */
info_temp = (uint16_t)(led_temp * 100); info_temp = (uint16_t)(led_temp * 100);
} }
else if (cmd_type_t == CMD_UART) else if (cmd_type_t == CMD_UART)