From 78c46c07ea090d6bc6362f2ec0a2af15391530b5 Mon Sep 17 00:00:00 2001 From: jhchun Date: Mon, 15 Jun 2026 11:58:41 +0900 Subject: [PATCH] =?UTF-8?q?=EC=98=A8=EB=8F=84=20=EC=84=BC=EC=84=9C=20TMP23?= =?UTF-8?q?5=20=EC=82=AD=EC=A0=9C(IMU=20=EC=98=A8=EB=8F=84=EB=A1=9C=20?= =?UTF-8?q?=EB=8C=80=EC=B2=B4)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CMakeLists.txt | 2 - README.md | 29 +++---- boards/nrf52840dk_nrf52840.overlay | 19 +---- boards/nrf5340dk_nrf5340_cpuapp.overlay | 15 +--- src/drivers/temperature/tmp235.c | 109 ------------------------ src/drivers/temperature/tmp235.h | 27 ------ src/main.c | 2 - src/parser.c | 35 ++------ 8 files changed, 25 insertions(+), 213 deletions(-) delete mode 100644 src/drivers/temperature/tmp235.c delete mode 100644 src/drivers/temperature/tmp235.h diff --git a/CMakeLists.txt b/CMakeLists.txt index d2c2ef4..ef441f2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,7 +12,6 @@ target_include_directories(app PRIVATE src/drivers/led src/drivers/imu src/drivers/piezo - src/drivers/temperature ) target_sources(app PRIVATE @@ -26,5 +25,4 @@ target_sources(app PRIVATE src/drivers/led/led_control.c src/drivers/imu/imu_i2c.c src/drivers/piezo/piezo.c - src/drivers/temperature/tmp235.c ) diff --git a/README.md b/README.md index fed5678..dce1e47 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ nRF52840 기반 VesiScan BASIC 펌웨어의 Zephyr 포팅 프로젝트 | 1 | LED 제어 (green/orange 패턴) | 완료 | | 2 | BLE 스택 + NUS (advertising, 연결, 재연결) | 완료 | | 3 | 배터리 ADC (AIN2, 12bit) | 완료 | -| 3 | 온도 센서 TMP235 (AIN3) | 완료 | +| 3 | IMU 내부 온도 센서 | 완료 | | 3 | IMU ICM42670P (I2C0) | 완료 | | 3 | 피에조 TX + mux 제어 | 완료 | | 3 | ADC121S051 echo capture (nrfx SPIM3) | 완료 | @@ -47,8 +47,6 @@ blinky/ │ └── led_control.c / .h # LED 패턴 제어 (k_timer 기반) ├── piezo/ │ └── piezo.c / .h # 피에조 전원, mux, SW burst - └── temperature/ - └── tmp235.c / .h # TMP235 온도 센서 (AIN3) ``` ## 빌드 방법 @@ -73,10 +71,9 @@ nRF Connect for VS Code → Build 패널 → **Pristine Build** 또는 `build` | `LED_BLE` | P0.12 | Output, Active LOW | 초록 LED | | `FUNCTION_LED` | P0.29 | Output, Active LOW | 주황 LED | | ADC AIN2 | P0.04 | Analog Input | 배터리 전압 분압 | -| ADC AIN3 | P0.05 | Analog Input | TMP235 온도 센서 | | I2C0 SCL | P1.14 | I2C | ICM42670P SCL | | I2C0 SDA | P1.15 | I2C | ICM42670P SDA | -| `PIEZO_PWR` | P1.09 | Output, Active HIGH | 피에조/TMP235 전원 enable | +| `PIEZO_PWR` | P1.09 | Output, Active HIGH | 피에조 전원 enable | | `PIEZO_PE` | P0.25 | Output, Active HIGH | 피에조 pulse enable | | `PIEZO_P_OUT` | P1.07 | Output | 피에조 P 출력 | | `PIEZO_N_OUT` | P1.06 | Output | 피에조 N 출력 | @@ -117,15 +114,16 @@ nRF Connect for VS Code → Build 패널 → **Pristine Build** 또는 `build` | `msn?` | `rsn:` + uint16 mV | 배터리 전압 측정 | | `mls?` | `rls:` + state | LED 상태 변경 | | `msp?` | `rsp:` + accel/gyro | IMU 단발 측정 | -| `mst?` | `rso:` + int16 cdeg | TMP235 온도 측정 | +| `mst?` | `rso:` + int16 cdeg | IMU 내부 온도 측정 | | `mpa?` | `rpa:` + status | 피에조 전원 ON | | `mpb?` | `rpb:` + status | 피에조 전원 OFF | | `mpc?` | `rpc:` + cycles/status | 피에조 burst 테스트 | -| `mec?` | `reb:` + `raa:` | 단일 채널 echo capture | -| `maa?` | `reb:` x6 + `raa:` | 6채널 echo sweep | -| `mbb?` | `rbb:` + `reb:` x6 + `raa:` | 배터리+IMU+온도+6채널 echo | +| `mec?` | `reb:` + `raa:` | 단일 채널 echo capture (`reb:` includes session/ch info) | +| `mad?` | `reb:` + `raa:` | burst 없이 ADC capture (`reb:` includes session/ch info) | +| `maa?` | `reb:` x6 + `raa:` | 6채널 echo sweep (`reb:` includes session/ch info) | +| `mbb?` | `rbb:` + `reb:` x6 + `raa:` | 배터리+IMU+온도+6채널 echo (`reb:` includes session/ch info) | | `mcf?` | `rcf:` | 측정 파라미터 읽기(현재 설정값 반환) | -| `mcs?` | `rcs:` + status | 측정 파라미터 쓰기 + NVS 저장 | +| `mcs?` | `rcs:` + current config | 측정 파라미터 쓰기 + NVS 저장 | | `mfv?` | `rfv:` | FW version 읽기 | | `mrh?` | `rrh:` | HW version 읽기(RAM/default) | | `mwh?` | `rwh:` | HW version 쓰기(RAM only) | @@ -156,10 +154,11 @@ nRF Connect for VS Code → Build 패널 → **Pristine Build** 또는 `build` | 16 | 피에조 전원 OFF | `mpb?` | `rpb:` | 구현 완료 | | 17 | 피에조 burst 테스트 | `mpc?` | `rpc:` | 구현 완료, `freq_option`은 아직 미사용 | | 18 | 단일 채널 측정 | `mec?` | `reb:` → `raa:` | 구현 완료, 테스트용 | -| 19 | 모든 채널(6) 측정 | `maa?` | `reb:`(6개) → `raa:` | 구현 완료 | -| 20 | 전체 측정 | `mbb?` | `rbb:` → `reb:`(6개) → `raa:` | 구현 완료 | -| 21 | 측정 파라미터 읽기 | `mcf?` | `rcf:` | 구현 완료, 현재 설정값 반환 | -| 22 | 측정 파라미터 쓰기 | `mcs?` | `rcs:` | 구현 완료, NVS 저장 | +| 19 | ADC only 측정 | `mad?` | `reb:` → `raa:` | 구현 완료, burst 없음 | +| 20 | 모든 채널(6) 측정 | `maa?` | `reb:`(6개) → `raa:` | 구현 완료 | +| 21 | 전체 측정 | `mbb?` | `rbb:` → `reb:`(6개) → `raa:` | 구현 완료 | +| 22 | 측정 파라미터 읽기 | `mcf?` | `rcf:` | 구현 완료, 현재 설정값 반환 | +| 23 | 측정 파라미터 쓰기 | `mcs?` | `rcs:` | 구현 완료, NVS 저장 | ## 남은 포팅 작업 @@ -207,7 +206,7 @@ nRF Connect for VS Code → Build 패널 → **Pristine Build** 또는 `build` | `CONFIG_BT_NUS` | y | Nordic UART Service | | `CONFIG_BT_L2CAP_TX_MTU` | 247 | MTU 크기 | | `CONFIG_BT_CTLR_TX_PWR_PLUS_8` | y | TX power +8dBm | -| `CONFIG_ADC` | y | ADC 드라이버 (배터리, 온도) | +| `CONFIG_ADC` | y | ADC 드라이버 (배터리) | | `CONFIG_I2C` | y | IMU I2C 드라이버 | | `CONFIG_NRFX_SPIM` | y | ADC121S051용 nrfx SPIM | | `CONFIG_BOOTLOADER_MCUBOOT` | y | MCUboot 사용 | diff --git a/boards/nrf52840dk_nrf52840.overlay b/boards/nrf52840dk_nrf52840.overlay index 1fa1bb9..d46885d 100644 --- a/boards/nrf52840dk_nrf52840.overlay +++ b/boards/nrf52840dk_nrf52840.overlay @@ -72,19 +72,6 @@ zephyr,oversampling = <2>; /* 2^2 = 4X */ }; - /* 온도 센서 채널 (AIN3 = P0.05, TMP235-Q1) - * 1/6 gain + 0.6V ref → 풀스케일 3.6V - * TMP235 출력 범위: 100mV(-40°C) ~ 2000mV(150°C) */ - channel@3 - { - reg = <3>; - zephyr,gain = "ADC_GAIN_1_6"; - zephyr,reference = "ADC_REF_INTERNAL"; - zephyr,acquisition-time = ; - zephyr,input-positive = ; - zephyr,resolution = <12>; - zephyr,oversampling = <2>; /* 2^2 = 4X */ - }; }; /* P0.04(AIN2)가 DK Arduino 헤더에 GPIO로 잡혀있어서 SAADC 충돌 → 비활성화 */ @@ -97,8 +84,8 @@ /* ADC 채널을 코드에서 참조하기 위한 zephyr,user 노드 */ zephyr,user { - io-channels = <&adc 2>, <&adc 3>; - io-channel-names = "battery", "temperature"; + io-channels = <&adc 2>; + io-channel-names = "battery"; }; led @@ -134,7 +121,7 @@ label = "Power Button"; }; - /* 피에조 TX/RX 전원 레일 제어 (TMP235 온도센서도 이 레일 공유) + /* 피에조 TX/RX 전원 레일 제어 * HIGH = 전원 ON, LOW = 전원 OFF */ PIEZO_PWR: PIEZO_PWR { diff --git a/boards/nrf5340dk_nrf5340_cpuapp.overlay b/boards/nrf5340dk_nrf5340_cpuapp.overlay index 9b5f02d..50599b2 100644 --- a/boards/nrf5340dk_nrf5340_cpuapp.overlay +++ b/boards/nrf5340dk_nrf5340_cpuapp.overlay @@ -7,7 +7,6 @@ * LED_BLE: P0.12 * LED_ORANGE: P0.29 * BATT_ADC: P0.04 - * TEMP_ADC: P0.05 * IMU_SCL: P1.14 * IMU_SDA: P1.15 */ @@ -64,16 +63,6 @@ zephyr,oversampling = <2>; }; - channel@1 - { - reg = <1>; - zephyr,gain = "ADC_GAIN_1_6"; - zephyr,reference = "ADC_REF_INTERNAL"; - zephyr,acquisition-time = ; - zephyr,input-positive = ; - zephyr,resolution = <12>; - zephyr,oversampling = <2>; - }; }; &arduino_adc @@ -84,8 +73,8 @@ / { zephyr,user { - io-channels = <&adc 0>, <&adc 1>; - io-channel-names = "battery", "temperature"; + io-channels = <&adc 0>; + io-channel-names = "battery"; }; led diff --git a/src/drivers/temperature/tmp235.c b/src/drivers/temperature/tmp235.c deleted file mode 100644 index c4b109a..0000000 --- a/src/drivers/temperature/tmp235.c +++ /dev/null @@ -1,109 +0,0 @@ -/******************************************************************************* - * @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 -#include -#include -#include - -#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_ERR("[TEMP] FAIL — ADC device not ready\r\n"); - return -1; - } - - int err = adc_channel_setup_dt(&temp_adc); - if (err) { - DBG_ERR("[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_ERR("[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_ERR("[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_ERR("[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; -} diff --git a/src/drivers/temperature/tmp235.h b/src/drivers/temperature/tmp235.h deleted file mode 100644 index bcede2a..0000000 --- a/src/drivers/temperature/tmp235.h +++ /dev/null @@ -1,27 +0,0 @@ -/******************************************************************************* - * @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 - -/** - * @brief 온도 센서 초기화 — ADC 채널 설정 - * @return 0 성공, 음수 에러 - */ -int temp_init(void); - -/** - * @brief 온도 1회 측정 - * @return 온도 (°C × 100), 에러 시 INT16_MIN - */ -int16_t temp_read_cdeg(void); - -#endif /* TMP235_H__ */ diff --git a/src/main.c b/src/main.c index 6b5f9c2..6cdc90f 100644 --- a/src/main.c +++ b/src/main.c @@ -26,7 +26,6 @@ #include "battery_adc.h" #include "parser.h" #include "imu_i2c.h" -#include "tmp235.h" LOG_MODULE_REGISTER(vesiscan, LOG_LEVEL_INF); @@ -606,7 +605,6 @@ int main(void) battery_adc_init(); battery_timer_init(); imu_init(); - temp_init(); piezo_config_init(); DBG_CORE(" gpio/timer/config/led/batt/imu/temp/piezo-cfg OK\r\n"); diff --git a/src/parser.c b/src/parser.c index 5dd1bb0..7598aeb 100644 --- a/src/parser.c +++ b/src/parser.c @@ -22,7 +22,6 @@ #include "echo_adc.h" #include "imu_i2c.h" #include "piezo.h" -#include "tmp235.h" /*============================================================================== * Piezo / echo measurement constants @@ -718,46 +717,24 @@ static int cmd_msp(const uint8_t *data, uint8_t data_len) return 1; } -/* mst? → 피에조 전원 ON → TMP235 온도 측정 → 전원 OFF → rso: + 온도(°C × 100, BE) - * - * TMP235가 피에조 레일을 공유하므로 ON/OFF 시퀀스를 한 커맨드에서 처리. - * 안정화 대기 10ms: TMP235 start-up(~2ms) + 레일 RC 필터 여유분. - * 에러 응답: 0xFFFF = ADC 읽기 실패 */ +/* mst? -> IMU internal temperature -> rso: + temperature (degC x 100, BE) + * Error response: 0xFFFF = IMU temperature read failed. */ static int cmd_mst(const uint8_t *data, uint8_t data_len) { ARG_UNUSED(data); ARG_UNUSED(data_len); - /* - * mst?는 "온도만 읽는 명령"처럼 보이지만, - * 실제로는 TMP235가 piezo 전원 레일을 같이 쓰기 때문에 - * 전원 ON/OFF 시퀀스까지 같이 처리해야 한다. - */ power_button_suspend(true); - if (piezo_init() != 0) - { - power_button_suspend(false); - send_response_u16("rso:", 0xFFFF); - DBG_PRINTF("[CMD] mst: piezo init fail\r\n"); - return 1; - } + int16_t t_cdeg = INT16_MIN; + int ret = imu_read_temperature_cdeg(&t_cdeg); - /* 전원 ON → 센서 안정화 대기 */ - piezo_power_on(); - k_msleep(10); - - int16_t t_cdeg = temp_read_cdeg(); - - /* 전원 OFF (측정 완료, 레일 끄기) */ - piezo_power_off(); power_button_suspend(false); - /* ADC 읽기 실패 → 에러 코드 0xFFFF */ - if (t_cdeg == INT16_MIN) + if ((ret != 0) || (t_cdeg == INT16_MIN)) { send_response_u16("rso:", 0xFFFF); - DBG_PRINTF("[CMD] mst: temp read fail\r\n"); + DBG_PRINTF("[CMD] mst: imu temp read fail ret=%d\r\n", ret); return 1; }