본문 바로가기
아날로그회로(Analog Circuit)/ADC관련

ZSC31014 Sensor Signal Conditioner IC 보정 공식과 파이썬을 이용한 계수 추출

by linuxgo 2025. 8. 2.

ZSC31014는 센서 신호를 디지털 방식으로 보정하는 칩으로, 브릿지 신호와 온도 신호를 보정하여 정확한 출력을 제공합니다 . 이 글에서는 ZSC31014 데이터시트의 보정 공식과 계수 계산 방법을 설명합니다.

1. 브릿지 신호 보정 (Bridge Signal Compensation)

브릿지 신호 보정은 원시 브릿지 신호(BR_Raw)를 보정하여 최종 출력(ZB)을 생성합니다 . 포물선형 보정(SOT_curve = 0)은 다음과 같은 공식을 사용합니다.

ZB = Gain_B * [1 + Delta_T * (SOT_tcg * Delta_T + Tcg)] * [BR_Raw + Offset_B - ADC_Offset + Delta_T * (SOT_tco * Delta_T + Tco) + SOT_bridge * (BR_Raw + Offset_B - ADC_Offset)^2] + 2000HEX

  •   Gain_B: 브릿지 게인 계수 (Bridge gain coefficient).
  •   Offset_B: 브릿지 오프셋 계수 (Bridge offset coefficient).
  •   Tcg, Tco: 게인과 오프셋의 온도 계수 (Temperature coefficients for gain and offset).
  •   SOT_tcg, SOT_tco, SOT_bridge: 2차 비선형 보정 계수 (Second-order nonlinearity correction coefficients).
  •   Delta_T: T_Raw - T_SETL (Temperature difference).
  •   2000HEX: 부호 없는 출력 오프셋 (Unsigned output offset).

최소 3개의 압력 포인트와 3개의 온도 포인트, 즉 9개의 데이터 포인트가 필요합니다.

2. 온도 신호 보정 (Temperature Signal Compensation)

온도 신호 보정은 원시 온도 신호(T_Raw)를 보정하여 최종 온도 출력(T)을 생성합니다. 공식은 다음과 같습니다.

ZT = Gain_T * [T_Raw + Offset_T]
T = ZT * (1 + SOT_T * ZT^2)

  •   Gain_T: 온도 게인 계수 (Temperature gain coefficient).
  •   Offset_T: 온도 오프셋 계수 (Temperature offset coefficient).
  •   SOT_T: 온도 신호의 2차 비선형 보정 계수 (Second-order nonlinearity correction coefficient for temperature).

최소 3개의 온도 포인트가 필요합니다 (At least 3 temperature points are required).

3. 계수 계산 방법 (Coefficient Calculation Method)

계수 계산은 다음 단계로 진행됩니다.

  1. 데이터 수집 (Data Collection):
    •   3개의 온도(-40°C, 25°C, 125°C)와 각 온도에서 3개의 압력(0%, 50%, 100%)을 측정하여 9개의 데이터 포인트를 수집합니다 .
    •   온도 데이터는 T_Raw와 실제 온도를 수집합니다 .
  2. 계수 계산 (Coefficient Calculation):
    •   최소제곱법을 사용하여 데이터와 보정 공식 간의 오차를 최소화합니다 .
    •   IDT의 캘리브레이션 소프트웨어(DLL)를 사용하거나, 파이썬의 scipy.optimize.least_squares로 구현할 수 있습니다 .
  3. EEPROM 저장 (EEPROM Storage):
    •   계산된 계수를 EEPROM에 저장합니다.
    •   예: Gain_B는 04HEX, Offset_B는 03HEX에 저장.

4. 파이썬 구현 예제 

다음은 파이썬으로 계수를 계산하는 코드 예제입니다.

import numpy as np
from scipy.optimize import least_squares

# 데이터시트의 상수
ADC_OFFSET = 0  # ADC 오프셋 (EEPROM에서 설정, 예: 0)
T_SETL = 8192  # 기준 온도에서의 T_Raw (예: 25°C, 14비트 중간값)
HEX_2000 = 8192  # 2000HEX = 8192 (부호 없는 출력 오프셋)

# 예제 데이터: 3 온도 x 3 압력 = 9 포인트
# BR_Raw: 원시 브릿지 신호 (14비트, -8192 ~ 8191)
# T_Raw: 원시 온도 신호 (14비트, 0 ~ 16383)
# 실제 압력 (예: kPa), 실제 온도 (°C)
data = [
    # 온도 -40°C
    {'T_Raw': 4096, 'BR_Raw': -4000, 'pressure': 0},    # 저압
    {'T_Raw': 4096, 'BR_Raw': 0, 'pressure': 50},       # 중간 압력
    {'T_Raw': 4096, 'BR_Raw': 4000, 'pressure': 100},   # 고압
    # 온도 25°C
    {'T_Raw': 8192, 'BR_Raw': -3800, 'pressure': 0},
    {'T_Raw': 8192, 'BR_Raw': 100, 'pressure': 50},
    {'T_Raw': 8192, 'BR_Raw': 4200, 'pressure': 100},
    # 온도 125°C
    {'T_Raw': 12288, 'BR_Raw': -3600, 'pressure': 0},
    {'T_Raw': 12288, 'BR_Raw': 200, 'pressure': 50},
    {'T_Raw': 12288, 'BR_Raw': 4400, 'pressure': 100},
]
# 온도 데이터
temp_data = [
    {'T_Raw': 4096, 'temperature': -40},
    {'T_Raw': 8192, 'temperature': 25},
    {'T_Raw': 12288, 'temperature': 125},
]

