온도 adc 측정 추가

This commit is contained in:
geniushyun
2026-04-12 19:15:59 +09:00
parent 6ac0490263
commit 201f1bcff2
6 changed files with 160 additions and 3 deletions
+1 -1
View File
@@ -29,7 +29,7 @@
#define ZEPHYR_USER_NODE DT_PATH(zephyr_user)
/* 디바이스트리에서 ADC 채널 스펙 가져오기 (gain, ref, acq time, input, resolution, oversampling) */
static const struct adc_dt_spec battery_adc = ADC_DT_SPEC_GET(ZEPHYR_USER_NODE);
static const struct adc_dt_spec battery_adc = ADC_DT_SPEC_GET_BY_NAME(ZEPHYR_USER_NODE, battery);
static int16_t adc_buffer;
+109
View File
@@ -0,0 +1,109 @@
/*******************************************************************************
* @file tmp235.c
* @brief TMP235-Q1 온도 센서 드라이버 (Zephyr SAADC, AIN3 = P0.05)
*
* 배터리 ADC와 동일한 방식 (ADC_DT_SPEC_GET_BY_NAME + adc_read_dt).
* 채널 설정은 overlay channel@3에서 관리.
*
* 변환 공식:
* V_mV = raw × 3600 / 4095 (1/6 gain, 0.6V ref, 12-bit)
* T(°C × 100) = (V_mV - 500) × 10
******************************************************************************/
#include <zephyr/kernel.h>
#include <zephyr/drivers/adc.h>
#include <zephyr/devicetree.h>
#include <limits.h>
#include "tmp235.h"
#include "debug_print.h"
/*==============================================================================
* ADC 디바이스트리 설정
*============================================================================*/
#define ZEPHYR_USER_NODE DT_PATH(zephyr_user)
static const struct adc_dt_spec temp_adc =
ADC_DT_SPEC_GET_BY_NAME(ZEPHYR_USER_NODE, temperature);
static int16_t adc_buffer;
/*==============================================================================
* 내부 변환
*============================================================================*/
/**
* @brief ADC raw → 온도 (°C × 100)
*
* V_mV = raw × 3600 / 4095
* T_cdeg = (V_mV - 500) × 10
*
* 정수 연산 (오버플로 없음):
* raw 최대 4095 → V_mV 최대 3600 → T_cdeg 최대 31000 → int32 OK
*/
static int16_t raw_to_cdeg(int16_t raw)
{
if (raw < 0) {
raw = 0;
}
int32_t v_mv = (int32_t)raw * 3600 / 4095;
int32_t t_cdeg = (v_mv - 500) * 10;
return (int16_t)t_cdeg;
}
/*==============================================================================
* 공개 API
*============================================================================*/
int temp_init(void)
{
if (!adc_is_ready_dt(&temp_adc)) {
DBG_PRINTF("[TEMP] FAIL — ADC device not ready\r\n");
return -1;
}
int err = adc_channel_setup_dt(&temp_adc);
if (err) {
DBG_PRINTF("[TEMP] FAIL — channel setup (err=%d)\r\n", err);
return -2;
}
DBG_PRINTF("[TEMP] OK — TMP235 ch=%d, res=%d, os=%d\r\n",
temp_adc.channel_id,
temp_adc.resolution,
temp_adc.oversampling);
return 0;
}
int16_t temp_read_cdeg(void)
{
/* 매번 채널 재설정 (배터리 ADC와 SAADC 공유) */
int err = adc_channel_setup_dt(&temp_adc);
if (err) {
DBG_PRINTF("[TEMP] FAIL — channel setup (err=%d)\r\n", err);
return INT16_MIN;
}
struct adc_sequence seq = {0};
err = adc_sequence_init_dt(&temp_adc, &seq);
if (err) {
DBG_PRINTF("[TEMP] FAIL — sequence init (err=%d)\r\n", err);
return INT16_MIN;
}
seq.buffer = &adc_buffer;
seq.buffer_size = sizeof(adc_buffer);
err = adc_read_dt(&temp_adc, &seq);
if (err) {
DBG_PRINTF("[TEMP] FAIL — read (err=%d)\r\n", err);
return INT16_MIN;
}
int16_t t = raw_to_cdeg(adc_buffer);
DBG_PRINTF("[TEMP] raw=%d -> %d.%02d C\r\n",
adc_buffer, t / 100, (t < 0 ? -t : t) % 100);
return t;
}
+27
View File
@@ -0,0 +1,27 @@
/*******************************************************************************
* @file tmp235.h
* @brief TMP235-Q1 온도 센서 드라이버 (Zephyr SAADC, AIN3 = P0.05)
*
* 출력 공식: V = 500mV + 10mV/°C × T
* → T(°C) = (V_mV - 500) / 10
* → T(°Cx100) = (V_mV - 500) × 10
******************************************************************************/
#ifndef TMP235_H__
#define TMP235_H__
#include <stdint.h>
/**
* @brief 온도 센서 초기화 — ADC 채널 설정
* @return 0 성공, 음수 에러
*/
int temp_init(void);
/**
* @brief 온도 1회 측정
* @return 온도 (°C × 100), 에러 시 INT16_MIN
*/
int16_t temp_read_cdeg(void);
#endif /* TMP235_H__ */
+3 -1
View File
@@ -24,6 +24,7 @@
#include "battery_adc.h"
#include "parser.h"
#include "imu_i2c.h"
#include "tmp235.h"
LOG_MODULE_REGISTER(vesiscan, LOG_LEVEL_INF);
@@ -309,8 +310,9 @@ int main(void)
led_init();
battery_adc_init();
battery_timer_init();
DBG_PRINTF(" gpio/timer/config/led/batt OK\r\n");
imu_init();
temp_init();
DBG_PRINTF(" gpio/timer/config/led/batt/imu/temp OK\r\n");
/*── Phase 2: BLE 스택 + NUS ──*/
DBG_PRINTF("[2] BLE Init\r\n");