文档
pH 传感器模组 — 代码例程 (ESP32 Arduino)
1. GPIO 初始化
#include <Arduino.h>
// pH 探头 ADC 引脚(可根据实际接线修改)
#define PH_ADC_PIN 4
// 标定参数:每块板不同,由 ph_calib 工具生成后填入
#ifndef PH_V686
#define PH_V686 1.3699f // pH=6.86 缓冲液对应电压 (V)
#endif
#ifndef PH_V918
#define PH_V918 1.1168f // pH=9.18 缓冲液对应电压 (V)
#endif
void setup() {
Serial.begin(115200);
// ADC 初始化:12-bit 分辨率,11dB 衰减(~3.3V 满量程)
analogReadResolution(12);
analogSetPinAttenuation(PH_ADC_PIN, ADC_11db);
Serial.println("pH Sensor ready.");
Serial.printf("PH_V686=%.4f PH_V918=%.4f\n", PH_V686, PH_V918);
}
2. 驱动函数
2.1 读取 pH 探头电压(多次采样取均值)
/**
* @brief 读取 pH 探头输出电压 (V)
* @note 连续采样 N 次取均值,降低噪声
* @return 电压值,单位 V
*/
static float read_ph_voltage() {
const int N = 20; // 采样次数
uint32_t sum_mv = 0;
for (int i = 0; i < N; ++i) {
sum_mv += analogReadMilliVolts(PH_ADC_PIN);
delay(2);
}
return (sum_mv / (float)N) / 1000.0f;
}
2.2 电压转 pH(两点线性插值)
/**
* @brief 电压转 pH 值
* @param v 探头电压 (V)
* @return pH 值
* @note 线性模型: pH = k·v + b
* 其中 k = (6.86-9.18)/(V686-V918)
* b = 6.86 - k*V686
*/
static float voltage_to_ph(float v) {
constexpr float k = (6.86f - 9.18f) / (PH_V686 - PH_V918);
return 6.86f + k * (v - PH_V686);
}
2.3 综合读取(电压 + pH 一起返回)
/**
* @brief 读取 pH 探头并返回电压和 pH
* @param v_out [out] 原始电压 (V)
* @return pH 值 (0.00 ~ 14.00)
*/
static float read_ph(float* v_out = nullptr) {
float v = read_ph_voltage();
if (v_out) *v_out = v;
float ph = voltage_to_ph(v);
// 钳位到合理范围
if (ph < 0.0f) ph = 0.0f;
if (ph > 14.0f) ph = 14.0f;
return ph;
}
3. 完整示例 — 每 2 秒打印一次 pH
#include <Arduino.h>
// ==================== 引脚 & 标定参数 ====================
#define PH_ADC_PIN 4
#ifndef PH_V686
#define PH_V686 1.3699f
#endif
#ifndef PH_V918
#define PH_V918 1.1168f
#endif
// ==================== 驱动函数 ====================
static float read_ph_voltage() {
const int N = 20;
uint32_t sum_mv = 0;
for (int i = 0; i < N; ++i) {
sum_mv += analogReadMilliVolts(PH_ADC_PIN);
delay(2);
}
return (sum_mv / (float)N) / 1000.0f;
}
static float voltage_to_ph(float v) {
constexpr float k = (6.86f - 9.18f) / (PH_V686 - PH_V918);
return 6.86f + k * (v - PH_V686);
}
static float read_ph(float* v_out = nullptr) {
float v = read_ph_voltage();
if (v_out) *v_out = v;
float ph = voltage_to_ph(v);
if (ph < 0.0f) ph = 0.0f;
if (ph > 14.0f) ph = 14.0f;
return ph;
}
// ==================== setup & loop ====================
void setup() {
Serial.begin(115200);
delay(300);
analogReadResolution(12);
analogSetPinAttenuation(PH_ADC_PIN, ADC_11db);
Serial.println("===== pH Sensor Demo =====");
Serial.printf("PH_ADC_PIN = GPIO%d\n", PH_ADC_PIN);
Serial.printf("PH_V686 = %.4f V\n", PH_V686);
Serial.printf("PH_V918 = %.4f V\n", PH_V918);
Serial.println("==========================");
}
void loop() {
float voltage = 0.0f;
float ph = read_ph(&voltage);
Serial.printf("[pH] voltage=%.4f V => pH=%.2f\n", voltage, ph);
delay(2000);
}
预期输出(串口 115200):
===== pH Sensor Demo =====
PH_ADC_PIN = GPIO4
PH_V686 = 1.3699 V
PH_V918 = 1.1168 V
==========================
[pH] voltage=1.2345 V => pH=7.12
[pH] voltage=1.2342 V => pH=7.13
...
4. 标定模式固件(calib)
烧录此固件后,配合 Python ph_calib 工具完成三点标定:
#include <Arduino.h>
#define PH_ADC_PIN 4
void setup() {
Serial.begin(115200);
analogReadResolution(12);
analogSetPinAttenuation(PH_ADC_PIN, ADC_11db);
Serial.println("[PH_CAL] CALIB MODE READY");
}
void loop() {
const int N = 16;
uint32_t sum_mv = 0;
for (int i = 0; i < N; ++i) {
sum_mv += analogReadMilliVolts(PH_ADC_PIN);
delay(5);
}
float v = (sum_mv / (float)N) / 1000.0f;
Serial.printf("[PH_CAL] v=%.4f\n", v);
delay(100); // ~5 Hz 输出
}
输出格式:[PH_CAL] v=1.2345,供标定工具正则匹配。
5. 在 platformio.ini 中覆盖标定参数
[env:my_node]
build_flags =
-DPH_V686=1.3699f
-DPH_V918=1.1168f
⚠️ 每块板的参数不同,务必用标定工具测量后填入!