【练习项目2】基于物联网MQTT技术的家用温度监测仪

要求:

以STM32F10x系列主控,利用ESP8266模块、GXH3L以及数码管,实现一个实时性较低的家用温度监测装置。用户可以通过手机订阅MQTT上的温度主题查看此时间段内室内的大致温度,也可以通过数码管清楚的看到室内温度。

实现代码:

main.c:

/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "dma.h"
#include "i2c.h"
#include "tim.h"
#include "usart.h"
#include "gpio.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
#include "tempget.h"
#include "NUMLED.h"
/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
#define AT "AT\r\n"
#define AT_WIFI_MODE "AT+CWMODE=3\r\n"
#define AT_SET_PSW "AT+CWJAP=\"DayDream\",\"cyberchino\"\r\n"
#define AT_SET_MQTT_CFG "AT+MQTTUSERCFG=0,1,\"NULL\",\"xxx\",\"xxx\",0,0,\"\"\r\n"
#define AT_SET_MQTT_CLENTID "AT+MQTTCLIENTID=0,\"xxx1|securemode=2\\,signmethod=hmacsha256\\,timestamp=1746264316150|\"\r\n"
#define AT_SET_MQTT_CONN "AT+MQTTCONN=0,\"iot-06z00dcx1hvlwd3.mqtt.iothub.aliyuncs.com\",1883,1\r\n"
#define AT_MQTT_SUB "AT+MQTTSUB=0,\"/sys/xxxx/xxx/thing/service/property/set\",1\r\n"
#define AT_MQTT_PUB "AT+MQTTPUB=0,\"/sys/xxx/xxx/thing/event/property/post\",\"{\\\"params\\\":{\\\"CurrentTemperature\\\":%d}}\",1,0\r\n"
//以上内容替换为你自己的信息
#define ACK_OK "OK"
#define BUFFER_SIZE 256
/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/

/* USER CODE BEGIN PV */
uint8_t rx_buf[BUFFER_SIZE]; 
uint8_t tx_buf[BUFFER_SIZE]; 
bool rx_status = false;
extern DMA_HandleTypeDef hdma_uart4_rx;
uint8_t dma_rxbuf[BUFFER_SIZE];

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */
static void init(void);
static bool send_cmd(uint8_t *cmd, uint8_t *ack);
static void read_cmd();
float temperature = 0.0;
uint8_t recv_dat[6] = {0};
uint8_t recv_status[3] = {0};
/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* USER CODE BEGIN 1 */
  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_DMA_Init();
  MX_UART4_Init();
  MX_USART1_UART_Init();
  MX_I2C2_Init();
  MX_TIM6_Init();
  /* USER CODE BEGIN 2 */
	printf("A Temperature Detect System by YU from AminiPro Developers\n");
  printf("EMBD APP INITING......\n");
	printf("Loading GXHT3L Detector......\n");
	GXHT3L_Reset();
	GXHT3L_Init();
	printf("*GXH3L Finished Loading*\n");
	__HAL_UART_ENABLE_IT(&huart4,UART_IT_IDLE);
	HAL_UART_Receive_DMA(&huart4,dma_rxbuf,sizeof(dma_rxbuf));
	init();
	printf("INIT Finished\n");
	printf("...............................................");
	HAL_TIM_Base_Start_IT(&htim6);
	if (GXHT3L_Read_Dat(recv_dat) == HAL_OK){
		GXHT3L_Dat_To_Float(recv_dat, &temperature);
		printf("temp == %f\n",temperature);
		}
//  uint8_t send_count = 0;
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
				display(temperature);
//		   send_count ++;
//                if(send_count >= 10){
//                        //10s????
//                        send_count = 0;
//                        sprintf((char *)tx_buf,"AT+MQTTPUB=0,\"/sys/a1Yd6Ze47ON/device1/thing/event/property/post\",\"{\\\"params\\\":{\\\"CurrentTemperature\\\":%d}}\",1,0\r\n", temperature);
//                        send_cmd(tx_buf,(uint8_t *)ACK_OK);
//                        temperature ++;
//                        if(temperature > 100)
//                                temperature = 20;
//                }
//                read_cmd();
//                HAL_Delay(1000);
  }
  /* USER CODE END 3 */
}

/**
  * @brief System Clock Configuration
  * @retval None
  */
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }
  /** Initializes the CPU, AHB and APB buses clocks
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
  {
    Error_Handler();
  }
}

/* USER CODE BEGIN 4 */
void DMA_to_APP(uint8_t* dma_rxbuf, uint8_t len){
		if(rx_status){
        return;
		}
    if(len > BUFFER_SIZE){
        return;
		}
		memcpy(rx_buf,dma_rxbuf,len);
		rx_status = true;
}

