spinmry's Lab

绝赞摸鱼中Orz

Category

  • Algorithm
  • Hardware
  • Homelab
  • Programming
  • Retro
  • Software

Tags

  • 算法
  • OI
  • Linux
  • 数据结构
  • HardwareHacking
  • Kruskal
  • 图论
  • 平衡树
  • Vintage
  • 计算设备
  • 单片机
  • RobotC
  • QQBot
  • 离散化
  • 线段树
  • VEX
  • 机器人
  • Homelab
  • Nspire
  • ACG
  • 分块
  • 树状数组
  • ARM
  • 爬虫
  • 网页
  • Wolfram
  • Mattermost
  • 数论
  • CUDA
  • 动态规划
  • Tarjan
  • Loongson
  • STM32
  • Python
  • iLO

Recent replies

  • jiyouzhan 发表于「使用 Debian + libvirt + WebVirtCloud 作为 homelab 虚拟化平台」
  • jianchen 发表于「在 Loongson 2F 上编译 Common Desktop Environment」
  • rantrism 发表于「解决 Linux Optimus 混合模式下独立显卡外接显示器卡顿的问题」
  • 千羽 发表于「在 Loongson 2F 上编译 Common Desktop Environment」
  • spinmry 发表于「QQ - Mattermost 双向转发机器人」

友情链接

空白酱
Woshiluo
FlyGoat
BeyondLimits
Memo von EFS
Paizhang
Ntzyz
ZephRay
Polarnova
Tautcany
NekoDaemon
MaxAlex
Abyss Studio
EE Archeology 电子考古学
桜庭清夏的小站
欠陥電気の摸鱼小池
白玉楼製作所
naivekun's blog

娱乐向跑分

Coremark
Linpack
标签:STM32

基于STM32的环境监测器

2019 年 2 月 17 日分类:Hardware#STM32#单片机

基于STM32的环境监测器

0x00 背景&功能描述

研究性学习课题要用到这玩意…于是尝试用stm32捏了一个… 第一次玩stm32,为了方便就直接拿STM32CubeMX生成了这个工程… 芯片为STM32F407GZT6,使用了外部RTC,具体时钟树设置参考CubeMX工程文件。 功能嘛,每隔一段时间获取实时PM2.5,PM10,CO2浓度与环境温湿度,并将其存储入SD卡(FAT32分区)中。同时也会向USART1中打印日志。 USART1-3波特率均为9600,

0x01 硬件部分

温湿度传感器(DHT22/AM2303) -> PA1 *USART1(PA9 PA10) PM2.5(G7 PMS7003) -> USART2(PA3 PA4) CO2(DS-CO2-20) -> USART3(PE14 PE15)

0x02 代码

项目由CubeMX自动生成,以下仅展示部分代码 GitHub项目地址 ps:请忽视逼死强迫症的缩进…就让Keil uvision那个辣鸡的IDE背锅吧

RTC_DateTypeDef sDate;
RTC_TimeTypeDef sTime;
uint8_t second_tmp = 0;

void LED0_off(){HAL_GPIO_WritePin(LED0_GPIO_Port, LED0_Pin, GPIO_PIN_SET);}
void LED1_off(){HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, GPIO_PIN_SET);}

void LED0_on(){HAL_GPIO_WritePin(LED0_GPIO_Port, LED0_Pin, GPIO_PIN_RESET);}
void LED1_on(){HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, GPIO_PIN_RESET);}

uint8_t PMSensorBuffer[128];
uint8_t PMSensor[17];
int TOT = 0, PMSensorLen;

//PM Sensor

struct PMSensor{
	int PM1_0_CF, PM2_5_CF, PM10_CF, PM1_0, PM2_5, PM10;
}PMResult;

void ListenPMSensor(){
	memset(PMSensorBuffer, 0, sizeof(PMSensorBuffer));
	memset(PMSensor, 0, sizeof(PMSensor));
	
	HAL_UART_Receive(&huart2, (uint8_t*)PMSensorBuffer, 128, 3200);
	HAL_Delay(800);
	
	//printf("", PMSensorBuffer);
	for(int i = 0; i <= 127; ++i){
		//printf("%c \n", PMSensorBuffer[i]);
		if(PMSensorBuffer[i] == 'B' && PMSensorBuffer[i+1] == 'M'){			
			for(PMSensorLen = 0; PMSensorLen <= 31; ++PMSensorLen){
				PMSensor[PMSensorLen] = PMSensorBuffer[i + PMSensorLen];
			}
			break;
		}
	}
	
	HAL_Delay(2000);
	return ;
}

