หน้าแรก ดูโปรเจกต์ทั้งหมด
Expert

โปรเจกต์ Plant Communicator (เครื่องสื่อสารกับต้นไม้)

เคยอยากลองพูดคุยกับต้นไม้ของคุณบ้างไหม?

โปรเจกต์ Plant Communicator (เครื่องสื่อสารกับต้นไม้)

รายการอุปกรณ์และเครื่องมือ

1x Arduino MKR IoT Bundle
-

รายละเอียดและวิธีทำ

Note: This tutorial could be outdated, please go ที่นี่ สำหรับเวอร์ชันที่เป็นปัจจุบันมากกว่า

บทนำ

อย่างที่กวีชาวอังกฤษ William Wordsworth เคยกล่าวไว้ว่า:

"จิตใจของคุณคือสวน ความคิดของคุณคือเมล็ดพันธุ์ การเก็บเกี่ยวอาจเป็นได้ทั้งดอกไม้หรือวัชพืช"

การดูแลต้นไม้ให้มีชีวิตรอดอาจเป็นเรื่องท้าทายทีเดียว เพราะพวกมันสื่อสารไม่เก่งเลย

วิธีหนึ่งที่จะทำให้พวกมันมีความสุขคือการพาต้นไม้ติดตัวไปด้วย แต่คุณคงไม่อยากแบกกระบองเพชรยักษ์หรือเฟิร์นไว้ในกระเป๋าเสื้อกันหนาวหรอก แถมต้นไม้ส่วนใหญ่ยังไม่ชอบอากาศหนาวด้วย

หลังจากพยายามสื่อสารกับต้นแมงมุม (Spider Plant) ของเราอยู่นานหลายเดือน เราจึงยอมแพ้และหันมาใช้ส่วนประกอบจาก MKR IoT Bundle เพื่อสร้างอุปกรณ์ที่ใช้ตรวจสอบความเป็นอยู่ของต้นไม้จากระยะไกลแทน

สรุปสั้นๆ:

ในบททดลองนี้ คุณจะได้เรียนรู้วิธีปกป้องต้นไม้ของคุณและทำให้แน่ใจว่าพวกมันจะอยู่รอดด้วยการใช้เวทมนตร์ของ Arduino

ด้วยการตรวจสอบความชื้น (moisture), อุณหภูมิ (temperature) และแสงสว่าง (light) คุณจะมั่นใจได้ว่าต้นไม้ของคุณมีความสุข อุปกรณ์นี้สามารถส่งอีเมลและกราฟเป็นประจำทุกวัน พร้อมทั้งแจ้งเตือนคุณเมื่อมันต้องการการดูแล

ส่วนประกอบ (Components)

  • TMP36 temperature sensor
  • Phototransistor
  • DIY moisture sensor

เป้าหมายการเรียนรู้

  • แนะนำบริการอินเทอร์เน็ต Zapier
  • การส่ง HTTP requests
  • การจัดการ Real Time Clock และการตั้งปลุก (alarms)
  • การสร้าง DIY moisture sensor
  • การพล็อตกราฟค่าต่างๆ ด้วย ThingSpeak #ProTips
  • การตกแต่งอีเมลด้วย HTML และ CSS #ProTips
  • การทดสอบ APIs ด้วย Postman #ProTips

ต้องการทราบข้อมูลเพิ่มเติมหรือไม่?

บทช่วยสอนนี้เป็นส่วนหนึ่งของชุดการทดลองที่จะทำให้คุณคุ้นเคยกับ MKR1000 และ IoT การทดลองทั้งหมดสามารถสร้างขึ้นได้โดยใช้ส่วนประกอบที่มีอยู่ใน MKR IoT Bundle

  • Plant Communicator

ตั้งค่า Zapier

Zapier เป็นเครื่องมืออัตโนมัติออนไลน์ที่สามารถจัดการ API ของแอปอื่นๆ ให้เราได้อย่างง่ายดาย เป็นเครื่องมือที่ยอดเยี่ยมในการรวมหลายงานเข้าด้วยกัน หรือในกรณีที่แอปที่เราต้องการใช้มี API ที่ซับซ้อนซึ่งไม่สามารถจัดการได้ด้วย Arduino

ในกรณีของเรา เราจะใช้มันเพื่อส่งอีเมลพร้อมข้อมูลที่ได้รับจาก Arduino

ทำตามขั้นตอนง่ายๆ เหล่านี้เพื่อสร้าง Zap ของคุณเอง!

