技能梳理20@stm32+ESP8266+onenet+dht11+mq2+led+风扇+oled

221 阅读3分钟

F103C8T6 ESP8266和ONENET通信 DHT11测温湿度 MQ-2测烟雾浓度 LED模拟室内灯 温湿度和烟雾超标,蜂鸣器报警,风扇转动;OLED显示数据;数据传输onenet,控制LED灯和风扇

1、项目简介

在这里插入图片描述

2、实现逻辑

在这里插入图片描述

3、应用场景

#远程检测室内环境
#厨房灭火

4、核心代码梳理

//stm32程序
/* USER CODE BEGIN 0 */
//smoke
void MQ2_PPM_Calibration(float RS)
{
    R0 = RS / pow(CAL_PPM / 613.9f, 1 / -2.074f);
}

float MQ2_GetPPM(void)
{

    float Vrl = 3.3f * ADC_num / 4095.f;
    float RS = (3.3f - Vrl) / Vrl * RL;
    if(HAL_GetTick() < 10000)
    {
        MQ2_PPM_Calibration(RS);
    }
    float ppm = 613.9f * pow(RS/R0, -2.074f);
    return  ppm;
}

//temp hump
void DHT11_IO_IN(void) {
    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.Pin = DHT11_Pin;
    GPIO_InitStructure.Mode = GPIO_MODE_INPUT;
    HAL_GPIO_Init(GPIOA,&GPIO_InitStructure);
}

void DHT11_IO_OUT(void) {
    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.Pin = DHT11_Pin;
    GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH;
    HAL_GPIO_Init(GPIOA,&GPIO_InitStructure);
}

void DHT11_Rst(void) {
    DHT11_IO_OUT(); 	//
    DHT11_DQ_OUT_LOW; 	//
    HAL_Delay(20);    	//
    DHT11_DQ_OUT_HIGH; 	//
    delay_us(30);     	//
}

uint8_t DHT11_Check(void) {
    uint8_t retry=0;
    DHT11_IO_IN();
    while (DHT11_DQ_IN && retry<100) {
        retry++;
        delay_us(1);
    };
    if(retry>=100)return 1;
    else retry=0;
    while (!DHT11_DQ_IN&&retry<100) {
        retry++;
        delay_us(1);
    };
    if(retry>=100)return 1;
    return 0;	//???DHT11??0
}

uint8_t DHT11_Read_Bit(void) {
    uint8_t retry=0;
    while(DHT11_DQ_IN&&retry<100) {
        retry++;
        delay_us(1);
    }
    retry=0;
    while(!DHT11_DQ_IN&&retry<100) {
        retry++;
        delay_us(1);
    }
    delay_us(40);
    if(DHT11_DQ_IN)return 1;
    else return 0;
}

uint8_t DHT11_Read_Byte(void) {
    uint8_t i,dat;
    dat=0;
    for (i=0; i<8; i++) {
        dat<<=1;
        dat|=DHT11_Read_Bit();
    }
    return dat;
}

uint8_t DHT11_Read_Data(uint16_t *temp,uint16_t *humi) {
    uint8_t buf[5];
    uint8_t i;
    DHT11_Rst();
    if(DHT11_Check()==0) {
        for(i=0; i<5; i++) {
            buf[i]=DHT11_Read_Byte();
        }
        if((buf[0]+buf[1]+buf[2]+buf[3])==buf[4]) {
            *humi=(buf[0]<<8) + buf[1];
            *temp=(buf[2]<<8) + buf[3];
        }
    } else return 1;
    return 0;
}

uint8_t DHT11_Init(void) {
    DHT11_Rst();
    return DHT11_Check();
}

/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
    /* USER CODE BEGIN 1 */
    uint16_t clk;
    tx_nbiot[0] = 0xff;
    tx_nbiot[1] = 0x74;
    tx_nbiot[13] = 0xff;
    /* 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();
    HAL_Delay(5000);
    MX_USART1_UART_Init();
    MX_I2C1_Init();
    /* USER CODE BEGIN 2 */
    OLED_Init();			//初始化OLED
    OLED_Clear();
    OLED_ShowString(0,0,"TEMP:    .    C",12);
    OLED_ShowString(0,2,"HUMP:    .    %",12);
    OLED_ShowString(0,4,"MQ2:     .   ppm",12);
    OLED_ShowString(0,6,"LED:   MOTOR:   ",12);
    //OLED_ShowNum(39,4,9999,4,12);
    //OLED_ShowNum(80,4,12,2,12);
    while(DHT11_Init()) {
        HAL_Delay(500);
    }

    __HAL_UART_ENABLE_IT(&huart1,UART_IT_RXNE);//open uart1 RXNE

    /* USER CODE END 2 */

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

        /* USER CODE BEGIN 3 */
        //OLED_Clear();
        clk++;