void GetPMSensor(void){
	uint16_t Buffer_Len;
	Buffer_Len = (uint16_t)((PMSensor[2] << 8) | PMSensor[3]);
	if(Buffer_Len == 28) {
		
		PMResult.PM1_0_CF = (uint16_t)((PMSensor[4]<<8) | PMSensor[5]);
		PMResult.PM2_5_CF = (uint16_t)((PMSensor[6]<<8) | PMSensor[7]);
		PMResult.PM10_CF 	= (uint16_t)((PMSensor[8]<<8) | PMSensor[9]);
		PMResult.PM1_0 	= (uint16_t)((PMSensor[10]<<8) | PMSensor[11]);
		PMResult.PM2_5 	= (uint16_t)((PMSensor[12]<<8) | PMSensor[13]);
		PMResult.PM10 	= (uint16_t)((PMSensor[14]<<8) | PMSensor[15]);		
		
	}
	else if(Buffer_Len == 20){
		
		PMResult.PM1_0_CF = (uint16_t)((PMSensor[4]<<8) | PMSensor[5]);
		PMResult.PM2_5_CF = (uint16_t)((PMSensor[6]<<8) | PMSensor[7]);
		PMResult.PM10_CF 	= (uint16_t)((PMSensor[8]<<8) | PMSensor[9]);
		PMResult.PM1_0 	= (uint16_t)((PMSensor[10]<<8) | PMSensor[11]);
		PMResult.PM2_5 	= (uint16_t)((PMSensor[12]<<8) | PMSensor[13]);
		PMResult.PM10 	= (uint16_t)((PMSensor[14]<<8) | PMSensor[15]);
		
	}
}

int CheckPMSensor(){
	
	uint16_t 	Cal_CheckSum;
	uint16_t 	Buffer_CheckSum;
	uint16_t 	Buffer_Len;
	uint8_t 	i;
	
	int Result = 0;

	if((PMSensor[0] == 'B')&&(PMSensor[1] == 'M')){
		Buffer_Len = (uint16_t)((PMSensor[2] << 8) | PMSensor[3]);

		Buffer_CheckSum = (uint16_t)((PMSensor[Buffer_Len + 2] << 8) | PMSensor[Buffer_Len + 3]);

		Cal_CheckSum = 0;
		for(i=0;i<(Buffer_Len + 2);i++){
			Cal_CheckSum += PMSensor[i];
		}

		if(Cal_CheckSum == Buffer_CheckSum)
			Result = 1;
	}
	return Result;
}


//CO2 sensor
uint8_t CO2SensorBuffer[12];
uint8_t CO2Sensor[12];

int CO2SensorLen = 0, CO2SensorResult = 0;

void ListenCO2Sensor(){
	memset(CO2SensorBuffer, 0, sizeof(CO2SensorBuffer));
	memset(CO2Sensor, 0, sizeof(CO2Sensor));
	
	uint8_t CO2Transmit[12] = {0x42, 0x4D, 0xE3, 0x00, 0x00, 0x01, 0x72};
	
	HAL_UART_Transmit(&huart3, CO2Transmit, 7, 0xFFFF);
	HAL_UART_Receive(&huart3, (uint8_t*)CO2SensorBuffer, 12, 800);
	HAL_Delay(800);
	
	for(int i = 0; i <= 11; ++i){
		//printf("%c", CO2SensorBuffer[i]);
		if(CO2SensorBuffer[i] == 'B' && CO2SensorBuffer[i+1] == 'M'){
			for(CO2SensorLen = 0; CO2SensorLen <= 11; ++CO2SensorLen){	
				CO2Sensor[CO2SensorLen] = CO2SensorBuffer[i + CO2SensorLen];
			}
			break;
		}
		HAL_Delay(500);
	}
	HAL_Delay(2000);
	return ;
}


int CheckCO2Sensor(){
	
	uint16_t 	Cal_CheckSum;
	uint16_t 	Buffer_CheckSum;
	uint16_t 	Buffer_Len;
	uint8_t 	i;
	
	int Result = 0;

	if((CO2Sensor[0] == 'B')&&(CO2Sensor[1] == 'M')){
		
		Buffer_Len = (uint16_t)((CO2Sensor[2] << 8) | CO2Sensor[3]);
		//printf("LEN:%d \n",Buffer_Len);
		Buffer_CheckSum = (uint16_t)((CO2Sensor[Buffer_Len + 2] << 8) | CO2Sensor[Buffer_Len + 3]);
        
		Cal_CheckSum = 0;
		for(i=0;i<(Buffer_Len + 2);i++){
			Cal_CheckSum += CO2Sensor[i];
		}
		//printf("CALSUM:%d, BUFFSUM:%d \n", Cal_CheckSum, Buffer_CheckSum);
		if(Cal_CheckSum == Buffer_CheckSum)
			Result = 1;
	}
	return Result;
}

void GetCO2Sensor(){
	CO2SensorResult = (uint16_t)((CO2Sensor[4]<<8) | CO2Sensor[5]);
	return ;
}

FATFS SDFatFs;
FIL MyFile;

