3560|5

7056

帖子

11

TA的资源

版主

楼主
 

【安信可NB-IoT开发板EC-01F-Kit测评】基于STM32F103C8T6 连接MQTT网络温度计 [复制链接]

本帖最后由 lugl4313820 于 2021-12-19 22:49 编辑

 昨天实现在MQTT的数据发布,今天实现了stm32F103C8T6用DS18B20采集温度,通过EC-01-Kit发布数据,用python编写展示程序。

1、18B20是常用的数字温度计传感器,也是单片机经常使用的温度计,我这里直接移值正点原子的18B20驱动库。

18B20.h

#ifndef __DS18B20_H
#define __DS18B20_H 
#include "sys.h"   
//////////////////////////////////////////////////////////////////////////////////	 
//本程序只供学习使用,未经作者许可,不得用于其它任何用途
//ALIENTEK战舰STM32开发板
//DS18B20驱动代码	   
//正点原子@ALIENTEK
//技术论坛:www.openedv.com
//修改日期:2012/9/12
//版本:V1.0
//版权所有,盗版必究。
//Copyright(C) 广州市星翼电子科技有限公司 2009-2019
//All rights reserved									  
//////////////////////////////////////////////////////////////////////////////////

//IO方向设置 这里使用了PA0,原来的库是用PE11的,更改过来还是费了一翻周折,翻看了寄存器的资料
#define DS18B20_IO_IN()  {GPIOA->CRL&=0XFFFFFFF0;GPIOA->CRL|=8;}
#define DS18B20_IO_OUT() {GPIOA->CRL&=0XFFFFFFF0;GPIOA->CRL|=3;}
////IO操作函数											   
#define	DS18B20_DQ_OUT PAout(0) //数据端口	PA0 
#define	DS18B20_DQ_IN  PAin(0)  //数据端口	PA0 
   	
u8 DS18B20_Init(void);//初始化DS18B20
short DS18B20_Get_Temp(void);//获取温度
void DS18B20_Start(void);//开始温度转换
void DS18B20_Write_Byte(u8 dat);//写入一个字节
u8 DS18B20_Read_Byte(void);//读出一个字节
u8 DS18B20_Read_Bit(void);//读出一个位
u8 DS18B20_Check(void);//检测是否存在DS18B20
void DS18B20_Rst(void);//复位DS18B20    
#endif

ds18B20.c

#include "ds18b20.h"
#include "delay.h"	
//////////////////////////////////////////////////////////////////////////////////	 
//本程序只供学习使用,未经作者许可,不得用于其它任何用途
//ALIENTEK战舰STM32开发板
//DS18B20驱动代码	   
//正点原子@ALIENTEK
//技术论坛:www.openedv.com
//修改日期:2012/9/12
//版本:V1.0
//版权所有,盗版必究。
//Copyright(C) 广州市星翼电子科技有限公司 2009-2019
//All rights reserved									  
//////////////////////////////////////////////////////////////////////////////////
  


//复位DS18B20
void DS18B20_Rst(void)	   
{                 
	DS18B20_IO_OUT(); 	//SET PG11 OUTPUT
    DS18B20_DQ_OUT=0; 	//拉低DQ
    delay_us(750);    	//拉低750us
    DS18B20_DQ_OUT=1; 	//DQ=1 
	delay_us(15);     	//15US
}
//等待DS18B20的回应
//返回1:未检测到DS18B20的存在
//返回0:存在
u8 DS18B20_Check(void) 	   
{   
	u8 retry=0;
	DS18B20_IO_IN();	//SET PG11 INPUT	 
    while (DS18B20_DQ_IN&&retry<200)
	{
		retry++;
		delay_us(1);
	};	 
	if(retry>=200)return 1;
	else retry=0;
    while (!DS18B20_DQ_IN&&retry<240)
	{
		retry++;
		delay_us(1);
	};
	if(retry>=240)return 1;	    
	return 0;
}
//从DS18B20读取一个位
//返回值:1/0
u8 DS18B20_Read_Bit(void) 	 
{
    u8 data;
	DS18B20_IO_OUT();	//SET PG11 OUTPUT
    DS18B20_DQ_OUT=0; 
	delay_us(2);
    DS18B20_DQ_OUT=1; 
	DS18B20_IO_IN();	//SET PG11 INPUT
	delay_us(12);
	if(DS18B20_DQ_IN)data=1;
    else data=0;	 
    delay_us(50);           
    return data;
}
//从DS18B20读取一个字节
//返回值:读到的数据
u8 DS18B20_Read_Byte(void)     
{        
    u8 i,j,dat;
    dat=0;
	for (i=1;i<=8;i++) 
	{
        j=DS18B20_Read_Bit();
        dat=(j<<7)|(dat>>1);
    }						    
    return dat;
}
//写一个字节到DS18B20
//dat:要写入的字节
void DS18B20_Write_Byte(u8 dat)     
 {             
    u8 j;
    u8 testb;
	DS18B20_IO_OUT();	//SET PG11 OUTPUT;
    for (j=1;j<=8;j++) 
	{
        testb=dat&0x01;
        dat=dat>>1;
        if (testb) 
        {
            DS18B20_DQ_OUT=0;	// Write 1
            delay_us(2);                            
            DS18B20_DQ_OUT=1;
            delay_us(60);             
        }
        else 
        {
            DS18B20_DQ_OUT=0;	// Write 0
            delay_us(60);             
            DS18B20_DQ_OUT=1;
            delay_us(2);                          
        }
    }
}
//开始温度转换
void DS18B20_Start(void) 
{   						               
    DS18B20_Rst();	   
	DS18B20_Check();	 
    DS18B20_Write_Byte(0xcc);	// skip rom
    DS18B20_Write_Byte(0x44);	// convert
} 

