目录
- 1 项目描述
- 2 项目需求
- 3 搭建环境
-
-
- 数字温湿度传感器DHT11
- 光敏传感器
- MPU6050
- wifi模块ESP8266
- OLED屏
- RC522
- W25Q128
- SR04超声波
-
- 4 技术描述
- 5 概要设计
- 6 界面一
- 7 界面二
- 8 界面三
- 9 界面四
- 10 ONENET云平台界面
- 11项目总结
1 项目描述
借用这个项目Keil uVision编写5个单片机C语言开发系统J-Link驱动下载HEX程序,烧录到STM32F407开发板运行。 实现DHT11读取温湿度,配置ADC3通道获得光强,SR04超声波测距,使用w25q128 Flash芯片存取比较值、通过MPU6050运动处理组件获取三轴坐标、使用RC522模块读卡,获取的数据OLED屏幕显示,再利用WIFI将数据传输到模块连接热点onenet云平台,云平台或手机无线控制功能通过串口中断实现。
2 项目需求
(1) 获取温湿度 (2)光强的获取 (3)陀螺仪 (4)测距 (5)比较值存取 (6)刷卡 (7)OLED屏显示 (8)上传云平台 (9)超值报警
3 搭建环境
软件环境:window 硬件环境:STM32F407
Keil uVision5、字模PCtoLCD2002、串口调试stc-isp-15xx
- DHT11
- 光敏传感器
- MPU6050
- wifi模块ESP8266
- OLED屏
- RC522
- W25Q128
- SR04
数字温湿度传感器DHT11
DHT11数字温湿度传感器是一种含有校准数字信号输出的温湿度复合传感器 传感器。采用特殊的数字模块采集技术和温湿度传感技术,确保产品极高 可靠性和优异的长期稳定性。 DHT供电电压为11 3-5.5V。 传感器上电后, 要等待 1s 本期无需发送任何指令,以越过不稳定状态。 电源引脚( VDD, GND)可以增加1000nF 的电容, 用于去耦滤波
DHT11 STM32 VCC --->3.3V DQ数字输出 ---> PG9 GND --->GND
光敏传感器
光敏传感器检测到模拟信号。随着光的亮度和光敏传感器的电阻值的变化,我们需要将模拟信号转换为电信号,提取数据ADC模数转换。 (ADC它是指将不断变化的模拟信号转换为离散数字信号的装置。真实世界的模拟信号,如温度、压力、声音或图像,需要转换为更容易存储、处理和发射的数字形式。模具/数字转换器可以实现这一功能,并可以在各种产品中找到。
MPU6050
MPU-6000(6050)是世界上第一个集成的6轴运动处理组件。与多组件方案相比,它消除了组合陀螺仪与加速器时间轴之间的差异,减少了大量的包装空间。当连接到三轴磁强度计时,MPU-60X0提供完整的9轴运动融合输出到其主I2C或SPI端口(SPI仅在MPU-6000上可用)。
wifi模块ESP8266
ESP8266是超低功耗UART-WiFi 传输模块是专门为移动设备和物联网应用设计的具有行业竞争力的包装尺寸和超低能耗技术,可以连接用户的物理设备Wi-Fi 互联网或局域网通信在无线网络上实现联网功能。
OLED屏
OLED,即有机发光二极管( Organic Light Emitting Diode )。 OLED 由于具有自发光、无背光源、对比度高、厚度薄、视角广、反应速度快、柔性面板、使用温度范围广、结构简单、工艺简单等优良特点,被认为是下一代平面显示器的新兴应用技术。
- GND 电源地
- VCC 电源正(3~5.5V)
- SCL OLED 的 D0 脚,在 IIC 时钟管脚在通信中
- SDA OLED 的 D1 脚,在 IIC 数据管脚在通信中
RC522
MF RC522是应用于13.56MHz非接触式通信高集成读写卡芯片是针对三表应用推出的低压、低成本、小型非接触式读写卡芯片。是智能仪器和便携式手持设备研发的更好选择。它与主机之间的通信SPI模式有利于减少连接和缩小PCB板体积,降低成本。
W25Q128
串行 flash 存储器 W25Q128BV 为那些对空间大小,引脚数,功耗有限制的系统提供了一个存储解决方案。W25Q128BV 由 65536 可编程的页组成的,每页有 256 个字节。一次最多可以写 256 个字节。可以一次擦除 16 页,128 页,256 页或者擦除一整片。W25Q128BV 支持标准 SPI 接口,以及更高性能的 DUAL/QUAD SPI ,对应的管脚为时钟,片选,(I/O0)DI,(I/O1)DO,I/O2(/WP),I/O3(/HOLD)。
SR04超声波
超声波测距是借助于超声脉冲回波渡越时间法来实现的。设超声波脉冲由传感器发 出到接收所经历的时间为 t ,超声波在空气中的传播速度为 c ,则从传感器到目标物体 的距离 D 可用下式求出:D = ct /2
4 技术描述
模块 | 功能 | 协议 |
---|---|---|
LED | 超值报警 | |
KEY | 中断切换界面 | |
BEEP | 云平台控制停响 | |
TIM | 呼吸灯 | |
Systick | 滴答定时器 | |
ADC | 光照 | |
DHT11 | 测温湿度 | 单总线协议 |
MPU6050 | 测姿势 | IIC协议 |
ESP8266 | 上传云平台 (温湿度/光照/距离) | UART协议 |
OLED | 显示(温湿度/光照/距离/坐标值/比较值/卡号) | IIC协议 |
RC522 | 刷卡 | SPI协议 |
W25Q128 | 存比较值(温湿度/光照/距离) | SPI协议 |
5 概要设计
6 界面一
实时获取温湿度、光照强度、超声波距离,与系统设置的各比较值对比,做超值亮灯报警判断,再将各数据上传到ONENET云平台中。同时实时等待云平台是否发送蜂鸣器报警指令,若有指令发送,则判断蜂鸣器响或停。 具体效果和代码如下:
/************************** 硬件初始化 **************************/
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //配置优先级分组:抢占优先级和响应优先级
Systick_Init(); //滴答定时器初始化
TIM14_Init(84,100);
W25Q128_Init(); //SPI初始化W25Q128
usartx_init(USART1,115200); //初始化串口1,不开启接收中断,主要用做发送数据串口显示调试
usartx_init(USART3,115200); //初始化串口3,开启接收中断,设置中断向量表分组和优先级
BEEP_Init();
LED_Init(); //LED灯初始化
EXTI0234_Init(); //按键中断初始化
OLED_Init(); //OLED初始化
SR04_Init(); //超声波初始化
DHT11_Init(); //温湿度引脚初始化
adc1_init(); //光照强度初始化
MPU6050_Init(); //MPU6050初始化
MFRC522_Initializtion(); //MFRC522初始化
ESP8266_init(); //初始化ESP8266模块,连接WIFI,接入平台IP
OneNet_DevLink(DEVID,APIKEY); //接入平台设备。
mode = 1; //串口3接收进入接收命令模式
delay_s(1); //延时一秒
printf("HardWare Init Success!\r\n");
TIM_SetCompare4(TIM1,100);//灭LED3灯
/************************** W25Q128读取比较值 **************************/
W25Q128_Read(Data,0,4);
temp_compare=Data[0];//温度比较值
humi_compare=Data[1];//湿度比较值
sun_compare=Data[2];//光照比较值
distance_compare=Data[3];//距离比较值
/************************** 界面显示 **************************/
if(page1_tmp==0)//温湿度光照界面
{
/*********************---获取值---*******************************/
sun_tmp=100-(get_adcvalue()/40); //获取光照强度
distance_tmp=sr04_get_distance(); //获取超声波距离
DHT11_ReadData(buffer); // 获取温湿度 ERROR SUCCESS
if(clear_oled==1)//清屏
{
OLED_Clear();
clear_oled=0;
}
OLED_ShowCHinese16X16(0,0,Chinese16X16 ,0);//温度
OLED_ShowCHinese16X16(16,0,Chinese16X16 ,1);
OLED_ShowCHinese16X16(0,2,Chinese16X16 ,2);//湿度
OLED_ShowCHinese16X16(16,2,Chinese16X16 ,3);
OLED_ShowCHinese16X16(0,4,Chinese16X16 ,4);//光照强度
OLED_ShowCHinese16X16(16,4,Chinese16X16 ,5);
OLED_ShowCHinese16X16(32,4,Chinese16X16 ,6);
OLED_ShowCHinese16X16(48,4,Chinese16X16 ,7);
OLED_ShowCHinese16X16(0,6,zhuangtai16X16 ,0);//距离
OLED_ShowCHinese16X16(16,6,zhuangtai16X16 ,1);
sprintf(humi,"%u.%u %%RH",buffer[0],buffer[1]);
sprintf(temp,"%u.%u %%C",buffer[2],buffer[3]);
OLED_ShowStr(32, 0, temp, 2);//显示温度
OLED_ShowStr(32, 2, humi, 2); //显示湿度
sprintf(sun,"%d",sun_tmp);
OLED_ShowStr(64, 4, sun, 2);//显示光照
//显示距离
OLED_Cleardistance();
sprintf(distance,"%dmm",distance_tmp);
OLED_ShowStr(32, 6, distance, 2);
/*************************---超值亮灯警报---***********************/
if(buffer[2]>=temp_compare || buffer[0]>=humi_compare)//温度或者湿度超值判断
{LED1(0);}
else{LED1(1);}
if(sun_tmp<=sun_compare)//光照低于值判断
{LED2(0);}
else{LED2(1);}
if(distance_tmp<=distance_compare)//距离低于值判断
{LED3(0);}
else{LED3(1);}
/*************************---上传数据---***********************/
//将数据上传网站
OneNet_SendData(send_but,"Temp",buffer[2]); //第二个参数不是随便写的,这个是你要上传的数据流的名字
OneNet_SendData(send_but,"Humi",buffer[0]);
OneNet_SendData(send_but,"Sun",sun_tmp);
OneNet_SendData(send_but,"distance",distance_tmp);
}
7 界面二
当用户通过KEY3按键切换到比较值界面时,读取W25Q128中的各比较值数据并显示,通过按键中断去选择其他功能:KEY0按键可切换不同比较值,KEY1增加比较值,KEY2减小比较值,KEY3界面切换。当修改完比较值,切换界面时,将各比较值重新存进W25Q128中,修改原来的数据。 具体效果和代码如下:
while(WorkType==2)
{
//显示温度比较值
sprintf(temp,"%u",temp_compare);
OLED_ShowStr(80, 0,temp, 2);
//显示温度比较值
sprintf(humi,"%u",humi_compare);
OLED_ShowStr(80, 2,humi, 2);
//显示光照比较值
sprintf(sun,"%u",sun_compare);
OLED_ShowStr(80, 4,sun, 2);
//显示距离比较值
sprintf(distance,"%d",distance_compare);
OLED_ShowStr(80, 6,distance, 2);
if(humi_compare==99)//最小值
{
OLED_Clearhumidata();
}
if(temp_compare==9)//最小值
{
OLED_Cleartempdata();
}
if(distance_compare==95)//最小值
{
OLED_Cleardis();
}
}
8 界面三
当跳转到界面三,RC522模块实时等待卡的到来,若有卡靠近时,通过SPI协议读取RFID卡的数据,获取到卡号,将卡号显示到OLED屏上。同时呼吸灯亮起… 具体效果与代码如下:
void show_face3()//显示界面3:读卡
{
int cnt = 100;
int led_tmp=0;
OLED_Clear();
/*********************显示屏幕****************************/
//请将卡放置感应区
OLED_ShowCHinese16X16(0,0,rfid16X16 ,0);
OLED_ShowCHinese16X16(16,0,rfid16X16 ,1);
OLED_ShowCHinese16X16(32,0,rfid16X16 ,2);
OLED_ShowCHinese16X16(48,0,rfid16X16 ,3);
OLED_ShowCHinese16X16(64,0,rfid16X16 ,4);
OLED_ShowCHinese16X16(80,0,rfid16X16 ,5);
OLED_ShowCHinese16X16(96,0,rfid16X16 ,6);
OLED_ShowCHinese16X16(112,0,rfid16X16 ,7);
while(WorkType==3)
{
MFRC522Test();//读卡
//呼吸灯
if(led_tmp==0)
{
TIM_SetCompare1(TIM14,cnt);
cnt-=10;
if(cnt==20) led_tmp=1;
}
else if(led_tmp==1)
{
TIM_SetCompare1(TIM14,cnt);
cnt+=10;
if(cnt==100) led_tmp=0;
}
delay_ms(200);
}
}
读卡
//MFRC522读卡
void MFRC522Test(void)
{
u8 status;
u8 card_pydebuf[2];
u8 card_numberbuf[5];
u8 card_key0Abuf[6]={0xff,0xff,0xff,0xff,0xff,0xff};
u8 card_writebuf[16]={0,1,2,3,4,5,6,7,8,9,10,44,12,13,14,15};
u8 card_readbuf[18];
char card_id[32];
status=MFRC522_Request(0x52, card_pydebuf); //寻卡
//
if(status==0) //如果读到卡
{
status=MFRC522_Anticoll(card_numberbuf); //防撞处理
MFRC522_SelectTag(card_numberbuf); //选卡
status=MFRC522_Auth(0x60, 4, card_key0Abuf, card_numberbuf); //验卡
status=MFRC522_Write(4, card_writebuf); //写卡(写卡要小心,特别是各区的块3)
status=MFRC522_Read(4, card_readbuf); //读卡
//显示卡号
OLED_ShowStr(32, 2,"card ID:", 2);
sprintf(card_id,"%X%X%X%X",card_numberbuf[0],card_numberbuf[1],card_numberbuf[2],card_numberbuf[3]);
OLED_ShowStr(32,4,card_id, 2);
MFRC522_Initializtion(); //初始化MFRC522
}
}
9 界面四
当跳转到界面四,MPU6050通过IIC协议测得当前三轴坐标值,通过坐标值与屏幕像素计算出显示的位置,实现像素点在屏幕上根据开发板的倾斜而发生移动… 具体效果和代码如下:
else if (page1_tmp==1)//陀螺仪界面
{
/*********************---获取值---*******************************/
MPU6050_Get_Angle(&data); // 获取三轴倾角
if(clear_oled==0)//清屏
{
OLED_Clear();
clear_oled=1;
}
//显示三轴坐标值
OLED_ShowCHinese16X16(16,0,xyz16X16 ,0);
OLED_ShowCHinese16X16(32,0,xyz16X16 ,1);
OLED_ShowCHinese16X16(48,0,xyz16X16 ,2);
OLED_ShowCHinese16X16(64,0,xyz16X16 ,3);
OLED_ShowCHinese16X16(80,0,xyz16X16 ,4);
if(data.X_Angle>105)
{
if(j>2)
{
j--;
j%=8;
n=j+1;
OLED_ShowStr(i,j,"*", 1);
OLED_ShowStr(i, n," ", 1);
}
}
else if(data.X_Angle<85)
{
if(j<7)
{
j++;
j%=8;
n=j-1;
OLED_ShowStr(i,j,"*", 1);
OLED_ShowStr(i, n," ", 1);
}
}
if(data.Y_Angle>105)
{
if(i>=6)
{
i-=6;
i%=122;
m=i+6;
OLED_ShowStr(i,j,"*", 1);
OLED_ShowStr(m,j," ", 1);
}
}
else if(data.Y_Angle<85)
{
if(i<120)
{
i+=6;
i%=122;
m=i-6;
OLED_ShowStr(i,j,"*", 1);
OLED_ShowStr(m,j," ", 1);
}
}
}
10 ONENET云平台界面
当OLED屏显示为界面一的时候,实时获取到各项数据后,将各项数据通过WIFI模块发送到平台上,再通过平台自定义的界面显示出来。同时,可通过手机或网页的平台界面上的蜂鸣器按钮回发指令控制单片机中蜂鸣器的响停。 具体效果和代码如下: 电脑网页 手机显示
//==========================================================
// 函数名称: OneNet_SendData
// 函数功能: 上传数据到平台
// 入口参数: type:发送数据的格式
// 返回参数: 无
// 说明:
//==========================================================
void OneNet_SendData(char *buf,char *buf1,u8 number)
{
OneNet_FillBuf(buf,buf1,number); //封装数据流
send_pkg = PacketSavedataSimpleString(NULL,(const char *) buf); //封包-Type5
ESP8266_SendData(send_pkg->_data, send_pkg->_write_pos);
DeleteBuffer(&send_pkg); //删包
}
11项目总结
此次基于STM32单片机开发项目使用了多种协议(IIC、SPI、UART、单总线),需要清楚各模块连接的引脚与GPIO的配置,根据手册资料去配置、获取数据,实现不同功能。各模块配置如图: