2023 年 馬來西亞 itex
作品報告
科別:普通科
班級:普科114級頂大班
作品名稱: 植物保母——智慧盆栽
(“Plant-Nanny”——The Smart Flowerpot)
組員: 施亮岑、顏佑翰、李昱錩
殷紹茗、吳晨瑄、張粲禾、曾楉童
1
內容
一、摘要
二、動機與目的
三、設備及器材
四、原理與過程
A.繼電器
B.土壤感測器
C.ESP8266
D.DHT11
E.Blynk
F.非接觸式水位感測器
G.光敏電阻和邏輯閘74LS32
H.邏輯閘
I.程式碼
K、 電路圖及介面
五、結論
六、競賽紀錄
2
3
3
4
6
6
6
7
8
8
9
9
10
10
17
17
19
一、摘要
現代生活節奏快速,許多植物愛好者常因上班、旅行等等的原因長時間無法親自
照顧植物,而為了忘記澆水、植物曬傷、養分不足等問題而煩惱。為了解決此類
問題,我們設計了「植物保母」,跟隨科技的腳步,利用物聯網、設計APP遠端監
控,不僅能自動澆水,也可偵測濕度、光度,並呈現在手機監控程式上,即使水箱
空了、光照過強,也會立即通知到手機上,APP上會同步亮起警示燈,盡其所能
讓一切便利、自動化。為了避免植物光照不足,我們在盆栽上方增設燈條,讓喜
日照植物在陰、雨天也能照光,甚至在植物有狀況時會亮不一樣的警示燈,讓使
用者得以知道植物狀況。在環保及永續發展的層面上,我們也在燈條上增設兼太
陽能板的行動電源,且透過特殊設計,讓裝置可進行魚菜共生系統,形成良性循
環,在滿足自身愛好的同時,也能為地球貢獻一份心力。
二、動機與目的
養殖花卉是不少人的愛好,但現代的快節奏生活卻讓人們太過勞累,想要享受植
物的綻放的美好卻又不想花太多心力去照顧,導致常常忘記澆水,也可能在長途
跋涉的旅行過後,回到家卻發現花朵已經枯萎,令心血功虧一簣。又或許是想養
花,卻怕不會照料,擔心水澆太多、太少,怕光線不夠、養分不足,導致遲遲不敢
踏出養殖的第一步。而氣候變遷,溫室效應等等,例如炙熱烈陽或傾盆大雨,也
讓許多植被無法負荷,死在環境的衝擊下。
為了解決此類問題,我們設計了「植物保母」,跟隨科技的腳步,利用物聯網、設
計APP遠端監控,不僅能自動澆水,也可偵測濕度、光度,即使水箱空了,也會立
即通知到手機上,並增設太陽能板,盡其所能讓一切便利化。環保上,我們透過
特殊設計,讓裝置可進行魚菜共生系統,形成良性循環,在滿足自身愛好的同時
,也能為地球貢獻一份心力。
希望在日常生活中已疲勞不勘或是想嘗試「沾花惹草」的人們,在使用我們的產
品後,都能結合科技,用最少的力量,養出最優秀的植物同時,亦能做到環保。
3
三、設備及器材
設備
規格
功能
電腦
自組電腦
程式及報告撰寫
手機
Samsung J4
連接blynk
基本工具組
基本工具
配置電路時所需的工具
焊錫
未標示
焊接所需材料
烙鐵
120V/30w
焊接開發板
吸錫器
未標示
吸收多餘的焊錫
行動電源
2.1A / 1A
提供電源
熱熔膠
100-240V/40W
固定器材
資料來源:研究者自行繪製
4
材料
規格
數量
8266開發版(圖3-1)
ESP-8266
1
繼電器
5V
4
DHT11
10A
1
杜邦線
不限
不限
單芯線
不限
不限
非接觸水位感測器
5V
1
抽水馬達
5V
1
光敏電阻
5V
1
邏輯閘74LS32
5V
1
土壤感測器
5V
1
日光燈
5V
1
按鈕
5V
2
盆栽
直徑17cm 高11cm
1
水箱
15*22*21 cm
1
發泡煉石
8L
1包
資料來源:研究者自行繪製
5
四、原理與過程
A.繼電器
繼電器(圖A-1)是一種電子控制器件,它是由電磁鐵和彈簧開關組合成的電子器
件,讓你可以用電的訊號來控制磁場,進而控制彈簧開關的開關。由圖A-1,可以
得知它是利用電磁鐵流過電流後所產生的磁性,去控制CA、CB的開路與通路,
藉由這個特性,我們可以輕易的控制電器的開與關。並且控制CA、CB是利用小
電流通過所產生的磁場,導通大電流的迴路,這樣具有保護電路和轉換電路的功
能。
圖A-2 繼電器運作原理
B.土壤感測器
我們都知道除了純水之外,由於水含有雜質所以會導電,所以土壤感測器的運作
原理(圖B-2)就是監測他兩端金屬片接觸到水時的導電度轉匯為濕度透過S腳位
6
進而傳送資料到開發版上,假如濕度過低則會啟動抽水馬達將水箱裡水抽上來。
圖B-2 土壤感測器接腳圖
C.ESP8266
ESP8266它擁有完整的Wi-Fi系統,能夠獨立運作
,也能配合其他開發板來使用,只需要透過
SPI/SDIO接口或I2C/UART的連接,就可以協同
運作。它同時具備濾波器、放大器和電源管理方案,所以外部電路不需太過複雜
即可形成一個簡易的系統。
圖C-1為8266開發板接腳圖
7
D.DHT11
DHT11可以分為兩個部分來檢測溫度和濕度,他是利用電阻來檢測濕度 ,
並利用熱敏電阻(NTC)來監測溫度,且DHT11內建八個微處理器(MCU) ,並把資
料統整後將資料透過資訊腳(DATA)傳輸在開發版上。
E.Blynk
8
blynk是一個新生的網絡服務平台,通過其他不同平台的條件來決定是否執行下
一條命令, 即對網絡服務通過其他網絡服務作出反應。我們利用blynk將盆栽與
手機連結,讓我們的APP和裝置能有效連動。
F.非接觸式水位感測器
智慧型非接觸式液位感應器是利用水的感應電容來檢測是否有液體存在,在沒
有液體接近感應器時,感應器上由於分佈電容的存在,因此感應器對地存在一定
的靜態電容,當液面慢慢升高接近感應器時,液體的寄生電容將耦合到這個靜態
電容上,使感應器的最終電容值變大,該變化的電容信號再輸入到控制IC進行信
號轉換,將變化的電容量轉換成某種電信號的變化量,再由一定的演算法來檢測
和判斷這個變化量的程度,當這個變化量超過一定的閾值時就認為液位到達感
應點。
G.光敏電阻和邏輯閘74LS32
光敏電阻又稱光電阻、光導體、光導管,是利用光電導效應的一種特
殊的電阻,它的電阻和入射光的強弱有直接關係。光強度增加,則電
9
阻減小;光強度減小,則電阻增大。
它被廣泛的應用在低成本的光感元件,比如說攝影用的測光計、火
災及煙霧警報器、 防盜警報器、工業上控制電路中或者是燈具的自
動開關上。
H.邏輯閘
是在積體電路上的基本組件。簡單的邏輯閘可由電晶體組成。這些電晶體的組合
可以使代表兩種訊號的高低電平在通過它們之後產生高電平或者低電平的訊
號。高、低電平可以分別代表邏輯上的「真」與「假」或二進位當中的1和0,從而實
現邏輯運算。常見的邏輯閘包括與閘,或閘,非閘,互斥或閘(也稱:互斥或)等
等。
邏輯閘是組成數字系統的基本結構,通常組合使用實現更為複雜的邏輯運算。一
些廠商通過邏輯閘的組合生產一些實用、小型、集成的產品,例如可程式邏輯裝
置等。
I.程式碼
#define BLYNK_TEMPLATE_ID "TMPL6cQJT-I8k"
#define BLYNK_TEMPLATE_NAME "plant nanny"
#define BLYNK_AUTH_TOKEN "1wttCRgtXjxIQyq_wxwHZZKcQMLsjsm7"
// Your WiFi credentials.
// Set password to "" for open networks.
char ssid[] = "";
char pass[] = "";
bool fetch_blynk_state = true; //true or false
//#define BLYNK_PRINT Serial
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <DHT.h>
#include <AceButton.h>
using namespace ace_button;
#define DHTPIN
0 //D3 pin connected with DHT
10
// Uncomment whatever type you're using!
#define DHTTYPE DHT11 // DHT 11
//#define DHTTYPE DHT22 // DHT 22, AM2302, AM2321
//#define DHTTYPE DHT21 // DHT 21, AM2301
// define the GPIO connected with Relays and switches
#define RelayPin1 16 //D0
#define RelayPin2 5 //D1
#define SwitchPin1 3 //RX
#define SwitchPin2 13 //D7
#define wifiLed 2 //D4
//Change the virtual pins according the rooms
#define VPIN_BUTTON_1 V1
#define VPIN_BUTTON_2 V2
#define VPIN_TEMPERATURE V3
#define VPIN_HUMIDITY V4
#define VPIN_WATER
V5
#define VPIN_SOIL
V6
// Relay State
bool toggleState_1 = LOW; //Define integer to remember the toggle state for relay 1
bool toggleState_2 = LOW; //Define integer to remember the toggle state for relay 2
int water_level = 0;
int soil_moisture = 0;
const int water_level1 = 14;
const int soil_moisture1 = 12;
int wifiFlag = 0;
float temperature1 = 0;
float humidity1 = 0;
char auth[] = BLYNK_AUTH_TOKEN;
ButtonConfig config1;
AceButton button1(&config1);
ButtonConfig config2;
AceButton button2(&config2);
void handleEvent1(AceButton*, uint8_t, uint8_t);
11
void handleEvent2(AceButton*, uint8_t, uint8_t);
BlynkTimer timer;
DHT dht(DHTPIN, DHTTYPE);
// When App button is pushed - switch the state
BLYNK_WRITE(VPIN_BUTTON_1) {
toggleState_1 = param.asInt();
digitalWrite(RelayPin1, !toggleState_1);
}
BLYNK_WRITE(VPIN_BUTTON_2) {
toggleState_2 = param.asInt();
digitalWrite(RelayPin2, !toggleState_2);
}
void all_SwitchOff(){
toggleState_1 = 1; digitalWrite(RelayPin1, LOW);
Blynk.virtualWrite(VPIN_BUTTON_1, toggleState_1); delay(100);
toggleState_2 = 1; digitalWrite(RelayPin2, LOW);
Blynk.virtualWrite(VPIN_BUTTON_2, toggleState_2); delay(100);
Blynk.virtualWrite(VPIN_HUMIDITY, humidity1);
Blynk.virtualWrite(VPIN_TEMPERATURE, temperature1);
Blynk.virtualWrite(VPIN_WATER, water_level);
Blynk.virtualWrite(VPIN_SOIL, soil_moisture);
}
void checkBlynkStatus() { // called every 3 seconds by SimpleTimer
bool isconnected = Blynk.connected();
if (isconnected == false) {
wifiFlag = 1;
Serial.println("Blynk Not Connected");
digitalWrite(wifiLed, HIGH);
}
if (isconnected == true) {
wifiFlag = 0;
if (!fetch_blynk_state){
Blynk.virtualWrite(VPIN_BUTTON_1, toggleState_1);
Blynk.virtualWrite(VPIN_BUTTON_2, toggleState_2);
}
digitalWrite(wifiLed, LOW);
//Serial.println("Blynk Connected");
}
}
12
BLYNK_CONNECTED() {
// Request the latest state from the server
if (fetch_blynk_state){
Blynk.syncVirtual(VPIN_BUTTON_1);
Blynk.syncVirtual(VPIN_BUTTON_2);
}
Blynk.syncVirtual(VPIN_TEMPERATURE);
Blynk.syncVirtual(VPIN_HUMIDITY);
Blynk.syncVirtual(VPIN_WATER);
Blynk.syncVirtual(VPIN_SOIL);
}
void readSensor(){
float h = dht.readHumidity();
float t = dht.readTemperature(); // or dht.readTemperature(true) for Fahrenheit
int readValue;
//value read from the sensor
int maxValue = 0;
// store max value here
int minValue = 1024;
// store min value here
if (isnan(h) || isnan(t)) {
Serial.println("Failed to read from DHT sensor!");
return;
}
else {
humidity1 = h;
temperature1 = t;
Serial.println(temperature1);
// Serial.println(humidity1);
}
}
void sendSensor()
{
readSensor();
// You can send any value at any time.
// Please don't send more that 10 values per second.
Blynk.virtualWrite(VPIN_HUMIDITY, humidity1);
Blynk.virtualWrite(VPIN_TEMPERATURE, temperature1);
Blynk.virtualWrite(VPIN_WATER, water_level);
Blynk.virtualWrite(VPIN_SOIL, soil_moisture);
}
void setup()
13
{
Serial.begin(9600);
pinMode(RelayPin1, OUTPUT);
pinMode(RelayPin2, OUTPUT);
pinMode(wifiLed, OUTPUT);
pinMode(SwitchPin1, INPUT_PULLUP);
pinMode(SwitchPin2, INPUT_PULLUP);
//During Starting all Relays should TURN OFF
digitalWrite(RelayPin1, !toggleState_1);
digitalWrite(RelayPin2, !toggleState_2);
dht.begin(); // Enabling DHT sensor
digitalWrite(wifiLed, HIGH);
config1.setEventHandler(button1Handler);
config2.setEventHandler(button2Handler);
button1.init(SwitchPin1);
button2.init(SwitchPin2);
//Blynk.begin(auth, ssid, pass);
WiFi.begin(ssid, pass);
timer.setInterval(2000L, checkBlynkStatus); // check if Blynk server is connected
every 2 seconds
timer.setInterval(1000L, sendSensor); // Sending Sensor Data to Blynk Cloud every 1
second
Blynk.config(auth);
delay(1000);
if (!fetch_blynk_state){
Blynk.virtualWrite(VPIN_BUTTON_1, toggleState_1);
Blynk.virtualWrite(VPIN_BUTTON_2, toggleState_2);
}
}
void loop()
{
Blynk.run();
timer.run(); // Initiates SimpleTimer
w();
s();
button1.check();
14
button2.check();
}
void button1Handler(AceButton* button, uint8_t eventType, uint8_t buttonState) {
Serial.println("EVENT1");
switch (eventType) {
case AceButton::kEventReleased:
digitalWrite(RelayPin1, toggleState_1);
toggleState_1 = !toggleState_1;
Blynk.virtualWrite(VPIN_BUTTON_1, toggleState_1);
break;
}
}
void button2Handler(AceButton* button, uint8_t eventType, uint8_t buttonState) {
Serial.println("EVENT2");
switch (eventType) {
case AceButton::kEventReleased:
digitalWrite(RelayPin2, toggleState_2);
toggleState_2 = !toggleState_2;
Blynk.virtualWrite(VPIN_BUTTON_2, toggleState_2);
break;
}
}
void w(){
water_level=digitalRead(water_level1);
if(water_level == LOW){
Blynk.virtualWrite(V5, HIGH);
// Blynk.email("shameer50@gmail.com", "Alert", "Temperature over 28C!");
Blynk.logEvent("water","水池水已經太低了"); }
else{
Blynk.virtualWrite(V5,LOW);
}
}
void s(){
soil_moisture=digitalRead(soil_moisture1);
if(soil_moisture == HIGH){
Blynk.virtualWrite(V6, HIGH);
digitalWrite(RelayPin2, HIGH);
// Blynk.email("shameer50@gmail.com", "Alert", "Temperature over 28C!");
Blynk.logEvent("soil","土壤太乾了"); }
else if(soil_moisture == LOW){
Blynk.virtualWrite(V6,LOW);
15
digitalWrite(RelayPin2, !toggleState_2);
}
}
J.運作過程
16
K、 電路圖及介面
17
五、結論
現代人的生活腳步極快,行程滿檔似乎已成為日常,要如何在忙碌之餘不顧
此失彼、保持從容,是我們的一大挑戰;便捷的交通網路,促使「一日生活圈」的形
成,每日通勤於兩地之間的人也不少,然而在為工作焦頭爛額時,許多人常會忽
略生活的小細節,使辛苦一天、早已精疲力盡的人們因為一些小問題,連回家後
都不能好好休息。因此我們設計這個智慧盆栽,讓人們返家後得以放心休息,準
備迎接明天的挑戰。
我們希望透過此智慧盆栽,達到便利與自動化的目的,使用自動化澆水功
能、APP遠端監控盆栽狀況,可以讓使用者無後顧之憂地將盆栽交給我們的產品
,也因應時下物聯網的風潮。因為植物枯死有多重原因,所以我們設計的智慧盆
栽相較於市面上的其他產品有更多監測項目,並且可在各種狀況發生時通知使
用者,讓盆栽真正「智慧」化。
將來,我們希望能更進一步地運用所學知識,改良我們的作品,讓植物在有
狀況時不只是通知使用者,而是作出具體防止植物被傷害或死亡的動作,甚至可
以結合生物防治觀念,加入病蟲害監測的功能,將能更加有效保護植物。
18
六、競賽紀錄
19
20
21
0
You can add this document to your study collection(s)
Sign in Available only to authorized usersYou can add this document to your saved list
Sign in Available only to authorized users(For complaints, use another form )