基于小熊派氣體傳感器MQ-2綜合實踐
前面,我們用光強(qiáng)傳感器做了很多實踐小項目,那么今天我們把項目稍微變一下,把光強(qiáng)傳感器換成氣體傳感器吧!原來光強(qiáng)傳感器相關(guān)文章鏈接如下:
基于小熊派光強(qiáng)傳感器BH1750實踐(multi_timer+狀態(tài)機(jī)工程應(yīng)用)
基于小熊派光強(qiáng)傳感器BH1750狀態(tài)機(jī)驅(qū)動項目升級(帶LCD屏顯示)
基于小熊派光強(qiáng)傳感器BH1750狀態(tài)機(jī)驅(qū)動項目再度升級(帶上位機(jī)曲線顯示)
今天我們介紹的這款傳感器是小熊派自帶的一個模塊,MQ-2氣體傳感器。
1、了解MQ-2
從手冊中了解到,這是一個可以檢測多種有害氣體的傳感器,看似很強(qiáng)大,等會我就來試一下,它是不是真的能檢測出來。
2、小熊派E53_SF1電路原理圖
這是模塊對應(yīng)底板的電路原理圖,從電路原理圖中了解到,這個傳感器是一個模擬轉(zhuǎn)數(shù)字的器件(ADC),接在PC2管腳。
3、實踐需求定義
-
具備顯示傳感器數(shù)值(LCD實現(xiàn)) -
具備聲光報警功能(SF1板載LED、無源蜂鳴器) -
當(dāng)傳感器數(shù)值超出用戶設(shè)定閾值時聲光報警(暫定用戶設(shè)定閾值為600ppm) -
實時曲線數(shù)據(jù)傳輸(自定義串口協(xié)議)
4、實現(xiàn)需求
4.1 stm32cubemx配置硬件驅(qū)動參數(shù)
由于前面已經(jīng)寫過很多軟件上的設(shè)置了,所以這里只給出配置表,配置表可以通過CubeMX軟件自動生成。
最后會得到一個pdf文件,如下:
4.2 軟件實現(xiàn)
(1)傳感器數(shù)據(jù)結(jié)構(gòu)定義
typedef struct Sensor
{
/*煙感值*/
int Smoke_Value;
/*報警燈狀態(tài)*/
uint8_t Alarm_Led_Status : 1;
/*報警蜂鳴器狀態(tài)*/
uint8_t Alarm_Buzzer_Status : 1;
/*是否打印曲線標(biāo)志*/
uint8_t Display_Plot_Flag : 1 ;
/*set方法*/
void (*led_control)(struct Sensor *sensor_handle, uint8_t status);
void (*buzzer_control)(struct Sensor *sensor_handle, uint8_t status);
void (*plot_control)(struct Sensor *sensor_handle, uint8_t status);
/*get方法*/
int (*get_smoke_value)(struct Sensor *sensor_handle);
int (*get_led_status)(struct Sensor *sensor_handle);
int (*get_buzzer_status)(struct Sensor *sensor_handle);
int (*get_plot_status)(struct Sensor *sensor_handle);
} Sensor ;
Sensor *MQ2_Sensor = NULL;
(2)實現(xiàn)傳感器數(shù)據(jù)結(jié)構(gòu)里對應(yīng)的set/get
方法
//設(shè)置報警燈狀態(tài)
void alarm_led_control(Sensor *sensor_handle, uint8_t status)
{
sensor_handle->Alarm_Led_Status = status ;
if(sensor_handle->Alarm_Led_Status)
HAL_GPIO_WritePin(SF1_LED_GPIO_Port, SF1_LED_Pin, GPIO_PIN_SET);
else
HAL_GPIO_WritePin(SF1_LED_GPIO_Port, SF1_LED_Pin, GPIO_PIN_RESET);
}
//設(shè)置報警蜂鳴器狀態(tài)
void alarm_buzzer_control(Sensor *sensor_handle, uint8_t status)
{
sensor_handle->Alarm_Buzzer_Status = status ;
if(sensor_handle->Alarm_Buzzer_Status)
HAL_TIM_PWM_Start(&htim16, TIM_CHANNEL_1);
else
HAL_TIM_PWM_Stop(&htim16, TIM_CHANNEL_1);
}
//設(shè)置曲線顯示
void plot_display_control(Sensor *sensor_handle, uint8_t status)
{
sensor_handle->Display_Plot_Flag = status ;
}
//獲取led狀態(tài)
int get_led_status(Sensor *sensor_handle)
{
return sensor_handle->Alarm_Led_Status ;
}
//獲取蜂鳴器狀態(tài)
int get_buzzer_status(Sensor *sensor_handle)
{
return sensor_handle->Alarm_Buzzer_Status ;
}
//獲取曲線狀態(tài)
int get_plot_status(Sensor *sensor_handle)
{
return sensor_handle->Display_Plot_Flag ;
}
//獲取煙感值
int get_smoke_value(Sensor *sensor_handle)
{
HAL_ADC_Start(&hadc1);
HAL_ADC_PollForConversion(&hadc1, 50);
sensor_handle->Smoke_Value = HAL_ADC_GetValue(&hadc1);
return sensor_handle->Smoke_Value ;
}
(3)實現(xiàn)傳感器接口注冊接口
/*提供訪問傳感器的接口*/
Sensor mq2_sensor_interface =
{
/*設(shè)置接口*/
.led_control = alarm_led_control,
.buzzer_control = alarm_buzzer_control,
.plot_control = plot_display_control,
/*獲取接口*/
.get_led_status = get_led_status,
.get_buzzer_status = get_buzzer_status,
.get_plot_status = get_plot_status,
.get_smoke_value = get_smoke_value
};
/*注冊傳感器*/
int Sensor_Register(Sensor *sensor_handle)
{
if(NULL == MQ2_Sensor)
{
MQ2_Sensor = sensor_handle ;
if(NULL == MQ2_Sensor)
return -1 ;
else
{
MQ2_Sensor->led_control(MQ2_Sensor, 0);
MQ2_Sensor->buzzer_control(MQ2_Sensor, 0);
MQ2_Sensor->plot_control(MQ2_Sensor, 0);
}
}
return 0 ;
}
(3)曲線傳輸協(xié)議定義
S1 序號 煙感值\r\n
(4)主程序?qū)崿F(xiàn)
int main(void)
{
/* USER CODE BEGIN 1 */
int smoke_value = 0 ;
int serial_number = 0 ;
char procol_buf[20] = {0};
char display_buf[20] = {0};
static uint8_t buzzer_flag = 0;
static uint8_t led_status = 0 ;
static uint8_t plot_status = 0 ;
/* 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_ADC1_Init();
MX_SPI2_Init();
MX_USART1_UART_Init();
MX_TIM16_Init();
/* USER CODE BEGIN 2 */
Sensor_Register(&mq2_sensor_interface);
printf("led_status:%d\n", mq2_sensor_interface.get_led_status(&mq2_sensor_interface));
printf("buzzer_status:%d\n", mq2_sensor_interface.get_buzzer_status(&mq2_sensor_interface));
printf("plot_status:%d\n", mq2_sensor_interface.get_plot_status(&mq2_sensor_interface));
LCD_Init();
LCD_Clear(BLACK);//清屏為黑色
LCD_ShowString(5, 10, 240, 32, 32, "BearPi MQ-2");//顯示字符串,字體大小32*32
Timer_Count = 0 ;
/*設(shè)置曲線顯示*/
mq2_sensor_interface.plot_control(&mq2_sensor_interface, 1);
plot_status = mq2_sensor_interface.get_plot_status(&mq2_sensor_interface);
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
//printf("煙感值:%d\n",mq2_sensor_interface.get_smoke_value(&mq2_sensor_interface));
/*判斷是否100ms到了,該計數(shù)由Systick提供,1ms中斷一次,100次則為100ms*/
if(100 == Timer_Count)
{
Timer_Count = 0 ;
/*流水號自增*/
++serial_number ;
if(serial_number > 65535)
serial_number = 0 ;
smoke_value = mq2_sensor_interface.get_smoke_value(&mq2_sensor_interface) ;
/*當(dāng)煙感值大于600ppm,則報警*/
if(smoke_value > 600)
{
/*這里的buzzer_flag只執(zhí)行一次,避免重復(fù)執(zhí)行*/
if(0 == buzzer_flag)
{
buzzer_flag = 1 ;
mq2_sensor_interface.buzzer_control(&mq2_sensor_interface, 1);
}
led_status = !led_status ;
mq2_sensor_interface.led_control(&mq2_sensor_interface, led_status);
}
else
{
/*這里的buzzer_flag只執(zhí)行一次,避免重復(fù)執(zhí)行*/
if(1 == buzzer_flag)
{
buzzer_flag = 0 ;
mq2_sensor_interface.buzzer_control(&mq2_sensor_interface, 0);
led_status = 0 ;
mq2_sensor_interface.led_control(&mq2_sensor_interface, led_status);
}
}
/*在LCD上顯示煙感值*/
sprintf(display_buf, "%d%d%d%dppm", smoke_value / 1000 % 100, smoke_value / 100 % 10, smoke_value / 10 % 10, smoke_value % 10);
LCD_ShowString(80, 50 + 24 + 32, 240, 32, 32, display_buf); //顯示字符串,字體大小32*32
/*拼接發(fā)送協(xié)議*/
sprintf(procol_buf, "S1 %d%d%d%d%d %d%d%d%d%d",
serial_number / 10000,
serial_number / 1000 % 100 % 10,
serial_number / 100 % 10,
serial_number / 10 % 10,
serial_number % 10,
smoke_value / 10000,
smoke_value / 1000 % 100 % 10,
smoke_value / 100 % 10,
smoke_value / 10 % 10,
smoke_value % 10
);
/*如果曲線標(biāo)志為1,則打印曲線*/
if(1 == plot_status)
printf("%s \r\n", procol_buf);
}
}
/* USER CODE END 3 */
}
5、運(yùn)行效果
曲線顯示
由于上位機(jī)增加了多通道曲線顯示以及其它綜合測試功能,故現(xiàn)在還不能開源,后期等完善全部功能后就會開源。
樣品測試:打火機(jī)氣體(一般采用的是丁烷氣體燃料)、75%酒精
實踐工程下載
公眾號后臺回復(fù):煙感 即可獲取下載鏈接。
公眾號粉絲福利時刻
這里我給大家申請到了福利,本公眾號讀者購買小熊派開發(fā)板可享受9折優(yōu)惠,有需要購買小熊派的朋友,淘寶搜索即可,跟客服說你是公眾號:嵌入式云IOT技術(shù)圈
的粉絲,立享9折優(yōu)惠!
往期精彩
分享一個近期開源火爆全網(wǎng)的額溫槍方案(硬件+源碼)
深圳云之手科技開源炫酷RGB燈板DIY項目
TKM32F499高性能MCU評估板試用之萬事開頭難,先點個燈來壓壓驚!
網(wǎng)紅物聯(lián)網(wǎng)開發(fā)板小熊派使用評測
若覺得本次分享的文章對您有幫助,隨手點[在看]
并轉(zhuǎn)發(fā)分享,也是對我的支持。
免責(zé)聲明:本文內(nèi)容由21ic獲得授權(quán)后發(fā)布,版權(quán)歸原作者所有,本平臺僅提供信息存儲服務(wù)。文章僅代表作者個人觀點,不代表本平臺立場,如有問題,請聯(lián)系我們,謝謝!