## บันทึกและคำนวณคู่ค่าความต้านทานต่ำ

เก็บค่าจริงและบริบทใน `blank-readings.csv` แทน `FILL_REAL_ID` ด้วยรหัสตัวอย่าง สามแถวใน `demo-readings.csv` แต่งขึ้น ไม่ใช่ผล MTTJ หรือตัวอย่างตรวจรับ `kelvin_pair_calc.py` คำนวณความต้านทานและออฟเซตจากคู่กระแสกับแรงดันที่มีเครื่องหมาย

Python ทำงานออฟไลน์ด้วยไลบรารีมาตรฐาน ไม่ต้องลงแพ็กเกจเพิ่ม ไม่ควบคุมเครื่อง ไม่ยืนยันวงจรแห้ง และไม่ตัดสินตรวจรับ ตรวจสมมติฐานกับข้อกำหนดแยกตามบทความ

## อินพุต 16 คอลัมน์

เก็บชื่อเดิม สคริปต์ใช้สี่คอลัมน์ค่าเพื่อคำนวณ ส่วนอื่นเก็บบริบทโดยไม่ตรวจค่า

| คอลัมน์ | ความหมายและหน่วย |
| --- | --- |
| `sample_id` | รหัสตัวอย่างของแถว |
| `sample_state` | สภาพเมื่อวัด |
| `spec_revision` | ฉบับข้อกำหนดที่ใช้ |
| `sense_A_B_drawing_ref` | อ้างอิงแผนภาพ Sense A/B |
| `fixture_id` | รหัสฟิกซ์เจอร์ |
| `method` | วิธีบันทึก แบบใช้ `four_wire_current_pair` |
| `range` | ย่านวัดของเครื่อง |
| `source_limit_mV` | ขีดจำกัดแรงดันแหล่งจ่ายที่บันทึก หน่วย mV |
| `sample_history` | ประวัติรวมทดสอบเชิงกล สิ่งแวดล้อม หรือไฟฟ้าก่อนหน้า |
| `i_plus_mA` | กระแสบวกวัดที่มีเครื่องหมาย หน่วย mA ต้องมากกว่า 0 เพื่อคำนวณ |
| `i_minus_mA` | กระแสลบวัดที่มีเครื่องหมาย หน่วย mA ต้องน้อยกว่า 0 เพื่อคำนวณ |
| `v_plus_uV` | แรงดันมีเครื่องหมายคู่กับ `i_plus_mA` หน่วย μV |
| `v_minus_uV` | แรงดันมีเครื่องหมายคู่กับ `i_minus_mA` หน่วย μV |
| `sampled_plus_at` | เวลาอ่านบวก เก็บเป็นข้อความ |
| `sampled_minus_at` | เวลาอ่านลบ เก็บเป็นข้อความ |
| `note` | หมายเหตุเก็บกับแถวเดิม |

คงเครื่องหมาย แรงดันศูนย์เป็นตัวเลข ว่างคือไม่มีค่าและต้องว่าง หากหนึ่งในสี่ช่องหาย ว่าง หรือมีแต่ช่องว่าง สคริปต์ไม่แทนด้วยศูนย์ ช่องบริบทว่างยังว่าง

## คำนวณและสี่เอาต์พุต

แต่ละคู่ครบและใช้ได้:

`R = (V+ − V−) / (I+ − I−)`

`E = V+ − I+ R`

สูตรสองหาออฟเซตจาก `V = IR + E` อินพุต μV กับ mA ให้ `R` mΩ และ `E` μV สมมติความเชิงเส้นและออฟเซตเสถียรระหว่างคู่ ผลไม่ได้ยืนยันสมมติฐาน แสดงผลด้วยเลขนัยสำคัญสูงสุด 12 หลัก