//初始化DS18B20的IO口 DQ 同时检测DS的存在
//返回1:不存在
//返回0:存在    	 
u8 DS18B20_Init(void)
{
 	GPIO_InitTypeDef  GPIO_InitStructure;
 	
 	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOG, ENABLE);	 //使能PORTG口时钟 
	
 	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;				//PORTG.11 推挽输出
 	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 		  
 	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
 	GPIO_Init(GPIOG, &GPIO_InitStructure);

 	GPIO_SetBits(GPIOG,GPIO_Pin_11);    //输出1

	DS18B20_Rst();

	return DS18B20_Check();
}  
//从ds18b20得到温度值
//精度:0.1C
//返回值:温度值 (-550~1250) 
short DS18B20_Get_Temp(void)
{
    u8 temp;
    u8 TL,TH;
	short tem;
    DS18B20_Start ();  			// ds1820 start convert
    DS18B20_Rst();
    DS18B20_Check();	 
    DS18B20_Write_Byte(0xcc);	// skip rom
    DS18B20_Write_Byte(0xbe);	// convert	    
    TL=DS18B20_Read_Byte(); 	// LSB   
    TH=DS18B20_Read_Byte(); 	// MSB  
	    	  
    if(TH>7)
    {
        TH=~TH;
        TL=~TL; 
        temp=0;					//温度为负  
    }else temp=1;				//温度为正	  	  
    tem=TH; 					//获得高八位
    tem<<=8;    
    tem+=TL;					//获得底八位
    tem=(float)tem*0.625;		//转换     
	if(temp)return tem; 		//返回温度值
	else return -tem;    
}



 

拿到18B20驱动下,在主程序里直接引用并采集就行了:

主程序更改如下:

main.c

#include "led.h"
#include "delay.h"
#include "key.h"
#include "sys.h"
#include "usart.h"
#include "EC616S.h"
#include "mqtt.h"
#include "tsensor.h"
#include "ds18b20.h"
/************************************************
 ALIENTEK战舰STM32开发板实验4
 串口实验 
 技术支持:www.openedv.com
 淘宝店铺:http://eboard.taobao.com 
 关注微信公众平台微信号:"正点原子",免费获取STM32资料。
 广州市星翼电子科技有限公司  
 作者:正点原子 @ALIENTEK
************************************************/


int main(void)
 {		
 	u16 t;  
	double temp;
	 short temp_ds18b20;
	u16 len;	
	char cData[40];
	u16 times=0;
	delay_init();	    	 //延时函数初始化	  
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
	uart_init(115200);	 //串口初始化为115200
	EC616S_Init(9600);	//command serial
 	LED_Init();			     //LED端口初始化
	//KEY_Init();          //初始化与按键连接的硬件接口
	//T_Adc_Init();		  		//ADC初始化
	 DS18B20_Init();
	EC616S_lugl_MQTTClient_connect();
 	while(1)
	{
		temp_ds18b20=DS18B20_Get_Temp();	//得到温度值
		printf("18b20温度为:%d\r\n",temp_ds18b20);	
		sprintf(cData,"{\"value\":\"%d\"}", temp_ds18b20);
		EC616S_lugl_MQTTClient_Test(cData);
		delay_ms(500);
	}
	
 }

 

串口监视助手显示为:发布数据正常返回OK。

上位机软件用pyqt5开发:

man.py程序为:

# encoding: utf-8

import sys
from PyQt5.QtWidgets import QApplication, QWidget, QLCDNumber, QVBoxLayout,QLabel
from PyQt5.QtCore import QTimer, QDateTime
from PyQt5.QtGui import QFont
import paho.mqtt.client as mqtt
import time
import json

host = "host_name"
port = 1883
username = 'user_name'
password = 'pwd'

mqttClient = mqtt.Client(protocol=3)           # 定义mqtt对象
temp_d = {'value': 0}

# noinspection PyUnusedLocal
def on_connect(client, userdata, flags, rc):
    print("连接成功" + "Connected with result code " + str(rc))


# noinspection PyUnusedLocal
def on_message(client, userdata, msg):         # 接收非图片数据
    if msg.topic == "topic/1":
        try:
            s = msg.payload.decode("utf-8")
            tab = json.loads(s)
            temp_d['value'] = int(tab['value'])/10
        except Exception as e:
            print(str(e))
# noinspection PyUnusedLocal
def on_subscribe(client, userdata, mid, granted_qos):
    print("消息订阅成功")

class Demo(QWidget):
    def __init__(self):
        super(Demo, self).__init__()
        self.resize(600, 600)

        self.lcd_1 = QLCDNumber(self)  # 1
        self.lcd_1.setDigitCount(5)
        self.lcd_1.display(20.5)

        self.label = QLabel(self)
        self.label.setFixedWidth(600)
        self.label.move(150, 200)

        self.v_layout = QVBoxLayout()
        self.v_layout.addWidget(self.lcd_1)
        self.v_layout.addWidget(self.label)

        self.setLayout(self.v_layout)
        timer = QTimer(self)
        # mqtt配置初始化
        mqttClient.username_pw_set("admin", "password")
        mqttClient.on_connect = on_connect  # 连接递归
        mqttClient.on_subscribe = on_subscribe  # 订阅递归
        mqttClient.on_message = on_message  # 消息递归
        mqttClient.username_pw_set(username, password=password)
        mqttClient.connect(host=host, port=port, keepalive=60)  # 订阅频道
        time.sleep(0.02)
        # 动态显示时间在label上
        timer.timeout.connect(self.showtime)
        timer.start()
        # 订阅消息
        mqttClient.subscribe(topic="topic/+", qos=0)
        mqttClient.loop_start()

    def showtime(self):
        datetime = QDateTime.currentDateTime()
        text = datetime.toString()
        self.label.setText(text)
        self.label.setFont(QFont("Roman times", 12, QFont.Bold))
        self.lcd_1.display(temp_d['value'])



if __name__ == '__main__':
    app = QApplication(sys.argv)
    demo = Demo()
    demo.show()
    sys.exit(app.exec_())

  实现的效果为:

 



经过这几天的学习NB-IoT的使用,感觉这块板子上手快,易用性,稳定性也挺好。

如果哪位老板想用于生产环境,我这里再加完善,可以先快的出成品。下一步准备手机实现温度展示。


用E4A写了一个手机的界面,有点丑,也是实现基本功能吧,很想找个美工美化一下。

  

WeChat_20211219204312.mp4

4.15 MB, 下载次数: 18

此帖出自无线连接论坛

最新回复

是不是需要一个mqtt服务器才能连?  详情 回复 发表于 2022-1-19 13:53
点赞(1) 关注
 

回复
举报

6828

帖子

0

TA的资源

五彩晶圆(高级)

沙发
 

采温程序移值正点原子的18B20驱动库成功,下载,跟着学习

此帖出自无线连接论坛
 
 

回复

1411

帖子

3

TA的资源

版主

板凳
 
很不错,点赞
此帖出自无线连接论坛
 
 
 

回复

1

帖子

0

TA的资源

一粒金砂(初级)

4
 

Good work. Keep it up.

此帖出自无线连接论坛
 
 
 

回复

119

帖子

2

TA的资源

一粒金砂(中级)

5
 

是不是需要一个mqtt服务器才能连?

此帖出自无线连接论坛

点评

对的,要有自己的mqtt服务器,而且要用公网的,因为NB-IOT直接连公网的。  详情 回复 发表于 2022-4-2 20:39
 
 
 

回复

7056

帖子

11

TA的资源

版主

6
 
xiyue521 发表于 2022-1-19 13:53 是不是需要一个mqtt服务器才能连?

对的,要有自己的mqtt服务器,而且要用公网的,因为NB-IOT直接连公网的。

此帖出自无线连接论坛
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
快速回复 返回顶部 返回列表