如何解决PH检测代码中的if/else语句异常问题?
Arduino PH检测代码修复与逻辑优化
问题需求
当PH值处于3.8-4.1、6.8-7.1、9.8-10.1区间时,LCD显示PH值和电压值;若PH值超出这些区间,则显示"Dosing is required"。当前代码无法正常运行,需修复逻辑与语法问题。
代码问题分析
- 变量类型错误:
Sensor_MINvalue1等阈值变量定义为int,但赋值为浮点数(如3.8),会导致精度丢失,应改为float类型。 - else语法错误:最后一个分支使用了
else (条件); { ... }的错误语法,这会导致条件被当作独立语句执行,else块无条件执行,逻辑完全混乱。 - 内部判断逻辑矛盾:每个区间内的
if(phvalue < Sensor_MIN && phvalue > Sensor_MAX)条件永远不成立(因为MIN < MAX),正确逻辑应为判断PH值超出当前区间,即phvalue < Sensor_MIN || phvalue > Sensor_MAX。 - 代码冗余:三个区间的显示与串口输出逻辑完全重复,可合并简化。
- 未使用函数:
breath函数定义后未被调用,可根据需求决定保留或移除。
修复后的代码
#include <Wire.h> #include "DFRobot_LCD.h" DFRobot_LCD lcd(16, 2); //16字符2行显示 #define PH_PIN 25 float voltage, phvalue, temperature = 25; float acidVoltage = 1990; //PH4.0缓冲液电压 float neutralVoltage = 1389; //PH7.0缓冲液电压 // 修正变量类型为float,保留阈值精度 float Sensor_MINvalue1 = 3.8; float Sensor_MAXvalue1 = 4.1; float Sensor_MINvalue2 = 6.8; float Sensor_MAXvalue2 = 7.1; float Sensor_MINvalue3 = 9.8; float Sensor_MAXvalue3 = 10.1; void setup() { Serial.begin(115200); // 修正波特率为常用的115200(原代码写11520,可能是笔误) lcd.init(); lcd.setCursor(4,0); lcd.print("Welcome"); delay(3000); lcd.clear(); lcd.setCursor(3,0); lcd.print("Reading PH"); delay(5000); lcd.clear(); lcd.setCursor(3,0); lcd.print("Please Wait"); delay(5000); lcd.clear(); } void loop() { static unsigned long timepoint = millis(); if(millis() - timepoint > 1000U){ timepoint = millis(); voltage = analogRead(PH_PIN) / 4095.0 * 3300; // 计算PH值的斜率与截距 float slope = (7.0 - 4.0) / ((neutralVoltage - 1500)/30.0 - (acidVoltage - 1500)/3.0); float intercept = 7.0 - slope * (neutralVoltage - 1500)/3.0; phvalue = slope * (voltage - 1500)/3.0 + intercept; // 标记是否在有效区间内 bool inValidRange = false; // 检查三个区间,符合则显示数据 if(phvalue >= Sensor_MINvalue1 && phvalue <= Sensor_MAXvalue1){ inValidRange = true; } else if(phvalue >= Sensor_MINvalue2 && phvalue <= Sensor_MAXvalue2){ inValidRange = true; } else if(phvalue >= Sensor_MINvalue3 && phvalue <= Sensor_MAXvalue3){ inValidRange = true; } if(inValidRange){ // 串口输出 Serial.print("Voltage:"); Serial.print(voltage, 1); Serial.print(" PH:"); Serial.println(phvalue, 2); // LCD显示 lcd.clear(); lcd.setCursor(0,0); lcd.print("PH : "); lcd.print(phvalue, 2); lcd.setCursor(0,1); lcd.print("Volt : "); lcd.print(voltage/1000, 2); } else { // 超出区间,提示需要加药 lcd.clear(); lcd.setCursor(2,0); lcd.print("Dosing required"); Serial.println("PH out of range - Dosing required"); delay(5000); } } }
修复说明
- 修正了阈值变量的类型为
float,避免精度丢失。 - 重构了区间判断逻辑,用一个布尔变量标记是否在有效区间,简化重复代码。
- 修复了else分支的语法错误,正确区分有效/无效区间的处理逻辑。
- 修正了波特率的笔误(原11520改为115200,常用波特率)。
- 移除了未使用的
breath函数,若需要LCD呼吸灯效果,可在setup或loop中调用。 - 调整了LCD显示的字符位置,确保"Dosing required"能完整显示在16字符屏上。
内容的提问来源于stack exchange,提问作者Muhammad Aniqchino
相关产品推荐
相关产品推荐

