#ifndef ECHEM_H #define ECHEM_H #include #define ECHEM_MAX_POINTS 500 typedef enum { LP_RTIA_200 = 0, LP_RTIA_1K, LP_RTIA_2K, LP_RTIA_3K, LP_RTIA_4K, LP_RTIA_6K, LP_RTIA_8K, LP_RTIA_10K, LP_RTIA_12K, LP_RTIA_16K, LP_RTIA_20K, LP_RTIA_24K, LP_RTIA_30K, LP_RTIA_32K, LP_RTIA_40K, LP_RTIA_48K, LP_RTIA_64K, LP_RTIA_85K, LP_RTIA_96K, LP_RTIA_100K, LP_RTIA_120K, LP_RTIA_128K, LP_RTIA_160K, LP_RTIA_196K, LP_RTIA_256K, LP_RTIA_512K, LP_RTIA_COUNT } EchemLpRtia; typedef struct { float v_start; /* mV, cell potential start */ float v_stop; /* mV, cell potential stop */ float scan_rate; /* mV/s */ EchemLpRtia lp_rtia; } LSVConfig; typedef struct { float v_mv; /* mV, applied cell potential */ float i_ua; /* uA, measured current */ } LSVPoint; typedef struct { float v_hold; /* mV, applied cell potential */ float interval_ms; /* sampling interval */ float duration_s; /* total duration, 0 = until stopped */ EchemLpRtia lp_rtia; } AmpConfig; typedef struct { float t_ms; /* timestamp */ float i_ua; /* uA, measured current */ } AmpPoint; /* Chlorine: multi-step chronoamperometry on Au/Ag */ typedef struct { float v_cond; /* mV, conditioning potential (surface cleaning) */ float t_cond_ms; /* ms, conditioning duration */ float v_free; /* mV, free chlorine measurement potential */ float v_total; /* mV, total chlorine measurement potential */ float t_dep_ms; /* ms, deposition/settling time per step */ float t_meas_ms; /* ms, measurement sampling time per step */ EchemLpRtia lp_rtia; } ClConfig; #define CL_PHASE_COND 0 #define CL_PHASE_FREE 1 #define CL_PHASE_TOTAL 2 typedef struct { float t_ms; float i_ua; uint8_t phase; } ClPoint; typedef struct { float i_free_ua; float i_total_ua; } ClResult; /* pH: open circuit potentiometry on Au/Ag */ typedef struct { float stabilize_s; /* seconds to wait for OCP stabilization */ float temp_c; /* temperature for Nernst calculation */ } PhConfig; typedef struct { float v_ocp_mv; /* measured OCP: V(SE0) - V(RE0) */ float ph; /* Nernst-derived pH */ float temp_c; /* temperature used */ } PhResult; typedef int (*lsv_point_cb_t)(uint16_t idx, float v_mv, float i_ua); typedef int (*amp_point_cb_t)(uint16_t idx, float t_ms, float i_ua); typedef int (*cl_point_cb_t)(uint16_t idx, float t_ms, float i_ua, uint8_t phase); int echem_clean(float v_mv, float duration_s); void echem_default_lsv(LSVConfig *cfg); void echem_default_amp(AmpConfig *cfg); void echem_default_cl(ClConfig *cfg); void echem_default_ph(PhConfig *cfg); uint32_t echem_lsv_calc_steps(const LSVConfig *cfg, uint32_t max_points); int echem_lsv(const LSVConfig *cfg, LSVPoint *out, uint32_t max_points, lsv_point_cb_t cb); int echem_amp(const AmpConfig *cfg, AmpPoint *out, uint32_t max_points, amp_point_cb_t cb); int echem_chlorine(const ClConfig *cfg, ClPoint *out, uint32_t max_points, ClResult *result, cl_point_cb_t cb); int echem_ph_ocp(const PhConfig *cfg, PhResult *result); #endif