水质检测 — TDS模块

本文介绍了一种TDS(总溶解固体)检测的程序,通过读取ADC模拟值并应用中值滤波算法来获取稳定的数据。程序还包含了温度补偿的计算,以更准确地反映不同温度下水的TDS值。通过DS18B20模块获取的温度数据可以用于修正读数,提高测量精度。
摘要由CSDN通过智能技术生成

TDS检测水质

   TDS(Total Dissolved Solids),总溶解固体,又称溶解性固体总量,表明1升水中溶有多少毫克溶解性固体。一般来说,TDS值越高,表示水中含有的溶解物越多,水就越不洁净。作为一种可快速检测的参数,TDS目前还是可以作为有效的水质情况反映参数来作为参考。
   Qhebot的TDS模块如图:
在这里插入图片描述
 读取TDS值的主要程序如下:


#define TdsSensorPin A0     //Nano接A6 ESP8266接A0 ESP32接A5或者其他ADC引脚
#define VREF 5.0            // ADC的模拟参考电压(Volt)
#define readCount 40        // 从ADC读取到的模拟值个数
#define SCOUNT  30          // 滤波之后的模拟值个数
int Buffer[SCOUNT];  		// 将模拟值存储在数组中,从ADC读取
int BufferTemp[SCOUNT];
int BufferIndex = 0, copyIndex = 0;
float averageVoltage = 0, tdsValue = 0;
float temperature = 25;		//未添加温度补偿默认25℃
float compensationVolatge;        //修正后的电压用于实现温度补偿
float compensationCoefficient;    //温度补偿系数

void setup()
{
  Serial.begin(115200);
  pinMode(TdsSensorPin, INPUT);
}

void loop()
{
  TDS();
  delay(500);
}

float TDS() {
  static unsigned long analogSampleTimepoint = millis();
  if (millis() - analogSampleTimepoint > 40U)  //每40毫秒,从ADC读取模拟值
  {
    analogSampleTimepoint = millis();
    for (int BufferIndex = 0; BufferIndex < readCount; BufferIndex++){
      Buffer[BufferIndex] = analogRead(TdsSensorPin);     //读取传感器输出引脚模拟电压存储到缓冲区
      //Serial.printf("Buffer[%d]: %d \n", BufferIndex, Buffer[BufferIndex]);
    }
  }
  static unsigned long printTimepoint = millis();
  if (millis() - printTimepoint > 800U) {
    printTimepoint = millis();
    for (copyIndex = 0; copyIndex < SCOUNT; copyIndex++)
      BufferTemp[copyIndex] = Buffer[copyIndex];

    //通过中值滤波算法读取更稳定的模拟值,并转换为电压值。getMedianNum见下
    averageVoltage = getMedianNum(BufferTemp, SCOUNT) * (float)VREF / 1024.0;

    //temperture待测溶液温度  compensationCoefficient温度校正系数
    //温度补偿公式: fFinalResult(25^C) = fFinalResult(current)/(1.0+0.02*(fTP-25.0));
    compensationCoefficient = 1.0 + 0.02 * (temperature - 25.0); 

    //温度补偿
    compensationVolatge = averageVoltage / compensationCoefficient;

    //转换为电压值,根据标准曲线
    tdsValue = (133.42 * compensationVolatge * compensationVolatge * compensationVolatge - 255.86 * compensationVolatge * compensationVolatge + 857.39 * compensationVolatge) * 0.5;
  }

  //串口输出tdsValue
  Serial.printf("\n TDS Value:"); Serial.print(tdsValue); Serial.printf("ppm \n");
}

  该程序是未添加温度补偿(默认水的温度是25℃),温度补偿只需将DS18B20模块获取的温度赋给全局变量temperature 即可。
  上述程序中的中值滤波 getMedianNum 如下,也可以考虑使用其他滤波算法,如:算术平均滤波、滑动平均滤波等。

// 中值滤波     bArray[]数据源  iFilterLen数据个数
int getMedianNum(int bArray[], int iFilterLen)
{
//  Serial.printf("\n滤波……");
  int bTab[iFilterLen];
  for (byte i = 0; i < iFilterLen; i++) {
    bTab[i] = bArray[i];
//    Serial.printf("\n bArray[%d]: %d ", i, bArray[i]);
  }

  int i, j, bTemp;
  for (j = 0; j < iFilterLen - 1; j++) {
    for (i = 0; i < iFilterLen - j - 1; i++) {
      if (bTab[i] > bTab[i + 1]) {    //使升序排列便于取中值bTemp
        bTemp = bTab[i];
        bTab[i] = bTab[i + 1];
        bTab[i + 1] = bTemp;
      }
    }
  }
  if ((iFilterLen & 1) > 0)    			  //和1相与判断奇偶
    bTemp = bTab[(iFilterLen - 1) / 2];   //奇数个元素取中值
  else
    bTemp = (bTab[iFilterLen / 2] + bTab[iFilterLen / 2 - 1]) / 2;   //偶数个元素取中值
  return bTemp;
}

  • 12
    点赞
  • 129
    收藏
    觉得还不错? 一键收藏
  • 31
    评论
评论 31
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值