เพื่อให้ดำเนินการต่อได้ เราจำเป็นต้องทดสอบ hook ของเราก่อน โดยคัดลอก URL ที่ได้รับมา จากนั้นเลือกปุ่ม Test and Review ที่ปรากฏขึ้นเมื่อคุณกด Continue เพิ่มพารามิเตอร์เหล่านี้ต่อท้าย URL:

custom_webhook_URL?temperature=0&moisture=0&light=0&warning=0

ตอนนี้เพียงแค่คัดลอกและวาง URL นี้ลงในหน้าเบราว์เซอร์ใหม่

คุณควรเห็นการตอบกลับดังนี้:

ยินดีด้วย! คุณเพิ่งส่ง http request สำเร็จ!

นี่คือสิ่งที่เราจะทำกับ Board Arduino ของเรา แต่แทนที่จะวาง URL นั้นลงในเบราว์เซอร์ เราจะส่งไปยังเซิร์ฟเวอร์ของ Zapier โดยตรง นอกจากนี้เราจะแก้ไขค่าของพารามิเตอร์ที่ตอนนี้ตั้งเป็นศูนย์ด้วยค่าจาก Sensor ของเรา

สำหรับวิธีที่ก้าวหน้าขึ้นในการทดสอบและทำงานกับ API ให้ดูที่ #ProTip ที่ด้านล่างของหน้า

หลังจากที่คุณทดสอบคำขอแล้ว คุณสามารถดำเนินการสร้าง Zap ต่อได้

ดำเนินการต่อในส่วน Edit ด้วย Do This...

ตรวจสอบกล่องจดหมายของคุณเพื่อดูอีเมลที่สร้างจาก Zapier ซึ่งจะส่งมาจากบัญชีที่คุณใช้ในขั้นตอนแรกของการกำหนดค่า Gmail

การตั้งค่า Board

ในการใช้งานฟังก์ชันทั้งหมด เราจะใช้ไลบรารีต่อไปนี้:

  • WiFi101 // เพื่อเชื่อมต่ออินเทอร์เน็ตและสแกนเครือข่าย
  • RTCZero // เพื่อจัดการเหตุการณ์ที่กระตุ้นด้วยเวลา

คุณสามารถดาวน์โหลดไลบรารีเหล่านี้ได้จาก Library Manager ตามที่อธิบายไว้ใน คู่มือนี้

ในการใช้ API ของ Zapier อันดับแรกเราต้อง upload certificates ลงใน MKR1000 สิ่งนี้ใช้กับบริการออนไลน์และ API ส่วนใหญ่!

อัปโหลดตัวอย่าง Firmware Updater จากไลบรารี WiFi101 และเพิ่ม hooks.zapier.com ลงใน domains

> examples > WiFi101 > FirmwareUpdater 

หากคุณใช้ Arduino Web Editor ฟีเจอร์นี้ยังไม่รองรับ และคุณต้องทำผ่าน Arduino Desktop Application

การส่ง HTTP request

ตอนนี้เราพร้อมที่จะส่ง HTTP request จาก Board Arduino แล้ว

สำหรับตอนนี้ เราจะตั้งค่าพารามิเตอร์เป็นค่าสมมติ ซึ่งภายหลังจะถูกแทนที่ด้วยค่าจริงจาก Sensor

 float temperature = 22; 
int moisture = 150;
int light = 40;
String warning = "This is a warning message";
warning.replace(" ", "%20");

โปรดทราบว่า String จะต้องถูกเข้ารหัส (encoded) เนื่องจากไม่สามารถส่งช่องว่างใน HTTP request ได้ ช่องว่างทั้งหมดจะถูกแทนที่ด้วยรหัสที่เทียบเท่าคือ %20

หลังจากตั้งค่าพารามิเตอร์แล้ว เราจะเรียกฟังก์ชัน send_email() ซึ่งจะแปลงค่าทั้งหมดเป็น String และ จะสร้าง URL แบบเดียวกับที่เราใช้ก่อนหน้านี้ เพื่อส่งไปยังเซิร์ฟเวอร์ของ Zapier

กรอกข้อมูล WiFi ของคุณและส่วนของ URL ที่คุณได้รับจาก Zapier ลงใน sketch นี้แล้วอัปโหลด

