1.设计概述

  本系统的软件设计采用模块化、层次化思想,以STM32F103C8T6为核心,完成底层硬件驱动、数据处理、通信协议解析及控制逻辑执行。整个软件架构从上到下分为应用层、中间层和硬件驱动层。应用层负责主控流程、按键响应、报警判断及UI刷新;中间层封装传感器标定算法、滤波处理、数据打包解包以及MQTT/AT指令集解析;硬件驱动层则直接操作寄存器或通过HAL库实现对GPIO、ADC、I2C、USART及定时器等外设的初始化与数据收发。采用这种分层设计可显著提高代码的可读性、可移植性和后续扩展能力。

  系统主程序采用前后台(超循环)架构:前台为中断服务程序,负责接收ESP8266 Wi-Fi模块的串口数据、处理定时器溢出中断以及按键外部中断;后台为主循环,顺序执行传感器采集、数据处理、OLED显示更新、数据上报及设备控制任务。为保证数据采集的实时性与控制响应的及时性,主循环周期控制在50ms以内,其中ADC多通道采样使用DMA传输,避免占用CPU过多时间;对于pH传感器和电导率传感器这类模拟量输入,软件中加入滑动平均滤波算法(窗口长度10)抑制随机噪声,并通过标定公式(如三阶多项式拟合)将ADC原始值转换为实际工程单位(pH值、μS/cm)。浊度传感器输出电压与NTU值之间采用分段线性插值法进行标定,提高不同浓度区间的测量精度。

2.ESP8266 WIFI模块

  在通信与数据上报方面,STM32通过USART3与ESP8266交互,采用AT指令集完成Wi-Fi模块的STA模式配置、TCP连接建立及MQTT协议登录。系统预先将网络SSID、密码及物联网平台地址(如阿里云IoT或OneNET的IP及端口)固化在代码中,上电后自动连接;屏幕上显示“ThingsColud connect…”连接信息。

  OLED_DisplayStr(20,26,16,"ThingsColud ");
  OLED_DisplayStr(16,42,16,"connect..... ");
  OLED_Refresh();
  u16 i=0;
  u16 idex=0;
  u8 stat;
  u8 setup_ctl=0;
  u8 buffer[200];
	while(1)
	{
		stat=Esp8266_STA_TCPclinet_Init((u8 *)WIFI_NAME,(u8 *)WIFI_PASSWORD,(u8 *)SERVER_IP,SERVER_PORT);
		if(stat==0)break;
		Delay_Ms(500);
		printf("stat=%d\r\n",stat);
	}  
	printf("服务器连接成功\r\n");
	while(1)
	{
		MQTT_Init();
		stat=MQTT_Connect(ClientID,Username,Password);
		if(stat==0)break;
		Delay_Ms(500);
		printf("正在连接....\r\n");
	}
	printf("连接成功\r\n");
	stat=MQTT_SubscribeTopic(SET_TOPIC,0,1);
	if(stat)printf("订阅失败\r\n");
	else printf("订阅成功\r\n");

  以5s为周期上报数据信息,数据内容包含有turbidity(浊度)、ph(ph值)、ec(电导率)、discharge(水流量)

		if(time3>=5000)//5s上报一次数据
		{
			time3=0;
      /*
        turbidity(浊度)
        ph(ph值)
        ec(电导率)
        discharge(水流量)
      */
      sprintf(mqtt_message,"{\"turbidity\":%d,\"ph\":%.1f,\"ec\":%.1f,\"discharge\":%.1f}",zhuodu_val,PH_val,TDS_value,discharge_temp);//温度
      printf("msg=%s\n",mqtt_message);
			MQTT_PublishData(POST_TOPIC,mqtt_message,0);
		} 

3.ThingsColud平台配置

  1.注册账号登录平台。thingscloud地址
在这里插入图片描述
  进入控制台,创建项目
在这里插入图片描述
在这里插入图片描述
  2.创建设备
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  3.创建设备类型
在这里插入图片描述
在这里插入图片描述
  4.关联设备
在这里插入图片描述
  5.添加功能
在这里插入图片描述
在这里插入图片描述
  6.创建用户
在这里插入图片描述
  7.创建用户应用
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
  8.配置应用UI
在这里插入图片描述
在这里插入图片描述
  9.接入平台
在这里插入图片描述
  10.数据上报与下发
在这里插入图片描述

3.PH传感器驱动

  溶液的酸碱度(PH 值)是溶液的一个重要特性。工业级PH 变送器价格昂贵;市面上的PH 测试笔是成熟产品,无法进行二次设计开发;PH 复合电极输出mV 级的电压信号,单片机无法直接进行识别处理,基于这些现状,本次采用了这款 PH 传感器模块。该模块价格低廉、使用方便、测量精度高、可直接输出0~5V。
  PH 传感器模块的组成如下图所示。该模块通过BNC 接头与PH复合电极进行连接,扩展有DS18B20 温度传感器接口,方便进行软件温度补偿设计。调节10K 蓝色电位器的旋钮可以进行放大倍数调节(顺时针调节增大、逆时针调节减小)。
