pH Sensor

The pH sensor provides water quality measurement critical for environmental monitoring and anomaly detection. 
 Hardware Specifications 
 Parameter Value Model DFRobot SEN0161 (Analog pH meter) Interface Analog ADC Reference Voltage 3.3V or 5.0V (configurable) Output Range 0-5V analog Measurement Range 0-14 pH units Accuracy ±0.1 pH @ 25°C Sample Rate Configurable (40 samples for averaging) 
 Calibration Model 
 The sensor uses linear voltage-to-pH conversion: 
 pH = (Voltage / Reference_Voltage) × Slope + Offset 
 Default Parameters for SEN0161 @ 25°C: 
 Slope : 3.5 Offset : Variable (user calibration) 
 Data Structure 
 typedef struct {
 // Raw ADC Reading
 uint16_t raw_value; // Raw ADC value
 
 // Calculated Values
 float voltage; // Converted voltage (0-5V)
 float ph_value; // Calculated pH (0-14)
 float reference_voltage; // ADC reference (typically 3.3V or 5.0V)
 
 // Calibration Parameters
 ph_calibration_t calibration; // { offset: float, slope: float }
 
 // Averaging Buffer (Noise Filtering)
 uint16_t sample_buffer[40]; // Last 40 samples
 uint8_t sample_index; // Current position in buffer
 uint8_t samples_collected; // Total samples collected (0-40)
} ph_sensor_t; 
 Initialization & Usage 
 Initialize pH Sensor 
 ph_sensor_t ph_sensor;
ph_sensor_init(&ph_sensor, 3.3f); // 3.3V reference voltage 
 Poll pH Sensor 
 result_t ph_result = poll_ph_sensor(&ph_sensor);

if (ph_result == RESULT_OK) {
 float ph_value = ph_sensor.ph_value;
 float voltage = ph_sensor.voltage;
} 
 Manual Sample Addition 
 // For manual sampling at regular intervals
uint16_t adc_reading = 2048; // Example ADC value
ph_sensor_add_sample(&ph_sensor, adc_reading); 
 Validation 
 result_t validate_ph_value(float ph_value);
// Returns RESULT_OK if 0 <= ph_value <= 14
// Returns RESULT_ERR_INVALID_DATA otherwise 
 Sample Averaging Strategy 
 Parameter Value Sample Buffer Size 40 samples Method Circular buffer moving average Purpose Noise filtering and stable readings Typical Update Latency 40ms-800ms 
 Averaging Algorithm 
 1. ADC sample added to circular buffer
2. All 40 samples averaged together
3. Averaged value converted to voltage
4. Voltage converted to pH via calibration 
 Two-Point Calibration Procedure 
 Step 1: Neutral Point (pH 7.0) 
 1. Immerse electrode in pH 7.0 buffer solution
2. Wait for stable reading (~2 minutes)
3. Record voltage: V_neutral
4. Calculate offset adjustment 
 Step 2: Slope Calibration (pH 4.0 or 10.0) 
 1. Immerse electrode in second known pH solution
2. Wait for stable reading
3. Record voltage: V_reference
4. Calculate slope from two points:
 slope = (pH_reference - 7.0) / (V_reference - V_neutral) 
 Protobuf Message Format 
 message SensorBoardPHInfo {
 float ph_value;
 float voltage;
 SensorState state;
 PHErrorCode error_code;
}

enum PHErrorCode {
 PH_NO_ERROR = 0;
 PH_COMMUNICATION_FAILURE = 1;
 PH_INVALID_DATA = 2;
} 
 Error Handling 
 if (ph_result == RESULT_ERR_UNIMPLEMENTED) {
 // Hardware not connected
 diagnostics.ph_sensor.state = SensorState_SENSOR_IDLE;
 diagnostics.ph_sensor.error_code = PHErrorCode_PH_COMMUNICATION_FAILURE;
} else if (ph_result == RESULT_OK) {
 if (validate_ph_value(ph_sensor.ph_value) == RESULT_OK) {
 diagnostics.ph_sensor.state = SensorState_SENSOR_OPERATING;
 diagnostics.ph_sensor.error_code = PHErrorCode_PH_NO_ERROR;
 } else {
 // Invalid data from sensor (out of 0-14 range)
 diagnostics.ph_sensor.state = SensorState_SENSOR_ERROR;
 diagnostics.ph_sensor.error_code = PHErrorCode_PH_INVALID_DATA;
 }
} 
 Integration Notes 
 Single sensor instance in main application Updates transmitted to network at main loop interval (5 seconds default) Temperature compensation not currently implemented (assumes ~25°C) Sample averaging reduces noise but introduces ~40ms latency per update Electrode response time: ~100-300ms depending on pH change magnitude