基于单片机设计的家用自来水水质监测装置
一、前言
本文介绍基于单片机设计的家用自来水水质监测装置。利用STM32F103ZET6作为主控芯片,结合水质传感器和ADC模块,实现对自来水水质的检测和监测功能。通过0.96寸OLED显示屏,将采集到的水质数据以直观的方式展示给用户。
随着人们对健康意识的提高和环境保护的重视,水质安全已经成为人们生活中一个重要的议题。自来水作为我们日常生活中最主要的饮用水来源之一,其水质的安全与否直接关系到我们的健康。
本设计采用了先进的STM32F103ZET6主控芯片,具备强大的处理能力和丰富的外设接口。通过水质传感器,可以实时采集与水质相关的模拟信号。然后,通过ADC模块将模拟数据转换为数字信号,再经过算法处理得到相应的水质参数。最后,将结果通过0.96寸OLED显示屏进行展示,用户可以清晰地了解自来水的水质状况。
该装置特点:易于携带、操作简单、实时性好、精度高。用户只需将传感器浸入自来水中,即可获取到水质参数,并通过显示屏直观地了解水质状况,为家庭提供了一个简单方便的水质监测解决方案。
二、硬件选型
【1】主控芯片:STM32F103ZET6,这是一款基于ARM Cortex-M3内核的高性能微控制器。具有丰富的外设接口和较大的存储容量,适合用于处理水质传感器的数据采集和处理。
【2】水质传感器:自来水水质监测的传感器。
【3】显示屏:选择0.96寸OLED显示屏,可以在小尺寸的装置上显示采集到的水质数据。OLED显示屏具有高对比度、低功耗和快速刷新的特点,适合嵌入式应用。
三、常见的水质传感器
以下是一些常见的水质传感器类型,可用于家用自来水水质监测装置:
【1】pH传感器:用于测量水的酸碱度,即pH值。pH传感器通常基于玻璃电极原理,可以提供准确的pH值。
【2】溶解氧传感器:用于测量水中的溶解氧含量。溶解氧传感器可以采用膜式传感器或电极式传感器,根据测量原理的不同,提供溶解氧浓度的准确值。
【3】浊度传感器:用于测量水中的悬浮颗粒物的浓度或水的浊度。浊度传感器可以采用光散射原理或光吸收原理进行测量。
【4】电导率传感器:用于测量水中的电导率,即水的导电性。电导率传感器可以提供水中的总溶解固体(TDS)值或盐度值。
四、家用自来水的水质标准
以下是常见水质指标和标准参考:
【1】pH值:pH值表示水的酸碱度,一般应在6.5-8.5之间。
【2】浑浊度:浑浊度表示水中悬浮颗粒物的浓度,常用浊度单位为NTU(涡轮比色法浊度单位)。根据国际标准,家用自来水的浑浊度应小于1 NTU。
【4】溶解氧:溶解氧表示水中溶解的氧气含量,通常以毫克/升(mg/L)为单位。对于家用自来水,溶解氧的标准范围可以在5-8 mg/L之间。
【5】铁和锰:铁和锰是常见的金属元素,高浓度的铁和锰会给水带来颜色和异味。根据标准,家用自来水中的铁含量应小于0.3 mg/L,锰含量应小于0.1 mg/L。
【6】氟化物:氟化物是一种有益的微量元素,但高浓度的氟化物对人体有害。一般而言,家用自来水中的氟化物含量应小于1.5 mg/L。
【7】各种有害物质:家用自来水应符合国家或地区的相关法规和标准,以确保其不含有害物质,如重金属、有机污染物、农药残留等。
五、硬件代码
5.1 采集数据显示
#include "stm32f10x.h"
#include "oled.h"// 定义ADC采集通道和引脚
#define ADC_CHANNEL 0 // 假设使用ADC1的通道0
#define ADC_PIN GPIO_Pin_0
#define ADC_PORT GPIOA// 定义OLED屏幕相关参数
#define OLED_WIDTH 128
#define OLED_HEIGHT 64// 全局变量
uint16_t adc_value = 0; // ADC采集到的数值// 函数声明
void ADC_Configuration(void);
void OLED_Init(void);int main(void)
{// 初始化ADC和OLEDADC_Configuration();OLED_Init();while (1){// 启动ADC转换ADC_SoftwareStartConvCmd(ADC1, ENABLE);// 等待ADC转换完成while (ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET);// 读取ADC转换结果adc_value = ADC_GetConversionValue(ADC1);// 在OLED上显示ADC采集的数值char str[10];sprintf(str, "%4d", adc_value);OLED_ShowString(0, 0, str); // 在坐标(0, 0)位置显示字符串// 延时一段时间for (uint32_t i = 0; i < 100000; i++);}
}// ADC配置函数
void ADC_Configuration(void)
{ADC_InitTypeDef ADC_InitStructure;GPIO_InitTypeDef GPIO_InitStructure;// 使能ADC1和GPIOA的时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_GPIOA, ENABLE);// 配置ADC引脚为模拟输入GPIO_InitStructure.GPIO_Pin = ADC_PIN;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;GPIO_Init(ADC_PORT, &GPIO_InitStructure);// ADC配置ADC_DeInit(ADC1);ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;ADC_InitStructure.ADC_ScanConvMode = DISABLE;ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;ADC_InitStructure.ADC_NbrOfChannel = 1;ADC_Init(ADC1, &ADC_InitStructure);// 配置ADC通道ADC_RegularChannelConfig(ADC1, ADC_CHANNEL, 1, ADC_SampleTime_13Cycles5);// 使能ADCADC_Cmd(ADC1, ENABLE);// 开启ADC校准ADC_ResetCalibration(ADC1);while (ADC_GetResetCalibrationStatus(ADC1));ADC_StartCalibration(ADC1);while (ADC_GetCalibrationStatus(ADC1));// 设置ADC转换序列ADC_RegularChannelConfig(ADC1, ADC_CHANNEL, 1, ADC_SampleTime_13Cycles5);
}// OLED屏幕初始化函数
void OLED_Init(void)
{// 初始化OLED屏幕OLED_Init();OLED_Clear();
}
5.2 oled.h
#ifndef __OLED_H__
#define __OLED_H__#include "stm32f10x.h"#define OLED_WIDTH 128
#define OLED_HEIGHT 64void OLED_Init(void);
void OLED_Clear(void);
void OLED_WriteByte(uint8_t data, uint8_t cmd);
void OLED_SetPos(uint8_t x, uint8_t y);
void OLED_ShowChar(uint8_t x, uint8_t y, char ch);
void OLED_ShowString(uint8_t x, uint8_t y, const char* str);#endif /* __OLED_H__ */
5.3 oled.c
#include "OLED.h"const uint8_t OLED_GRAM[128][8] = {0}; // OLED显示缓存void OLED_Init(void)
{// ... 初始化OLED屏幕的相关操作 ...
}void OLED_Clear(void)
{// 清空OLED显示缓存(全黑)memset((void*)OLED_GRAM, 0x00, sizeof(OLED_GRAM));// 更新OLED屏幕显示OLED_SetPos(0, 0);for (uint8_t i = 0; i < 8; i++){OLED_WriteByte(0xb0 + i, 0x00); // 设置页地址(0-7)OLED_WriteByte(0x00, 0x00); // 设置列地址低4位(0-3)OLED_WriteByte(0x10, 0x00); // 设置列地址高4位(4-7)for (uint8_t j = 0; j < 128; j++){OLED_WriteByte(0x00, 0x40); // 写入数据,全黑}}
}void OLED_WriteByte(uint8_t data, uint8_t cmd)
{// ... 将数据写入OLED屏幕的具体操作 ...
}void OLED_SetPos(uint8_t x, uint8_t y)
{// ... 设置OLED屏幕显示位置的具体操作 ...
}void OLED_ShowChar(uint8_t x, uint8_t y, char ch)
{uint8_t c = ch - ' '; // 获取字库中的字模if (x >= OLED_WIDTH || y >= OLED_HEIGHT) return;for (uint8_t i = 0; i < 6; i++){uint8_t line = cFont6x8[c][i];for (uint8_t j = 0; j < 8; j++){if (line & 0x01){OLED_GRAM[y + j][x + i] = 1;}else{OLED_GRAM[y + j][x + i] = 0;}line >>= 1;}}// 更新OLED屏幕显示OLED_SetPos(x, y / 8);for (uint8_t i = 0; i < 8; i++){OLED_WriteByte(0xb0 + (y / 8) + i, 0x00); // 设置页地址OLED_WriteByte((x & 0x0f), 0x00); // 设置列地址低4位OLED_WriteByte((x >> 4) | 0x10, 0x00); // 设置列地址高4位for (uint8_t j = 0; j < 128; j++){OLED_WriteByte(OLED_GRAM[y + i][j], 0x40); // 写入数据}}
}void OLED_ShowString(uint8_t x, uint8_t y, const char* str)
{while (*str != '\0'){OLED_ShowChar(x, y, *str++);x += 6;if (x >= OLED_WIDTH){x = 0;y += 8;}}
}
相关文章:

基于单片机设计的家用自来水水质监测装置
一、前言 本文介绍基于单片机设计的家用自来水水质监测装置。利用STM32F103ZET6作为主控芯片,结合水质传感器和ADC模块,实现对自来水水质的检测和监测功能。通过0.96寸OLED显示屏,将采集到的水质数据以直观的方式展示给用户。 随着人们对健…...

ubuntu20.04运用startup application开机自启动python程序
运用startup application开机自启动python程序。在终端中输入gnome-session-properties,如果显示没有则先进行安装,sudo apt-get update 和sudo apt install StartupApplications(根据显示提示安装)。在显示程序中搜索startup,打开应用程序。 在程序目录…...

SpringBoot整合Caffeine实现缓存
Caffeine Caffeine是一种基于Java的高性能缓存库,它提供了可配置、快速、灵活的缓存实现。Caffeine具有以下特点: 高性能:Caffeine使用了一些优化技术,如基于链表的并发哈希表和无锁算法,以提供卓越的读写性能。容量…...

DVWA-弱会话IDS
弱会话IDS Session简介: 用户登录后,在服务器就会创建一个会话(session),叫做会话控制,接着访问页面的时候就不用登录,只需要携带Session去访问即可。 sessionID作为特定用户访问站点所需要的唯一内容。如果能够计算…...