void WriteFile(){
	
	LED0_off();
	LED1_off();
	
	uint32_t byteswritten;
	char nowdate[21];
	sprintf(nowdate, "[20%02d-%02d-%02d %02d:%02d:%02d]\n",
				sDate.Year,
				sDate.Month,
				sDate.Date,
				sTime.Hours,
				sTime.Minutes,
				sTime.Seconds
	);
	char wtext[150] = " ";
	sprintf(wtext, "%sCO2 : _%04d_ ppm\nPM2.5 : _%04d_ ug/m3\nPM10 : _%04d_ ug/m3\n", 
		nowdate,
		CO2SensorResult, 
		PMResult.PM2_5, 
		PMResult.PM10
	);
	char FileName[25] = " ";
	sprintf(FileName, "Sensor_%02d%02d%02d%02d%02d_.txt", 
		sDate.Year,
		sDate.Month,
		sDate.Date,
		sTime.Hours,
		sTime.Minutes
	);
	printf("%s\nFileName:%s\n", wtext, FileName);
	if(f_mount(&SDFatFs, (TCHAR const*)SDPath, 0) == FR_OK){
		PrintTime();
		printf("[SD_FATFS_STAT] Mount Successful!\n");
		if(f_open(&MyFile, (TCHAR const*)FileName, FA_CREATE_ALWAYS | FA_WRITE) == FR_OK){
			PrintTime();
			printf("[SD_FATFS_STAT] Open File Successful!\n");
			FRESULT res = f_write(&MyFile, wtext, (unsigned int)strlen(wtext), (void *)&byteswritten);
			if((byteswritten == 0) || (res != FR_OK)){
				PrintTime();
				printf("[SD_FATFS_STAT] Write Failed!\n");
			}
			else{
				f_close(&MyFile);
				PrintTime();
				printf("[SD_FATFS_STAT] Write Successful!\n");
			}
		}
		else{
				PrintTime();
				printf("[SD_FATFS_STAT] Open File Failed!\n");
		}
	}else{
		PrintTime();
		printf("[SD_FATFS_STAT] Mount Failed!\n");
	}
	
}

void PrintTime(){
	
	printf("[20%02d-%02d-%02d %02d:%02d:%02d]",
				sDate.Year,
				sDate.Month,
				sDate.Date,
				sTime.Hours,
				sTime.Minutes,
				sTime.Seconds
	);
	return ;
}

void CheckState(){
	
	LED0_on();
	LED1_off();
	
	ListenCO2Sensor();
	if(CheckCO2Sensor()){
		PrintTime();
		printf("[CO2_SENSOR_STATE] Success!\n");
		GetCO2Sensor();
	}
	
	else{
		PrintTime();
		printf("[CO2_SENSOR_STATE] Error!\n");
	}
	
	/*PM SENSOR READ*/
	HAL_Delay(100);
	LED0_on();
	LED0_off();
	ListenPMSensor();
	if(CheckPMSensor()){
		PrintTime();
		printf("[PM_SENSOR_STATE] Success!\n");
		GetPMSensor();
	}
	else{
		PrintTime();
		printf("[PM_SENSOR_STATE] Error!\n");
	}
	
	PrintTime();
	printf("\nCO2: %d ppm \nPM2.5: %d ug/m^3\nPM10: %d ug/m^3\n", CO2SensorResult, PMResult.PM2_5, PMResult.PM10);
	WriteFile();
	//WriteFile(filename);
	HAL_Delay(1000);
	
	return ;
 }

/* USER CODE END 0 */

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_SDIO_SD_Init();
  MX_USART1_UART_Init();
  MX_USART2_UART_Init();
  MX_USART3_UART_Init();
  MX_FATFS_Init();
  MX_RTC_Init();
  /* USER CODE BEGIN 2 */

  /* USER CODE END 2 */
	
  while (1){
    
		/* USER CODE BEGIN 3 */
		
		HAL_Delay(100);
		HAL_RTC_GetTime(&hrtc, &sTime, RTC_FORMAT_BIN);
		HAL_RTC_GetDate(&hrtc, &sDate, RTC_FORMAT_BIN);
		if(second_tmp != sTime.Seconds){
			second_tmp = sTime.Seconds;
			//printf("20%d%d-%d%d-%d%d\n", sDate.Year/10%10, sDate.Year%10, sDate.Month/10%10, sDate.Month%10, sDate.Date/10%10, sDate.Date%10);
			printf("[20%02d-%02d-%02d %02d:%02d:%02d] LOOP = %d\n",
				sDate.Year,
				sDate.Month,
				sDate.Date,
				sTime.Hours,
				sTime.Minutes,
				sTime.Seconds,
				TOT
			);
		}
		
		TOT++;
		LED0_on();
		LED1_on();
		
		CheckState();
		
		HAL_Delay(100);

  }
  /* USER CODE END 3 */
}
  • «
  • 1
  • »
Copyright © 2019-2023 spinmry. All rights reserved.
Except where otherwise noted, content on this blog is licensed under CC BY-SA 4.0.