# 브릿지 신호 보정 공식
def bridge_correction(params, BR_Raw, T_Raw, ADC_Offset, T_SETL):
    Gain_B, Offset_B, Tcg, Tco, SOT_tcg, SOT_tco, SOT_bridge = params
    Delta_T = T_Raw - T_SETL
    gain_term = Gain_B * (1 + Delta_T * (SOT_tcg * Delta_T + Tcg))
    offset_term = BR_Raw + Offset_B - ADC_Offset + Delta_T * (SOT_tco * Delta_T + Tco) + \
                  SOT_bridge * (BR_Raw + Offset_B - ADC_Offset)**2
    ZB = gain_term * offset_term + HEX_2000
    return ZB

# 온도 신호 보정 공식
def temp_correction(params, T_Raw):
    Gain_T, Offset_T, SOT_T = params
    ZT = Gain_T * (T_Raw + Offset_T)
    T = ZT * (1 + SOT_T * ZT**2)
    return T

# 브릿지 신호 잔차 함수
def bridge_residuals(params, data, ADC_Offset, T_SETL):
    residuals = []
    for d in data:
        ZB = bridge_correction(params, d['BR_Raw'], d['T_Raw'], ADC_Offset, T_SETL)
        # ZB를 실제 압력과 비교 (압력을 0~16383 범위로 스케일링 가정)
        scaled_pressure = d['pressure'] * (16383 / 100)  # 0~100 kPa -> 0~16383
        residuals.append(ZB - scaled_pressure)
    return residuals

# 온도 신호 잔차 함수
def temp_residuals(params, temp_data):
    residuals = []
    for d in temp_data:
        T = temp_correction(params, d['T_Raw'])
        residuals.append(T - d['temperature'])
    return residuals

# 초기 계수 추정값
initial_bridge_params = [1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]  # Gain_B, Offset_B, Tcg, Tco, SOT_tcg, SOT_tco, SOT_bridge
initial_temp_params = [1.0, 0.0, 0.0]  # Gain_T, Offset_T, SOT_T

# 계수 범위 제한 (데이터시트 표 3.8 참고)
bounds_bridge = (
    [0, -8192, -0.01, -0.01, -0.0001, -0.0001, -0.0001],  # 하한
    [4, 8191, 0.01, 0.01, 0.0001, 0.0001, 0.0001]        # 상한
)
bounds_temp = (
    [0, -8192, -0.0001],  # 하한
    [4, 8191, 0.0001]     # 상한
)

# 브릿지 신호 계수 최적화
bridge_result = least_squares(
    bridge_residuals,
    initial_bridge_params,
    args=(data, ADC_OFFSET, T_SETL),
    bounds=bounds_bridge,
    verbose=1
)

# 온도 신호 계수 최적화
temp_result = least_squares(
    temp_residuals,
    initial_temp_params,
    args=(temp_data,),
    bounds=bounds_temp,
    verbose=1
)

# 최적화된 계수
bridge_coeffs = bridge_result.x
temp_coeffs = temp_result.x

# 계수를 EEPROM 형식으로 변환 (예: 16비트 이진수)
def to_eeprom_format(value, bits=16, is_gain=False):
    if is_gain:
        # Gain_B, Gain_T: 단위 게인 2000HEX(8192), 범위 [0, 4)
        scaled = int(value * 8192)  # 단위 게인 = 2000HEX
        return max(0, min(scaled, 2**bits - 1))
    else:
        # Offset_B, Offset_T, Tco, Tcg, SOT_*: 2의 보수 형식
        if value < 0:
            return int(2**bits + value)
        return int(value)

# 결과 출력
bridge_coeff_names = ['Gain_B', 'Offset_B', 'Tcg', 'Tco', 'SOT_tcg', 'SOT_tco', 'SOT_bridge']
temp_coeff_names = ['Gain_T', 'Offset_T', 'SOT_T']
print("Bridge Coefficients:")
for name, value in zip(bridge_coeff_names, bridge_coeffs):
    eeprom_value = to_eeprom_format(value, bits=16 if name not in ['Gain_B'] else 15, is_gain=name == 'Gain_B')
    print(f"{name}: {value:.6f} (EEPROM: {eeprom_value:04X})")

print("\nTemperature Coefficients:")
for name, value in zip(temp_coeff_names, temp_coeffs):
    eeprom_value = to_eeprom_format(value, bits=16 if name not in ['Gain_T'] else 15, is_gain=name == 'Gain_T')
    print(f"{name}: {value:.6f} (EEPROM: {eeprom_value:04X})")

5. 결론 (Conclusion)

ZSC31014의 보정 공식은 센서의 비선형성과 온도 의존성을 효과적으로 보상합니다. 파이썬을 사용하면 최소 9개의 데이터 포인트로 계수를 추출할 수  있습니다.