元件清单:

stm32f103c8t6、mq2 检测烟雾浓度(模拟量输出)、mq7 检测一氧化碳浓度、mq135 检测空气质量、OLED屏幕(四引脚仅支持iic协议通信)、dht11检测温湿度(数字量输出)、风扇模块、无源蜂鸣器、两引脚按键、WH-NB73-B5、ttl-usb


接线图:



0:实现了dht11的温湿度以及mq2烟雾浓度的采集并通过OLED显示屏显示

/*
湿度整数 湿度小数 温度整数  温度小数  校验位
00000000 00000000 00000000  00000000  000000001  看原理图确认GPIO引脚
2、 输出模式, 输出起始信号  :输出低电平18~30ms, 20ms
3、 IO口配置浮空输入模式,准检测响应信号传感器把数据总线( SDA)拉低 83μs,再接高 87μs 以响应主机的起始信号。
4、 40 个位的数据,高位先发;一位一位的收,数据0: 54us低电平 + 23~27高电平 数据1: 54us低电平 + 68~74高电平注意高位先发的(每个字节)
5、校验数据前4个字节,求和,把和值的末八位和校验位对比相同数据正确、否则数据异常
*/
//程序未写零下
char tmp = 0,hum = 0;
void DHT_GPIO_Config(u8 flag)
{       GPIO_InitTypeDef GPIO_Config; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE); //开启端口时钟GPIO_Config.GPIO_Pin = GPIO_Pin_8; if(flag==OUTPUT)GPIO_Config.GPIO_Mode = GPIO_Mode_Out_PP;//推挽输出elseGPIO_Config.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入GPIO_Config.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOB,&GPIO_Config);
}u8 DHT_GetData(void)
{u8 i = 0;u8 count = 0;u8 data[5]={0};//输出模式, 输出起始信号  :输出低电平18~30ms, 20ms  DHT_GPIO_Config(OUTPUT);DHT_High;DHT_Low;Delay_ms(20);//DHT_High;DHT_GPIO_Config(INPUT);/*IO口配置浮空输入模式,准检测响应信号传感器把数据总线( SDA)拉低 83μs,再接高 87μs 以响应主机的起始信号。*/while(DHT_CHECK==1){delay_1us();count++;if(count>100)return 1;}count=0;while(DHT_CHECK==0){delay_1us();count++;if(count>100)return 2;}  for(i=0;i<40;i++){count=0;while(DHT_CHECK==1){delay_1us();count++;if(count>100)return 3;  }count=0;while(DHT_CHECK==0){delay_1us();count++;if(count>100)return 4; }Delay_us(30);if(DHT_CHECK==1){data[i/8] |= (1<<(7-i%8)); //置1}else{data[i/8] &=~ (1<<(7-i%8));//清零}    }/*校验数据前4个字节,求和,把和值的末八位和校验位对比相同数据正确、否则数据异常*/if((data[0]+data[1]+data[2]+data[3])==data[4]){tmp=data[2];hum=data[0];    return 0;}else{return 5;}
}

1:在上边的基础上利用DMA实现多通道的数据采集(设置阀值,驱动风扇转动,并可手动按键改变阀值,并在屏幕显示变化;通过NB模块上传数据至有人云)

//mq2 mq7 mq135的采集
void ADC1_Config(void)
{GPIO_InitTypeDef GPIO_Struct = {0};ADC_InitTypeDef ADC_Struct = {0};RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);GPIO_Struct.GPIO_Mode = GPIO_Mode_AIN;//模拟输入GPIO_Struct.GPIO_Pin = GPIO_Pin_1|GPIO_Pin_6|GPIO_Pin_7;GPIO_Struct.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA,&GPIO_Struct);RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);RCC_ADCCLKConfig(RCC_PCLK2_Div6);//设置ADC时钟 72/6<14ADC_Struct.ADC_Mode = ADC_Mode_Independent; //独立工作模式ADC_Struct.ADC_ContinuousConvMode = ENABLE;//连续模式ADC_Struct.ADC_ScanConvMode = ENABLE; //多通道模式ADC_Struct.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; //转换由软件触发启动ADC_Struct.ADC_DataAlign = ADC_DataAlign_Right;//右对齐ADC_Struct.ADC_NbrOfChannel = 3;//规定了顺序进行规则转换的 ADC 通道的数目ADC_Init(ADC1,&ADC_Struct);//设置指定 ADC 的规则组通道,设置它们的转化顺序和采样时间//MQ2ADC_RegularChannelConfig(ADC1,ADC_Channel_1,1,ADC_SampleTime_239Cycles5);//MQ7ADC_RegularChannelConfig(ADC1,ADC_Channel_6,2,ADC_SampleTime_239Cycles5);//MQ135ADC_RegularChannelConfig(ADC1,ADC_Channel_7,3,ADC_SampleTime_239Cycles5);ADC_DMACmd(ADC1,ENABLE);DMA_Config();   ADC_Cmd(ADC1,ENABLE); //校准:减小误差ADC_ResetCalibration(ADC1);//重置寄存器while(ADC_GetResetCalibrationStatus(ADC1)==SET)//等待重置完成{}ADC_StartCalibration(ADC1);//启动校准,用校准寄存器 校准 ADC1while(ADC_GetCalibrationStatus(ADC1)==SET)//等待校准完成{}           ADC_SoftwareStartConvCmd(ADC1,ENABLE); //启动转换    使能或者失能指定的 ADC 的软件转换启动功能
}u16 DMA_buf[3]={0};
void DMA_Config(void)
{DMA_InitTypeDef DMA_Struct={0};RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE); //开启DMA时钟DMA_Struct.DMA_PeripheralBaseAddr =(u32) &ADC1->DR; //定义DMA外设基地址DMA_Struct.DMA_DIR = DMA_DIR_PeripheralSRC; //外设作为数据传输的来源DMA_Struct.DMA_BufferSize = 3; //地址递增两次(单位为字宽)DMA_Struct.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //外设地址寄存器不变DMA_Struct.DMA_MemoryInc = DMA_MemoryInc_Enable; //内存地址寄存器递增DMA_Struct.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; //数据宽度为16位DMA_Struct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; //数据宽度为16位DMA_Struct.DMA_Mode = DMA_Mode_Circular; //工作在循环缓存模式DMA_Struct.DMA_Priority = DMA_Priority_High;//优先级DMA_Struct.DMA_M2M = DMA_M2M_Disable;//DMA通道没有设置为内存到内存传输DMA_Struct.DMA_MemoryBaseAddr = (u32)&DMA_buf[0]; //内存基地址DMA_Init(DMA1_Channel1,&DMA_Struct);DMA_Cmd(DMA1_Channel1,ENABLE);
}//不采用DMA的多通道采集方法
//u16 ADC_Result(u8 ADC_Channel_x)
//{
//  u16 ADC_val = ADC_GetConversionValue(ADC1); //返回最近一次 ADCx 规则组的转换结果
//  ADC_RegularChannelConfig(ADC1,ADC_Channel_x,1,ADC_SampleTime_239Cycles5);
//  ADC_SoftwareStartConvCmd(ADC1,ENABLE); //启动转换    使能或者失能指定的 ADC 的软件转换启动功能
//  while((ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC))==RESET);
//
//  //float ADC_Cha = (ADC_val*3.3/4096);
//  //printf("ADC_val == %d\r\n",ADC_val);
//  return ADC_val;
//}

2:将按键连接PB引脚,通过外部终端配置实现部分功能

3、在进行有人云端链接之前,需要先再云端添加设备模板、创建设备。有人透传云

在通信过程中,由底层开发板采集数据,并将数据封装成MODBUS-RTU格式,通过串口发送给NB模块,然后NB模块将数据上传到云端(创建模板时选择了MODBUS-RTU格式),NB模块是直连有人云的,在这里,我们访问云端,并将数据写入到云端的寄存器中。

在云端设置完成后,NB模块主动发送数据、或重新上电之后即可上线。因为在测试阶段已经保证了设备是正常工作的,在这里我们直接尝试上传数据了。

在上传数据时,有人云平台支持MODBUS-RTU协议,我们只需要将采集的数据进行封装,然后将数据通过串口发送给NB模块。数据上传成功后,可以在设备概况、监控大屏或者云组态当中查看数据内容、上传时间、异常信息、设备上下线等。

通信格式: 设备号 功能码 起始地址 寄存器数量 数据长度 数据块(寄存器) 校验(CRC)

