【智能家居入门1】环境信息监测(STM32、ONENET云平台、微信小程序、HTTP协议)

作为入门本篇只实现微信小程序接收下位机上传的数据,之后会持续发布如下项目:①可以实现微信小程序控制下位机动作,真正意义上的智能家居;②将网络通讯协议换成MQTT协议再实现上述功能,此时的服务器也不再是ONENET,可以是公用的MQTT服务器也可以自己搭建或者租

    • 最终效果
    • 一、下位机模块测试与分析
      • 1、MQ系列传感器
      • 2、DHT11温湿度传感器
      • 3、Esp8266-01s
      • 4、oled液晶屏
    • 二、微信小程序
    • 三、项目获取

这个项目参考的是b站up主:彼岸有光我们有船

最终效果

实物图:
主控是STM32F103C8T6,这里arduino开发板我只是拿来给几个模块供电的,有面包板的话也可以用面包板,用到的模块有:MQ-4天然气传感器、MQ-9可燃气体传感器、0.96寸oled液晶屏、DHT11温湿度传感器、Esp8266-01s、J-Link下载器。
在这里插入图片描述
ONENET云平台:
在这里插入图片描述
微信小程序:
在这里插入图片描述

一、下位机模块测试与分析

1、MQ系列传感器

MQ气体传感器使用的气敏材料是在清洁空气中电导率较低的二氧化锡。当传感器所处环境中存在可燃气体时,传感器的电导率随空气中可燃气体浓度的增加而增大。使用简单的电路即可将电导率的变化转换为与该气体浓度相对应的输出信号。MQ气体传感器对甲烷的灵敏度高,对丙烷、丁烷也有较好的灵敏度。这种传感器可检测多种可燃性气体,特别是天然气。
在这里插入图片描述
关于这个传感器的详细资料可以下载阅读:我用夸克网盘分享了「MQ-2-135-3-7-9烟雾空气敏酒精氢一氧化碳可燃液化传感器模块探头.rar」,点击链接即可保存。打开「夸克APP」,无需下载在线播放视频,畅享原画5倍速,支持电视投屏。
链接:https://pan.quark.cn/s/22c08247dd8a
提取码:xLRC

在这个项目中只需要接三个引脚:VCC、GND、AO。AO输出接开发板的IO口,通过ADC将传感器的模拟输出转换成数字量。这里用到了开发板上ADC1的通道2、3,对应GPIOA-2、GPIOA-3。 关于 ADC的使用可以直接看视频:
https://www.bilibili.com/video/BV1th411z7sn/?p=21&spm_id_from=pageDriver&vd_source=2a10d30b8351190ea06d85c5d0bfcb2a
下面是多通道ADC源码,如果想再加的话只需要在初始化gpio的时候加上需要的io口即可,但是需要对应io口与adc通道的对应关系:
在这里插入图片描述

#include "stm32f10x.h"                  // Device headervoid AD_Init(void)
{GPIO_InitTypeDef GPIO_InitStructure;ADC_InitTypeDef ADC_InitStructure;						//定义结构体变量/*开启时钟*/RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);	//开启ADC1的时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);	//开启GPIOA的时钟/*设置ADC时钟*/RCC_ADCCLKConfig(RCC_PCLK2_Div6);						//选择时钟6分频,ADCCLK = 72MHz / 6 = 12MHz/*GPIO初始化*/GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);					//将PA0、PA1、PA2和PA3引脚初始化为模拟输入/*不在此处配置规则组序列,而是在每次AD转换前配置,这样可以灵活更改AD转换的通道*//*ADC初始化*/ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;		//模式,选择独立模式,即单独使用ADC1ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;	//数据对齐,选择右对齐ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;	//外部触发,使用软件触发,不需要外部触发ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;		//连续转换,失能,每转换一次规则组序列后停止ADC_InitStructure.ADC_ScanConvMode = DISABLE;			//扫描模式,失能,只转换规则组的序列1这一个位置ADC_InitStructure.ADC_NbrOfChannel = 1;					//通道数,为1,仅在扫描模式下,才需要指定大于1的数,在非扫描模式下,只能是1ADC_Init(ADC1, &ADC_InitStructure);						//将结构体变量交给ADC_Init,配置ADC1/*ADC使能*/ADC_Cmd(ADC1, ENABLE);									//使能ADC1,ADC开始运行/*ADC校准*/ADC_ResetCalibration(ADC1);								//固定流程,内部有电路会自动执行校准while (ADC_GetResetCalibrationStatus(ADC1) == SET);ADC_StartCalibration(ADC1);while (ADC_GetCalibrationStatus(ADC1) == SET);
}/*** 函    数:获取AD转换的值* 参    数:ADC_Channel 指定AD转换的通道,范围:ADC_Channel_x,其中x可以是0/1/2/3* 返 回 值:AD转换的值,范围:0~4095*/
uint16_t AD_GetValue(uint8_t ADC_Channel)
{ADC_RegularChannelConfig(ADC1, ADC_Channel, 1, ADC_SampleTime_55Cycles5);	//在每次转换前,根据函数形参灵活更改规则组的通道1ADC_SoftwareStartConvCmd(ADC1, ENABLE);					//软件触发AD转换一次while (ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET);	//等待EOC标志位,即等待AD转换结束return ADC_GetConversionValue(ADC1);					//读数据寄存器,得到AD转换的结果
}

2、DHT11温湿度传感器

1、DHT11 采用单总线协议与单片机通信,概括起来是两个大过程:配对和数据传输,下面对两个过程进行分析:
①配对过程
(1)Data引脚在默认状态时处于高电平;
(2)在开始通信时,MCU将Data引脚拉低并保持18ms,然后再将Data引脚拉高20-40us;
(3)当DHT11收到命令后,它会主动拉低Data引脚,持续80us;
(4)DHT11再次拉高DATA引脚,80us后开始发送数据给MCU。
在这里插入图片描述
②数据传输
(1)在每次发送数据之前,DHT11会把Data引脚先拉低50us,这表示单片机要继续发送下一位数据;
(2)DHT11拉高Data引脚,如果拉高持续时间是26-28us,表示发送0;如果拉高的持续时间是116-118us,表示发送1。

在这里插入图片描述
2、驱动代码:
①c文件:

#include "dht11.h"
#include "delay.h"//复位DHT11
void DHT11_Rst(void)	   
{                 DHT11_IO_OUT(); 	//SET OUTPUTDHT11_DQ_OUT=0; 	//拉低DQdelay_ms(20);    	//拉低至少18msDHT11_DQ_OUT=1; 	//DQ=1 delay_us(30);     	//主机拉高20~40us
}
//等待DHT11的回应
//返回1:未检测到DHT11的存在
//返回0:存在
u8 DHT11_Check(void) 	   
{   u8 retry=0;DHT11_IO_IN();//SET INPUT	 while (DHT11_DQ_IN&&retry<100)//DHT11会拉低40~80us{retry++;delay_us(1);};	 if(retry>=100)return 1;else retry=0;while (!DHT11_DQ_IN&&retry<100)//DHT11拉低后会再次拉高40~80us{retry++;delay_us(1);};if(retry>=100)return 1;	    return 0;
}
//从DHT11读取一个位
//返回值:1/0
u8 DHT11_Read_Bit(void) 			 
{u8 retry=0;while(DHT11_DQ_IN&&retry<100)//等待变为低电平{retry++;delay_us(1);}retry=0;while(!DHT11_DQ_IN&&retry<100)//等待变高电平{retry++;delay_us(1);}delay_us(40);//等待40usif(DHT11_DQ_IN)return 1;else return 0;		   
}
//从DHT11读取一个字节
//返回值:读到的数据
u8 DHT11_Read_Byte(void)    
{        u8 i,dat;dat=0;for (i=0;i<8;i++) {dat<<=1; dat|=DHT11_Read_Bit();}						    return dat;
}
//从DHT11读取一次数据
//temp:温度值(范围:0~50°)
//humi:湿度值(范围:20%~90%)
//返回值:0,正常;1,读取失败
u8 DHT11_Read_Data(u8 *temp,u8 *humi)    
{        u8 buf[5];u8 i;DHT11_Rst();if(DHT11_Check()==0){for(i=0;i<5;i++)//读取40位数据{buf[i]=DHT11_Read_Byte();}if((buf[0]+buf[1]+buf[2]+buf[3])==buf[4]){*humi=buf[0];*temp=buf[2];}}else return 1;return 0;	    
}
//初始化DHT11的IO口 DQ 同时检测DHT11的存在
//返回1:不存在
//返回0:存在    	 
u8 DHT11_Init(void)
{	 GPIO_InitTypeDef  GPIO_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);	 //使能PA端口时钟GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;				 //PA0端口配置GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 		 //推挽输出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);				 //初始化IO口GPIO_SetBits(GPIOA,GPIO_Pin_8);						 //PA0 输出高DHT11_Rst();  //复位DHT11return DHT11_Check();//等待DHT11的回应
} 

