pH cal: correct borate to 9.18, add NIST buffer temp correction

This commit is contained in:
jess 2026-04-09 19:03:22 -07:00
parent e1dd4ec436
commit 4c893fb64e
3 changed files with 45 additions and 6 deletions

View File

@ -656,7 +656,43 @@ float eis_get_ph_offset(void) { return ph_offset_cached; }
/* ---- 3-buffer × 3-temperature pH calibration ---- */ /* ---- 3-buffer × 3-temperature pH calibration ---- */
static const float PH_BUFFERS[PH_CAL_BUFFERS] = {4.0f, 6.86f, 9.0f}; /* nominal 25 C pH of the three NIST primary buffers (phthalate, phosphate, borate) */
static const float PH_BUFFERS[PH_CAL_BUFFERS] = {4.01f, 6.86f, 9.18f};
/* NIST SRM buffer pH vs temperature, 0-50 C in 5 C steps */
#define PH_NIST_T_MIN 0
#define PH_NIST_T_STEP 5
#define PH_NIST_N 11
static const float PH_NIST_PHTHALATE[PH_NIST_N] = {
4.003f, 3.999f, 3.998f, 3.999f, 4.002f, 4.008f,
4.015f, 4.024f, 4.035f, 4.047f, 4.060f
};
static const float PH_NIST_PHOSPHATE[PH_NIST_N] = {
6.984f, 6.951f, 6.923f, 6.900f, 6.881f, 6.865f,
6.853f, 6.844f, 6.838f, 6.834f, 6.833f
};
static const float PH_NIST_BORATE[PH_NIST_N] = {
9.464f, 9.395f, 9.332f, 9.276f, 9.225f, 9.180f,
9.139f, 9.102f, 9.068f, 9.038f, 9.011f
};
static const float * const PH_NIST_TABLES[PH_CAL_BUFFERS] = {
PH_NIST_PHTHALATE, PH_NIST_PHOSPHATE, PH_NIST_BORATE
};
float eis_ph_buffer_at_temp(uint8_t buf, float temp_c)
{
if (buf >= PH_CAL_BUFFERS) return 0.0f;
const float *tbl = PH_NIST_TABLES[buf];
if (temp_c <= (float)PH_NIST_T_MIN) return tbl[0];
float t_max = (float)(PH_NIST_T_MIN + PH_NIST_T_STEP * (PH_NIST_N - 1));
if (temp_c >= t_max) return tbl[PH_NIST_N - 1];
float f = (temp_c - (float)PH_NIST_T_MIN) / (float)PH_NIST_T_STEP;
int i = (int)f;
float frac = f - (float)i;
return tbl[i] + frac * (tbl[i + 1] - tbl[i]);
}
#define NVS_PH_CAL_PTS_KEY "ph_cal9" #define NVS_PH_CAL_PTS_KEY "ph_cal9"
@ -682,7 +718,7 @@ static void ph_cal_recalculate(void)
int bit = i * PH_CAL_TEMPS + PH_TEMP_BASE; int bit = i * PH_CAL_TEMPS + PH_TEMP_BASE;
if (!(ph_cal.valid & (1 << bit))) continue; if (!(ph_cal.valid & (1 << bit))) continue;
float x = ph_cal.s[i][PH_TEMP_BASE].ocp_mv; float x = ph_cal.s[i][PH_TEMP_BASE].ocp_mv;
float y = PH_BUFFERS[i]; float y = eis_ph_buffer_at_temp(i, ph_cal.s[i][PH_TEMP_BASE].temp_c);
sx += x; sy += y; sxx += x * x; sxy += x * y; sx += x; sy += y; sxx += x * x; sxy += x * y;
n++; n++;
} }

View File

@ -90,5 +90,6 @@ void eis_ph_cal_clear_all(void);
bool eis_ph_cal_get_point(uint8_t buf, uint8_t tslot, float *ocp_mv, float *temp_c); bool eis_ph_cal_get_point(uint8_t buf, uint8_t tslot, float *ocp_mv, float *temp_c);
int eis_ph_cal_count(void); int eis_ph_cal_count(void);
float eis_ph_cal_buffer_ph(uint8_t buf); float eis_ph_cal_buffer_ph(uint8_t buf);
float eis_ph_buffer_at_temp(uint8_t buf, float temp_c);
#endif #endif

View File

@ -254,8 +254,8 @@ void app_main(void)
uint8_t bid = cmd.ph_cal_point.buffer_id; uint8_t bid = cmd.ph_cal_point.buffer_id;
uint8_t tsl = cmd.ph_cal_point.temp_slot; uint8_t tsl = cmd.ph_cal_point.temp_slot;
if (bid >= PH_CAL_BUFFERS || tsl >= PH_CAL_TEMPS) break; if (bid >= PH_CAL_BUFFERS || tsl >= PH_CAL_TEMPS) break;
float buf_ph = eis_ph_cal_buffer_ph(bid); printf("pH cal: buffer %u slot %u (nominal pH %.2f)\n",
printf("pH cal: buffer %u slot %u (pH %.2f)\n", bid, tsl, buf_ph); bid, tsl, eis_ph_cal_buffer_ph(bid));
PhConfig ph_cfg; PhConfig ph_cfg;
ph_cfg.stabilize_s = cmd.ph_cal_point.stabilize_s; ph_cfg.stabilize_s = cmd.ph_cal_point.stabilize_s;
@ -266,12 +266,14 @@ void app_main(void)
eis_ph_cal_set_point(bid, tsl, ph_result.v_ocp_mv, ph_result.temp_c); eis_ph_cal_set_point(bid, tsl, ph_result.v_ocp_mv, ph_result.temp_c);
float buf_ph = eis_ph_buffer_at_temp(bid, ph_result.temp_c);
int baseline_n = 0; int baseline_n = 0;
for (int i = 0; i < PH_CAL_BUFFERS; i++) for (int i = 0; i < PH_CAL_BUFFERS; i++)
if (eis_ph_cal_get_point(i, PH_TEMP_BASE, NULL, NULL)) baseline_n++; if (eis_ph_cal_get_point(i, PH_TEMP_BASE, NULL, NULL)) baseline_n++;
printf("pH cal: [%u][%u] OCP=%.1f mV T=%.1f C (%d/%d)\n", printf("pH cal: [%u][%u] OCP=%.1f mV T=%.1f C pH=%.3f (%d/%d)\n",
bid, tsl, ph_result.v_ocp_mv, ph_result.temp_c, bid, tsl, ph_result.v_ocp_mv, ph_result.temp_c, buf_ph,
baseline_n, eis_ph_cal_count()); baseline_n, eis_ph_cal_count());
send_ph_cal_point(bid, tsl, ph_result.v_ocp_mv, ph_result.temp_c, send_ph_cal_point(bid, tsl, ph_result.v_ocp_mv, ph_result.temp_c,
buf_ph, (uint8_t)baseline_n); buf_ph, (uint8_t)baseline_n);