bool send_cmd(uint8_t *cmd, uint8_t *ack){
		int time_out=500;
		memset(rx_buf,0,sizeof(rx_buf));
		printf("send -----> %s\n",cmd);
		HAL_UART_Transmit_DMA(&huart4,(uint8_t *)cmd,strlen((const char*)cmd));
		while(time_out--){
		if(rx_status){
				printf("read-----> %s\n",rx_buf);
				if(strstr((const char*)rx_buf, (const char*)ack)!=NULL){
						printf("ack ok\n");
						rx_status = false;
						return true;				
				}
				memset(rx_buf,0,sizeof(rx_buf));
				rx_status = false;
		}
		    HAL_Delay(10);
		}
		printf("ack fail\n");
		return false;	
}

void read_cmd(){
        if(rx_status){
                printf("read ----> %s\n",rx_buf);
                rx_status = false;
        }
}

void init(){
//		send_cmd((uint8_t *)AT,(uint8_t *)ACK_OK);
//    HAL_Delay(500);
    send_cmd((uint8_t *)AT_WIFI_MODE,(uint8_t *)ACK_OK);
    HAL_Delay(500);
    send_cmd((uint8_t *)AT_SET_PSW,(uint8_t *)ACK_OK);
    HAL_Delay(500);
    send_cmd((uint8_t *)AT_SET_MQTT_CFG,(uint8_t *)ACK_OK);
    HAL_Delay(500);
    send_cmd((uint8_t *)AT_SET_MQTT_CLENTID,(uint8_t *)ACK_OK);
    HAL_Delay(500);
    send_cmd((uint8_t *)AT_SET_MQTT_CONN,(uint8_t *)ACK_OK);
    HAL_Delay(500);
    send_cmd((uint8_t *)AT_MQTT_SUB,(uint8_t *)ACK_OK);
    HAL_Delay(500);
}

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim){
    if (htim==&htim6){
            if (GXHT3L_Read_Dat(recv_dat) == HAL_OK){
                GXHT3L_Dat_To_Float(recv_dat, &temperature);
								sprintf((char *)tx_buf,"AT+MQTTPUB=0,\"/sys/a1Yd6Ze47ON/device1/thing/event/property/post\",\"{\\\"params\\\":{\\\"CurrentTemperature\\\":%f}}\",1,0\r\n", temperature);
                send_cmd(tx_buf,(uint8_t *)ACK_OK);
            }
    }
}

void UART_IDLEHandler(){
		if(__HAL_UART_GET_FLAG(&huart4, UART_FLAG_IDLE) == SET){
				__HAL_UART_CLEAR_FLAG(&huart4, UART_FLAG_IDLE);
				HAL_UART_DMAStop(&huart4);
				uint8_t rlen = BUFFER_SIZE - __HAL_DMA_GET_COUNTER(&hdma_uart4_rx);
				DMA_to_APP(dma_rxbuf, rlen);
				HAL_UART_Receive_DMA(&huart4,dma_rxbuf,sizeof(dma_rxbuf));
		}
}

int fputc(int ch, FILE *f){
		HAL_UART_Transmit(&huart1,(uint8_t*) &ch, 1, 0xFFFF);
		return ch;
}
/* USER CODE END 4 */

/**
  * @brief  This function is executed in case of error occurrence.
  * @retval None
  */
