目录
项目介绍
一、 项目需求
1.水资源保护与管理的需求
随着工业化和城市化的快速发展,水资源的污染问题日益严重,对水质进行实时监测和 管理变得尤为重要。水质检测与水位控制器项目的实施,旨在提高水质监测的效率和准确性,为水资源保护和管理提供科学依据。
2.技术进步的推动
近年来,传感器技术、物联网技术、大数据分析等先进技术的快速发展,为水质检测和 水位控制提供了强有力的技术支持。这些技术的应用,使得水质检测更加精准,水位控制更加智能化。
3.市场需求与政策导向
国家和地方政府对水资源保护和管理的重视程度不断提高,出台了一系列相关政策法规,要求加强水质监测和水位控制。同时,随着人们生活水平的提高,对水质安全和水资源有效利用的需求也日益增长。
4.更方便检测与监管
本项目可以将传感器的数据实时更新在阿里云平台,用户只需要下载云智能平台便可以实时检测。使用更加方便。
5.IM1281B 电能计量模块
本项目使用了电能计量,可以更好的使用水泵进行加水,可以检测其电压,电流,功率等一系列数据。
二、设计方案
本方案底层有节点和网关2部分组成。节点板采用 STM32F103C8T6芯片作为主控芯片,节点和网关通过 Lora 进行组网和远距离传输,传输距离在3千米左右。网关主控芯片采用STM32F103 RET6芯片,搭载 oled 显示屏,实现界面的设计、实时传感器数据的显示以及设备运行状态的显示,并可以通过IM1281B 电能计量模块检测模块监控电机的过载情况。同时网关搭载EC800K 芯片作为核心的 4G 联网模组,通过 MQTT 协议把数据传输给有阿里云联网平台,并通过阿里云物联网平台,实现监控大屏的显示和报警信息的推送。
三、相关技术点
- 采集水箱内的水质传感器的水质和水温,功率等参数 。
- 检测到没水之后,可以通过电机进行上水,并可以调节电磁阀的大小,并通过电能检测 模块检测电机的负载情况(空载保护和过载保护)。
- 局域网 Lora 通信,该系统包含网关和节点板组成,节点板和网关通过 Lora 进行组网, 把传感器的数据传输给网关 。
- 网关使用 oled 显示屏,实现数据的显示,并可以通过按键对系统的参数(温度,水质, 功率)阈值进行设置。
- 广域网 4G 通信,网关通过 4G 模组,把数据传输给有人云物联网平台,同时实现 web 监控大屏显示和手机报警信息推送。
四、预计效果
1.开机后自动设置LORA通信模块的工作方式及其地址和信道,并且4G模块自动连接有人云。
2.节点板通过tds传感器将采集的数据通过LORA模块发送给主控板。
3.主控板采集的数据和节点板采集的数据通过oled屏显示出来。
4.将采集到的数据通过4G模块传送至有人云。
5.判断水位是否过低或已满,若过满则打开电机进行上水,若水满则关闭电机停止上水。
6.上电后可以通过计量器模块检测电压,电流,功率等一系列数据,便于使用水泵进行加水和抽水。
设备开发
一、TDS模块
TDS水质传感器是我公司研制的一款高精度产品,用于测量水的TDS值,TDS数值可反应水的洁净程度,可用于生活用水、水培等领域的水质检测。
TDS (Total Dissolved Solids), 中文名:总溶解固体,又称溶解性固体总量,表明1升水中溶有多少毫克溶解性固体。一般来说,TDS值越高,表示水中含有的溶解物越多,水就越不洁净。因此,TDS值的大小,可作为反映水的洁净程度的依据之一。
产品外观:
每一个模块可以搭载两个tds,所以数据一共有8字节。水质水样占四个字节,两个温度占两个字节,还有一个前帧与尾帧。
引脚定义:
主动发送格式:
TDS1计算:TDS1_H256+TDS1_L(ppm)
TDS2计算:TDS2_H256+TDS2_L(ppm)
由于TDS探头的个体差异或者未进行温度补偿等原因,会导致测量值有较大的误差。因此,为获得更精确的TDS值,在测量之后,必须进行校准,校准公式如下:
TDS=[TDS实测值+(T温度-25℃)*0.0108]/[1+(T温度-25)*0.0388]
其中TDS实测值为读取浓度值,T温度为待测溶液测量温度,通过温补公式算出最TDS后值。
二、LORA模块
产品介绍:
E32-433T20D 是一款基于 Semtech 公司 SX1278射频芯片的无线串口模块(TTL电平),透明传输方式,工作在 410~441MHz 频段(默认 433MHz),采用 LoRa 扩频技术。
SX1278 支持 LoRa 扩频技术,LoRa 直序扩频技术具有更远的通讯距离,抗干扰能力强的优势,同时有极强的保密性。在低速通信领域 SX1278具有里程碑意义,并受到业内人士的青睐。该系列默认空中速率为2.4kbps,发射功率为 20dBm,采用工业级晶振,保证其稳定性、一致性精度均小于业内普遍采用的 10ppm。目前已经稳定量产,已经大量应用三表行业、物联网改造、智能家具等领域。模块具有数据加密和压缩功能。模块在空中传输的数据,具有随机性,通过严密的加解密算法,使得数据截获失去意义。而数据压缩功能有概率减小传输时间,减小受干扰的概率,提高可靠性和传输效率。
引脚定义:
M0:与M1配合设置LORA工作模式
M1:与M0配合设置LORA工作模式
Tx:连接外部的RX
Rx:连接外部的TX
Aux:用于只是模块的工作模式
Vcc:电源,2.3-2.5V
Gnd:接地
指令格式:
通过将M0,M1设置为11进入休眠模式可进行指令的设置。
在休眠模式下(M0=1,M1=1),向模块串口发出命令(HEX 格式):C1 C1 C1,模块会返回当前的配置参数,比如:C0 00 00 1A 06 44。此作用是为了检测自己的lora模块可以正常工作。之后根据连接指令发布自己的连接设置
定点发射功能:
三、OLED模块
屏幕采用中景园1.8寸OLED屏幕,无触摸功能。中景园提供屏幕的相关驱动代码和例程,通过将OLED屏幕的驱动代码移植至自己的工程即可点亮屏幕。通过取模软件进行相关汉字取模。最后即可通过厂家提供的函数进行界面的设计。
OLED的移植:将下面的文件移植到自己的工程中,然后修改一下引脚,修改成自己的引脚,之后进行初始化和修改屏幕设置。
最后加上OLED_Refresh()进行实时更新。
字体取模方式:
首先打开取模软件
然后进行设置,设置如下,点阵内的数字手动输入999,然后点击确定。
之后选择以生成16x16的汉字为例
3.1字宽,字高选择16
在输入栏输入需要取模的汉字(只能是汉字),然后点击生成字模。
将生成的字模复制到oledfont.h的数组中
图片取模与之类似,开始时先选择图片取模
点击文件,打开要取模的图片
点击选项,进行设置,图片设置如下,然后点击确定。
将生成的字模复制到bmp.h的数组中
四、4G通信模块
概述:
4G模块是一款采用EC800K为核心的性能出色、小巧便携、高性价比的LTE Cat 1无线通信模块。它凭借其核心特性和设计优势,在物联网领域具有广泛的应用前景,为各种物联网应用提供了稳定、高效的通信解决方案。
4G模块基于ARM、嵌入式等技术,能够满足完成各种设备连接广域网及远程视频传输相关的实验实训,硬件资源开放,人机交互友好,实验手段方法先进。
注意事项:
在操作4G模块时,应保证模块的天线功率合适并检查是否插好
在操作4G模块时,应保证所查SIM卡可正常使用无欠费
在操作4G模块时,应保证正负极是否接插无误
整体结构及工作原理:
4G模块整体上由一个EC800K芯片,一根天线,外围电路构成。
工作原理:
此 4G 模块使用移远 EC800K 芯片作为核心板,支持全网通,使用时可插自己的手机 卡(不需要卡托,可直接插)。模块上电开始工作后,右上角网络指示灯(D1 蓝灯)开始 闪烁,如果 D1 不亮则需要测量电压或检查 PWRKEY 管脚是否接地。
EC800K 通信使用主串口,已经引出管脚排针(VCC GND TX RX 空脚)
串口默认配置:
之后进行AT检测,SIM卡状态查询,注网状态查询,最后进行服务器连接。
之后便可以与阿里云连接,并实时上传数据到阿里云
最终在手机云智能平台可以实时看到数据变化。
五、IM1281B 电能计量模块
模块概述:
IM1281B 单相交流电能计量模块是深圳市艾锐达光电有限公司为了适应各类厂家对自己的产品用电情况进行监控研发而成;也是交流充电桩,路灯监控、机房、基 站监控、节能改造、智能用电管理、动环、安防监控、设备能耗监测等诸多行业各类电力监控需求厂家的配套模 块。该模块准确度优于国家 1 级标准;
模块采用工业级专用电能计量 SOC 芯片,电压电流全隔离采样。集成度更高,可靠性更好。模块体积小,方便集成嵌入到各种系统中;
模块应用:
目前,公司 IM 系列交直流计量模块已经在交直流充电桩、智能家居、动环监控 FSU、智能安防、照明 监控、智能园区、数字机房、能耗管理、电池监控等领域广泛应用,得到各行业标杆企业的采用和认可。此模块可方便嵌入应用于路灯监控、智能家居、智能家电、节能改造、智能用电管理、安防监控、设备能耗监测等诸多行业,是迈入物联网时代的重要配套模块。
模块通讯:
模块引脚定义:
本模块采用Modbus 通信协议,需要采集的数据如下:
Modbus 通信协议规则:
Modbus 协议在一根通讯线上采用主从应答方式的通讯连接方式。首先,主计算机的信号寻址到一台唯一地址的终端设备(从机),然后,终端设备发出的应答信号以相反的方向传输给主机,即:在一根单独的通讯线上信号沿着相反的两个方向传输所有的通讯数据流(半双工的工作模式)。Modbus 协议只允许在主机(PC,PLC 等)和终端设备之间通讯,而不允许独立的终端设备之间的数据交换,这样各终端设备不会在它们初始化时占据通讯线路,而仅限于响应到达本机的查询信号。
主机查询:查询消息帧包括设备地址、功能代码、数据信息码、校验码。地址码表明要选中的从机设备;功能代码告之被选中的从设备要执行何种功能,例如功能代码 03 或 04 是要求从设备读寄存器并返回它们的内容;数据段包含了从设备要执行功能的任何附加信息,校验码用来检验一帧信息的正确性,从设备提供了一种验证消息内容是否正确的方法,它采用 CRC16 的校准规则。
**从机响应:**如果从设备产生正常的回应,在回应消息中有从机地址码、功能代码、数据信息码和 CRC16校验码。数据信息码则包括了从设备收集的数据:像寄存器值或状态。如果有错误发生,我们约定是从机不进行响应。
CRC校验检测:
CRC16 占用两个字节,包含了一个 16 位的二进制值。CRC 值由传输设备计算出来,然后附
加到数据帧上,接收设备在接收数据时重新计算 CRC 值,然后与接收到的 CRC 域中的值进行比较,如果这两个值不相等,就发生了错误。
本项目用到的主机和从机数据帧如下:
最后解析数据段得到电压、电流、功率、电能、功率因素、温度、二氧化碳、频率等数据。
最后还要按照实际结果计算方式得到最终的数据。
解析对应的数据方式:
主机发送数据,从机接受并且保存方式
#include "im1281b.h"
UART5_DATA IM1281bData={0};
IM1218_Struct IM1218_Data={0};
uint8_t Tx_Buffer[8];//接受的数据储存
int Voltage_data,Current_data,Power_data,Energy_data,Pf_data,CO2_data,Tem_data,Hz_data;
/**
* @brief 发送1字节数据
* @param 无
* @retval 无
*/
void UART5_SendData(uint8_t data)
{
HAL_UART_Transmit(&huart5, &data, 1, HAL_MAX_DELAY);
}
/**
* @brief 使用串口发送1字节数据
* @param data:传入的1字节数据
* @retvel 无
*/
void UART5_SendArray(uint8_t* data,uint16_t size)
{
for(int i=0;i<size;i++)
{
UART5_SendData(*(data++));
}
}
/*****************************************************************
*函 数 名 称:calccrc chkcrc
*函 数 功 能:CRC校验
*******************************************************************/
unsigned int calccrc(unsigned char crcbuf,unsigned int crc)
{
unsigned char i;
unsigned char chk;
crc=crc ^ crcbuf;
for(i=0;i<8;i++)
{
chk=( unsigned char)(crc&1);
crc=crc>>1;
crc=crc&0x7fff;
if (chk==1)
crc=crc^0xa001;
crc=crc&0xffff;
}
return crc;
}
unsigned int chkcrc(unsigned char *buf,unsigned char len)
{
unsigned char hi,lo;
unsigned int i;
unsigned int crc;
crc=0xFFFF;
for(i=0;i<len;i++)
{
crc=calccrc(*buf,crc);
buf++;
}
hi=( unsigned char)(crc%256);
lo=( unsigned char)(crc/256);
crc=(((unsigned int)(hi))<<8)|lo;
return crc;
}
/**
* @brief 读取0048H起始地址的后8个寄存器数值
*/
void Read_Data(void)
{
union crcdata
{
unsigned int word16;
unsigned char byte[2];
}crcnow;
Tx_Buffer[0]=0x01; //模块的 ID 号,默认 ID 为 0x01
Tx_Buffer[1]=0x03;
Tx_Buffer[2]=0x00;
Tx_Buffer[3]=0x48;
Tx_Buffer[4]=0x00;
Tx_Buffer[5]=0x08;
crcnow.word16=chkcrc(Tx_Buffer,6); //CRC校验
Tx_Buffer[6]=crcnow.byte[1]; //CRC 校验低字节在前
Tx_Buffer[7]=crcnow.byte[0];
UART5_SendArray(Tx_Buffer,8);
}
/**
* @brief 解析获得对应的数据
*/
void IM1218_DataAnalysis(void)
{
// unsigned char i;
union crcdata
{
unsigned int word16;
unsigned char byte[2];
}crcnow;
if(IM1281bData.myflag!=1)
{
memset(&IM1281bData,0,sizeof(IM1281bData));
return;
}
if(IM1281bData.mydata[0]!=0x01)
{
memset(&IM1281bData,0,sizeof(IM1281bData));
return;
}
crcnow.word16=chkcrc(IM1281bData.mydata,IM1281bData.datalen-2); //reveive_numbe 是接收数据总长度
if((crcnow.byte[0]!=IM1281bData.mydata[IM1281bData.datalen-1])||(crcnow.byte[1]!=IM1281bData.mydata[IM1281bData.datalen-2]))
{
memset(&IM1281bData,0,sizeof(IM1281bData));
return;
}
Voltage_data=(IM1281bData.mydata[3]<<24)|(IM1281bData.mydata[4]<<16)|(IM1281bData.mydata[5]<<8)|IM1281bData.mydata[6];
Current_data=(IM1281bData.mydata[7]<<24)|(IM1281bData.mydata[8]<<16)|(IM1281bData.mydata[9]<<8)|IM1281bData.mydata[10];
Power_data=(IM1281bData.mydata[11]<<24)|(IM1281bData.mydata[12]<<16)|(IM1281bData.mydata[13]<<8)|IM1281bData.mydata[14];
Energy_data=(IM1281bData.mydata[15]<<24)|(IM1281bData.mydata[16]<<16)|(IM1281bData.mydata[17]<<8)|IM1281bData.mydata[18];
Pf_data=(IM1281bData.mydata[19]<<24)|(IM1281bData.mydata[20]<<16)|(IM1281bData.mydata[21]<<8)|IM1281bData.mydata[22];
CO2_data=(IM1281bData.mydata[23]<<24)|(IM1281bData.mydata[24]<<16)|(IM1281bData.mydata[25]<<8)|IM1281bData.mydata[26];
Tem_data=(IM1281bData.mydata[27]<<24)|(IM1281bData.mydata[28]<<16)|(IM1281bData.mydata[29]<<8)|IM1281bData.mydata[30];
Hz_data=(IM1281bData.mydata[31]<<24)|(IM1281bData.mydata[32]<<16)|(IM1281bData.mydata[33]<<8)|IM1281bData.mydata[34];
IM1218_Data.Voltage=Voltage_data*0.0001;
IM1218_Data.Current=Current_data*0.0001;
IM1218_Data.Power=Power_data*0.0001;
IM1218_Data.Energy=Energy_data*0.0001;
IM1218_Data.Pf=Pf_data*0.001;
IM1218_Data.CO2=CO2_data*0.0001;
IM1218_Data.Tem=Tem_data*0.01;
IM1218_Data.Hz=Hz_data*0.01;
printf("电压%.4f\r\n",IM1218_Data.Voltage);
printf("电流%.4f\r\n",IM1218_Data.Current);
printf("有功功率%.4f\r\n",IM1218_Data.Power);
printf("有功电能%.4f\r\n",IM1218_Data.Energy);
printf("功率因数%.4f\r\n",IM1218_Data.Pf);
printf("二氧化碳排量%.4fkg\r\n",IM1218_Data.CO2);
printf("温度%.1f\r\n",IM1218_Data.Tem);
printf("频率%.2f\r\n",IM1218_Data.Hz);
}
项目结项
一、该项目能让自己有什么收获
(1)认识并学会使用了std水质水位模块
(2)了解了不同厂商和尺寸的屏幕,并对屏幕的移植更加了解
(3)学会配置和使用LORA模块,并对SPI更加了解
(4)学会配置和使用4G模块,对4G模块的指令格式以及通信协议有了一定的认识。
(5)学习使用了IM1281B 单相交流电能计量模块,对Modbus 通信协议有了更深入的了解,掌握了主机和从机发送的数据帧具体是什么,和如何去解析从机回复的数据。
二、总结项目中遇到的问题,以及解决办法
(1)在4G模块调试中出现无法连接的情况?
解决办法:在每次连接前先发送“+++”,用来退出透传模式,之后在进行正常的检测
(2)在进行串口调试时,数据末尾的数据得不到,导致数据错误?
解决办法:在串口接受时加入一个判断或者标志位,用于判断是否接受完成。必须等数据接受完毕后才可以进行解析。
(3)在调节lora模块时,lora通信出现问题,主控收不到数据?
解决办法:发送数据时地址或者信道两者不一样,导致数据传输失败。