Files
VesiScan-Basic-firmware-test/project/ble_peripheral/ble_app_bladder_patch/tmp235_q1.c
jhChun 4881c7f937 - Piezo 6ch 측정 + 센서(배터리, IMU, 온도) 측정: mbb 명령어 추가
- Flash Memory Piezo 측정 파라미터 추가

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 13:54:06 +09:00

206 lines
7.8 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*******************************************************************************
* @file tmp235_q1.c
* @author CandyPops Co.
* @version V1.0.0
* @date 2022-09-05
* @brief
******************************************************************************/
/*******************************************************************************
* [모듈 개요] TMP235-Q1 아날로그 온도센서 드라이버
*
* TMP235-Q1은 온도에 비례하는 아날로그 전압(Vout)을 출력하는 센서
* nRF52840 SAADC의 AIN3 채널로 Vout을 읽고, mV로 변환한 뒤 온도(°C)로 계산
*
* 온도 계산 공식 (구간별 선형 보간):
* - Vout <= 1500mV (0~100°C): Ta = (Vout - 500) / 10.0
* - Vout <= 1750mV (100~125°C): Ta = (Vout - 1500) / 10.1 + 100
* - Vout <= 2000mV (125~150°C): Ta = (Vout - 1752.5) / 10.6 + 125
* - Vout > 2000mV: 오류 (150°C 초과)
*
* info4 모드(전체 센서 수집) 동작 순서:
* 배터리(go_batt) → 온도(go_temp) → IMU(motion_raw_data_enabled)
* 온도 측정 완료 시 go_temp=false, motion_raw_data_enabled=true 로 전환
******************************************************************************/
#include "sdk_common.h"
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include "nrf.h"
#include "boards.h"
#include "app_error.h"
#include "nrf_drv_saadc.h"
#include "ble_nus.h"
#include "tmp235_q1.h"
#include "main.h"
/* 2026-03-17: cmd_parse.h 삭제 — main.h는 이미 포함됨 */
#include "main_timer.h"
#include "debug_print.h"
/* SAADC 내부 기준전압 600mV (부동소수점) */
#define TMP235_REF_VOLTAGE_IN_MILLIVOLTS 600.0f /**< Reference voltage (in milli volts) used by ADC while doing conversion. */
/* 1/3 프리스케일링 보상 계수 x6 (부동소수점) */
#define TMP235_PRE_SCALING_COMPENSATION 6.0f /**< The ADC is configured to use VDD with 1/3 prescaling as input. And hence the result of conversion is to be multiplied by 3 to get the actual value of the battery voltage.*/
/* 10비트 ADC 최대값 1024 (부동소수점, 분해능 기준) */
#define TMP235_ADC_RES_10BITS 1024.0f /**< Maximum digital value for 10-bit ADC conversion. */
/**@brief Macro to convert the result of ADC conversion in millivolts.
*
* @param[in] ADC_VALUE ADC result.
*
* @retval Result converted to millivolts.
*/
/* ADC 원시값 → TMP235 출력전압(mV) 변환 매크로: ADC x (600/1024) x 6 */
#define TMP235_VOUT_IN_MILLI_VOLTS(ADC_VALUE)\
((((ADC_VALUE) * TMP235_REF_VOLTAGE_IN_MILLIVOLTS) / TMP235_ADC_RES_10BITS) * TMP235_PRE_SCALING_COMPENSATION)
/* SAADC 변환 결과 저장 버퍼 (1채널) */
static nrf_saadc_value_t adc_buf;
extern char ble_tx_buffer[BLE_NUS_MAX_DATA_LEN];
extern uint8_t ble_bin_buffer[BLE_NUS_MAX_DATA_LEN] ;
/* 현재 명령 소스: CMD_UART 또는 CMD_BLE */
extern which_cmd_t cmd_type_t;
/* info4: 전체 센서 데이터 수집 모드 플래그 */
extern bool info4; // main.c
/* 온도 측정 순서 제어 플래그 */
extern bool go_temp; // main_timer.c
/* info4 모드에서 온도값 임시 저장 (°C x 100, 정수 표현) */
volatile uint16_t info_temp; //48_C
extern bool motion_raw_data_enabled;
/**@brief Function for handling the ADC interrupt.
*
* @details This function will fetch the conversion result from the ADC, convert the value into
* percentage and send it to peer.
*/
/**
* @brief TMP235 온도센서 ADC 완료 콜백
*
* SAADC 변환 완료 시 호출된다.
* ADC값 → Vout(mV) → 온도(°C) 순으로 변환하고, 동작 모드에 따라:
* - info4 모드: info_temp에 저장 (°C x 100 정수), 이후 IMU 측정으로 전환
* - 일반 모드: BLE("rso:" 바이너리) 또는 UART로 온도값 전송
*/
void tmp235_voltage_handler(nrf_drv_saadc_evt_t const * p_event) /* TMP325 Vout reading */
{
float led_temp; /* 계산된 온도 (°C, 부동소수점) */
uint16_t led_temp_16; /* BLE 전송용 온도 (°C x 100, 정수) */
if (p_event->type == NRF_DRV_SAADC_EVT_DONE)
{
nrf_saadc_value_t adc_result;
float tmp235_voltage_in_milli_volts = 0;
/* ADC 변환 결과 읽기 */
adc_result = p_event->data.done.p_buffer[0];
DBG_PRINTF("[TMP] adc=%d\r\n", adc_result);
/* SAADC 해제 — 배터리/압력센서 측정과 하드웨어 공유 */
nrf_drv_saadc_uninit();
nrf_drv_saadc_channel_uninit(0);
/* ADC값 → TMP235 출력전압(mV) 변환 */
tmp235_voltage_in_milli_volts = TMP235_VOUT_IN_MILLI_VOLTS(adc_result);
/*
* Vout → 온도(°C) 변환 (구간별 선형 보간)
* TMP235 데이터시트 기반:
* 0~100°C 구간: 기울기 10.0 mV/°C, 오프셋 500mV
* 100~125°C 구간: 기울기 10.1 mV/°C
* 125~150°C 구간: 기울기 10.6 mV/°C
*/
if(tmp235_voltage_in_milli_volts <= 1500)
{
/* 0~100°C: Ta = (Vout - 500mV) / 10.0 mV/°C */
led_temp = (tmp235_voltage_in_milli_volts - 500.0f) / 10.0f + 0.0f;
}
else if(tmp235_voltage_in_milli_volts <= 1750)
{
/* 100~125°C: 기울기가 10.1로 약간 증가 */
led_temp = (tmp235_voltage_in_milli_volts - 1500.0f) / 10.1f + 100.0f;
}
else if(tmp235_voltage_in_milli_volts <= 2000)
{
/* 125~150°C: 기울기가 10.6으로 더 증가 */
led_temp = (tmp235_voltage_in_milli_volts - 1752.5f) / 10.6f + 125.0f;
}
else
{
/* 150°C 초과 — 센서 측정 범위 벗어남 */
DBG_PRINTF("ERR!!! Temprature is over 150c\r\n");
}
/* info4 모드: 온도값을 정수(°C x 100)로 저장 (예: 36.50°C → 3650) */
if (info4 == true)
{
info_temp =(uint16_t)(led_temp*100);
}
/* UART 모드: 소수점 2자리까지 텍스트로 출력 */
else if(cmd_type_t == CMD_UART)
{
DBG_PRINTF("To%.2f\r\n\r\n",led_temp);
}
/* BLE 모드: °C x 100 정수를 "rso:" 헤더로 바이너리 전송 */
else if(cmd_type_t == CMD_BLE)
{
led_temp_16 = (uint16_t)(led_temp*100);
single_format_data(ble_bin_buffer, "rso:", led_temp_16);
dr_binary_tx_safe(ble_bin_buffer,3);
// sprintf(ble_tx_buffer, "To%.2f\r\n",led_temp);
// data_tx_handler(ble_tx_buffer);
}
}
}
/**
* @brief TMP235 온도센서 SAADC 초기화 및 측정 시작
*
* AIN3 채널을 싱글엔드 모드로 설정하고 즉시 샘플링을 트리거한다.
* 결과는 tmp235_voltage_handler 콜백에서 비동기로 처리된다.
*/
void tmp235_init(void)
{
/* SAADC 드라이버 초기화 (기본 설정 + 온도센서 이벤트 핸들러 등록) */
ret_code_t err_code = nrf_drv_saadc_init(NULL, tmp235_voltage_handler);
APP_ERROR_CHECK(err_code);
/* AIN3 채널 설정: TMP235-Q1 Vout 핀 (싱글엔드 입력) */
nrf_saadc_channel_config_t config = NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(NRF_SAADC_INPUT_AIN3); /* TMP235_Q1 Voltage Output Measurement */
err_code = nrf_drv_saadc_channel_init(0, &config);
APP_ERROR_CHECK(err_code);
/* ADC 버퍼 등록 (1채널, 1샘플) */
err_code = nrf_drv_saadc_buffer_convert(&adc_buf, 1);
APP_ERROR_CHECK(err_code);
/* 즉시 ADC 샘플링 시작 (비동기) */
err_code = nrf_drv_saadc_sample();
APP_ERROR_CHECK(err_code);
}
/* Ta = (Vout Voffs ) / Tc + Tinfl */
/**
* @brief 온도 측정 외부 호출 함수
*
* tmp235_init()을 호출하여 SAADC 초기화 + 측정을 일괄 수행한다.
* 내부적으로 init 시 바로 샘플링이 시작되므로 별도 sample 호출 불필요.
*/
void tmp235_voltage_level_meas(void)
{
tmp235_init(); // init 함수에 있는 걸 그냥 여기 넣어도
//tmp235_uninit();
}