//nbiot receive
        if(rx_ok)
        {
            //rx_order++;
            rx_ok = 0;
            if(rx_order == 1)//open led
            {
                HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_RESET);
                OLED_ShowString(35,6,"O",12);
                led_sta = rx_order;
            }
            else if(rx_order == 2)//close led
            {
                HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_SET);
                OLED_ShowString(35,6,"X",12);
                led_sta = rx_order;
            }
            else if(rx_order == 3)//open motor
            {
                HAL_GPIO_WritePin(MOTOR_GPIO_Port, MOTOR_Pin, GPIO_PIN_RESET);
                OLED_ShowString(105,6,"O",12);
                motor_sta = rx_order;
            }
            else if(rx_order == 4)//close motor
            {
                HAL_GPIO_WritePin(MOTOR_GPIO_Port, MOTOR_Pin, GPIO_PIN_SET);
                OLED_ShowString(105,6,"X",12);
                motor_sta = rx_order;
            }
            else if(rx_order == 5)//open beep
            {
                beep_sta = 0;
            }
            else if(rx_order == 6)//close beep
            {
                beep_sta = 1;
            }
        }
//send nbiot/display
        if(clk % 20 == 0) //1s -- 10
        {
            //check smoke
            HAL_ADC_Start_IT(&hadc1);
            check_smoke = MQ2_GetPPM();


            intS = (int)check_smoke;
            float tmp = check_smoke-intS;
            decS = tmp * 100;
            OLED_ShowNum(39,4,intS,4,12);
            OLED_ShowNum(80,4,decS,2,12);

            //check  temp hump
            DHT11_Read_Data(&temperature,&humidity);
            OLED_ShowNum(39,0,temperature>>8,4,12);
            OLED_ShowNum(80,0,temperature&0xff,2,12);
            OLED_ShowNum(39,2,humidity>>8,4,12);
            OLED_ShowNum(80,2,humidity&0xff,2,12);
            //printf("DHT11 Temperature = %d.%d degree\r\n",temperature>>8,temperature&0xff);
            //printf("DHT11 Humidity = %d.%d%%\r\n",humidity>>8,humidity&0xff);

            tx_nbiot[2] = temperature>>8;
            tx_nbiot[3] = temperature&0xff;
            tx_nbiot[4] = humidity>>8;
            tx_nbiot[5] = humidity&0xff;
            tx_nbiot[6] = intS / 256;
            tx_nbiot[7] = intS % 256;
            tx_nbiot[8] = decS;
            tx_nbiot[9] = led_sta;
            tx_nbiot[10] = motor_sta;
            tx_nbiot[11] = alarm_sta;
            tx_nbiot[12] = beep_sta + 5;


            HAL_UART_Transmit(&huart1, (uint8_t *)tx_nbiot, 14, 0xFFFF);

            //alarm
            temp = tx_nbiot[2];
            hump = tx_nbiot[4];
            smoke = check_smoke;
            if((temp > 40) || (hump > 50))
            {
//                HAL_GPIO_WritePin(GPIOA, BEEP_Pin, GPIO_PIN_RESET); //active
//						HAL_GPIO_WritePin(MOTOR_GPIO_Port, MOTOR_Pin, GPIO_PIN_RESET); //active

                alarm_dht = 1;
            }
            else
            {
                //  HAL_GPIO_WritePin(GPIOA, BEEP_Pin, GPIO_PIN_SET);
                alarm_dht = 0;
            }

            if(smoke > 300)//fan+beep
            {
                alarm_smoke = 1;
								motor_sta = 3;
                HAL_GPIO_WritePin(MOTOR_GPIO_Port, MOTOR_Pin, GPIO_PIN_RESET);
            }
            else if(smoke < 100)//NO ACTIVE
            {
                alarm_smoke = 0;
                //motor_sta = 4;
                //HAL_GPIO_WritePin(MOTOR_GPIO_Port, MOTOR_Pin, GPIO_PIN_SET);
                //OLED_ShowString(105,6,"X",12);
            }
            else //30-300 fan
            {
                alarm_smoke = 0;
                motor_sta = 3;
                HAL_GPIO_WritePin(MOTOR_GPIO_Port, MOTOR_Pin, GPIO_PIN_RESET);
                OLED_ShowString(105,6,"O",12);
            }


            if(alarm_dht || alarm_smoke)//beep
            {
                if(beep_sta == 0)
                    HAL_GPIO_WritePin(GPIOA, BEEP_Pin, GPIO_PIN_RESET); //active
								else HAL_GPIO_WritePin(GPIOA, BEEP_Pin, GPIO_PIN_SET);
                alarm_sta = 7;
            }
            else
            {
                HAL_GPIO_WritePin(GPIOA, BEEP_Pin, GPIO_PIN_SET);
                alarm_sta = 8;
            }
        }

        HAL_Delay(100);

    }
    /* USER CODE END 3 */
}



