/*程序: 本程序目的是实现环境实时监控以及操作自动化,分为自动化和蓝牙控制两部分
操作自动化部分包括:1、温度大于30自动开启风扇
2、土壤湿度小于300水泵自动加水
3、亮度系数小于150打开补光灯
3、超过以上限度开启警示灯
蓝牙部分:用app inventor设计软件通过蓝牙控制使不在限制条件下手动控制用电器开关。包括:开启(关闭)风扇、水泵、补光灯、警示灯、门
其他部分:12864OLED显示温度、湿度、MQ(烟雾)、亮度系数等*/
- #include <SPI.h>
- #include <SoftwareSerial.h>
- #include <Wire.h>
- #include <Adafruit_GFX.h>
- #include <Adafruit_SSD1306.h>
- #include <dht.h>
- #include <Servo.h>
- dht DHT;
- #define LOGO16_GLCD_HEIGHT 16 //定义显示高度
- #define LOGO16_GLCD_WIDTH 16 //定义显示宽度
- //#define YELLOW 1 //黄灯警报闪烁端口1
- #define GREEN 2 //绿灯警报闪烁端口2
- #define DUOJI 3 //舵机pwn端口口3
- #define OLED_RESET 4 //OLED复位端口4
- #define YELLOW 5 //烟雾端口5
- #define FAN 6 //风扇端口6(pwn口 具体修改)
- #define DHT22_PIN 7 //温湿度端口7
- #define PUMP 8 //水泵端口8
- #define HLED 9 //高光食人鱼LED端口9
- #define RED 12 //红灯警报闪烁端口12
- #define analogMoistue 0 //读取蓝牙监测信息读取端口0
- int TSignal=A0; //土壤信息端口A0
- int MQ=analogRead(A1); //烟雾信息端口A1
- int BSignal=A2; //亮度模块端口A2
- int ck003 = 155; //亮度系数
- int turang = 300; //土壤湿度系数
- //int bluetooth=0; //定义蓝牙接入开关
- //char android=' ';
- int is_auto =1;
- int time_count;
- Servo myservo;
- SoftwareSerial I2CBT(10,11);
- byte serialA;
- Adafruit_SSD1306 display(OLED_RESET);
- static const unsigned char PROGMEM str_1[] =
- {
- 0x00,0x08,0x43,0xFC,0x32,0x08,0x12,0x08,
- 0x83,0xF8,0x62,0x08,0x22,0x08,0x0B,0xF8,
- 0x10,0x00,0x27,0xFC,0xE4,0xA4,0x24,0xA4,
- 0x24,0xA4,0x24,0xA4,0x2F,0xFE,0x20,0x00,
- };//温
- static const unsigned char PROGMEM str_2[] =
- {
- 0x01,0x00,0x00,0x84,0x3F,0xFE,0x22,0x20,
- 0x22,0x28,0x3F,0xFC,0x22,0x20,0x23,0xE0,
- 0x20,0x00,0x2F,0xF0,0x22,0x20,0x21,0x40,
- 0x20,0x80,0x43,0x60,0x8C,0x1E,0x30,0x04,
- }; // 度
- static const unsigned char PROGMEM str_3[] =
- {
- 0x00,0x08,0x47,0xFC,0x34,0x08,0x14,0x08,
- 0x87,0xF8,0x64,0x08,0x24,0x08,0x0F,0xF8,
- 0x11,0x20,0x21,0x20,0xE9,0x24,0x25,0x28,
- 0x23,0x30,0x21,0x24,0x3F,0xFE,0x20,0x00,
- }; //湿
- static const unsigned char PROGMEM str_4[] =
- {
- 0x60,0x00,0x91,0xF4,0x96,0x0C,0x6C,0x04,0x08,0x04,0x18,0x00,0x18,0x00,0x18,0x00,
- 0x18,0x00,0x18,0x00,0x18,0x00,0x08,0x00,0x0C,0x04,0x06,0x08,0x01,0xF0,0x00,0x00
- }; //(℃)
- static const unsigned char PROGMEM str_5[] =
- {
- 0x00,0x00,0x00,0x00,0x70,0x00,0xD8,0x00,0xDA,0x00,0x76,0x00,0x0C,0x00,0x18,0x00,
- 0x30,0x00,0x6E,0x00,0x5B,0x00,0x1B,0x00,0x0E,0x00,0x00,0x00,0x00,0x00,0x00,0x00
- }; //(%)
- #if (SSD1306_LCDHEIGHT != 64)
- #error("Height incorrect, please fix Adafruit_SSD1306.h!"); //OLED显示分高度
- #endif
- void setup()
- {
- myservo.attach(DUOJI);
- pinMode(FAN,OUTPUT);
- pinMode(PUMP,OUTPUT);
- pinMode(HLED,OUTPUT);
- pinMode(RED,OUTPUT);
- pinMode(YELLOW,OUTPUT);
- pinMode(GREEN,OUTPUT);
- pinMode(TSignal,INPUT);
- pinMode(BSignal,INPUT);
- digitalWrite(FAN,LOW);
- digitalWrite(PUMP,LOW);
- digitalWrite(HLED,LOW); ;
- digitalWrite(RED,LOW);
- digitalWrite(YELLOW,LOW);
- digitalWrite(GREEN,LOW);
- Serial.begin(9600); //输出比特率
- I2CBT.begin(9600); //蓝牙传输比特率
- display.begin(SSD1306_SWITCHCAPVCC, 0x3C); //OLED显示起始地址位
- display.clearDisplay();
- }
- void loop()
- {
- time_count+=1;
- oled_display();
- byte Data[3]; //显示温度
- byte cmmd[20];
- int insize;
- char str[256];
- int i=(int)(DHT.temperature*10);
- //serialA=I2CBT.read();
- Data[0]='a';
- Data[1]=i/256;
- Data[2]=i%256;
- if(is_auto==1)
- {
- AUTOFAN();
- AUTOBRIGHTNESS();
- AUTOPUMP();
- AUTOJINGGAO();
- AUTOYELLOW ();
- AUTOGREEN ();
- }
- if((insize=(I2CBT.available()))>0)
- {
- is_auto=0; //关闭自动控制
- time_count=0;
- Serial.print("蓝牙数据字节数 = ");
- Serial.println(insize);
- for (int i=0; i<insize; i++)
- {
- Serial.print(cmmd[i]=char(I2CBT.read()),i);
- Serial.print("\n");
- }
- }
- else
- {
- cmmd[0]='z';
- if(time_count>3000)
- {
- is_auto=1;
- }
- }
- switch(cmmd[0]) //读取第一个字节
- {case 49:
- Serial.println(DHT.temperature);
- I2CBT.write(Data[0]);
- I2CBT.write(Data[1]);
- I2CBT.write(Data[2]);
- break;
- case 'g': digitalWrite(RED, HIGH); break; //'g'开警示灯
- case 'h': digitalWrite(RED, LOW); break; //‘h’关警示灯
- case 'k': analogWrite(FAN,255); break; //'k'开风扇
- case 'l': analogWrite(FAN,0); break; //‘l’关风扇
- case 'i': myservo.write(0); break; //'i'开门
- case 'j': myservo.write(90); break; //‘j’关门
- case 'e': digitalWrite(PUMP,HIGH);
- delay(5000); digitalWrite(PUMP,LOW); break; //'e'开水泵
- // case 'f': digitalWrite(PUMP,LOW); break; //‘f’关水泵
- case 'c': digitalWrite(HLED,HIGH); break; //'i'开补光灯
- case 'd': digitalWrite(HLED,LOW); break; //‘d’关补光灯
- case 'b': is_auto=1; break; //‘b’开启自动化
- case 'z': break; //直接退出
- default: is_auto=1;
- }
- }
- void oled_display()
- {
- int chk = DHT.read22(DHT22_PIN); //读取DH22数据
- display.setTextSize(1); //设置字体大小
- display.setTextColor(WHITE); //设置字体颜色白色
- display.setCursor(0,0); //设置字体的起始位置
- display.drawBitmap(0, 20, str_1, 16, 16, 1); //在坐标X:0 Y:20的位置显示中文字符温
- display.drawBitmap(18, 20, str_2, 16, 16, 1); //在坐标X:42 Y:16的位置显示中文字符度
- display.drawBitmap(80, 20, str_4, 16, 16,1); //在坐标X:42 Y:16的位置显示中文字符℃
- display.setCursor(36,25); //设置字体的起始位置(36,25)
- display.setTextSize(1); //设置字体大小为1
- display.print(":"); //显示符号“:”
- display.println((float)DHT.temperature, 2); //显示实时温度
- display.drawBitmap(0, 40, str_3, 16, 16, 1); //在坐标X:0 Y:40的位置显示中文字符湿
- display.drawBitmap(18, 40, str_2, 16, 16, 1); //在坐标X:18 Y:40的位置显示中文字符度
- display.drawBitmap(80, 40, str_5, 16, 16, 1); //在坐标X:80 Y:40的位置显示中文字符%
- display.setCursor(36,45); //设置字体的起始位置(36,25)
- display.setTextSize(1); //设置字体大小为1
- display.print(":"); //显示符号“:”
- display.println((float)DHT.humidity, 2); //显示实时湿度
- display.setCursor(5,5); //设置字体的起始位置(5,5)
- display.setTextSize(1); //设置字体大小为1
- display.println("MQ-2:"); //输出字符"MQ-2:"并换行
- display.setCursor(33,5); //设置字体的起始位置(5,5)
- display.println(analogRead(A1),1); //显示模拟口A1的数据并换行
- display.display(); //把缓存的都显示
- display.clearDisplay();
- }
- void AUTOFAN()
- {
- if(DHT.temperature>30)
- {
- analogWrite(FAN,255); //温度大于30℃打开风扇
- }
- else if(DHT.temperature<30)
- {
- analogWrite(FAN,0); //温度小于30℃关闭风扇
- }
- }
- void AUTOPUMP() //如土壤湿度不足开启水泵自动加水
- {
- Serial.print("土壤湿度:");
- Serial.println(analogRead(A0));
- if(analogRead(A0) < turang)
- {
- digitalWrite(PUMP,HIGH);
- }
- else if(analogRead(A0) > turang)
- {
- digitalWrite(PUMP,LOW);
- }
- }
- void AUTOJINGGAO() //红灯警告
- {
- if((analogRead(TSignal) < turang)) //判断水是否足够,不足则闪烁,足够则不闪烁
- {
- digitalWrite(RED, HIGH);
- delay(300);
- digitalWrite(RED, LOW);
- delay(300);
- }
- else if((analogRead(TSignal) > turang))
- {
- digitalWrite(RED,LOW);
- }
- }
- void AUTOYELLOW ()
- {
- if(DHT.temperature>30) //判断水是否足够,不足则闪烁,足够则不闪烁
- {
- digitalWrite(YELLOW, HIGH);
- delay(300);
- digitalWrite(YELLOW, LOW);
- delay(300);
- }
- else if(DHT.temperature<30)
- {
- digitalWrite(YELLOW,LOW);
- }
- }
- void AUTOGREEN()
- {
- if(analogRead(BSignal) < ck003) //判断水是否足够,不足则闪烁,足够则不闪烁
- {
- digitalWrite(GREEN, HIGH);
- delay(300);
- digitalWrite(GREEN, LOW);
- delay(300);
- }
- else if(analogRead(BSignal) > ck003)
- {
- digitalWrite(GREEN,LOW);
- }
- }
- void AUTOBRIGHTNESS() //光度不够时增加亮度呼吸灯
- {
- Serial.print("光度系数:");
- Serial.println(analogRead(BSignal));
- if(analogRead(BSignal) < ck003)
- {
- digitalWrite(HLED,HIGH);
- delay(500);
- }
- else if(analogRead(BSignal) > ck003)
- {
- digitalWrite(HLED,LOW);
- }
- delay(500);
- }
复制代码
/*
app inventor 部分
组间设计:
逻辑设计:
初始化
蓝牙准备与选择
各种用电器
获取数据
App inventor上述aia文件 (无密码)
App inventor 可用网站 app.gzjkw点net/login/
问题:1、无法通过蓝牙控制用电器
2、程序划线部分无法在arduino串口监视器中观察到由Android输入的数据
思考(这样思考是不是正确的):1、arduino是由收到Android手机发送的文本开控制IO口的电位拉高或者置低。接受Android收的文本指令传到串口,我们要做的就是读取串口的数据(Serial .read),再输出指令并执行(Serial .println)。(即划线部分)问题在于打开串口监视器无法观察到由Android端接受的指令。
2、显示器不在自动化与蓝牙模式之内。是否可以用中断来减低运存(仅思想,首要解决第一个问题)。
*/
全部资料51hei下载地址:
arduino211.7z
(1.68 MB, 下载次数: 71)
|