void Error_Handler(void)
{
  /* USER CODE BEGIN Error_Handler_Debug */
  /* User can add his own implementation to report the HAL error return state */
  __disable_irq();
  while (1)
  {

tempget.h:

#include "main.h"
#define    GXHT3L_ADDR_WRITE    0x44<<1         //10001000
#define    GXHT3L_ADDR_READ     (0x44<<1)+1     //10001001
typedef enum
{
    /* ?????? */

    SOFT_RESET_CMD = 0x30A2,    
    /* ????/???? */
    PREHEAT_ENABLE_CMD = 0x306D,
    PREHEAT_DISENABLE_CMD = 0x3066,
    /* ?????? */
    DEVICE_STATUS_CMD = 0xF32D,
    
    /*
    ??????
    ????:Repeatability_CS_CMD
    CS:Clock stretching
    */
    HIGH_ENABLED_CMD    = 0x2C06,
    MEDIUM_ENABLED_CMD  = 0x2C0D,
    LOW_ENABLED_CMD     = 0x2C10,
    HIGH_DISABLED_CMD   = 0x2400,
    MEDIUM_DISABLED_CMD = 0x240B,
    LOW_DISABLED_CMD    = 0x2416,

    /*
    ??????
    ????:Repeatability_MPS_CMD
    MPS:measurement per second
    */
    HIGH_0_5_CMD   = 0x2032,
    MEDIUM_0_5_CMD = 0x2024,
    LOW_0_5_CMD    = 0x202F,
    HIGH_1_CMD     = 0x2130,
    MEDIUM_1_CMD   = 0x2126,
    LOW_1_CMD      = 0x212D,
    HIGH_2_CMD     = 0x2236,
    MEDIUM_2_CMD   = 0x2220,
    LOW_2_CMD      = 0x222B,
    HIGH_4_CMD     = 0x2334,
    MEDIUM_4_CMD   = 0x2322,
    LOW_4_CMD      = 0x2329,
    HIGH_10_CMD    = 0x2737,
    MEDIUM_10_CMD  = 0x2721,
    LOW_10_CMD     = 0x272A,
    /* ???????????? */
    READOUT_FOR_PERIODIC_MODE = 0xE000,
} GXHT3L_CMD;

extern float temperature;
extern uint8_t recv_dat[6];
extern uint8_t recv_status[3];

uint8_t GXHT3L_Send_Cmd(GXHT3L_CMD cmd);
void GXHT3L_Reset(void);
void GXHT3L_Preheat_Disable(void);
uint8_t GXHT3L_Read_Status(uint8_t* dat);
uint8_t GXHT3L_Init(void);
uint8_t GXHT3L_Read_Dat(uint8_t* dat);
uint8_t GXHT3L_Dat_To_Float(uint8_t* const dat, float* temperature);

tempget.c

#include "tempget.h"
#include "i2c.h"
uint8_t GXHT3L_Send_Cmd(GXHT3L_CMD cmd)
{
    uint8_t cmd_buffer[2];
    cmd_buffer[0] = cmd >> 8;
    cmd_buffer[1] = cmd;
    return HAL_I2C_Master_Transmit(&hi2c2, GXHT3L_ADDR_WRITE, (uint8_t*) cmd_buffer, 2, 0xFFFF);
}

void GXHT3L_Reset(void)
{
    GXHT3L_Send_Cmd(SOFT_RESET_CMD);
    HAL_Delay(20);
}

void GXHT3L_Preheat_Disable(void)
{
    GXHT3L_Send_Cmd(PREHEAT_DISENABLE_CMD);
    HAL_Delay(20);
}

uint8_t GXHT3L_Read_Status(uint8_t* dat)
{
    GXHT3L_Send_Cmd(DEVICE_STATUS_CMD);
    return HAL_I2C_Master_Receive(&hi2c2, GXHT3L_ADDR_READ, dat, 3, 0xFFFF);
}

uint8_t GXHT3L_Init(void)
{
    return GXHT3L_Send_Cmd(MEDIUM_2_CMD);
}

uint8_t GXHT3L_Read_Dat(uint8_t* dat)
{
    GXHT3L_Send_Cmd(READOUT_FOR_PERIODIC_MODE);
    return HAL_I2C_Master_Receive(&hi2c2, GXHT3L_ADDR_READ, dat, 6, 0xFFFF);
}

uint8_t GXHT3L_Dat_To_Float(uint8_t* const dat, float* temperature)
{
    uint16_t recv_temperature = 0;
	
    /* ?????? */
    recv_temperature = ((uint16_t)dat[0]<<8)|dat[1];
    *temperature = -45 + 175*((float)recv_temperature/65535);
		
    return 0;
}

NUMLED.h

#include "main.h"
void hc595_shift_input(uint8_t byte);
void hc595_storage_input(uint8_t data, uint8_t addr);
void display(uint8_t dat);

NUMLED.c

#include "NUMLED.h"
#include "tempget.h"
void hc595_shift_input(uint8_t byte){
    uint32_t i;
    for (i=0;i<8;i++){
        if (byte&0x80){
                HAL_GPIO_WritePin(DS_GPIO_Port,DS_Pin,GPIO_PIN_SET);
        }
        else {
                HAL_GPIO_WritePin(DS_GPIO_Port,DS_Pin,GPIO_PIN_RESET);
        }
    HAL_GPIO_WritePin(SHCP_GPIO_Port,SHCP_Pin,GPIO_PIN_SET);
    HAL_GPIO_WritePin(SHCP_GPIO_Port,SHCP_Pin,GPIO_PIN_RESET);
    byte<<=1;
}
}

void hc595_storage_input(uint8_t data, uint8_t addr){
    hc595_shift_input(data);
    HAL_GPIO_WritePin(STCP_GPIO_Port,STCP_Pin,GPIO_PIN_RESET);
    HAL_GPIO_WritePin(STCP_GPIO_Port,STCP_Pin,GPIO_PIN_SET);
    hc595_shift_input(1<<addr);
    HAL_GPIO_WritePin(STCP_GPIO_Port,STCP_Pin,GPIO_PIN_RESET);
    HAL_GPIO_WritePin(STCP_GPIO_Port,STCP_Pin,GPIO_PIN_SET);
}

uint8_t num[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};

void display(uint8_t dat){
    uint8_t first = dat/10;
    uint8_t second = dat%10;
    hc595_storage_input(num[first],1);
    hc595_storage_input(num[second],0);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值