#include "nbiot.h"
/*buf[0]  :温度buf[1] :湿度buf[2]   :光照强度buf[3]  :烟雾浓度
*/
void NB_Send_IOT1(uint16_t buf[4])
{char sendbuf[256]={0};char sendbuf1[256]={0};uint8_t tmpbuf[64]={0};uint16_t CRC_Tmp;tmpbuf[0]=0x01;//从机地址tmpbuf[1]=0x46;//操作码tmpbuf[2]=0x00;tmpbuf[3]=0x00;//寄存器起始地址  tmpbuf[4]=0x00;tmpbuf[5]=0x04;//寄存器数量tmpbuf[6]=0x08;//字节数 = 寄存器数量 * 2tmpbuf[7]=(buf[0]>>8);tmpbuf[8]=(buf[0]&0xFF);//高位清零tmpbuf[9]=(buf[1]>>8);tmpbuf[10]=(buf[1]&0xFF);tmpbuf[11]=(buf[2]>>8);tmpbuf[12]=(buf[2]&0xFF);tmpbuf[13]=(buf[3]>>8);tmpbuf[14]=(buf[3]&0xFF);CRC_Tmp=CRC_16_Tab(tmpbuf,15);tmpbuf[15]=(CRC_Tmp>>8);tmpbuf[16]=(CRC_Tmp&0xFF);//把16进制数据转换为字符串,放入sendbufSIM7020_Hex_to_Str((char *)tmpbuf,17,sendbuf,256);//拼接字符串,拼接成上述格式
//设备号 功能码 起始地址 寄存器数量 数据长度 数据块(寄存器) 校验(CRC)strcpy((char *)tmpbuf,"AT+NMGS=17,");strcat(sendbuf1,(char *)tmpbuf);strcat(sendbuf1,sendbuf);strcat(sendbuf1,"\r\n");NB_SendString((char *)sendbuf1);//Send_String_NBlot((uint8_t *)sendbuf1);printf("发送内容= %s\r\n",sendbuf1);
}
/***************************************************************************/
//转化数据,转成16进制字符串
/*
char *data      :数据来源
int data_len        :数据长度
char *out       :存储地址
int out_len     :存储地址长度
*/
void SIM7020_Hex_to_Str(char *data, int data_len, char *out, int out_len)
{char temp[2];int  i;memset(out,0,out_len);              //清空缓冲区for(i=0;i<data_len;i++){            //for循环sprintf(temp,"%02X",data[i]);   //转化数据,转成16进制字符串strcat(out,temp);               //追加到out缓冲区              }
}

上传后:可以发现,数据已经改变

也可以在“监控大屏”中左侧选择设备、右侧查看实时数据,点击变量可以下发数据,或控制指令,完成数据指令下发。

在数据或指令下发时,云端下发指令也是MODBUS-RTU格式,以03功能码为例:云端下发读保持寄存器指令(03功能码),通过 UDP链接传输到我们的NB模块,然后NB模块将相应的指令转到我们的设备串口,在开发板上我们可以检测串口的接收,在串口接收数据完成后,将所接收的数据,按照MODBUS协议进行解析,如果下发的为03码,则参照03功能码的响应方式对云端进行数据响应。如果是其他功能码,则根据需求进行解析。

程序资料已经上传到资源可以下载。

stm32c8t6+dht11+MQ系列环境检测模块+oled显示屏(基于物联网的家庭环境检测系统设计)-智能家居文档类资源-CSDN下载

如果这篇博客对你有帮助,给博主一个免费的点赞或者评论收藏以示鼓励呀~感谢!

stm32c8t6+dht11+MQ系列环境检测模块+oled显示屏(基于物联网的家庭环境检测系统设计)相关推荐

  1. 基于物联网的室内环境检测云系统设计(树莓派RPI、Arduino、智能家居、RFID、APP)

    题 目: 基于物联网的室内环境检测云系统设计 关键词: 树莓派RPI.Arduino.智能家居.物联网 目录 摘要 2 引言 3 系统方案 3 系统硬件设计 6 1)Arduino介绍 6 2)DHT ...

  2. 基于 STM32 的语音识别智能家居控制系统的设计(LD3320语音识别芯片+ESP8266 WIFI模块+DHT11温湿度采集+MQ系列 烟雾及可燃气体+蜂鸣器+步进电机模拟窗帘+OLED液晶显示+

    ## **基于 STM32 的语音识别智能家居控制系统的设计(LD3320语音识别芯片+ESP8266 WIFI模块(阿里云 或ONENET或局域网)+DHT11温湿度采集+MQ系列 烟雾及可燃气体+ ...

  3. 7.STM32C8T6+DHT11在OLED上显示 温度,湿度

    STM32C8T6+DHT11在OLED上显示 温度,湿度 平台 STM32T103C8T6 传感器:DHT11 1.DTH11的工作原理 在这里我就不读说了,在我的另一篇博客有说明,关于对DHT11 ...

  4. STM32系列——驱动0.96寸oled显示屏

    一OLED介绍 使用了0.96寸的oled显示屏(SSD1306驱动),128*64像素,查阅店主给的相关资料后知道,这种屏幕有串行通信和并行通信方式,串行通信可以选择IIC(只需要2个管脚SCL.S ...

  5. 6. 毕业设计温湿度监控系统(ESP8266 + DHT11 +OLED 实时上传温湿度数据给公网服务器并在OLED显示屏上显示实时温湿度)

    文章目录 硬件环境 软件环境 1. WiFi联网和HttpPost配置 2. DHT11温湿度读取和OLED显示配置 3. Web服务器配置(用于接收HTTP数据请求) 实验过程 1. ESP8266 ...

  6. Esp8266 进阶之路31【外设篇】分享一个乐鑫esp8266 SDK编程使用 IIC总线驱动 0.96寸的OLED显示屏,显示天气预报信息。(附带Demo)

    本系列博客学习由非官方人员 半颗心脏 潜心所力所写,不做开发板.仅仅做个人技术交流分享,不做任何商业用途.如有不对之处,请留言,本人及时更改. 序号 SDK版本 内容 链接 1 nonos2.0 搭建 ...

  7. 0.96寸OLED显示屏标准库移植HAL库(模拟IIC) - 基于STM32

    ** 0.96寸OLED显示屏标准库移植HAL库,使用模拟IIC ** 由于项目的需要使用OLED屏显示,并且现有的项目程序是基于HAL库编写的,而手头能找到的程序是标准库的驱动程序,大概看了一下代码 ...

  8. STM32操作OLED显示屏

    个人网站:Geek交流圈 文末附代码 简介 OLED主要涉及SPI协议/IIC协议,汉字点阵编码原理等知识,在这里且先不谈,这个系列主要讲运用,尽量减少文本的书写.本文利用STM32RCT6操作七针O ...

  9. 关于STM32+OLED显示屏的简单应用

    文章目录 一.题目要求 二.SPI通信协议相关介绍 1. SPI 协议简介 2.STM32 的 SPI 特性及架构 3.STM32 的 SPI 外设简介 4. STM32 的 SPI 架构剖析 5. ...

最新文章

  1. 04:sqlalchemy操作数据库 不错
  2. c#强制执行内存回收
  3. python删除中文停用词_python词云 wordcloud+jieba生成中文词云图
  4. bert本质理解记录一
  5. Maven环境配置及IntelliJ IDEA中的Maven部署(亲自测试)
  6. 关于Typora编辑器编写markdown文档时插入出现前字吞后字的解决方法
  7. mongodb备份还原
  8. python提高——类(私有化,封装、继承、多态)
  9. 间接寻址级别不同_「计算机组成原理」:常见的指令寻址方式
  10. 交运集团开设“技师工作站“ 创新“机电一体化“人才培养模式
  11. 2022年4月30号Mysql语句增删改查(CRUB)重在实操。
  12. 数据分析学习笔记--航空公司客户价值分析(代码)
  13. 佐治亚理工计算机科学录取,佐治亚理工学院计算机科学专业排名第8(2020年USNEWS美国排名)...
  14. 4-adjacent
  15. 【Running latest Apollo with SVL Simulator 使用 SVL 模拟器运行最新的 Apollo】
  16. 右击文件夹转圈圈,有时卡死
  17. 洛谷日报 2020年3月前索引
  18. 让你秒懂的Lambda表达式超级详细讲解
  19. linux配置https不安全链接,配置HTTPS证书后,浏览器出现不安全提示的解决方法
  20. 168-203-javajvm-垃圾收集器

热门文章

  1. Composing Programs 2.3 Sequence - 02
  2. 迷宫寻宝(自编简单版)
  3. HashMap中的hash与rehash
  4. 世界棒球经典赛:从WBC走进中国棒球·棒球1号位
  5. 【树莓派不吃灰】基础篇① 半小时搭建树莓派3B可运行环境(不需要显示器,不需要网线)
  6. 神经网络编程的34个案例,java调用神经网络模型
  7. 微信js 大转盘抽奖
  8. 三峡大学计算机与信息工程学院,三峡大学计算机与信息学院.doc
  9. 解决mini_httpd_v1.30在使用http post请求出现 socket hang up的问题
  10. C++:未定义引用静态类成员?