Files
Calculators-for-University-…/python/Bridge resistance measurement.py

312 lines
13 KiB
Python
Raw Permalink 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.
import math
from decimal import Decimal
from utils import (
scientific_round,
calculate_stats,
input_decimal,
input_int
)
"""
Wheatstone Bridge Resistance Measurement Calculator
电桥法测量电阻计算器
参考了表面张力系数计算器的高精度与不确定度修约逻辑。
公式说明:
1. 惠斯通电桥平衡条件 (Bridge Balance Equation):
当检流计示数为零时,电桥平衡:
Rx / R0 = R1 / R2
即:
Rx = R0 * (R1 / R2) (也写作 Rx = R0 * C,C = R1/R2 为比例臂比值)
其中:
Rx : 待测电阻
R0 : 比较臂标准电阻(电桥读数)
R1/R2 : 比例臂之比,取 1:1, 1:10, 10:1
2. 灵敏度公式 (Bridge Sensitivity):
S = Δn / (ΔR0 / R0)
其中:
S : 电桥灵敏度(格/相对变化量)
Δn : 检流计偏转格数(通常取 5 小格)
ΔR0 : 使检流计偏转 Δn 格时 R0 的改变量
ΔR0 = |R0' - R0|,R0' 为偏转 5 格时的读数
R0 : 平衡时的标准电阻读数
也可写为:
S = Δn * R0 / ΔR0
3. 不确定度传递公式 (Uncertainty Propagation):
Rx = R0 * C (C 为比例臂比值)
(a) R0 的不确定度:
u(R0) = sqrt( u_A(R0)^2 + u_B(R0)^2 )
其中:
u_A(R0) = s(R0) / sqrt(n) (A 类不确定度, s 为标准偏差)
u_B(R0) = Δ_inst / sqrt(3) (B 类不确定度, Δ_inst 为仪器误差限)
(b) 仪器误差限 Δ_inst 的确定 (与灵敏度有关):
Δ_inst = R0 / S
即由灵敏度决定的电桥最小可分辨电阻变化量
(c) 比例臂 C 视为精确值(标准电阻箱),则:
u(Rx) = C * u(R0)
(d) 相对不确定度:
u_r(Rx) = u(Rx) / Rx = u(R0) / R0
(e) 修约规则:
不确定度保留一位有效数字,四舍六入五凑偶
Rx 末位与不确定度对齐
"""
def measure_one_ratio(ratio_label, C_value, R_nominal, n_measurements):
"""
对单一比例臂进行测量与分析
参数:
ratio_label: 比例臂标签,如 "1:1"
C_value: 比例臂比值 C = R1/R2
R_nominal: 标定电阻标称值 (Ω)
n_measurements: 测量次数
"""
C = Decimal(str(C_value))
print(f"\n{'─'*50}")
print(f" 比例臂 Rx:R0 = {ratio_label},比例因子 C = {C_value}")
print(f" 标定电阻标称值: {R_nominal} Ω")
print(f"{'─'*50}")
# --- 输入平衡时的 R0 读数 ---
print(f"\n请输入 {n_measurements} 次平衡时的 R0 读数 (Ω):")
R0_data = []
for i in range(n_measurements):
while True:
try:
val = input(f" 第 {i+1} 次 R0 = ").strip()
if not val: continue
R0_data.append(Decimal(val))
break
except Exception:
print(" 输入无效,请输入数字。")
# --- 输入偏差 5 小格时的 R0' ---
print(f"\n请输入偏转 5 小格时的 R0' 读数 (Ω):")
R0_prime = input_decimal(" R0'")
delta_n = Decimal("5") # 检流计偏转格数
# --- 计算 R0 的平均值 ---
R0_mean = sum(R0_data) / Decimal(len(R0_data))
# --- 计算灵敏度 ---
# S = Δn * R0 / |R0' - R0|
delta_R0 = abs(R0_prime - R0_mean)
if delta_R0 == 0:
print(" ⚠ 警告: R0' = R0,无法计算灵敏度,请检查数据!")
S = Decimal("Infinity")
delta_inst = Decimal("0")
else:
S = delta_n * R0_mean / delta_R0
# 仪器误差限 (由灵敏度决定)
# Δ_inst = R0 / S = |R0' - R0| / Δn = ΔR0 / 5
delta_inst = R0_mean / S
# --- 不确定度分析 ---
R0_mean_final, u_R0, u_a_R0, u_b_R0, _ = calculate_stats(R0_data, str(delta_inst))
# Rx = C * R0
Rx_mean = C * R0_mean_final
u_Rx = C * u_R0
# 相对不确定度
if Rx_mean != 0:
u_r_Rx = u_Rx / Rx_mean
else:
u_r_Rx = Decimal("0")
# --- 修约 ---
Rx_final, u_Rx_final = scientific_round(Rx_mean, u_Rx)
# --- 输出结果 ---
print(f"\n{'═'*50}")
print(f" 结果 (比例臂 {ratio_label}, 标定 {R_nominal} Ω)")
print(f"{'═'*50}")
# 打印 R0 测量数据表
print(f"\n R0 测量数据:")
for i, val in enumerate(R0_data):
print(f" 第 {i+1} 次: {val} Ω")
print(f"\n R0 平均值 = {R0_mean_final:.4f} Ω")
print(f" R0' = {R0_prime} Ω")
print(f" ΔR0 = |R0'-R0| = {delta_R0:.4f} Ω")
print(f" 偏转格数 Δn = {delta_n} 格")
print(f"{'─'*50}")
print(f" 灵敏度 S = Δn·R0/ΔR0 = {S:.2f}")
print(f" 仪器误差限 Δ_inst = R0/S = {delta_inst:.4f} Ω")
print(f"{'─'*50}")
print(f" u_A(R0) = {u_a_R0:.6f} Ω")
print(f" u_B(R0) = {u_b_R0:.6f} Ω")
print(f" u(R0) = {u_R0:.6f} Ω")
print(f"{'─'*50}")
print(f" Rx = C × R0 = {C} × {R0_mean_final:.4f} = {Rx_mean:.4f} Ω")
print(f" u(Rx) = C × u(R0) = {u_Rx:.6f} Ω")
print(f" 相对不确定度 u_r = {u_r_Rx*100:.2f}%")
print(f"{'─'*50}")
print(f" ★ 最终结果: Rx = {Rx_final} ± {u_Rx_final} Ω")
print(f"{'═'*50}")
return {
"ratio_label": ratio_label,
"C": C,
"R_nominal": R_nominal,
"R0_data": R0_data,
"R0_mean": R0_mean_final,
"R0_prime": R0_prime,
"delta_R0": delta_R0,
"S": S,
"delta_inst": delta_inst,
"u_a_R0": u_a_R0,
"u_b_R0": u_b_R0,
"u_R0": u_R0,
"Rx_mean": Rx_mean,
"u_Rx": u_Rx,
"u_r_Rx": u_r_Rx,
"Rx_final": Rx_final,
"u_Rx_final": u_Rx_final
}
def main():
print("════════════════════════════════════════════════")
print(" 电桥法测量电阻计算器 (Wheatstone Bridge)")
print("════════════════════════════════════════════════")
print()
print("实验原理:")
print(" 惠斯通电桥平衡条件: Rx = R0 × C (C = R1/R2)")
print(" 灵敏度: S = Δn × R0 / ΔR0")
print(" 不确定度: u(Rx) = C × u(R0), u(R0) = √(u_A² + u_B²)")
print()
# --- 1. 基本参数 ---
n_meas = input_int("每组测量次数 n", default=5)
# --- 2. 定义测量方案 ---
# 标定电阻: 10kΩ 和 2kΩ
# 比例臂: 1:1, 1:10, 10:1
# 注意: 2kΩ 不会有 1:10 的比例臂 (因为 R0 = Rx/(C) 会超出电阻箱量程)
calibration_plan = [
# (标定电阻标称值, 比例臂标签, C 值)
# ---- 10kΩ 标定 ----
("10000", "1:1", 1),
("10000", "10:1", 10),
# ---- 2kΩ 标定 ----
("2000", "1:1", 1),
("2000", "10:1", 10),
# ---- 200Ω 标定 ----
("200", "1:1", 1),
("200", "1:10", 0.1),
("200", "10:1", 10),
]
print(f"\n{'━'*55}")
print(" 测量方案如下:")
print(f"{'━'*55}")
print(f" {'序号':<6}{'标定电阻':>10}{'比例臂 Rx:R0':>14}{'C = R1/R2':>12}")
print(f" {'─'*46}")
for idx, (R_nom, ratio, C_val) in enumerate(calibration_plan, 1):
print(f" {idx:<6}{R_nom + ' Ω':>10}{ratio:>14}{C_val:>12}")
print(f"{'━'*55}")
print()
print(" 注: 2kΩ 标定不进行 1:10 比例臂测量")
print(" (R0 = 2000/0.1 = 20000 Ω,超出电阻箱量程)")
print()
# --- 3. 逐项测量 ---
all_results = []
for idx, (R_nom, ratio_label, C_val) in enumerate(calibration_plan, 1):
print(f"\n{'▓'*55}")
print(f" 第 {idx} 组: 标定 {R_nom} Ω,比例臂 Rx:R0 = {ratio_label}")
print(f"{'▓'*55}")
result = measure_one_ratio(ratio_label, C_val, R_nom, n_meas)
all_results.append(result)
if idx < len(calibration_plan):
input("\n按回车继续下一组测量...")
# --- 4. 汇总表 ---
print("\n")
print("╔══════════════════════════════════════════════════════════════════════════════╗")
print("║ 测 量 结 果 汇 总 表 ║")
print("╠══════════════════════════════════════════════════════════════════════════════╣")
header = (f" {'标定':>6} {'比例臂':>8} {'R0均值(Ω)':>12} "
f"{'S(灵敏度)':>10} {'Δ_inst(Ω)':>10} "
f"{'Rx(Ω)':>12} {'u(Rx)(Ω)':>10} {'u_r(%)':>8}")
print(header)
print(f" {'─'*74}")
for res in all_results:
S_str = f"{res['S']:.1f}" if res['S'] != Decimal("Infinity") else "∞"
line = (f" {res['R_nominal']:>6} {res['ratio_label']:>8} "
f"{res['R0_mean']:>12.4f} {S_str:>10} "
f"{res['delta_inst']:>10.4f} "
f"{res['Rx_mean']:>12.4f} {res['u_Rx']:>10.6f} "
f"{res['u_r_Rx']*100:>7.2f}%")
print(line)
print("╚══════════════════════════════════════════════════════════════════════════════╝")
# --- 5. 灵敏度分析总结 ---
print("\n")
print("┌──────────────────────────────────────────────┐")
print("│ 灵 敏 度 分 析 总 结 │")
print("├──────────────────────────────────────────────┤")
for res in all_results:
S_str = f"{res['S']:.2f}" if res['S'] != Decimal("Infinity") else "∞"
print(f"│ 标定 {res['R_nominal']:>5}Ω 比例臂 {res['ratio_label']:>4} "
f"S = {S_str:>8} │")
print("├──────────────────────────────────────────────┤")
# 找灵敏度最大和最小
finite_results = [r for r in all_results if r['S'] != Decimal("Infinity")]
if finite_results:
best = max(finite_results, key=lambda r: r['S'])
worst = min(finite_results, key=lambda r: r['S'])
print(f"│ 最高灵敏度: 标定{best['R_nominal']:>5}Ω 比例臂{best['ratio_label']:>4} │")
print(f"│ S = {best['S']:.2f} │")
print(f"│ 最低灵敏度: 标定{worst['R_nominal']:>5}Ω 比例臂{worst['ratio_label']:>4} │")
print(f"│ S = {worst['S']:.2f} │")
print("├──────────────────────────────────────────────┤")
print("│ 分析: │")
print("│ · 灵敏度 S 越大,测量精度越高 │")
print("│ · S = Δn·R0/ΔR0 │")
print("│ · 比例臂比值影响灵敏度 │")
print("│ · 合理选择比例臂可优化测量精度 │")
print("└──────────────────────────────────────────────┘")
# --- 6. 最终修约结果汇总 ---
print("\n")
print("╔═══════════════════════════════════════════════════╗")
print("║ 最 终 结 果 (修约后) ║")
print("╠═══════════════════════════════════════════════════╣")
for res in all_results:
print(f"║ 标定 {res['R_nominal']:>5}Ω 比例臂 {res['ratio_label']:>4}: ║")
print(f"║ Rx = {res['Rx_final']} ± {res['u_Rx_final']} Ω ║")
print(f"║ (相对不确定度 {res['u_r_Rx']*100:.2f}%) ║")
print(f"╟───────────────────────────────────────────────────╢")
print("╚═══════════════════════════════════════════════════╝")
if __name__ == "__main__":
main()