#include <WiFi101.h> 
#include<WiFiSSLClient.h>
const char* ssid = SECRET_SSID; // your network SSID (name)
const char* password = SECRET_PSWD; // your network password
String httpsRequest = SECRET_REQUEST; // your Zapier URL
const char* host = "hooks.zapier.com";
WiFiSSLClient client;
void setup() {
Serial.begin(9600);
while (!Serial);
delay(2000);
Serial.print("Connecting Wifi: ");
Serial.println(ssid);
while (WiFi.begin(ssid, password) != WL_CONNECTED) {
Serial.print(".");
delay(500);
}
Serial.println("");
Serial.println("WiFi connected");
}
void loop() {
float temperature = 22;
int moisture = 150;
int light = 40;
String warning = "This is a warning message";
warning.replace(" ", "%20");
send_email(temperature, moisture, light, warning );
delay(20000);
}
void send_email(float temperature, int moisture, int light, String warning) {
// convert values to String
String _temperature = String(temperature);
String _moisture = String(moisture);
String _light = String(light);
String _warning = warning;
if (client.connect(host, 443)) {
client.println("POST " + httpsRequest + "?temperature=" + _temperature + "&moisture=" + _moisture + "&light=" + _light + "&warning=" + _warning + " HTTP/1.1");
client.println("Host: " + String(host));
client.println("Connection: close");
client.println();
delay(1000);
while (client.available()) { // Print on the console the answer of the server
char c = client.read();
Serial.write(c);
}
client.stop(); // Disconnect from the server
}
else {
Serial.println("Failed to connect to client");
}
}

มันจะส่งอีเมลไปยังที่อยู่ที่คุณเลือกทุกๆ 20 วินาที

ระวังเรื่องจำนวนคำขอ Zapier ให้คุณส่งได้ฟรีเพียง 100 ครั้งต่อเดือนเท่านั้น

RTC และ Alarms

เราสามารถใช้ Real Time Clock ของ MKR1000 เพื่อส่งอีเมลทุกวันในเวลาที่กำหนด

sketch นี้จะตั้งเวลาและวันที่เป็น 16:00 ของวันที่ 4 ธันวาคม 2017 แล้วจึงตั้งปลุกทุกวันเวลา 16:01

โปรดทราบว่าเนื่องจากการปลุกเชื่อมต่อกับฟังก์ชัน interrupt เราจึงไม่สามารถใส่คำสั่ง delay ได้ แต่เราสามารถใช้ Variable ประเภท boolean เพื่อกระตุ้นการทำงานใน loop()

#include <RTCZero.h> 
RTCZero rtc; // create RTC object
/* Change these values to set the current initial time */
const byte seconds = 0;
const byte minutes = 0;
const byte hours = 16;
/* Change these values to set the current initial date */
const byte day = 4;
const byte month = 12;
const byte year = 17;
bool email_already_sent = false;
void setup() {
Serial.begin(9600);
while (!Serial);
delay(2000);
rtc.begin(); // initialize RTC 24H format
rtc.setTime(hours, minutes, seconds);
rtc.setDate(day, month, year);
rtc.setAlarmTime(16, 1, 0); // Set the time for the Arduino to send the email
rtc.enableAlarm(rtc.MATCH_HHMMSS);
rtc.attachInterrupt(alarmMatch);
}
void loop() {
if (!email_already_sent) {
// send_email();
email_already_sent = true;
}
}
void alarmMatch() { // triggered when the alarm goes on
Serial.println("Alarm Match!");
email_already_sent = false;
}

DIY Soil Moisture Sensor

สายไฟสองเส้นที่วางอยู่ในกระถางดินทำหน้าที่เป็นตัวต้านทานที่แปรค่าได้ ซึ่งความต้านทานจะเปลี่ยนไปตามความชื้นในดิน

ตัวต้านทานที่แปรค่าได้นี้จะถูกเชื่อมต่อในรูปแบบวงจรแบ่งแรงดัน (voltage divider) และ Arduino จะเก็บค่าแรงดันไฟฟ้าที่เป็นสัดส่วนกับความต้านทานระหว่างสายไฟ 2 เส้นนั้น

หมายความว่า ยิ่งดินมีความชื้นมากเท่าไหร่ แรงดันไฟฟ้าที่วัดได้จาก Arduino ก็จะยิ่งน้อยลงเท่านั้น

โดยการใช้ ตัวต้านทานขนาด 1 Mega Ohm และสายไฟสองเส้น เราสามารถสร้าง DIY soil moisture sensor ของเราเองได้!

การต่อวงจร Soil moisture sensor

เมื่ออัปโหลด sketch ต่อไปนี้ คุณสามารถเริ่มอ่านค่าจาก Sensor ได้ เราขอแนะนำให้คุณ เริ่มทดสอบในดินแห้งก่อน และจดค่าที่อ่านได้ไว้

