画板子,有至少8个io口(分别连ds18b20传感器、烟雾传感器、CO传感器,后三个传感器检测到发高电平),两个串口,一个蜂鸣器,nbiot用的YED-C724 核心板(AIR724) 后改为基于esp8266的nodemcu
1、项目简介
2、实现逻辑
#配置好esp8266,烧录好nodemcu固件,编写lua脚本,识别固定协议的数据onenet #通过adc检测烟雾值(mq2) #检测CO(MQ7) #检测火灾情况(红外传感器) #检测ds18b20测温 #分析参数,判断是否符合蜂鸣器报警条件 #发送参数onenet(通过nodemcu),自动发送每5秒一次 #oled显示每个状态参数 #如果 烟雾>=1000 ‖ co>=1000 ‖ 温度>=50 ‖ 检测到红外,蜂鸣器提示,否则不响 #远端网页版加红外情况:放开关检测红外开关变化on,反之off。 #火灾情况,放开关,烟雾>=1000 ‖ co>=1000 ‖ 温度>=50 ‖ 如果检测到红外,如果这串结果是1开关变化
3、应用场景
4.梳理核心代码
//stm32程序 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_smoke / 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; } void MQ7_PPM_Calibration(float RS) { R0_CO = RS / pow(CAL_PPM_CO / 98.322, 1 / -); } // 获取传感器的值 float MQ7_GetPPM(void) { float Vrl = 33.3f * ADC_num_co/ 4095.f; Vrl = ( (float)( (int)( (Vrl+0.005)*100 ) ) )/100; float RS_CO = (3.3f - Vrl) / Vrl * RL; if(HAL_GetTick() < 10000) { MQ7_PPM_Calibration(RS_CO); } float ppm = 98.322f * pow(RS_CO/R0_CO, -1.458f); return ppm; } //复位DS18B20 void DS18B20_Rst(void) { HAL_GPIO_WritePin(DS18B20_GPIO_Port,DS18B20_Pin,GPIO_PIN_RESET); //拉低DQ delay_us(750); //拉低750us HAL_GPIO_WritePin(DS18B20_GPIO_Port,DS18B20_Pin,GPIO_PIN_SET); //DQ=1 delay_us(15); //15US } //等待DS18B20的回应 //返回1:未检测到DS18B20的存在 //返回0:存在 uint8_t DS18B20_Check(void) { uint8_t retry=0; //SET PB1 INPUT while (HAL_GPIO_ReadPin(DS18B20_GPIO_Port,DS18B20_Pin) && retry<200) { retry++; delay_us(1); }; if(retry>=200)return 1; else retry=0; while (!HAL_GPIO_ReadPin(DS18B20_GPIO_Port,DS18B20_Pin)&&retry<240) { retry++; delay_us(1); }; if(retry>=240)return 1; return 0; } //从DS18B20读取一个位 //返回值:1/0 uint8_t DS18B20_Read_Bit(void) // read one bit { uint8_t data; HAL_GPIO_WritePin(DS18B20_GPIO_Port,DS18B20_Pin,GPIO_PIN_RESET); delay_us(2); HAL_GPIO_WritePin(DS18B20_GPIO_Port,DS18B20_Pin,GPIO_PIN_SET); delay_us(12); if(HAL_GPIO_ReadPin(DS18B20_GPIO_Port,DS18B20_Pin))data=1; else data=0; delay_us(50); return data; } //从DS18B20读取一个字节 //返回值:读到的数据 uint8_t DS18B20_Read_Byte(void) // read one byte { uint8_t i,j,dat; dat=0; for (i=1; i<=8; i++) { j=DS18B20_Read_Bit(); dat=(j<<7)|(dat>>1); } return dat; } //写一个字节到DS18B20 //dat:要写入的字节 void DS18B20_Write_Byte(uint8_t dat) { uint8_t j; uint8_t testb; for (j=1; j<=8; j++) { testb=dat&0x01; dat=dat>>1; if (testb) { HAL_GPIO_WritePin(DS18B20_GPIO_Port,DS18B20_Pin,GPIO_PIN_RESET);// Write 1 delay_us(2); HAL_GPIO_WritePin(DS18B20_GPIO_Port,DS18B20_Pin,GPIO_PIN_SET); delay_us(60); } else { HAL_GPIO_WritePin(DS18B20_GPIO_Port,DS18B20_Pin,GPIO_PIN_RESET);// Write 0 delay_us(60); HAL_GPIO_WritePin(DS18B20_GPIO_Port,DS18B20_Pin,GPIO_PIN_SET); delay_us(2); } } } //开始温度转换 void DS18B20_Start(void)// ds1820 start convert { DS18B20_Rst(); DS18B20_Check(); DS18B20_Write_Byte(0xcc);// skip rom DS18B20_Write_Byte(0x44);// convert } //初始化DS18B20的IO口 DQ 同时检测DS的存在 //返回1:不存在 //返回0:存在 uint8_t DS18B20_Init(void) { DS18B20_Rst(); return DS18B20_Check(); } //从ds18b20得到温度值 //精度:0.1C //返回值:温度值 (-550~1250) float DS18B20_Get_Temp(void) { uint8_t temp; uint8_t TL,TH; short tem; float return_tem; DS18B20_Start(); // ds1820 start convert DS18B20_Rst(); DS18B20_Check(); DS18B20_Write_Byte(0xcc);// skip rom DS18B20_Write_Byte(0xbe);// convert TL=DS18B20_Read_Byte(); // LSB TH=DS18B20_Read_Byte(); // MSB if(TH>7) { TH=~TH; TL=~TL; temp=0;//温度为负 } else temp=1;//温度为正 tem=TH; //获得高八位 tem<<=8; tem+=TL;//获得底八位 return_tem = (float)tem*0.625;//转换 if(temp)return return_tem; //返回温度值 else return -return_tem; } /* 向onenet平台发数据函数 * return 1 ok; 0 fail */ uint8_t send_onenet(void) { char text[200]; uint8_t len; memset(text, 0, sizeof(text)); //组包 memset(text, 0, sizeof(text)); sprintf(text, "{\"id\": 123,\"dp\": {\"SMOKE\": [{\"v\": %.2f}],\"FIRE\": [{\"v\": %d}],\"RED\": [{\"v\": %d}],\"TEMP\": [{\"v\": %.2f}],\"CO\": [{\"v\": %.2f}]}}",check_smoke, fire_sta, red_sta, check_temp, check_co); //封包 len = strlen(text); HAL_UART_Transmit(&huart1, (uint8_t *)text, len, 0xFFFF); //发送 return 1; } /* USER CODE END 0 */ /** * @brief The application entry point. * @retval int */ int main(void) { /* USER CODE BEGIN 1 */ uint16_t clk, adcBuf[3]; 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(); MX_USART1_UART_Init(); MX_USART3_UART_Init(); /* USER CODE BEGIN 2 */ OLED_Init(); OLED_ColorTurn(0);// OLED_DisplayTurn(0);// OLED_Refresh(); OLED_Clear(); OLED_ShowString(0,0,"TEMP: . C",12); OLED_ShowString(0,10,"CO: . PPM",12); OLED_ShowString(0,20,"SMO: . PPM",12); OLED_ShowString(0,30,"RED: ",12); OLED_ShowString(0,40,"FIRE: ",12); OLED_Refresh(); //__HAL_UART_ENABLE_IT(&huart1,UART_IT_RXNE);//open uart1 RXNE HAL_Delay(100); HAL_GPIO_WritePin(GPIOA, BEEP_Pin, GPIO_PIN_SET); DS18B20_Init(); /* 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; } //send nbiot/display if(clk % 20 == 0) //1s -- 10 { //check smoke //HAL_ADC_Start_IT(&hadc1); for(uint8_t i=0; i<3; i++) { HAL_ADC_Start(&hadc1); HAL_ADC_PollForConversion(&hadc1,0xffff); adcBuf[i]=HAL_ADC_GetValue(&hadc1); } ADC_num_smoke = adcBuf[0]; ADC_num_co = adcBuf[1]; ADC_num_fire = adcBuf[2]; check_smoke = MQ2_GetPPM(); intS = (int)check_smoke; float tmp = check_smoke-intS; decS = tmp * 100; OLED_ShowNum(25,20,intS,6,12); OLED_ShowNum(72,20,decS,2,12); //check CO //10ppm - 10000ppm check_co = MQ7_GetPPM(); intCO = (int)check_co; float tmpC0 = check_co-intCO; decCO = tmpC0 * 100; OLED_ShowNum(25,10,intCO,6,12); OLED_ShowNum(72,10,decCO,2,12); // OLED_ShowNum(39,2,CO>>8,4,12); // OLED_ShowNum(80,2,CO&0xff,2,12); //check fire if(HAL_GPIO_ReadPin(GPIOA,FIRE_DO_Pin)) { red_sta = 0; OLED_ShowString(55,30,"NO ",12); } else { red_sta = 1; OLED_ShowString(55,30,"YES",12); } //check DS18B20 check_temp = DS18B20_Get_Temp()/10; intT = (int)check_temp; /*合成实际温度整数部分****精度相对上面的更高*/ float tem_tmp = check_temp-intT; /*合成实际温度小数部分*/ decT = tem_tmp*100; OLED_ShowNum(40,0,intT,2,12); OLED_ShowNum(60,0,decT,2,12); tx_nbiot[2] = decT; tx_nbiot[3] = tem_tmp; tx_nbiot[4] = CO>>8; tx_nbiot[5] = CO&0xff; tx_nbiot[6] = intS / 256; tx_nbiot[7] = intS % 256; tx_nbiot[8] = decS; tx_nbiot[9] = fire_sta; // tx_nbiot[10] = motor_sta; // tx_nbiot[11] = alarm_sta; // tx_nbiot[12] = beep_sta + 5; //alarm temp = tx_nbiot[2]; hump = tx_nbiot[4]; smoke = check_smoke; if((temp > 40) || (CO > 50)) { } else { } if(smoke > 300) { alarm_smoke = 1; } else if(smoke < 100) { alarm_smoke = 0; } else //30-300 fan { alarm_smoke = 0; } if(alarm_smoke || fire_sta) alarm_sta = 1; else alarm_sta = 0; if(alarm_sta)//beep { // HAL_GPIO_WritePin(GPIOA, BEEP_Pin, GPIO_PIN_RESET); //active } else { // HAL_GPIO_WritePin(GPIOA, BEEP_Pin, GPIO_PIN_SET); } if(check_smoke>=1000 || check_co>=1000 || check_temp>=50 || red_sta)//check_smoke, fire_sta, red_sta, check_temp, check_co fire_sta = 1; else fire_sta = 0; if(!fire_sta) { OLED_ShowString(55,40,"NO ",12); HAL_GPIO_WritePin(GPIOA, BEEP_Pin, GPIO_PIN_SET); } else { OLED_ShowString(55,40,"YES",12); HAL_GPIO_WritePin(GPIOA, BEEP_Pin, GPIO_PIN_RESET); //active } } if(clk % 50 == 0) //1s -- 10 { send_onenet();//tx onenet data } HAL_Delay(100); OLED_Refresh(); } /* USER CODE END 3 */ } //lua脚本 cfg = { } cfg.ssid = "esp8266" cfg.pwd = "esp8266test" wifi.setmode(wifi.STATIONAP) wifi.sta.config(cfg) wifi.sta.connect() DeviceId = "704xxx0230" ProductId ="41xxx85" AuthoTnfo = "96jNf6YzxxxxxSznrgULsQ=" KeepAlive = 200 host = "183.230.40.39" port = 6002 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