在这里插入图片描述
在这里插入图片描述
PH数据处理:
  依据测的得电压值用excel 进行曲线公式拟合。图中橙色线为5V ADC 采集系统标准公式,蓝色线为3.3V ADC 采集系统标准公式。
在这里插入图片描述

float PH_val;
//PH值数据处理
void PH_Value_Conversion(u16 ad_val)
{  	
//此模块输出电压范围调整为0~3V3,调整方法如下
//需要在PH计放在9.18标准缓冲液里,调节旋转电位器,将输出调整为1.3V
//需要在PH计放在6.86标准缓冲液里,调节旋转电位器,将输出调整为1.7V
//需要在PH计放在PH4.0标准缓冲液里,调节旋转电位器,将输出调整为2.2V 
  char buffer_show[100];  

		PH_val=(float)ad_val*(3.3/4096);
		PH_val = -5.7541*PH_val+16.654;   //输出电压范围0~3V3
//		printf("adc4 val: %d\r\n",ad_val);
//		printf("PH val: %f\n",PH_val);
  if(PH_val>=10 ||PH_val<0)BEEP=1;
  else BEEP=0;
  snprintf(buffer_show,sizeof(buffer_show),"%.1f   ",PH_val);
  OLED_DisplayStr(45,48,16,(u8*)buffer_show);
}

4.TDS电导率传感器驱动

  TDS(TotalDissolved Solids),中文名总溶解固体,又称溶解性固体总量,表明1升水中溶有多少毫克溶解性固体。一般来说,TDS值越高,表示水中含有的溶解物越多,水就越不洁净。虽然在特定情况下TDS并不能有效反映水质的情况,但作为一种可快速检测的参数,TDS目前还是可以作为有效的水质情况反映参数来作为参考。常用的TDS检测设备为TDS笔,虽然价格低廉,简单易用但不能把数据传给控制系统,做长时间的在线监测,并做水质状况分析。使用专门的仪器,虽然能传数据,精度也高,但价格很贵。为此,推出了这款TDS传感器模块。该模块即插即用,使用简单方便。测量用的激励源采用交流信号,可有效防止探头极化,延长探头寿命的同时,也增加了输出信号的稳定性.TDS探头为防水探头,可长期浸入水中测量。该产品可应用于生活用水、水培等领域的水质检测。有了这个传感器,可轻松DIY-套TDS检测仪了,轻松检测水的洁净程度,为你的水质把好关。
在这里插入图片描述

  • 产品参数

  • 供电电压:3.3 ~ 5.0V

  • 工作电流:3~6mA

  • TDS探针接口:2Pin XH-2.54

  • 温度传感器接口:3PinXH-2.54

  • 输出信号范围:0~ 2.3V

  • TDS测量范围:0~1000ppm

  • TDS测量精度:土5%F.S.(25C)

  • 模块尺寸:42mmX31.2mm

  • 信号输出:0~2.3V模拟信号输出,兼容5V、3.3V两种控制系统

  • DS探头参数:TDS探头适用2分PE管

  • 激励源为交流信号,有效防止探头极化

  • 防水:防水探头,可长期浸入水中测量

  • 引脚说明:
    在这里插入图片描述

  • VCC:供电电压正级

  • GND:供电电压负极

  • T1:温度传感器DS18B20信号输出口(可通过软件进行温度补偿)

  • A0:模拟信号输出(输出电压范围0-2.3V)

  • +:温度传感器电源正级

  • T:温度传感器信号线

  • :温度传感器电源负极

  • 1:TDS探针引线1

  • 2:TDS探针引线2

  • 程序驱动:

