/*程序: 本程序目的是實現環境實時監控以及操作自動化,分為自動化和藍牙控制兩部分
操作自動化部分包括: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、顯示器不在自動化與藍牙模式之內。是否可以用中斷來減低運存(僅思想,首要解決第一個問題)。
*/
0.png (43.31 KB, 下載次數: 78)
下載附件
2018-5-29 23:29 上傳
全部資料51hei下載地址:
arduino211.7z
(1.68 MB, 下載次數: 72)
2018-5-29 23:12 上傳
點擊文件名下載附件
包括源碼和額外庫文件 下載積分: 黑幣 -5
|