ค่านั้นจะถูกใช้เพื่อตั้งค่าเกณฑ์ (threshold) เพื่อให้ Arduino รู้ว่าเมื่อใดที่ต้นไม้ของคุณต้องการน้ำ และส่ง อีเมลฉุกเฉิน มาหาคุณ

int moisturePin = A2; 
// Set this threshold accordingly to the resistance you used
// The easiest way to calibrate this value is to test the sensor in both dry and wet soil
int threshold = 800;
void setup() {
Serial.begin(9600);
while (!Serial);
delay(2000);
}
void loop() {
Serial.println(get_average_moisture());
delay(5000);
}
int get_average_moisture() { // make an average of 10 values to be more accurate
int tempValue = 0; // variable to temporarily store moisture value
for (int a = 0; a < 10; a++) {
tempValue += analogRead(moisturePin);
delay(100);
}
return tempValue / 10;
}

เพิ่ม Sensor อุณหภูมิและแสง

ดูแผนผังด้านล่างเพื่อต่อวงจร Sensor ทั้งสองตัว เราจะใช้ฟังก์ชันสองตัวนี้ในการอ่านค่าจาก Sensor:

float get_temperature(){ 
int reading = analogRead(A1);
float voltage = reading * 3.3;
voltage /= 1024.0;
// Print temperature in Celsius
float temperatureC = (voltage - 0.5) * 100 ; //converting from 10 mv per degree with 500 mV offset
// Convert to Fahrenheit
float temperatureF = (temperatureC * 9.0 / 5.0) + 32.0;
return temperatureC;
}
int get_light(){
int light_value=analogRead(A0);
return light_value;
}

โปรดทราบว่าคุณสามารถใช้หน่วย Fahrenheit ได้โดยการสั่ง return temperatureF แทน temperatureC

#ProTip: พล็อตกราฟค่าต่างๆ โดยใช้ ThingSpeak

สำหรับคนที่ชอบควบคุมทุกอย่าง นี่คือคำแนะนำในการพล็อตกราฟข้อมูลทั้งหมดที่เก็บรวบรวมได้ให้เป็นกราฟที่สวยงามแบบนี้:

กราฟอุณหภูมิ

เราจะใช้แพลตฟอร์ม ThingSpeak เพื่อพล็อตกราฟ ทำตามขั้นตอนเหล่านี้เพื่อเริ่มต้น

ดาวน์โหลดไลบรารี ThingSpeak และมาเริ่มต้นกันเลย sketch ด้านล่างนี้จะอัปโหลดค่าจาก Sensor ขึ้นระบบ cloud ทุกๆ นาที เพียงกรอกข้อมูล WiFi และ API keys ของ channel ของคุณแล้วอัปโหลด

#include <WiFi101.h> 
#include<WiFiSSLClient.h>
#include "ThingSpeak.h"
const char* ssid = SECRET_SSID; // your network SSID (name)
const char* password = SECRET_PSWD; // your network password
WiFiClient ThingSpeakClient;
unsigned long myChannelNumber = 356392;
const char * myWriteAPIKey = SECRET_WRITE_API;
int lightPin = A0; //the analog pin the light sensor is connected to
int tempPin = A1; //the analog pin the TMP36's Vout (sense) pin is connected to
int moisturePin = A2;
void setup() {
Serial.begin(9600);
while (!Serial);
delay(2000);
Serial.print("Connecting Wifi: ");
Serial.println(ssid);
while (WiFi.begin(ssid, password) != WL_CONNECTED) {
Serial.print(".");
delay(500);
}
Serial.println("");
Serial.println("WiFi connected");
ThingSpeak.begin(ThingSpeakClient);
}
void loop() {
ThingSpeak.setField(1, get_light());
ThingSpeak.setField(2, get_temperature());
ThingSpeak.setField(3, get_average_moisture());
ThingSpeak.writeFields(myChannelNumber, myWriteAPIKey);
Serial.println("message sent to cloud");
delay(60000); // send values every 1 minute
}
float get_temperature() {
int reading = analogRead(tempPin);
float voltage = reading * 3.3;
voltage /= 1024.0;
// Print temperature in Celsius
float temperatureC = (voltage - 0.5) * 100 ; //converting from 10 mv per degree with 500 mV offset
// Convert to Fahrenheit
float temperatureF = (temperatureC * 9.0 / 5.0) + 32.0;
return temperatureC;
}
int get_average_moisture() { // make an average of 10 values to be more accurate
int tempValue = 0; // variable to temporarily store moisture value
for (int a = 0; a < 10; a++) {
tempValue += analogRead(moisturePin);
delay(10);
}
return tempValue / 10;
}
int get_light() {
int light_value = analogRead(A0);
return light_value;
}