②头文件:

#ifndef __DHT11_H
#define __DHT11_H 
#include "sys.h"   //IO方向设置
#define DHT11_IO_IN()  {GPIOA->CRH&=0XFFFFFFF0;GPIOA->CRH|=8;}
#define DHT11_IO_OUT() {GPIOA->CRH&=0XFFFFFFF0;GPIOA->CRH|=3;}
IO操作函数											   
#define	DHT11_DQ_OUT PAout(8) //数据端口	PA0出方向 
#define	DHT11_DQ_IN  PAin(8)  //数据端口	PA0入方向u8 DHT11_Init(void);//初始化DHT11
u8 DHT11_Read_Data(u8 *temp,u8 *humi);//读取温湿度
u8 DHT11_Read_Byte(void);//读出一个字节
u8 DHT11_Read_Bit(void);//读出一个位
u8 DHT11_Check(void);//检测是否存在DHT11
void DHT11_Rst(void);//复位DHT11    
#endif

主函数中直接调用DHT11_Read_Data,定义两个变量接收即可。

3、Esp8266-01s

在使用单片机连接此模块前最好先进行测试,测试可以参考之前的一篇博客(这篇博客还有如何在ONENET云平台创建产品和设备):https://blog.csdn.net/m0_71523511/article/details/135887108
驱动代码:

#include "esp8266.h"char *str[4] = {"POST /devices/1038xxxxxxxx/datapoints HTTP/1.1","api-key:wfsF4bCGtQIQmW=xxxxxxxx","Host:api.heclouds.com",""};
char strValue[8] = {0};// 向onenet发送数据
u8 *esp8266_str_data(char *key, char *value)
{u8 i;u8 *back;char temp[512];char temp3[64];		// 长度char temp5[128];		// 发送值// 拼接post报文strcpy(temp5, "{\"datastreams\":[{\"id\":\"");strcat(temp5, key);strcat(temp5, "\",\"datapoints\":[{\"value\":");strcat(temp5, value);strcat(temp5, "}]}]}");strcpy(temp3, "Content-Length:");sprintf(temp, "%d", strlen(temp5) + 1);strcat(temp3, temp);strcpy(temp, "");for (i = 0; i < 3; i++){strcat(temp, str[i]);strcat(temp, "\r\n");}strcat(temp, temp3);strcat(temp, "\r\n\r\n");strcat(temp, temp5);strcat(temp, "\r\n");back = esp8266_send_data((u8 *)temp, 50);// printf("server:%s\r\n", back);if (strstr((char *)back, "ERROR"))		//发送失败, 重新初始化,发送{esp8266_send_cmd("AT+RST", "OK", 50);esp8266_send_cmd("AT+CIPCLOSE", "OK", 50);esp8266_send_cmd("AT+CWMODE=1", "OK", 50);esp8266_send_cmd("AT+CWDHCP=1", "OK", 50);//esp8266_send_cmd("AT+CIPMUX=0", "OK", 50);while (esp8266_send_cmd("AT+CIPSTART=\"TCP\",\"183.230.40.33\",80", "CONNECT", 100));//esp8266_send_cmd("AT+CIPMODE=1", "OK", 50);//esp8266_send_cmd("AT+CIPSEND", "OK", 20);return esp8266_send_data((u8 *)temp, 50);}return back;
}// 向esp8266请求数据
u16 esp8266_get_data(char *vStr)
{u8 i;u16 value = 0;char *back;char temp[160] = "GET /devices/1038269453/datastreams/";// 拼接请求报文strcat(temp, vStr);strcat(temp, " HTTP/1.1\r\n");for (i = 1; i < 4; i++){strcat(temp, str[i]);strcat(temp, "\r\n");}// 发送报文, 获取返回字符串back = (char *)esp8266_send_data((u8 *)temp, 50);// 在回送报文中截取出数值back = strchr(strstr(back, "\"current_value\":"), ':') + 1;while (*back != '}'){if(*back == '\"'){back++;continue;}value = value * 10 + (*back - '0');back++;}return value;
}//ESP8266模块和PC进入透传模式
void esp8266_start_trans(void)
{//让Wifi模块重启的命令esp8266_send_cmd("AT+RST", "OK", 50);esp8266_send_cmd("AT+CIPCLOSE", "OK", 50);esp8266_send_cmd("AT+CWMODE=1", "OK", 50);esp8266_send_cmd("AT+CWDHCP=1", "OK", 50);delay_ms(1000); //延时2S等待重启成功delay_ms(1000);//让模块连接上自己的路由WIFI GOT IPwhile (esp8266_send_cmd("AT+CWJAP=\"WZQ\",\"1234567890\"", "WIFI GOT IP", 500)){delay_ms(1);};//建立TCP连接  这四项分别代表了 要连接的ID号0~4   连接类型  远程服务器IP地址   远程服务器端口号while (esp8266_send_cmd("AT+CIPSTART=\"TCP\",\"183.230.40.33\",80", "CONNECT", 200)){delay_ms(1);};
}//ESP8266退出透传模式   返回值:0,退出成功;1,退出失败
//配置wifi模块,通过想wifi模块连续发送3个+(每个+号之间 超过10ms,这样认为是连续三次发送+)
u8 esp8266_quit_trans(void)
{u8 result = 1;u3_printf("+++");delay_ms(1000);							   //等待500ms太少 要1000ms才可以退出result = esp8266_send_cmd("AT", "OK", 20); //退出透传判断.if (result)printf("quit_trans failed!");elseprintf("quit_trans success!");return result;
}//向ESP8266发送命令
//cmd:发送的命令字符串;ack:期待的应答结果,如果为空,则表示不需要等待应答;waittime:等待时间(单位:10ms)
//返回值:0,发送成功(得到了期待的应答结果);1,发送失败
u8 esp8266_send_cmd(u8 *cmd, u8 *ack, u16 waittime)
{u8 res = 0;USART3_RX_STA = 0;u3_printf("%s\r\n", cmd); //发送命令delay_ms(1);if (ack && waittime)	  //需要等待应答{while (--waittime) //等待倒计时{delay_ms(10);if (USART3_RX_STA&0X8000) //接收到期待的应答结果{if (esp8266_check_cmd(ack)){printf("%s\r\n", (u8 *)USART3_RX_BUF);break; //得到有效数据}USART3_RX_STA = 0;//strcpy((char *)USART3_RX_BUF, "");		// 清空接收缓存区}}if (waittime == 0) res = 1;}return res;
}//ESP8266发送命令后,检测接收到的应答
//str:期待的应答结果
//返回值:0,没有得到期待的应答结果;其他,期待应答结果的位置(str的位置)
u8 *esp8266_check_cmd(u8 *str)
{char *strx = 0;if (USART3_RX_STA & 0X8000) //接收到一次数据了{USART3_RX_BUF[USART3_RX_STA & 0X7FFF] = 0; //添加结束符strx = strstr((const char *)USART3_RX_BUF, (const char *)str);}return (u8 *)strx;
}//向ESP8266发送数据
//cmd:发送的命令字符串;waittime:等待时间(单位:10ms)
//返回值:发送数据后,服务器的返回验证码
u8 *esp8266_send_data(u8 *cmd, u16 waittime)
{char temp[1024];char *ack = temp;USART3_RX_STA = 0;u3_printf("%s", cmd); //发送命令delay_ms(1);if (waittime)		  //需要等待应答{while (--waittime) //等待倒计时{delay_ms(10);if (USART3_RX_STA & 0X8000) //接收到期待的应答结果{USART3_RX_BUF[USART3_RX_STA & 0X7FFF] = 0; //添加结束符ack = (char *)USART3_RX_BUF;USART3_RX_STA = 0;break; //得到有效数据}}}return (u8 *)ack;
}// 将数字转为字符串
void numToString(u16 value)
{int k = 0, j = 0;int num = (int)value;char tem[10];if (value == 0){strValue[0] = '0';strValue[1] = '\0';return;}while (num){tem[k++] = num % 10 + '0'; //将数字加字符0就变成相应字符num /= 10;				   //此时的字符串为逆序}tem[k] = '\0';k = k - 1;while (k >= 0){strValue[j++] = tem[k--]; //将逆序的字符串转为正序}strValue[j] = '\0'; //字符串结束标志
}

需要注意的是这段代码有两个地方需要修改:
在这里插入图片描述
分别换成自己云平台的设备ID和master-keyapi。

4、oled液晶屏

这是调试程序的好帮手,用的好可以很快找出程序是哪里出问题了。这个驱动代码网上都有很多封装好的,这里就不贴出来了。本项目用的是四引脚oled,使用IIC通信协议,IIC协议的原理可以看此视频:https://www.bilibili.com/video/BV1th411z7sn/?p=31&spm_id_from=pageDriver&vd_source=2a10d30b8351190ea06d85c5d0bfcb2a
想连接oled的详细代码可以看此视频:
https://www.bilibili.com/video/BV1EN41177Pc/?spm_id_from=333.337.search-card.all.click&vd_source=2a10d30b8351190ea06d85c5d0bfcb2a

二、微信小程序

微信小程序最关键的地方就是与云平台的数据交互,其他比如界面、功能都是在这个的基础上才有用。对微信小程序开发感兴趣的可以学一下javascript,比较简单。
下载文章末尾的开源项目压缩包,解压之后可以看到里面有一个文件夹叫:基于STM32的环境信息采集_微信小程序,打开微信开发者工具,选择导入,选择此小程序文件夹打开即可。
在这里插入图片描述
在这里插入图片描述
进入工程之后修改设备ID和master-keyapi:
在这里插入图片描述
index.js代码:

Page({data: {temp:0},// 事件处理函数getinfo(){var that = thiswx.request({url: "https://api.heclouds.com/devices/1038269453/datapoints",   //将请求行中的数字换成自己的设备IDheader: {"api-key": "wfsF4bCGtQIQmW=3wTsPnrdjuFA=" //自己的api-key},method: "GET",success: function (e) {console.log("获取成功",e)that.setData({temp:e.data.data.datastreams[2].datapoints[0].value,humi:e.data.data.datastreams[7].datapoints[0].value,gas_ch4:e.data.data.datastreams[0].datapoints[0].value,ranqi:e.data.data.datastreams[4].datapoints[0].value})console.log("temp==",that.data.temp),console.log("humi==",that.data.humi),console.log("gas==",that.data.gas_ch4),console.log("ranqi==",that.data.ranqi)}});},onLoad() {var that = thissetInterval(function(){that.getinfo()},5000)}})

三、项目获取

我用夸克网盘分享了「基于STM32的环境信息采集(ONENET+HTTP).rar」,点击链接即可保存。打开「夸克APP」,无需下载在线播放视频,畅享原画5倍速,支持电视投屏。
链接:https://pan.quark.cn/s/23b7bdc7b54b
提取码:pR55

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/17286.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

解决Springboot服务启动报错:“Reason: Failed to determine suitable jdbc url”

1、错误详情 *************************** APPLICATION FAILED TO START *************************** Description: Failed to configure a DataSource: url attribute is not specified and no embedded datasource could be configured. Reason: Failed to determine sui…

canvas层级太高?解决方法

这个方法主要是依赖于邀请好有页面展示的canvas二维码二维码以及其他容器的图片 有一个保存图片功能&#xff0c;这个保存图片是需要将二维码以及涉及到的其他容器比如下图&#xff1a; 所以这时候需要canvas来绘制一个保存图片的效果&#xff0c;然后对这个canvas绘制的图片保…

web网络安全知多少

web安全性包括: 客户端脚本安全和服务器端应用服务器 客户端脚本安全: ● 跨站脚本攻击(XSS ) ● 跨站点请求伪造(CSRF) ● 点击劫持(ClickJacking) ● HTML 5 安全性 服务端应用安全: ● 注入攻击 ● 文件上传漏洞 ● 认证与会话管理 ● 访问控制 ● DDos攻击 个人意识和个人…

【CALayer-时钟练习-界面-锚点 Objective-C语言】

一、接下来,我们来说这个时钟练习 1.这个里边呢,有这么一个表盘的一个效果,然后呢,这个秒针,跟我们的时间,是同步的, 新建一个项目, Name:05-时钟练习 然后呢,给这个控制器的View,一个背景颜色,先, 背景颜色, 2.接下来,我们开始来做,我们现在这个表盘啊,是我们…

绿色瓶装水“暗战”竞争越发激烈,华润饮料谋上市同时多地扩产能

《港湾商业观察》黄懿 4月23日&#xff0c;纯净水牌“怡宝”母公司华润饮料&#xff08;控股&#xff09;有限公司&#xff08;下称“华润饮料”&#xff09;向港交所主板提交上市申请&#xff0c;联席保荐人为中银国际、中信证券、美银美林、瑞银集团。 在华润饮料递表不久之…

【ARM+Codesys案例】基于全志T3+Codesys软PLC的3C点胶边缘控制解决方案:整合了运动控制、视觉、激光测高等技术

视觉精密点胶控制方案 针对直交型机构的平面点涂胶应用&#xff0c;基于CODESYS软件平台开发的一站式PC型控制器解决方案&#xff0c;包含运动控制器硬件和点胶应用软件。方案整合了运动控制、视觉、激光测高等技术&#xff0c;高效精密的控制胶水点涂于产品表面或内部&#x…

CHIMA专访美创高级总监丁斐:为医疗数据安全构筑体系化防御新机制

5月17-19日&#xff0c;中国医院信息网络大会&#xff08;CHIMA 2024&#xff09;在南京隆重召开。作为结识多年的老友&#xff0c;美创科技再携以数据为中心的全系列安全业务、新一代数字化安全平台、医疗行业解决方案精彩亮相。 会议期间&#xff0c;CHIMA专访美创科技&…

[数据集][目标检测]RSNA肺炎检测数据集VOC+YOLO格式6012张1类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;6012 标注数量(xml文件个数)&#xff1a;6012 标注数量(txt文件个数)&#xff1a;6012 标注…

【基础算法总结】前缀和二

前缀和二 1.和为 K 的子数组2.和可被 K 整除的子数组3.连续数组4. 矩阵区域和 点赞&#x1f44d;&#x1f44d;收藏&#x1f31f;&#x1f31f;关注&#x1f496;&#x1f496; 你的支持是对我最大的鼓励&#xff0c;我们一起努力吧!&#x1f603;&#x1f603; 1.和为 K 的子数…

Java语言ADR药物不良反应系统源码Java+IntelliJ+IDEA+MySQL一款先进的药物警戒系统

Java语言ADR药物不良反应系统源码JavaIntelliJIDEAMySQL一款先进的药物警戒系统源码 ADR药物不良反应监测系统是一个综合性的监测平台&#xff0c;旨在收集、报告、分析和评价药品在使用过程中可能出现的不良反应&#xff0c;以确保药品的安全性和有效性。 以下是对该系统的详细…

Modbus工业网关

随着工业自动化程度的不断提高&#xff0c;设备之间的数据通信与交互变得至关重要。在这一背景下&#xff0c;Modbus协议凭借其简单、可靠、开放的特点&#xff0c;成为了工业自动化领域中最常用的通信协议之一。而HiWoo Box网关作为一款支持Modbus协议的工业网关设备&#xff…

【全开源】防伪溯源一体化管理系统源码(FastAdmin+ThinkPHP和Uniapp)

一款基于FastAdminThinkPHP和Uniapp进行开发的多平台&#xff08;微信小程序、H5网页&#xff09;溯源、防伪、管理一体化独立系统&#xff0c;拥有强大的防伪码和溯源码双码生成功能&#xff08;内置多种生成规则&#xff09;、批量大量导出防伪和溯源码码数据、支持代理商管理…

Springboot项目——博客平台

前言&#xff1a;为巩固之前学习的知识&#xff0c;同时锻炼自己的代码能力&#xff0c;项目经验&#xff0c;熟悉前后端交互方式等&#xff0c;特此完成一个博客平台系统。&#xff08;总之&#xff0c;为了学习&#xff0c;为了进步&#xff09; 博客平台&#xff1a;本项目…

网络安全的重要组成部分:数据库审计

数据库审计&#xff08;简称DBAudit&#xff09;以安全事件为中心&#xff0c;以全面审计和精确审计为基础&#xff0c;实时记录网络上的数据库活动&#xff0c;对数据库操作进行细粒度审计的合规性管理&#xff0c;对数据库遭受到的风险行为进行实时告警。它通过对用户访问数据…

线性稳压电路和开关稳压电路

稳压二极管稳压电路 电网电压增大&#xff0c;导到u1端的电压增大&#xff0c;从而使输出电压&#xff0c;稳压二极管两端的电压增大&#xff0c;稳压二极管两端电压增大&#xff0c;使流过的电注增大。那么&#xff0c;流过线性电阻R的总电流增大。 Ur电压增大&#xff0c;从…

PGP软件安装文件加密解密签名实践记录

文章目录 环境说明PGP软件安装PGP软件汉化AB电脑新建密钥并互换密钥对称密钥并互换密钥 文件加密和解密A电脑加密B电脑解密 文件签名A电脑签名文件B电脑校验文件修改文件内容校验失败修改文件名称正常校验 环境说明 使用VM虚拟两个win11,进行操作演示 PGP软件安装 PGP软件下…

AI赋能:人工智能技术驱动下的品牌海外市场精准分析与营销策略

随着全球化的加速和科技的飞速发展&#xff0c;品牌在海外市场的竞争愈发激烈。为了在竞争激烈的国际市场中脱颖而出&#xff0c;品牌需要更深入地了解海外消费者的行为、趋势和偏好。在这个过程中&#xff0c;人工智能&#xff08;AI&#xff09;技术以其强大的数据处理和分析…

【高阶数据结构(七)】B+树, 索引原理讲解

&#x1f493;博主CSDN主页:杭电码农-NEO&#x1f493;   ⏩专栏分类:高阶数据结构专栏⏪   &#x1f69a;代码仓库:NEO的学习日记&#x1f69a;   &#x1f339;关注我&#x1faf5;带你学习更多数据结构   &#x1f51d;&#x1f51d; 高阶数据结构 1. 前言2. B树讲解…

音视频开发9 FFmpeg 解复用框架说明,重要API说明

一&#xff0c;播放器框架 二 常用音视频术语 容器&#xff0f;文件&#xff08;Conainer/File&#xff09;&#xff1a; 即特定格式的多媒体文件&#xff0c; 比如mp4、flv、mkv等。 媒体流&#xff08;Stream&#xff09;&#xff1a; 表示时间轴上的一段连续数据&#xff0…

HAL工程应该这样搭建~

目录 一、为何要自己手动搭建一个软件工程&#xff1f; 二、在Keil5STM32F429**平台下的软件工程搭建 三、打开Keil MDK5软件创建一个新工程 四、在各个文件夹下添加所需文件 五、在MDK工程下添加文件 六、在MDK下添加路路径 一、为何要自己手动搭建一个软件工程&#xff…