//lua脚本
myClient = mqtt.Client(DeviceId, KeepAlive, ProductId, AuthoTnfo)
--print("115200 8-n-1")
uart.setup(0, 115200, 8, uart.PARITY_NONE, uart.STOPBITS_1, 0)

        
timer1 = tmr.create()

timer2 = tmr.create()
 
function ReConnect()
    if wifi.sta.getip() == nil then
        --print("Connect AP,waitting...")
    else
        --print("Connected AP,Success!")
        --print("IP is:"..wifi.sta.getip())
        --print("MAC address:"..wifi.sta.getmac())
        timer1:stop()
 
        myClient:connect(host, port, function(client)
           -- print("Connected OneNET success!")
            gpio.write(pin,gpio.LOW) 
        end)
        
       
        uart.on("data", function(data) 
            cnt = string.len(data)
            timer1.stop(1)
            timer1.interval(1, 1)
            timer1.start(1)
            --uart.write(0, data)
            --print("len:",string.len(data))
            ---print(type(data))
            if(cnt == 13) then
                cnt = 0
                if(string.find(data,"t") == 1) then
                    --print("t!") 
                    --print(string.byte(data,2))
                    --print(string.byte(data,3)/100)
                    TEM = string.byte(data,2) + string.byte(data,3)/100
                    HUM = string.byte(data,4) + string.byte(data,5)/100
                    SMOKE = string.byte(data,6)*256 + string.byte(data,7)+ string.byte(data,8)/100
                    LED = string.byte(data,9)
                    MOTOR = string.byte(data,10)
					ALARM_STA = string.byte(data,11)
					BEEP_STA = string.byte(data,12)
                end
            end
            Update_Message()
        end, 0)
        
        myClient:on("message", function(client , topic , message)
            --print("get a message.\n")
            --print(topic..":"..message)
        print("order:"..message)
        end)
 
        --timer2:alarm(3000, tmr.ALARM_AUTO, Update_Message)
    end
end
 
timer1:alarm(1000,tmr.ALARM_AUTO,ReConnect)


     
function Update_Message()
    info = {}
    info.tem = TEM
    info.hum = HUM
    info.smoke = SMOKE
    info.led = LED
    info.motor = MOTOR
	info.alarm = ALARM_STA
    info.beep = BEEP_STA 
 
    --TEM = TEM + 1
    --HUM = HUM - 1
    --SMOKE = SMOKE + 0.1
    ok,message = pcall(cjson.encode, info)
    --print("message:"..message)
 
    header = string.char(3, 0 ,string.len(message))..message
    myClient:publish("$dp", header, 0, 0, function(client)
        --print("Publish info success!")
    end)
end

5、部分参考资料

ESP8266开发板NodeMCU 资料:
链接: pan.baidu.com/s/1n8gJToN1… 提取码: ni62
NodeMCU 烧录固件教程:www.cnblogs.com/0pen1/p/125…
DHT11温湿度教程
www.jianshu.com/p/3aba3ce1a…
学习资料免费下载:链接: pan.baidu.com/s/1TRTU1f-3… 提取码: vttk
其他软件链接: pan.baidu.com/s/1YZZ3Gvjq… 提取码:28uc
0.96寸OLED资料:新版本资料下载链接:pan.baidu.com/s/13_WpuJZD… 提取码: 2frr

esp8266官网:www.nodemcu.com/index_cn.ht…

脚本下载参考:www.bigiot.net/help/20.htm…

太极创客:www.taichi-maker.com/homepage/es…

LUA脚本语言学习:blog.csdn.net/DEEP_M/arti…
blog.csdn.net/FourLeafClo…
菜鸟:www.runoob.com/lua/lua-tut…
语言基础:www.jianshu.com/p/5927eae24…
nodemcu.readthedocs.io/en/latest/u…
连接onenet:blog.csdn.net/zwb_5782091…
串口透传:www.jianshu.com/p/df339cfed…
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

6、注意事项

#涉及到onenet端和线下谁控制设备优先级高的问题需要关注一下
#其它和之前项目的注意事项差不多

完整可运行项目地址