ใน sketch แบบ Pro ตัวเต็มด้านล่าง คุณจะเห็นวิธีเชื่อมต่อการอัปโหลดนี้เข้ากับ RTC alarm ที่จะถูกกระตุ้นทุกๆ นาที

น่าเสียดายที่ Gmail ไม่อนุญาตให้เราฝัง กราฟ และ iframes ลงในเนื้อหาอีเมล แต่เราสามารถส่งลิงก์ผ่านอีเมลในรูปแบบปุ่มที่สวยงามได้ ดูคำแนะนำด้านล่าง

เราเลือกใช้ ThingSpeak แต่ยังมีทางเลือกอื่นอีกมากมาย! เช่น ลองดู Dweet.io และ freeboard.io เป็นต้น

#ProTip: ตกแต่งอีเมลของคุณ

Zapier อนุญาตให้เรา ฝังโค้ด html และ css ในเนื้อหา ของอีเมล เราสามารถใช้สิ่งนั้นเพื่อส่งอีเมลที่ตกแต่งอย่างสวยงามแบบนี้:

เนื้อหาอีเมลที่ตกแต่งแล้ว

เพื่อให้ได้ผลลัพธ์นี้ เพียงแค่เปลี่ยน body type เป็น html บนหน้าจอ Zapier และเพิ่ม HTML และ CSS ของคุณเอง

คัดลอกและวาง template นี้:

<!doctype html> 
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
.container{
margin-left: 10%;
margin-right: 10%;
background-color: #ECF1F1;
min-height: 100%;
padding-top: 5%;
padding-bottom: 10%;
font-family: monospace;
letter-spacing: 2px;
}
.title{
text-align: center;
color: #0CA1A6;
font-size: 1.5em;
padding-top: 0.2vh;
}
.subtitle{
text-align: center;
color: #0CA1A6;
font-size: 1.1em;
padding-bottom: 4%;
padding-left: 4%;
padding-right: 4%;
}
.data{
padding-bottom: 2%;
padding-top: 2%;
padding-left: 5%;
margin-left: 15%;
margin-right: 15%;
background-color: #F7F9F9;
text-align: left;
color: #4E5B61;
font-size: 1em;
font-weight: bold;
}
.bttn{
padding-bottom: 3%;
padding-top: 3%;
margin-left: 25%;
margin-right: 25%;
margin-top: 10%;
background-color: #00979D;
text-align: center;
color: #F7F9F9;
font-size: 1.4em;
}
.disclaimer{
text-align:center;
color:#DA5B4A;
font-size: 1.1em;
font-weight: bold;
margin-top: 10%;
}
.bttn:hover{
background-color: #008184;
}
a{
text-decoration: none;
}
</style>
</head>
<body>
<div class="container">
<h2 class="title">HELLO !</h2>
<h4 class="subtitle">Here's your daily update about your garden &#9752;</h4>
<div class="data"> &#9832; Temperature: {{querystring__temperature}} C </div>
<div id="humidity" class="data"> &#9748; Moisture: {{_querystring__moisture}}</div>
<div class="data"> &#9728; Light: {{querystring__light}}</div>
<div class="disclaimer">{{querystring__warning}}</div>
<a href="your_link_to_thingSpeak">
<div class="bttn">SEE THE GRAPH</div>
</a>
</div>
</body>
</html>

#ProTip: ทดสอบ API ด้วย Postman

การทำงานกับ HTTP request อาจเป็นเรื่องยาก โชคดีที่มีเครื่องมือมากมายที่ช่วยเราสร้าง URL ที่เราต้องการได้

Postman เป็นตัวอย่างที่ยอดเยี่ยม:

เพียงวาง URL เริ่มต้นที่ได้รับจาก Zapier เพิ่มพารามิเตอร์แล้วกดส่ง มันจะแสดงผลการตอบกลับจากเซิร์ฟเวอร์และประกอบ URL ให้กับคุณ

Code

🔒 ปลดล็อก Code

สนับสนุนเพื่อรับ Source Code หรือแอปพลิเคชันสำหรับโปรเจกต์นี้

รหัสอ้างอิงโปรเจกต์: plant-communicator-0ab3c8
699 บาท
PromptPay QR Code