(包括4线OLED,Sim800a,Ds18b20,3个模拟IO输入),主要是Sim800a和Ds18b20发生了冲突的样子
这是正常的程序和结果
//毕业设计--基于arduino单片机进行环境检测的系统
#include <SoftwareSerial.h> // 采用软件的串口
//**********************************//
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h> //oled头文件
Adafruit_SSD1306 display(128, 64, &Wire); //设置oled显示范围128*64
//**********************************//
//**********************************//
SoftwareSerial SIM800C(8, 9); // Serial RX, TX//接短信通信模块
int MESSAGE_TIMES=0; //用来控制短消息发送的次数
//**********************************//
//**********************************//
//PM2.5检测模块配置
int PM_AO = A0; //A0口用于数据输入
int PM_ledPower = 2; //2号引脚用于检测模块的指示灯
unsigned int samplingTime = 280;
unsigned int deltaTime = 40;
unsigned int sleepTime = 9680;
int PM_voMeasured = 0; //空气测量指数
float PM_calcVoltage = 0; //实际电压
int PM_PPM = 0; //PM2.5的当前浓度
int PM_WARN_SET=500; //PM2.5浓度预定值
//**********************************//
//*************CH4*********************//
#define CH4_AO A2 //定义端口A1
int CH4_WARN_SET=100; //提前设置CH4的浓度预警值(浓度量化PPM)
int CH4_A=0; //用来存储从CH4检测模块读取的模拟量。
float CH4_voltage=0; //模拟量转换成电压量
int CH4_PPM=0; //粗略的CH4浓度
/*正常情况下(电压为0.1v—0.5v(对应0-100数值)为相对无污染)气体浓度越高,电压值越高。
甲烷的爆炸下限是5%VOL,所以10%LEL的甲烷气体有以下对应关系: 10%LEL=5000ppm=0.5%VOL
天然气的爆炸极限范围是5%-15%,即天然气在空气中浓度小于5%或大于15%均不会爆炸,只有在这个值内遇热源(明火)才会爆炸。
*/
//**************CH4********************//
//*************CO*********************//
#define CO_AO A1 //定义端口A2
int CO_WARN_SET=100; //提前设置CO的浓度预警值(浓度量化PPM)
int CO_A=0; //用来存储从CO检测模块读取的模拟量。
float CO_voltage=0; //模拟量转换成电压量,正常情况下(电压为0.1v—0.5v为相对无污染)气体浓度越高,电压值越高。
int CO_PPM=0; //粗略的CO浓度
/*国家规定一氧化碳浓度达到24PPM可以正常工作,车间空气中CO的最高容许浓度为30mg/m3,报警器通常设置50PPM为警戒线。
*
*/
//*************CO*********************//
//**********************************//
int pwm=255; //电机驱动占空比
int ENA=3; //电机驱动模块使能端
int IN1=5;
int IN2=4;
//**********************************//
//**********************************//
int led_WARN=6; //气体浓度过高报警指示灯(蓝灯)
int led_NORMAL=7; //气体浓度正常指示灯(绿灯)
int BUZZER=10; //蜂鸣器
//**********************************//
//**********************************//
int BLUTOOTH_MODE=0; //用来控制用户是否连接蓝牙状态和未连接时的状态
char BLUTOOTH_MESSAGE=""; //用于接收蓝牙发送的内容
int BLUTOOTH_FLAG=0; //用来标记检测装置在一定的间隔时间向蓝牙用户发送检测数据
//**********************************//
int warning_kind=0;
//**********************************//
int flag_s1,flag_s1_last;
int flag_s2,flag_s2_last;//**********按键检测部分定义****//
int flag_s3,flag_s3_last;
int MODE=0; //用于切换oled显示内容
int S1=11,S2=12,S3=13; //IO口,A0,A1用于检测按键
//**********************************//
//**********************************//
//************************************************************************************************//
//************************************************************************************************//
//取16X16汉字字模 逐行式 顺向高位在前
// 预(0) 定(1) 值(2) 为(3) :(4)
static const unsigned char PROGMEM str0[] =
{0x00,0x00,0xF9,0xFE,0x08,0x20,0x50,0x40,0x21,0xFC,0x11,0x04,0xFD,0x24,0x25,0x24,
0x29,0x24,0x21,0x24,0x21,0x24,0x21,0x44,0x20,0x50,0x20,0x88,0xA1,0x04,0x42,0x02};/*"预",0*/
static const unsigned char PROGMEM str1[] =
{0x02,0x00,0x01,0x00,0x7F,0xFE,0x40,0x02,0x80,0x04,0x00,0x00,0x3F,0xF8,0x01,0x00,
0x01,0x00,0x11,0x00,0x11,0xF8,0x11,0x00,0x11,0x00,0x29,0x00,0x47,0xFE,0x80,0x00};/*"定",1*/
static const unsigned char PROGMEM str2[] =
{0x08,0x40,0x08,0x40,0x0F,0xFC,0x10,0x40,0x10,0x40,0x33,0xF8,0x32,0x08,0x53,0xF8,
0x92,0x08,0x13,0xF8,0x12,0x08,0x13,0xF8,0x12,0x08,0x12,0x08,0x1F,0xFE,0x10,0x00};/*"值",2*/
static const unsigned char PROGMEM str3[] =
{0x01,0x00,0x21,0x00,0x11,0x00,0x11,0x00,0x01,0x00,0x7F,0xF8,0x02,0x08,0x02,0x08,
0x02,0x88,0x04,0x48,0x04,0x48,0x08,0x08,0x10,0x08,0x20,0x08,0x40,0x50,0x80,0x20};/*"为",3*/
static const unsigned char PROGMEM str4[] =
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x30,0x00,0x30,0x00,0x00,0x00,0x30,0x00,0x30,0x00,0x00,0x00,0x00,0x00};/*":",4*/
// 当(5)前(6)浓(7) 度(8) 为(9) :(10)
static const unsigned char PROGMEM str5[] =
{0x01,0x00,0x21,0x08,0x11,0x08,0x09,0x10,0x09,0x20,0x01,0x00,0x7F,0xF8,0x00,0x08,
0x00,0x08,0x00,0x08,0x3F,0xF8,0x00,0x08,0x00,0x08,0x00,0x08,0x7F,0xF8,0x00,0x08};/*"当",5*/
static const unsigned char PROGMEM str6[] =
{0x10,0x10,0x08,0x10,0x08,0x20,0xFF,0xFE,0x00,0x00,0x3E,0x08,0x22,0x48,0x22,0x48,
0x3E,0x48,0x22,0x48,0x22,0x48,0x3E,0x48,0x22,0x08,0x22,0x08,0x2A,0x28,0x24,0x10};/*"前",6*/
static const unsigned char PROGMEM str7[] =
{0x00,0x40,0x20,0x40,0x10,0x40,0x17,0xFC,0x84,0x84,0x48,0x88,0x41,0x40,0x11,0x44,
0x13,0x48,0x25,0x30,0xE9,0x20,0x21,0x10,0x21,0x08,0x21,0x44,0x21,0x82,0x01,0x00};/*"浓",7*/
static const unsigned char PROGMEM str8[] =
{0x01,0x00,0x00,0x80,0x3F,0xFE,0x22,0x20,0x22,0x20,0x3F,0xFC,0x22,0x20,0x22,0x20,
0x23,0xE0,0x20,0x00,0x2F,0xF0,0x24,0x10,0x42,0x20,0x41,0xC0,0x86,0x30,0x38,0x0E};/*"度",8*/
static const unsigned char PROGMEM str9[] =
{0x01,0x00,0x21,0x00,0x11,0x00,0x11,0x00,0x01,0x00,0x7F,0xF8,0x02,0x08,0x02,0x08,
0x02,0x88,0x04,0x48,0x04,0x48,0x08,0x08,0x10,0x08,0x20,0x08,0x40,0x50,0x80,0x20};/*"为",9*/
static const unsigned char PROGMEM str10[] =
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x30,0x00,0x30,0x00,0x00,0x00,0x30,0x00,0x30,0x00,0x00,0x00,0x00,0x00};/*":",10*/
//************************************************************************************************//
//************************************************************************************************//
void setup()
{
// Open serial communications and wait for port to open
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
display.setTextColor(WHITE);//开像素点发光
display.clearDisplay();//清屏
pinMode(led_WARN, OUTPUT); //led初始化,蓝灯-PM2.5浓度大于预定值时亮
pinMode(led_NORMAL, OUTPUT); //led初始化,绿灯-PM2.5浓度小于预定值时亮
pinMode(BUZZER, OUTPUT);
digitalWrite(BUZZER,1);
pinMode(PM_ledPower,OUTPUT); //led初始化,PM2.5检测模块指示灯
pinMode(CH4_AO,INPUT); //CH4浓度检测输入端口
pinMode(CO_AO,INPUT); //CO浓度检测输入端口
pinMode(S1,INPUT_PULLUP); //按键端口初始化
pinMode(S2,INPUT_PULLUP);
pinMode(S3,INPUT_PULLUP);
motor_set(); //电机初始化
Serial.begin(9600); //串口波特率设置
SIM800C.begin(9600); //短信通信模块波特率设置
SIM800C.println("AT+CMGF=1");
while (!Serial)
{
;
}
Serial.println("Good Morning, my old friend!");
delay(100);
display.clearDisplay();
display.setTextSize(2); //设置字体大小
display.setCursor(0, 0);//设置显示位置(列,行)
display.println("welcome");//输出字符
display.setCursor(20, 20);//设置显示位置(列,行)
display.println("to use!");//输出字符
display.display();//开显示
}
void loop()
{
BT_check();//检测蓝牙是否连接到单片机了
// PM_check(); //PM2.5检测
// CO_check(); //CO检测
// CH4_check(); //CH4检测
// display.clearDisplay();
// PM_CO_CH4_TENSE_CHECK_SHOW();
}
//************************************************************************************************//
//************************************************************************************************//
//检测蓝牙连接并检测用户是否想要进行控制风扇排气
void BT_check()
{
BLUTOOTH_MESSAGE="";
if( Serial.available())//接收蓝牙模块发送的字符(用户使用蓝牙控制风扇排风部分)
{
BLUTOOTH_MESSAGE=Serial.read();
Serial.println(BLUTOOTH_MESSAGE);
if(BLUTOOTH_MESSAGE=='A')
{
BLUTOOTH_MODE++;
motor();//启动风扇排风
}
if(BLUTOOTH_MESSAGE=='B')
{
BLUTOOTH_MODE++;
motor_stop();//关闭风扇排风
}
if(BLUTOOTH_MESSAGE=='C')//退出蓝牙指令模式
{
BLUTOOTH_MODE=0;
}
BLUTOOTH_MESSAGE="";
}
else if(BLUTOOTH_MODE==0)//(检测系统自动进行检测PM2.5浓度并且自动排风)
{
function_group();
}
}
//************************************************************************************************//
//************************************************************************************************//
//SIM800a发送英文短消息函数
void SEND_MESSAGE_ENGLISH()
{
//Serial.println("AT+CMGF=1");
SIM800C.println("AT+CMGF=1");
delay(100);
// Serial.println("AT+CSCS=\"GSM\"");
SIM800C.println("AT+CSCS=\"GSM\"");
delay(100);
// Serial.println("AT+CSCA?");
SIM800C.println("AT+CSCA?");
delay(100);
// Serial.println("AT+CSMP=17,167,0,241");
SIM800C.println("AT+CSMP=17,167,0,241");
delay(100);
// Serial.println("AT+CMGS=\"19396354219\"");//电话号码
SIM800C.println("AT+CMGS=\"19396354219\"");//电话号码
delay(100);
// Serial.println("PM2.5:");//发送的内容(英文类型)
SIM800C.println("PM2.5:");//发送的内容(英文类型)
delay(100);
// Serial.println(PM_PPM);//发送的内容(英文类型)
SIM800C.println(PM_PPM);//发送的内容(英文类型)
delay(100);
// Serial.println("CO:");//发送的内容(英文类型)
SIM800C.println("CO:");//发送的内容(英文类型)
delay(100);
// Serial.println(CO_PPM);//发送的内容(英文类型)
SIM800C.println(CO_PPM);//发送的内容(英文类型)
delay(100);
// Serial.println("CH4:");//发送的内容(英文类型)
SIM800C.println("CH4:");//发送的内容(英文类型)
delay(100);
// Serial.println(CH4_PPM);//发送的内容(英文类型)
SIM800C.println(CH4_PPM);//发送的内容(英文类型)
delay(100);
// Serial.println("warning!\r\n");//发送的内容(英文类型)
SIM800C.println("warning!\r\n");//发送的内容(英文类型)
delay(100);
SIM800C.write(0x1A);//发送的时contrl+z的十六进制
}
//************************************************************************************************//
//************************************************************************************************//
//风扇初始化,停止和启动函数
void motor_set()
{
pinMode(IN1,OUTPUT);//IN1,注意:电机驱动模块要和板子共GND。
pinMode(IN2,OUTPUT);//IN2
pinMode(ENA,OUTPUT);//ENA
digitalWrite(IN1,LOW);
digitalWrite(IN2,LOW);
analogWrite(ENA,pwm);
}
void motor()
{
digitalWrite(IN1,1);
digitalWrite(IN2,0);
analogWrite(ENA,pwm);
}
void motor_stop()
{
digitalWrite(IN1,0);
digitalWrite(IN2,0);
analogWrite(ENA,pwm);
}
//************************************************************************************************//
//************************************************************************************************//
//按键检测部分函数
//************************PM2.5的预警值的设置加减****************************//
void PM_key12()
{
if(flag_s1 != flag_s1_last) //检测S1按键
{
if(flag_s1)
{
// Serial.println("S1,on");
Serial.println("S1");
Serial.println(PM_WARN_SET);
}
else
{
PM_WARN_SET+=50; //S1按键用于预定值的 加
}
delay(100);
}
flag_s1_last = flag_s1;
if(flag_s2 != flag_s2_last) //检测S2按键
{
if(flag_s2)
{
//Serial.println("S2,on");
Serial.println("S2");
Serial.println(PM_WARN_SET);
}
else
{
PM_WARN_SET-=50; //S2按键用于预定值的 减
}
delay(100);
}
flag_s2_last = flag_s2;
}
//************************CO的预警值的设置加减****************************//
void CO_key12()
{
if(flag_s1 != flag_s1_last) //检测S1按键
{
if(flag_s1)
{
// Serial.println("S1,on");
Serial.println("S1");
Serial.println(CO_WARN_SET);
}
else
{
CO_WARN_SET+=20; //S1按键用于预定值的 加
}
delay(100);
}
flag_s1_last = flag_s1;
if(flag_s2 != flag_s2_last) //检测S2按键
{
if(flag_s2)
{
//Serial.println("S2,on");
Serial.println("S2");
Serial.println(CO_WARN_SET);
}
else
{
CO_WARN_SET-=20; //S2按键用于预定值的 减
}
delay(100);
}
flag_s2_last = flag_s2;
}
//************************CH4的预警值的设置加减****************************//
void CH4_key12()
{
if(flag_s1 != flag_s1_last) //检测S1按键
{
if(flag_s1)
{
// Serial.println("S1,on");
Serial.println("S1");
Serial.println(CH4_WARN_SET);
}
else
{
CH4_WARN_SET+=20; //S1按键用于预定值的 加
}
delay(100);
}
flag_s1_last = flag_s1;
if(flag_s2 != flag_s2_last) //检测S2按键
{
if(flag_s2)
{
//Serial.println("S2,on");
Serial.println("S2");
Serial.println(CH4_WARN_SET);
}
else
{
CH4_WARN_SET-=20; //S2按键用于预定值的 减
}
delay(100);
}
flag_s2_last = flag_s2;
}
//************************按键检测主程序****************************//
void KEY_check()
{
flag_s1 = digitalRead(S1);//用于读取S1当前状态
flag_s2 = digitalRead(S2);//用于读取S2当前状态
flag_s3 = digitalRead(S3);//用于读取S3当前状态
if(MODE<4)
{
switch(MODE)
{
case 1:PM_key12();
case 2:CO_key12();
case 3:CH4_key12();
}
}
if(flag_s3 != flag_s3_last) //检测S3按键
{
if(flag_s3)
{
// Serial.println("S1,on");
Serial.println("S3");
Serial.println(MODE);
}
else
{
MODE++; //S3按键用于oled显示状态切换
if(MODE>=5)
{
MODE=1;
}
}
delay(100);
}
flag_s3_last = flag_s3;
}
//************************************************************************************************//
//************************************************************************************************//
//oled显示函数
//*************************************PM2.5*******************************************************//
void PM_CO_CH4_TENSE_CHECK_SHOW()
{
//PM2.5:PM_PPM
//CO:CO_PPM
//CH4:CH4_PPM
display.setTextSize(2); //设置字体大小
display.setCursor(0,0);//设置显示位置(列,行)
display.println("PM2.5");//输出字符
display.setTextSize(2); //设置字体大小
display.setCursor(80, 0);//设置显示位置(列,行)
display.println(PM_PPM);//输出字符
display.setTextSize(2); //设置字体大小
display.setCursor(0,20);//设置显示位置(列,行)
display.println("CO");//输出字符
display.setTextSize(2); //设置字体大小
display.setCursor(80, 20);//设置显示位置(列,行)
display.println(CO_PPM);//输出字符
display.setTextSize(2); //设置字体大小
display.setCursor(0,40);//设置显示位置(列,行)
display.println("CH4");//输出字符
display.setTextSize(2); //设置字体大小
display.setCursor(80, 40);//设置显示位置(列,行)
display.println(CH4_PPM);//输出字符
display.display();//开显示
}
//PM2.5预定值(警戒值)为:PM_WARN_SET
void PM_WARN_SET_SHOW()
{
display.setTextSize(2); //设置字体大小
display.setCursor(0, 5);//设置显示位置(列,行)
display.println("PM2.5");//输出字符
display.drawBitmap(70, 5, str0, 16, 16, 1); //画出字符对应点阵数据(列,行,字,16,16,1)
display.drawBitmap(90, 5, str1, 16, 16, 1); //画出字符对应点阵数据
display.drawBitmap(110, 5, str2, 16, 16, 1); //画出字符对应点阵数据
display.drawBitmap(30, 30, str3, 16, 16, 1); //画出字符对应点阵数据
display.drawBitmap(50, 30, str4, 16, 16, 1); //画出字符对应点阵数据
display.setTextSize(2); //设置字体大小
display.setCursor(70, 30);//设置显示位置(列,行)
display.println(PM_WARN_SET);//输出字符
display.display();//开显示
}
//*************************************PM2.5*******************************************************//
//*************************************CO*******************************************************//
//CO预定值(警戒值)为:CO_WARN_SET
void CO_WARN_SET_SHOW()
{
display.setTextSize(2); //设置字体大小
display.setCursor(0, 5);//设置显示位置(列,行)
display.println("CO");//输出字符
display.drawBitmap(40, 5, str0, 16, 16, 1); //画出字符对应点阵数据(列,行,字,16,16,1)
display.drawBitmap(60, 5, str1, 16, 16, 1); //画出字符对应点阵数据
display.drawBitmap(80, 5, str2, 16, 16, 1); //画出字符对应点阵数据
display.drawBitmap(100, 5, str3, 16, 16, 1); //画出字符对应点阵数据
display.drawBitmap(120, 5, str4, 16, 16, 1); //画出字符对应点阵数据
display.setTextSize(2); //设置字体大小
display.setCursor(70, 30);//设置显示位置(列,行)
display.println(CO_WARN_SET);//输出字符
display.display();//开显示
}
//*************************************CO*******************************************************//
//*************************************CH4*******************************************************//
//CH4预定值(警戒值)为:CH4_pre_set
void CH4_WARN_SET_SHOW()
{
display.setTextSize(2); //设置字体大小
display.setCursor(0, 5);//设置显示位置(列,行)
display.println("CH4");//输出字符
display.drawBitmap(40, 5, str0, 16, 16, 1); //画出字符对应点阵数据(列,行,字,16,16,1)
display.drawBitmap(60, 5, str1, 16, 16, 1); //画出字符对应点阵数据
display.drawBitmap(80, 5, str2, 16, 16, 1); //画出字符对应点阵数据
display.drawBitmap(100, 5, str3, 16, 16, 1); //画出字符对应点阵数据
display.drawBitmap(120, 5, str4, 16, 16, 1); //画出字符对应点阵数据
display.setTextSize(2); //设置字体大小
display.setCursor(70,30);//设置显示位置(列,行)
display.println(CH4_WARN_SET);//输出字符
display.display();//开显示
}
//*************************************CH4*******************************************************//
//************************************************************************************************//
//************************************************************************************************//
//PM2.5检测函数
void PM_check()
{
digitalWrite(PM_ledPower,LOW);
delayMicroseconds(samplingTime);
PM_voMeasured = analogRead(PM_AO);
delayMicroseconds(deltaTime);
digitalWrite(PM_ledPower,HIGH);
delayMicroseconds(sleepTime);
PM_PPM= PM_voMeasured;
delay(100);
}
//************************************************************************************************//
//CH4浓度检测
void CH4_check()
{
CH4_A=analogRead(CH4_AO);//0-5v电压对应数字量(0-1023),10位ADC精度读取
CH4_PPM=CH4_A;
}
//************************************************************************************************//
//CO浓度检测
void CO_check()
{
// put your main code here, to run repeatedly:
CO_A=analogRead(CO_AO);//0-5v电压对应数字量(0-1023);
CO_PPM=CO_A;
}
//************************************************************************************************//
//************************************************************************************************//
//设计组程序
void function_group()
{
KEY_check(); //按键检测
switch (MODE)
{
case 1:PM_WARN_SET_SHOW();display.clearDisplay();break; //oled显示PM2.5预定值数据
case 2:CO_WARN_SET_SHOW();display.clearDisplay();break; //oled显示CO预定值数据
case 3:CH4_WARN_SET_SHOW();display.clearDisplay();break; //oled显示CH4预定值数据
case 4:PM_CO_CH4_TENSE_CHECK_SHOW();display.clearDisplay();break;//oled显示PM2.5检测的实际数据
}
if(MODE==4)
{
PM_check(); //PM2.5检测
delay(100);
CO_check(); //CO检测
delay(100);
CH4_check(); //CH4检测
delay(100);
BLUTOOTH_FLAG++;
switch(BLUTOOTH_FLAG)
{
case 2:BLUTOOTH_FLAG=0;Serial.print(" CO浓度:");Serial.print(CO_PPM);
Serial.print(" CH4浓度:");Serial.print(CH4_PPM);
Serial.print(" P.M2.5浓度:");Serial.println(PM_PPM);
break;
}
//*************************************************************//
if((PM_PPM>=PM_WARN_SET)||(CO_PPM>=CO_WARN_SET)||(CH4_PPM>=CH4_WARN_SET))//PM2.5/CO/CH4浓度达到预定值时进行短信报警和启动风扇排风系统
{
MESSAGE_TIMES++;
if(MESSAGE_TIMES==1)
{
SEND_MESSAGE_ENGLISH();//发送短信报警
MESSAGE_TIMES++;
}
digitalWrite(led_NORMAL, LOW); //绿灯指示熄灭
digitalWrite(led_WARN, HIGH); //蓝灯指示报警
digitalWrite(BUZZER,0);
motor();//风扇启动函数
}
if((PM_PPM<PM_WARN_SET)&(CO_PPM<CO_WARN_SET)&(CH4_PPM<CH4_WARN_SET))//判断PM2.5浓度是否小于预定值
{
MESSAGE_TIMES=0;
digitalWrite(led_WARN, LOW); //蓝灯指示熄灭
digitalWrite(led_NORMAL, HIGH); //绿灯指示正常
digitalWrite(BUZZER,1);
motor_stop();//风扇停止函数
}
//*****************************************************//
}
}
加入ds18b20之后
红色部分为新加的
#include <SoftwareSerial.h> // 采用软件的串口
#include <OneWire.h>
#include <DallasTemperature.h>
//**********************************//
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h> //oled头文件
Adafruit_SSD1306 display(128, 64, &Wire); //设置oled显示范围128*64
//**********************************//
// 数据输出脚接开发板数字引脚A3
#define ONE_WIRE_BUS A3
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
float tem=0.0; //用来存读取的温度的值
//**********************************//
SoftwareSerial SIM800C(8, 9); // Serial RX, TX//接短信通信模块
int MESSAGE_TIMES=0; //用来控制短消息发送的次数
//**********************************//
//**********************************//
//PM2.5检测模块配置
int PM_AO = A0; //A0口用于数据输入
int PM_ledPower = 2; //2号引脚用于检测模块的指示灯
unsigned int samplingTime = 280;
unsigned int deltaTime = 40;
unsigned int sleepTime = 9680;
int PM_voMeasured = 0; //空气测量指数
float PM_calcVoltage = 0; //实际电压
int PM_PPM = 0; //PM2.5的当前浓度
int PM_WARN_SET=500; //PM2.5浓度预定值
//**********************************//
//*************CH4*********************//
#define CH4_AO A2 //定义端口A1
int CH4_WARN_SET=100; //提前设置CH4的浓度预警值(浓度量化PPM)
int CH4_A=0; //用来存储从CH4检测模块读取的模拟量。
float CH4_voltage=0; //模拟量转换成电压量
int CH4_PPM=0; //粗略的CH4浓度
/*正常情况下(电压为0.1v—0.5v(对应0-100数值)为相对无污染)气体浓度越高,电压值越高。
甲烷的爆炸下限是5%VOL,所以10%LEL的甲烷气体有以下对应关系: 10%LEL=5000ppm=0.5%VOL
天然气的爆炸极限范围是5%-15%,即天然气在空气中浓度小于5%或大于15%均不会爆炸,只有在这个值内遇热源(明火)才会爆炸。
*/
//**************CH4********************//
//*************CO*********************//
#define CO_AO A1 //定义端口A2
int CO_WARN_SET=100; //提前设置CO的浓度预警值(浓度量化PPM)
int CO_A=0; //用来存储从CO检测模块读取的模拟量。
float CO_voltage=0; //模拟量转换成电压量,正常情况下(电压为0.1v—0.5v为相对无污染)气体浓度越高,电压值越高。
int CO_PPM=0; //粗略的CO浓度
/*国家规定一氧化碳浓度达到24PPM可以正常工作,车间空气中CO的最高容许浓度为30mg/m3,报警器通常设置50PPM为警戒线。
*
*/
//*************CO*********************//
//**********************************//
int pwm=255; //电机驱动占空比
int ENA=3; //电机驱动模块使能端
int IN1=5;
int IN2=4;
//**********************************//
//**********************************//
int led_WARN=6; //气体浓度过高报警指示灯(蓝灯)
int led_NORMAL=7; //气体浓度正常指示灯(绿灯)
int BUZZER=10; //蜂鸣器
//**********************************//
//**********************************//
int BLUTOOTH_MODE=0; //用来控制用户是否连接蓝牙状态和未连接时的状态
char BLUTOOTH_MESSAGE=""; //用于接收蓝牙发送的内容
int BLUTOOTH_FLAG=0; //用来标记检测装置在一定的间隔时间向蓝牙用户发送检测数据
//**********************************//
int warning_kind=0;
//**********************************//
int flag_s1,flag_s1_last;
int flag_s2,flag_s2_last;//**********按键检测部分定义****//
int flag_s3,flag_s3_last;
int MODE=0; //用于切换oled显示内容
int S1=11,S2=12,S3=13; //IO口,A0,A1用于检测按键
//**********************************//
//**********************************//
//************************************************************************************************//
//************************************************************************************************//
//取16X16汉字字模 逐行式 顺向高位在前
// 预(0) 定(1) 值(2) 为(3) :(4)
static const unsigned char PROGMEM str0[] =
{0x00,0x00,0xF9,0xFE,0x08,0x20,0x50,0x40,0x21,0xFC,0x11,0x04,0xFD,0x24,0x25,0x24,
0x29,0x24,0x21,0x24,0x21,0x24,0x21,0x44,0x20,0x50,0x20,0x88,0xA1,0x04,0x42,0x02};/*"预",0*/
static const unsigned char PROGMEM str1[] =
{0x02,0x00,0x01,0x00,0x7F,0xFE,0x40,0x02,0x80,0x04,0x00,0x00,0x3F,0xF8,0x01,0x00,
0x01,0x00,0x11,0x00,0x11,0xF8,0x11,0x00,0x11,0x00,0x29,0x00,0x47,0xFE,0x80,0x00};/*"定",1*/
static const unsigned char PROGMEM str2[] =
{0x08,0x40,0x08,0x40,0x0F,0xFC,0x10,0x40,0x10,0x40,0x33,0xF8,0x32,0x08,0x53,0xF8,
0x92,0x08,0x13,0xF8,0x12,0x08,0x13,0xF8,0x12,0x08,0x12,0x08,0x1F,0xFE,0x10,0x00};/*"值",2*/
static const unsigned char PROGMEM str3[] =
{0x01,0x00,0x21,0x00,0x11,0x00,0x11,0x00,0x01,0x00,0x7F,0xF8,0x02,0x08,0x02,0x08,
0x02,0x88,0x04,0x48,0x04,0x48,0x08,0x08,0x10,0x08,0x20,0x08,0x40,0x50,0x80,0x20};/*"为",3*/
static const unsigned char PROGMEM str4[] =
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x30,0x00,0x30,0x00,0x00,0x00,0x30,0x00,0x30,0x00,0x00,0x00,0x00,0x00};/*":",4*/
// 当(5)前(6)浓(7) 度(8) 为(9) :(10)
static const unsigned char PROGMEM str5[] =
{0x01,0x00,0x21,0x08,0x11,0x08,0x09,0x10,0x09,0x20,0x01,0x00,0x7F,0xF8,0x00,0x08,
0x00,0x08,0x00,0x08,0x3F,0xF8,0x00,0x08,0x00,0x08,0x00,0x08,0x7F,0xF8,0x00,0x08};/*"当",5*/
static const unsigned char PROGMEM str6[] =
{0x10,0x10,0x08,0x10,0x08,0x20,0xFF,0xFE,0x00,0x00,0x3E,0x08,0x22,0x48,0x22,0x48,
0x3E,0x48,0x22,0x48,0x22,0x48,0x3E,0x48,0x22,0x08,0x22,0x08,0x2A,0x28,0x24,0x10};/*"前",6*/
static const unsigned char PROGMEM str7[] =
{0x00,0x40,0x20,0x40,0x10,0x40,0x17,0xFC,0x84,0x84,0x48,0x88,0x41,0x40,0x11,0x44,
0x13,0x48,0x25,0x30,0xE9,0x20,0x21,0x10,0x21,0x08,0x21,0x44,0x21,0x82,0x01,0x00};/*"浓",7*/
static const unsigned char PROGMEM str8[] =
{0x01,0x00,0x00,0x80,0x3F,0xFE,0x22,0x20,0x22,0x20,0x3F,0xFC,0x22,0x20,0x22,0x20,
0x23,0xE0,0x20,0x00,0x2F,0xF0,0x24,0x10,0x42,0x20,0x41,0xC0,0x86,0x30,0x38,0x0E};/*"度",8*/
static const unsigned char PROGMEM str9[] =
{0x01,0x00,0x21,0x00,0x11,0x00,0x11,0x00,0x01,0x00,0x7F,0xF8,0x02,0x08,0x02,0x08,
0x02,0x88,0x04,0x48,0x04,0x48,0x08,0x08,0x10,0x08,0x20,0x08,0x40,0x50,0x80,0x20};/*"为",9*/
static const unsigned char PROGMEM str10[] =
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x30,0x00,0x30,0x00,0x00,0x00,0x30,0x00,0x30,0x00,0x00,0x00,0x00,0x00};/*":",10*/
//************************************************************************************************//
//************************************************************************************************//
void setup()
{
// Open serial communications and wait for port to open
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
display.setTextColor(WHITE);//开像素点发光
display.clearDisplay();//清屏
pinMode(led_WARN, OUTPUT); //led初始化,蓝灯-PM2.5浓度大于预定值时亮
pinMode(led_NORMAL, OUTPUT); //led初始化,绿灯-PM2.5浓度小于预定值时亮
pinMode(BUZZER, OUTPUT);
digitalWrite(BUZZER,1);
pinMode(PM_ledPower,OUTPUT); //led初始化,PM2.5检测模块指示灯
pinMode(CH4_AO,INPUT); //CH4浓度检测输入端口
pinMode(CO_AO,INPUT); //CO浓度检测输入端口
pinMode(S1,INPUT_PULLUP); //按键端口初始化
pinMode(S2,INPUT_PULLUP);
pinMode(S3,INPUT_PULLUP);
motor_set(); //电机初始化
Serial.begin(9600); //串口波特率设置
sensors.begin(); //温度
SIM800C.begin(9600); //短信通信模块波特率设置
SIM800C.println("AT+CMGF=1");
while (!Serial)
{
;
}
Serial.println("Good Morning, my old friend!");
delay(100);
display.clearDisplay();
display.setTextSize(2); //设置字体大小
display.setCursor(0, 0);//设置显示位置(列,行)
display.println("welcome");//输出字符
display.setCursor(20, 20);//设置显示位置(列,行)
display.println("to use!");//输出字符
display.display();//开显示
}
void loop()
{
BT_check();//检测蓝牙是否连接到单片机了
// PM_check(); //PM2.5检测
// CO_check(); //CO检测
// CH4_check(); //CH4检测
// display.clearDisplay();
// PM_CO_CH4_TENSE_CHECK_SHOW();
}
//************************************************************************************************//
//************************************************************************************************//
//检测蓝牙连接并检测用户是否想要进行控制风扇排气
void BT_check()
{
BLUTOOTH_MESSAGE="";
if( Serial.available())//接收蓝牙模块发送的字符(用户使用蓝牙控制风扇排风部分)
{
BLUTOOTH_MESSAGE=Serial.read();
Serial.println(BLUTOOTH_MESSAGE);
if(BLUTOOTH_MESSAGE=='A')
{
BLUTOOTH_MODE++;
motor();//启动风扇排风
}
if(BLUTOOTH_MESSAGE=='B')
{
BLUTOOTH_MODE++;
motor_stop();//关闭风扇排风
}
if(BLUTOOTH_MESSAGE=='C')//退出蓝牙指令模式
{
BLUTOOTH_MODE=0;
}
BLUTOOTH_MESSAGE="";
}
else if(BLUTOOTH_MODE==0)//(检测系统自动进行检测PM2.5浓度并且自动排风)
{
function_group();
}
}
//************************************************************************************************//
//************************************************************************************************//
//SIM800a发送英文短消息函数
void SEND_MESSAGE_ENGLISH()
{
//Serial.println("AT+CMGF=1");
SIM800C.println("AT+CMGF=1");
delay(100);
// Serial.println("AT+CSCS=\"GSM\"");
SIM800C.println("AT+CSCS=\"GSM\"");
delay(100);
// Serial.println("AT+CSCA?");
SIM800C.println("AT+CSCA?");
delay(100);
// Serial.println("AT+CSMP=17,167,0,241");
SIM800C.println("AT+CSMP=17,167,0,241");
delay(100);
// Serial.println("AT+CMGS=\"19396354219\"");//电话号码
SIM800C.println("AT+CMGS=\"19396354219\"");//电话号码
delay(100);
// Serial.println("PM2.5:");//发送的内容(英文类型)
SIM800C.println("PM2.5:");//发送的内容(英文类型)
delay(100);
// Serial.println(PM_PPM);//发送的内容(英文类型)
SIM800C.println(PM_PPM);//发送的内容(英文类型)
delay(100);
// Serial.println("CO:");//发送的内容(英文类型)
SIM800C.println("CO:");//发送的内容(英文类型)
delay(100);
// Serial.println(CO_PPM);//发送的内容(英文类型)
SIM800C.println(CO_PPM);//发送的内容(英文类型)
delay(100);
// Serial.println("CH4:");//发送的内容(英文类型)
SIM800C.println("CH4:");//发送的内容(英文类型)
delay(100);
// Serial.println(CH4_PPM);//发送的内容(英文类型)
SIM800C.println(CH4_PPM);//发送的内容(英文类型)
delay(100);
// Serial.println("warning!\r\n");//发送的内容(英文类型)
SIM800C.println("warning!\r\n");//发送的内容(英文类型)
delay(100);
SIM800C.write(0x1A);//发送的时contrl+z的十六进制
}
//************************************************************************************************//
//************************************************************************************************//
//风扇初始化,停止和启动函数
void motor_set()
{
pinMode(IN1,OUTPUT);//IN1,注意:电机驱动模块要和板子共GND。
pinMode(IN2,OUTPUT);//IN2
pinMode(ENA,OUTPUT);//ENA
digitalWrite(IN1,LOW);
digitalWrite(IN2,LOW);
analogWrite(ENA,pwm);
}
void motor()
{
digitalWrite(IN1,1);
digitalWrite(IN2,0);
analogWrite(ENA,pwm);
}
void motor_stop()
{
digitalWrite(IN1,0);
digitalWrite(IN2,0);
analogWrite(ENA,pwm);
}
//************************************************************************************************//
//************************************************************************************************//
//按键检测部分函数
//************************PM2.5的预警值的设置加减****************************//
void PM_key12()
{
if(flag_s1 != flag_s1_last) //检测S1按键
{
if(flag_s1)
{
// Serial.println("S1,on");
Serial.println("S1");
Serial.println(PM_WARN_SET);
}
else
{
PM_WARN_SET+=50; //S1按键用于预定值的 加
}
delay(100);
}
flag_s1_last = flag_s1;
if(flag_s2 != flag_s2_last) //检测S2按键
{
if(flag_s2)
{
//Serial.println("S2,on");
Serial.println("S2");
Serial.println(PM_WARN_SET);
}
else
{
PM_WARN_SET-=50; //S2按键用于预定值的 减
}
delay(100);
}
flag_s2_last = flag_s2;
}
//************************CO的预警值的设置加减****************************//
void CO_key12()
{
if(flag_s1 != flag_s1_last) //检测S1按键
{
if(flag_s1)
{
// Serial.println("S1,on");
Serial.println("S1");
Serial.println(CO_WARN_SET);
}
else
{
CO_WARN_SET+=20; //S1按键用于预定值的 加
}
delay(100);
}
flag_s1_last = flag_s1;
if(flag_s2 != flag_s2_last) //检测S2按键
{
if(flag_s2)
{
//Serial.println("S2,on");
Serial.println("S2");
Serial.println(CO_WARN_SET);
}
else
{
CO_WARN_SET-=20; //S2按键用于预定值的 减
}
delay(100);
}
flag_s2_last = flag_s2;
}
//************************CH4的预警值的设置加减****************************//
void CH4_key12()
{
if(flag_s1 != flag_s1_last) //检测S1按键
{
if(flag_s1)
{
// Serial.println("S1,on");
Serial.println("S1");
Serial.println(CH4_WARN_SET);
}
else
{
CH4_WARN_SET+=20; //S1按键用于预定值的 加
}
delay(100);
}
flag_s1_last = flag_s1;
if(flag_s2 != flag_s2_last) //检测S2按键
{
if(flag_s2)
{
//Serial.println("S2,on");
Serial.println("S2");
Serial.println(CH4_WARN_SET);
}
else
{
CH4_WARN_SET-=20; //S2按键用于预定值的 减
}
delay(100);
}
flag_s2_last = flag_s2;
}
//************************按键检测主程序****************************//
void KEY_check()
{
flag_s1 = digitalRead(S1);//用于读取S1当前状态
flag_s2 = digitalRead(S2);//用于读取S2当前状态
flag_s3 = digitalRead(S3);//用于读取S3当前状态
if(MODE<4)
{
switch(MODE)
{
case 1:PM_key12();
case 2:CO_key12();
case 3:CH4_key12();
}
}
if(flag_s3 != flag_s3_last) //检测S3按键
{
if(flag_s3)
{
// Serial.println("S1,on");
Serial.println("S3");
Serial.println(MODE);
}
else
{
MODE++; //S3按键用于oled显示状态切换
if(MODE>=5)
{
MODE=1;
}
}
delay(100);
}
flag_s3_last = flag_s3;
}
//************************************************************************************************//
//************************************************************************************************//
//oled显示函数
//*************************************PM2.5*******************************************************//
void PM_CO_CH4_TENSE_CHECK_SHOW()
{
//PM2.5:PM_PPM
//CO:CO_PPM
//CH4:CH4_PPM
display.setTextSize(2); //设置字体大小
display.setCursor(0,0);//设置显示位置(列,行)
display.println("PM2.5");//输出字符
display.setTextSize(2); //设置字体大小
display.setCursor(80, 0);//设置显示位置(列,行)
display.println(PM_PPM);//输出字符
display.setTextSize(2); //设置字体大小
display.setCursor(0,20);//设置显示位置(列,行)
display.println("CO");//输出字符
display.setTextSize(2); //设置字体大小
display.setCursor(80, 20);//设置显示位置(列,行)
display.println(CO_PPM);//输出字符
display.setTextSize(2); //设置字体大小
display.setCursor(0,40);//设置显示位置(列,行)
display.println("CH4");//输出字符
display.setTextSize(2); //设置字体大小
display.setCursor(80, 40);//设置显示位置(列,行)
display.println(CH4_PPM);//输出字符
display.display();//开显示
}
//PM2.5预定值(警戒值)为:PM_WARN_SET
void PM_WARN_SET_SHOW()
{
display.setTextSize(2); //设置字体大小
display.setCursor(0, 5);//设置显示位置(列,行)
display.println("PM2.5");//输出字符
display.drawBitmap(70, 5, str0, 16, 16, 1); //画出字符对应点阵数据(列,行,字,16,16,1)
display.drawBitmap(90, 5, str1, 16, 16, 1); //画出字符对应点阵数据
display.drawBitmap(110, 5, str2, 16, 16, 1); //画出字符对应点阵数据
display.drawBitmap(30, 30, str3, 16, 16, 1); //画出字符对应点阵数据
display.drawBitmap(50, 30, str4, 16, 16, 1); //画出字符对应点阵数据
display.setTextSize(2); //设置字体大小
display.setCursor(70, 30);//设置显示位置(列,行)
display.println(PM_WARN_SET);//输出字符
display.display();//开显示
}
//*************************************PM2.5*******************************************************//
//*************************************CO*******************************************************//
//CO预定值(警戒值)为:CO_WARN_SET
void CO_WARN_SET_SHOW()
{
display.setTextSize(2); //设置字体大小
display.setCursor(0, 5);//设置显示位置(列,行)
display.println("CO");//输出字符
display.drawBitmap(40, 5, str0, 16, 16, 1); //画出字符对应点阵数据(列,行,字,16,16,1)
display.drawBitmap(60, 5, str1, 16, 16, 1); //画出字符对应点阵数据
display.drawBitmap(80, 5, str2, 16, 16, 1); //画出字符对应点阵数据
display.drawBitmap(100, 5, str3, 16, 16, 1); //画出字符对应点阵数据
display.drawBitmap(120, 5, str4, 16, 16, 1); //画出字符对应点阵数据
display.setTextSize(2); //设置字体大小
display.setCursor(70, 30);//设置显示位置(列,行)
display.println(CO_WARN_SET);//输出字符
display.display();//开显示
}
//*************************************CO*******************************************************//
//*************************************CH4*******************************************************//
//CH4预定值(警戒值)为:CH4_pre_set
void CH4_WARN_SET_SHOW()
{
display.setTextSize(2); //设置字体大小
display.setCursor(0, 5);//设置显示位置(列,行)
display.println("CH4");//输出字符
display.drawBitmap(40, 5, str0, 16, 16, 1); //画出字符对应点阵数据(列,行,字,16,16,1)
display.drawBitmap(60, 5, str1, 16, 16, 1); //画出字符对应点阵数据
display.drawBitmap(80, 5, str2, 16, 16, 1); //画出字符对应点阵数据
display.drawBitmap(100, 5, str3, 16, 16, 1); //画出字符对应点阵数据
display.drawBitmap(120, 5, str4, 16, 16, 1); //画出字符对应点阵数据
display.setTextSize(2); //设置字体大小
display.setCursor(70,30);//设置显示位置(列,行)
display.println(CH4_WARN_SET);//输出字符
display.display();//开显示
}
//*************************************CH4*******************************************************//
//************************************************************************************************//
//************************************************************************************************//
//PM2.5检测函数
void PM_check()
{
digitalWrite(PM_ledPower,LOW);
delayMicroseconds(samplingTime);
PM_voMeasured = analogRead(PM_AO);
delayMicroseconds(deltaTime);
digitalWrite(PM_ledPower,HIGH);
delayMicroseconds(sleepTime);
PM_PPM= PM_voMeasured;
}
//************************************************************************************************//
//CH4浓度检测
void CH4_check()
{
CH4_A=analogRead(CH4_AO);//0-5v电压对应数字量(0-1023),10位ADC精度读取
CH4_PPM=CH4_A;
}
//************************************************************************************************//
//CO浓度检测
void CO_check()
{
// put your main code here, to run repeatedly:
CO_A=analogRead(CO_AO);//0-5v电压对应数字量(0-1023);
CO_PPM=CO_A;
}
//************************************************************************************************//
//************************************************************************************************//
//设计组程序
void function_group()
{
KEY_check(); //按键检测
switch (MODE)
{
case 1:PM_WARN_SET_SHOW();display.clearDisplay();break; //oled显示PM2.5预定值数据
case 2:CO_WARN_SET_SHOW();display.clearDisplay();break; //oled显示CO预定值数据
case 3:CH4_WARN_SET_SHOW();display.clearDisplay();break; //oled显示CH4预定值数据
// case 4:PM_CO_CH4_TENSE_CHECK_SHOW(); delay(500);display.clearDisplay();break;//oled显示PM2.5检测的实际数据
}
if(MODE==4)
{
PM_check(); //PM2.5检测
delay(10);
CO_check(); //CO检测
delay(10);
CH4_check(); //CH4检测
delay(10);
BLUTOOTH_FLAG++;
switch(BLUTOOTH_FLAG)
{
case 10:BLUTOOTH_FLAG=0;
PM_CO_CH4_TENSE_CHECK_SHOW();display.clearDisplay();
Serial.print(" CO浓度:");Serial.print(CO_PPM);
Serial.print(" CH4浓度:");Serial.print(CH4_PPM);
Serial.print(" P.M2.5浓度:");Serial.println(PM_PPM);
tempreyure_get();break;
}
//*************************************************************//
if((PM_PPM>=PM_WARN_SET)||(CO_PPM>=CO_WARN_SET)||(CH4_PPM>=CH4_WARN_SET))//PM2.5/CO/CH4浓度达到预定值时进行短信报警和启动风扇排风系统
{
MESSAGE_TIMES++;
if(MESSAGE_TIMES==1)
{
SEND_MESSAGE_ENGLISH();//发送短信报警
MESSAGE_TIMES++;
}
digitalWrite(led_NORMAL, LOW); //绿灯指示熄灭
digitalWrite(led_WARN, HIGH); //蓝灯指示报警
digitalWrite(BUZZER,0);
motor();//风扇启动函数
}
if((PM_PPM<PM_WARN_SET)&(CO_PPM<CO_WARN_SET)&(CH4_PPM<CH4_WARN_SET))//判断PM2.5浓度是否小于预定值
{
MESSAGE_TIMES=0;
digitalWrite(led_WARN, LOW); //蓝灯指示熄灭
digitalWrite(led_NORMAL, HIGH); //绿灯指示正常
digitalWrite(BUZZER,1);
motor_stop();//风扇停止函数
}
//*****************************************************//
}
}
//****************************温度读取**************************//
void tempreyure_get(void)
{
sensors.requestTemperatures(); // 发送命令获取温度
tem=sensors.getTempCByIndex(0);
Serial.print("Temperature: ");
Serial.println(tem);
delay(100);
}
//****************************温度读取**************************//
出现程序卡死了,但编译正常
这是ds18b20的程序
#include <OneWire.h>
#include <DallasTemperature.h>
// 数据输出脚接开发板数字引脚A3
#define ONE_WIRE_BUS A3
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
float tem=0.0;
void setup(void)
{
Serial.begin(9600);
sensors.begin();
}
void loop()
{
tempreyure_get();
}
void tempreyure_get(void)
{
sensors.requestTemperatures(); // 发送命令获取温度
tem=sensors.getTempCByIndex(0);
Serial.print("Temperature: ");
Serial.println(tem);
delay(100);
}
单个的程序都没有问题。
经过调试很久解决不了呀,无法了,球球了