| เอาต์พุต | ความหมาย |
| --- | --- |
| `r_pair_mohm` | ความต้านทาน mΩ ว่างเมื่อคู่ขาดหรือไม่ใช้ได้ |
| `offset_pair_uV` | ออฟเซต μV ว่างเมื่อคู่ขาดหรือไม่ใช้ได้ |
| `calculation_status` | สถานะ `calculated`, `missing` หรือ `invalid` |
| `calculation_note` | อธิบายสถานะและสมมติฐาน |

| สถานะ | เมื่อเขียน |
| --- | --- |
| `calculated` | อินพุตทั้งสี่และผลคำนวณเป็นจำนวนที่มีค่าจำกัด ไม่ใช่ NaN หรือบวก/ลบอนันต์ กระแสบวกมากกว่า 0 และกระแสลบน้อยกว่า 0 ข้อความเดิม `Assumes a linear resistor and stable offset. No acceptance judgment.` สมมติเชิงเส้นและเสถียร ไม่ตัดสินตรวจรับ |
| `missing` | ค่าหายหรือว่าง ผลตัวเลขสองช่องว่าง `Missing readings; no zero imputation.` คือค่าขาด ไม่เติมศูนย์ |
| `invalid` | อินพุตไม่ใช่ตัวเลข หรือเป็น NaN หรือบวก/ลบอนันต์ เครื่องหมายกระแสผิด หรือผลคำนวณเป็น NaN หรือบวก/ลบอนันต์ ตัวเลขว่าง หมายเหตุบอกเหตุ |

ข้อความเดิมคือ `Readings must be numeric.`, `Require finite readings and Iplus>0, Iminus<0.` หรือ `Non-finite calculated output.` ต้องเป็นตัวเลขที่มีค่าจำกัด ไม่ใช่ NaN หรือบวก/ลบอนันต์ และมีเครื่องหมายกระแสตามเงื่อนไข หรือแจ้งว่าผลคำนวณเป็น NaN หรือบวก/ลบอนันต์ สถานะอธิบายคำนวณ ไม่ใช่ตรวจรับ

## อ่านตัวอย่างแต่งขึ้น

| แถว | I+ / I− (mA) | V+ / V− (μV) | `r_pair_mohm` (mΩ) | `offset_pair_uV` (μV) | `calculation_status` |
| --- | --- | --- | ---: | ---: | --- |
| `DEMO_STABLE` | +10 / −10 | +110 / −90 | 10 | 10 | `calculated` |
| `DEMO_DRIFT` | +10 / −10 | +110 / −86 | 9.8 | 12 | `calculated` |
| `DEMO_UNEQUAL` | +12 / −8 | +130 / −70 | 10 | 10 | `calculated` |

ดริฟต์เปลี่ยนออฟเซตสมมติ 10 เป็น 14 μV ได้ 9.8 mΩ กับ 12 μV `calculated` ไม่ตรวจหรือกำจัดดริฟต์ ตัวอย่างกระแสต่าง +12 และ −8 mA ให้ 10 mΩ ค่าว่างให้ผลสองช่องว่างและ `missing`

## รันออฟไลน์และเก็บอินพุต

ใช้ไฟล์ในเครื่องแล้วรัน `python kelvin_pair_calc.py demo-readings.csv result.csv` ค่าจริงใช้แบบกรอกและเอาต์พุตคนละไฟล์ สคริปต์ปฏิเสธเส้นทางอินพุตกับเอาต์พุตซึ่งเมื่อแปลงเป็นเส้นทางสมบูรณ์แล้วชี้ไปยังเส้นทางจริงเดียวกัน เพื่อเก็บต้นฉบับ

เก็บคอลัมน์อินพุตและเพิ่มสี่คอลัมน์คำนวณ หากมีชื่อเอาต์พุตเดิมแล้ว จะแทนด้วยผลใหม่ เขียน CSV UTF-8 พร้อมเครื่องหมายลำดับไบต์ ค่าขาดยังว่าง ไม่มีผ่าน/ไม่ผ่าน
