实物图
一、简介
本项目的主要功能是监测工厂中的一氧化碳的浓度,酒精的浓度,设备的温度,还有空气中的温度和湿度,在屏幕上显示出来,也可以通过WiFi在电脑端显示出来。
二、硬件
主控芯片:意法半导体
STM32F103VCT6
WIFI模块:乐鑫
ESP8266
降压芯片:Maxim (本次活动推荐芯片)
MAX17624
低压温度传感器:ADI (本次活动推荐芯片)
TMP36
温湿度传感器:
DHT22
酒精浓度传感器:
MQ-3
空气质量传感器:
MQ-135
屏幕显示:
ST7735
三、一氧化碳对人体的危害
一氧化碳是种无色、无味的气体,吸入后对人体有十分大的伤害。它会结合血红蛋白生成碳氧血红蛋白导致人缺氧。随着现代工业的发展、城市化的进程加快以及车辆的普及,工业上的有害气体大量产生,其中最常见的便是一氧化碳,暴露在过量一氧化碳中可能严重损害心脏和中枢神经系统,会有后遗症。因此对一氧化碳浓度的检测研究是必不可少的。
1、一氧化碳是细胞原浆毒物,对全身组织均有直接的毒性作用,一氧化碳还可以直接抑制细胞内呼吸过程,导致细胞内缺氧。
2、一氧化碳可以引起组织缺氧,一氧化碳与血红蛋白有巨大的亲和力,可以使血浆中氧合血红蛋白急剧下降,使血液运氧发生障碍,导致低氧血症,引起组织缺氧。
3、一氧化碳与血红蛋白结合,形成碳氧血红蛋白后不易解离,可以加重组织缺氧,而且碳氧血红蛋白对人体的脏器和组织细胞均有持久的毒性作用。
4、由于急性低氧血症、高碳氧血红蛋白血症和一氧化碳的直接毒性作用,可以导致心、脑、肝、肾等机体多脏器损害,严重病人会引起迟发性脑病。
四、使用的软件
主控芯片的编程软件是Keil,Keil提供了包括C编译器、宏汇编、连接器、库管理和一个功能强大的仿真调试器等在内的完整开发方案,通过一个集成开发环境(uVision)将这些部分组合在一起。
PCB及原理图由立创EDA绘制,立创EDA是一个用心为中国人定制的电路板开发平台,高效的在线电子设计工具,永久免费,同时支持多操作系统Windows、苹果Mac、Linux 。它能够绘制出美观的电路图,吸引电子工程师,学生,无线电爱好者的使用,从电路原理图无缝转换PCB图。
五、原理图及PCB
该原理图为ESP8266核心板,使用的降压芯片为Maxim的MAX17624,5V输入,3.3V输出,最高可达1A的电流。
六、驱动代码
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file : main.c
* @brief : Main program body
******************************************************************************
* @attention
*
* <h2><center>© Copyright (c) 2021 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under BSD 3-Clause license,
* the "License"; You may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
* opensource.org/licenses/BSD-3-Clause
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "adc.h"
#include "tim.h"
#include "usart.h"
#include "gpio.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "stdio.h"
#include "oled.h"
#include "pic.h"
#include "dht22.h"
#include "beepoff.h"
#include "beepon.h"
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
#define ESP8266_IP "192.168.68.199"
#define ESP8266_Port "8000"
__IO uint16_t ADC0_ConvertedValue;
__IO uint16_t ADC1_ConvertedValue;
__IO uint16_t ADC2_ConvertedValue;
extern ADC_HandleTypeDef hadc1;
extern ADC_HandleTypeDef hadc2;
extern ADC_HandleTypeDef hadc3;
extern char HumitureData[5];
static int BeepFlag = 0;
/* USER CODE END PTD */
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
const unsigned char *point;
/* USER CODE END PD */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV */
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */
/* 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 */
int ADC0_Vol = 0;
int ADC1_Vol = 0;
int ADC2_Vol = 0;
char cStr[100] = { 0 };
float T,RH;
/* 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_USART1_UART_Init();
MX_ADC1_Init();
MX_TIM6_Init();
MX_ADC2_Init();
MX_ADC3_Init();
/* USER CODE BEGIN 2 */
HAL_ADC_Start(&hadc1);
HAL_ADC_Start(&hadc2);
HAL_ADC_Start(&hadc3);
LCD_Init();//LCD初始化
LCD_Fill(0,0,LCD_W,LCD_H,WHITE);
LCD_ShowChinese(5,0,"酒精浓度",BLACK,WHITE,16,0);
LCD_ShowString(93,0,"mg/100ml",BLACK,WHITE,16,0);
LCD_ShowString(20,16,"CO",BLACK,WHITE,16,0);
LCD_ShowChinese(37,16,"浓度",BLACK,WHITE,16,0);
LCD_ShowString(101,16,"PPM",BLACK,WHITE,16,0);
LCD_ShowChinese(5,32,"设备温度",BLACK,WHITE,16,0);
LCD_ShowChinese16x16(101,32,"℃",BLACK,WHITE,16,0);
LCD_ShowChinese(5,48,"温度",BLACK,WHITE,16,0);
LCD_ShowChinese16x16(78,48,"℃",BLACK,WHITE,16,0);
LCD_ShowChinese(5,64,"湿度",BLACK,WHITE,16,0);
LCD_ShowString(78,64,"%",BLACK,WHITE,16,0);
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
HAL_Delay(2000);
HAL_Delay(2000);
HAL_Delay(2000);
sprintf ( cStr,"AT+CIPSTART=\"%s\",\"%s\",%s", "TCP", ESP8266_IP, ESP8266_Port );
printf("%s\r\n", cStr);
HAL_Delay(2000);
printf("AT+CIPMODE=1\r\n");
HAL_Delay(2000);
printf("AT+CIPSEND\r\n");
while (1)
{
Humitureoutput();
ADC0_ConvertedValue = HAL_ADC_GetValue(&hadc1);
ADC1_ConvertedValue = HAL_ADC_GetValue(&hadc2);
ADC2_ConvertedValue = HAL_ADC_GetValue(&hadc3);
ADC0_Vol = ADC0_ConvertedValue * 3.3/4096*5;//PA0,酒精浓度传感器:ad值*3.3/4096*25
ADC1_Vol = ((ADC1_ConvertedValue * 3300/4096)-500)/10;//PA1,温度传感器:ad值转换成电压值(mv)-500/10
ADC2_Vol = ADC2_ConvertedValue * 3.3/4096*15;//PA2,气体浓度传感器:ad值*3.3/4096*25
T = (float)(HumitureData[2]*256+HumitureData[3])/10;
RH = (float)(HumitureData[0]*256+HumitureData[1])/10;
if(ADC0_Vol < 30)
{
LCD_ShowIntNum(69,0,ADC0_Vol,3,BLACK,WHITE,16);//酒精浓度
}else{
LCD_ShowIntNum(69,0,ADC0_Vol,3,RED,WHITE,16);//酒精浓度
BeepFlag = 1;
}
if(ADC2_Vol < 50)
{
LCD_ShowIntNum(69,16,ADC2_Vol,4,BLACK,WHITE,16);//CO浓度
}else{
LCD_ShowIntNum(69,16,ADC2_Vol,4,RED,WHITE,16);//CO浓度
BeepFlag = 1;
}
if(ADC1_Vol < 80)
{
LCD_ShowIntNum(69,32,ADC1_Vol,4,BLACK,WHITE,16);//设备温度
}else{
LCD_ShowIntNum(69,32,ADC1_Vol,4,RED,WHITE,16);//设备温度
BeepFlag = 1;
}
if(T < 35)
{
LCD_ShowFloatNum1(38,48,T,4,BLACK,WHITE,16);//温度
}else{
LCD_ShowFloatNum1(38,48,T,4,RED,WHITE,16);//温度
BeepFlag = 1;
}
if(RH < 70)
{
LCD_ShowFloatNum1(38,64,RH,4,BLACK,WHITE,16);//湿度
}else{
LCD_ShowFloatNum1(38,64,RH,4,RED,WHITE,16);//湿度
BeepFlag = 1;
}
if(BeepFlag == 1)
{
HAL_GPIO_WritePin(GPIOC, BEEP_Pin, GPIO_PIN_SET);//打开蜂鸣器
LCD_ShowPicture(120,40,40,40,gImage_beepon);//图片显示:蜂鸣器打开
}else{
HAL_GPIO_WritePin(GPIOC, BEEP_Pin, GPIO_PIN_RESET);//关闭蜂鸣器
LCD_ShowPicture(120,40,40,40,gImage_beepoff);//图片显示:蜂鸣器关闭
}
BeepFlag = 0;
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
HAL_Delay(500);
HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);
HAL_Delay(500);
HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);
printf("\r\n");
printf("酒精浓度:%dmg/100ml\r\n",ADC0_Vol);
printf("设备温度:%d℃\r\n",ADC1_Vol);
printf(" CO 浓度:%dppm\r\n",ADC2_Vol);
printf(" 温度:%.2f℃\r\n",T);
printf(" 湿度:%.2f%\r\n",RH);
printf("\r\n");
}
/* USER CODE END 3 */
}
/**
* @brief System Clock Configuration
* @retval None
*/
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
RCC_PeriphCLKInitTypeDef PeriphClkInit = {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();
}
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_ADC;
PeriphClkInit.AdcClockSelection = RCC_ADCPCLK2_DIV6;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
{
Error_Handler();
}
}
/* USER CODE BEGIN 4 */
/* 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)
{
}
/* USER CODE END Error_Handler_Debug */
}
#ifdef USE_FULL_ASSERT
/**
* @brief Reports the name of the source file and the source line number
* where the assert_param error has occurred.
* @param file: pointer to the source file name
* @param line: assert_param error line source number
* @retval None
*/
void assert_failed(uint8_t *file, uint32_t line)
{
/* USER CODE BEGIN 6 */
/* User can add his own implementation to report the file name and line number,
ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
/* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
七、总结
终于在最后几天的时间内完成了这个项目,之前一直忙于自己的事,没时间做,拖到现在,还好活动延期,赶出来了,虽然复杂度不高,但也是自己完成的一个小项目,期待下次的活动,希望越办越好