// 用于保存转换计算后的电压值 	 
float ADC_ConvertedValueLocal[4]; 
float compensationCoefficient=1.0;//温度校准系数
float TEMP_Value=25.0;
float compensationVolatge;
float TDS_value=0.0,voltage_value;
float kValue=1.67;
/**************TDS值采集函数***************/
void TDS_Value_Conversion(u16 ad_val)
{
  char buffer_show[100];
  ADC_ConvertedValueLocal[0]=(float)ad_val/4096*3.3; //AD转换
  compensationCoefficient=1.0+0.02*((TEMP_Value/10)-25.0); 
  compensationVolatge=ADC_ConvertedValueLocal[0]/compensationCoefficient;
  TDS_value=(133.42*compensationVolatge*compensationVolatge*compensationVolatge - 
  255.86*compensationVolatge*compensationVolatge + 857.39*compensationVolatge)*0.5*kValue;
  if((TDS_value<=0)){TDS_value=0;}
  if((TDS_value>1400)){TDS_value=1400;}	
//  printf("TDS=%.2f\n",TDS_value);//单位ppm,溶解性总固体≤1000ppm
  //电导率
  if(TDS_value>1000)
  {
    BEEP=1;
  }
  else BEEP=0;
  snprintf(buffer_show,sizeof(buffer_show),"%.1f   ",TDS_value);
  OLED_DisplayStr(61,32,16,(u8*)buffer_show);
  /*
  (1)TDS 的测量单位有时也用 mg/L 表示,与 ppm 的换算关系为 1mg/L=1ppm;
  (2)TDS 和电导率往往存在一种相通的关系,有时候 TDS 也可以用来表示电导率,
  两者的关系:1ppm =2uS/cm,其中 uS/cm 为电导率的单位。
  */
}

5.浊度传感器

  水的浑浊度是指水中含有的泥沙,粘土,有机物,浮游生物和微生物等悬浮物质,造成的浑浊程度。工业级的浊度传感器或浊度仪价格昂贵,在电子产品设计中成本太高不适合选用;因此我们选取了一款在家用电器洗衣机、洗碗机上广泛应用的浑浊度传感器,这款浊度传感器利用光学原理,通过溶液中的透光率和散射率来综合判断浊度情况。传感器内部是一个红外线对管,当光线穿过一定量的水时,光线的透过量取决于该水的污浊程度,水越污浊,透过的光就越少。光接收端把透过的光强度转换为对应的电流大小,透过的光多,电流大,反之透过的光少,电流小。浊度传感器模块将传感器输出的电流信号转换为电压信号,通过单片机进行 AD 转换数据处理。改款模块具有模拟量和数字量输出接口。模拟量可通过单片机A/D 转换器进行采样处理,以获知当前水的污浊度。数字量可通过模块上的电位器调节触发阈值,当浊度达到设置好的阈值后,D1 指示灯会被点亮,传感器模块输出由高电平变成低电平,单片机通过监测电平的变化,判断水的浊度是否超标,从而预警或者联动其他设备。该模块价格低廉、使用方便、测量精度高可以用于洗衣机、洗碗机等产品的水污浊程度的测量;也可以用于工业现场控制,环境污水采集等需要浊度检测控制的场合。

在这里插入图片描述
  传感器模块输出电压与浑浊度关系如下图所示:
在这里插入图片描述
  浊度值与模块输出电压满足如下关系:
    TU=-865 .68*U +K
  上式中TU 为当前浊度值,U 为当前温度条件下模块的输出电压值,K 为截距值,需通过标定方法得到。
  传感器输出电压值大小受温度影响,输出电压与温度曲线关系如下图所示。进行浊度测量时需进行温度补偿以保证测量精度。
在这里插入图片描述
  温度校正公式:
    △U=-0 .0192 *(T -25)
  上式中△U 为温度变化引起的电压差;T 为当前测量温度值。

  • 校准方法
      由于浊度传感器的个体差异、环境光或未进行温度补偿等原因。为获得更精确的浊度值,在测量之前,必须进行校准。具体操作方法介绍如下。
      第一步:安装浊度传感器,给传感器模块供电。使用0NTU 的标准溶液(或者接近0NTU 的纯净水或蒸馏水)进行校准;
      第二步:在传感器使用环境状态下(尽量避免光线强弱引起的误差)测量记录当前校准溶液的温度值并记录为T测试;测量并记录传感器模块的输出电压为U 测试
      第三步:计算温差引起的电压差值U。将测量得到T 测试代入温度修正公式。
        △U =-0.0192*(T测试-25)
      第四步:计算0NTU 标准液(25℃)标准电压值U25℃。
        U 25℃=U 测试-△U
      第五步:计算K 值,将计算得到标准电压值U25℃代入标准曲线公式。
        K =865.68*U 25℃
      第六步:修正标准曲线公式。将计算得到的K 代入标准曲线公式。
        TU =865 .68 * U + K

  • 程序设计

/**************TDS值采集函数***************/
float TU=0.0;//读取的AD数值转换为电压值
float TU_value=0.0;//浊度值
float TU_calibration=0.0;//校准后的电压值
float temp_data=0.0;//温度值
float K_Value=3047.19;
void TU_Value_Conversion()
{
	temp_data=DS18B20_Get_Temp();//读取温度
	TU =(float) ADC_ConvertedValue/4096*3.3; // 读取转换的AD值
	
		TU_calibration=-0.0192*(temp_data/10-25)+TU;  
	  TU_value=-865.68*TU_calibration + K_Value;
	
		if(TU_value<=0){TU_value=0;}
		if(TU_value>=3000){TU_value=3000;}

}
Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