【C++中cin、cin.get()、cin.getline()、getline() 的区别】
文章目录 引入cin基本用法输入多个变量换行符存放在缓冲区中 cin.get()基本用法重载函数换行符残留在缓冲区中 cin.getline()基本使用重载函数换行符不会残留在缓冲区中 string 流中的 getline()总结用法总结几个输入实例输入格式输入格式输入格式输入格式 输出格式 写在最后 引…...

SSH连接华为交换机慢
ssh连接交换机慢是因为交换计算密钥算法阶段默认使用安全性更高的秘钥,由于性能问题导致连接比较慢,如一台华为S5735S-L24T4S-QA2的交换机默认使用如下秘钥,安全行由高到低。 ssh server key-exchange dh_group16_sha512 dh_group15_sha512 …...

Web攻防03_MySQL注入_数据请求
文章目录 PHP-MYSQL-数据请求类型1、数字型(无符号干扰)2、字符型(有符号干扰)3、搜索型(有多符号干扰)4、框架型(有各种符号干扰) PHP-MYSQL-数据请求方法数据请求方法GET:POST:Coo…...

JS加密/解密那些必须知道的事儿
一直以来,字符串的编码问题对于新手程序员来说,或者平常不太涉猎这方面的程序员来说,是犹如灵异学一样的存在。经常会遇到莫名其妙的编码问题,导致的各种的无法理解的错误。 今天,本问就来介绍一下作者所知晓的一切…...

搭建伪分布式Hadoop
文章目录 一、Hadoop部署模式(一)独立模式(二)伪分布式模式(三)完全分布式模式 二、搭建伪分布式Hadoop(一)登录虚拟机(二)上传安装包(三…...

【C++】特殊类的设计(只在堆、栈创建对象,单例对象)
🌏博客主页: 主页 🔖系列专栏: C ❤️感谢大家点赞👍收藏⭐评论✍️ 😍期待与大家一起进步! 文章目录 一、请设计一个类,只能在堆上创建对象二、 请设计一个类,只能…...

分类预测 | MATLAB实现基于GRU-AdaBoost门控循环单元结合AdaBoost多输入分类预测
分类预测 | MATLAB实现基于GRU-AdaBoost门控循环单元结合AdaBoost多输入分类预测 目录 分类预测 | MATLAB实现基于GRU-AdaBoost门控循环单元结合AdaBoost多输入分类预测预测效果基本介绍模型描述程序设计参考资料 预测效果 基本介绍 1.MATLAB实现基于GRU-AdaBoost门控循环单元结…...

【Spring Boot项目】根据用户的角色控制数据库访问权限
文章目录 简介方法一添加数据库依赖配置数据库连接创建用户角色表创建Spring Data JPA实体和仓库实现自定义的网关过滤器配置网关过滤器几个简单的测试API 方法二创建数据库访问接口实现数据库访问接口创建用户角色判断逻辑创建网关过滤器配置网关过滤器 总结 简介 在一些特定…...

EthernetIP 转MODBUS RTU协议网关连接FANUC机器人作为EthernetIP通信从站
远创智控YC-EIPM-RTU网关产品是一款高效的数据采集工具,它可以通过各种数据接口与工业领域的仪表、PLC、计量设备等产品连接,实时采集这些设备中的运行数据、状态数据等信息。采集到的数据经过整合和运算等操作后,可以被传输到其他设备或者云…...

如何注册微信小程序
如何注册微信小程序 前言 因为最近沉迷和朋友们一起下班去打麻将,他们推荐了一个计分的小程序,就不需要每局都转账或者用扑克牌记录了,但是这个小程序不仅打开有广告,各个页面都植入了广告,用起来十分不适。 于是我…...

移动App安全检测的必要性,app安全测试报告的编写注意事项
随着移动互联网的迅猛发展,移动App已经成为人们日常生活中不可或缺的一部分。然而,虽然App给我们带来了便利和乐趣,但也伴随着一些潜在的安全风险。黑客、病毒、恶意软件等威胁着用户的隐私和财产安全,因此进行安全检测就显得尤为…...

DVWA-JavaScript Attacks
JavaScript Attacks JavaScript Attack即JS攻击,攻击者可以利用JavaScript实施攻击。 Low 等级 核心源码,用的是dom语法这是在前端使用的和后端无关,然后获取属性为phrase的值然后来个rot13和MD5双重加密在复制给token属性。 <script&…...

算法通关村第二关|白银|链表反转拓展【持续更新】
1.指定区间反转 1.1 头插法:将区间内遍历到的结点插入到起始处之前。 public ListNode reverseBetween(ListNode head, int left, int right) {ListNode dummyNode new ListNode(-1);dummyNode.next head;ListNode pre dummyNode;// 将pre移动到区间的前一位&a…...

开发者职场“生存状态”大调研报告分析 - 第四版
听人劝、吃饱饭,奉劝各位小伙伴,不要订阅该文所属专栏。 作者:不渴望力量的哈士奇(哈哥),十余年工作经验, 跨域学习者,从事过全栈研发、产品经理等工作,现任研发部门 CTO 。荣誉:2022年度博客之星Top4、博客专家认证、全栈领域优质创作者、新星计划导师,“星荐官共赢计…...

代码与细节(一)
在用到 Java17的新特性 Unmodifiable Lists 时不知道你是否和我有同样的惊讶 为什么弄了这么多重载方法? 先说结论:为了性能。 其实一细想,都能想明白:varargs(可变参数) 的背后是数组的内存分配和初始化,相比正常的…...

AI绘画使用Stable Diffusion(SDXL)绘制中国古代神兽
一、引言 说到神奇异兽,脑海中首先就会跳出我国古代神话传说中的各种神兽。比如青龙、白虎、朱雀、玄武,再比如麒麟、凤凰、毕方、饕餮等等,这些都是大家耳熟能详的的神兽。 这些神兽不仅体现了人们丰富的创造力和想象力,更是我…...

老卫带你学---leetcode刷题(148. 排序链表)
148. 排序链表 问题: 给你链表的头结点 head ,请将其按 升序 排列并返回 排序后的链表 。 示例 1:输入:head [4,2,1,3] 输出:[1,2,3,4]示例 2:输入:head [-1,5,3,4,0] 输出:[-1…...

21.1 stm32使用LTDC驱动LCD--配置说明
本文讲解如何配置LTDC驱动LCD的参数配置,以及CubeMx参数配置说明 本文使用的是淘宝买的一块带电容触摸的液晶显示屏:5寸TFT液晶显示屏高清800*480免驱40P通用RGBIPS全视角彩屏GT911 说实话,价格还是相对挺便宜的,值得入手…...

zabbix监控nginx的状态页面
zabbix监控nginx的状态页面 文章目录 zabbix监控nginx的状态页面1.环境说明2.所涉及到的知识点3.在nginx主机上安装zabbix_agent4.开启nginx状态显示页面5.进入zabbix的web页面配置主机,监控项,触发器5.1.添加主机5.2.创建监控项5.3.创建触发器 1.环境说…...

C语言初学者工具选择:vscode + MSYS2 + cmake 搭建 C环境
文章目录 前言1. MSYS2 安装1. 下载安装包2. 安装3. pacman 换清华大学源4. 安装 mingw-w64 toolchain 和 cmake ninja5. 将 toolchain 加入系统环境变量 2. 设置 vscode1. 必要的插件2. 一个简单的 vscode cmake 项目 最后C数据结构与算法CMake 前言 网上关于使用 vscode 配…...

【四:httpclient的使用】
目录 1、Demo案例2、请求一个带cookies的get请求3、请求一个带cookies的post请求案例一,案例二的properties的配置 1、Demo案例 public class MyHttpClient {Testpublic void test1() throws IOException {//用来存放我们的结果String result;HttpGet get new Htt…...

在innodb引擎中,count(*)、count(1)、count(主键)、count(字段)哪个性能最高?
在InnoDB引擎中,这四种计数值的效率高低取决于具体的数据库和数据表结构,无法一概而论哪个性能最高。不过,一般情况下可以按照以下顺序进行选择: count():统计所有行的数量。由于InnoDB引擎的行锁是锁住整行ÿ…...

华为OD 跳格子2(200分)【java】B卷
华为OD统一考试A卷B卷 新题库说明 你收到的链接上面会标注A卷还是B卷。目前大部分收到的都是B卷。 B卷对应20022部分考题以及新出的题目,A卷对应的是新出的题目。 我将持续更新最新题目 获取更多免费题目可前往夸克网盘下载,请点击此链接进入:…...

javascript/python 笔记: folium feature group自动切换
1 python部分 python部分只能是静态的结果 1.1 导入库 import folium import math 1.2 数据 cell_lst表示基站位置,location_lst表示 用户实际位置(均为伪数据) cell_lst[[1.341505, 103.682498],[1.342751, 103.679604],[1.341505, 10…...

Python中的元组
Python 元组 Python 的元组与列表类似,不同之处在于元组的元素不能修改。以下是关于Python元组的一些基本信息: 元组的使用:元组是一个不可变的序列类型,使用小括号 () 来定义。元组没有增加元素append、修改元素、删除元素pop的…...

在云计算环境中,如何利用 AI 改进云计算系统和数据库系统性能
文章目录 前言一、关于唐明洁教授二、AI for System2.1 面向分布式作业的人工智能2.1.1 现阶段企业云计算系统环境所遇到的普遍痛点2.1.2 云计算系统环境所遇到的普遍痛点的解决方案(一)Google Autopilot Eurosys 2021方案(Pod级别࿰…...