Karena tanaman saya selalu kekurangan air dan saya suka memasukkan banyak tanaman ke dalam piring saya, saya memutuskan untuk membuat sistem irigasi khusus. Kotak untuk ramuan saya harus dapat dikonfigurasi dan bekerja secara otomatis atau manual. Oleh karena itu antarmuka ke situs web ada untuk mengaktifkan pengaturan dan menunjukkan kelembapan dalam bagan yang bagus. Langkah terakhir adalah integrasi kontrol suara untuk meminta kelembapan dari Amazon Alexa, menyalakan/mematikan lampu tanam, dan memulai irigasi, jika otomatisasi dinonaktifkan. Klik di sini untuk menemukan hasilnya.
Saya mulai dengan bagian teknis proyek dan membeli Arduino. Setelah beberapa tutorial, saya tegas dengan perangkat lunak dan mengendalikan Arduino. Saya memesan pengontrol wifi, beberapa sensor kelembaban, pompa, lampu tumbuh tanaman dan perangkat keras tambahan yang diperlukan (pelindung relai untuk memisahkan sirkuit untuk lampu dan pompa dari Arduino, beberapa kabel dan kayu beech untuk bingkai). Kode hasil Arduino disediakan dalam tutorial ini, di samping beberapa informasi tentang cara menggunakan komponen dalam proyek Anda. Kode situs web/api tidak disediakan (kecuali permintaan sangat tinggi;)).
Langkah Satu:Sensor Kelembaban
Tonggak pertama adalah membaca kelembaban dengan Arduino saya. Sensor kelembaban YL-69 mudah dihubungkan dengan Arduino. Anda perlu menghubungkan pin VCC ke pin GPIO (dalam contoh saya pin 06), ground ke ground dan A0 ke pin analog (dalam contoh saya pin A1) dari Arduino.
Tutorial:Sensor Kelembaban Tanah
byte vccPin =6;byte dataPin =A1;pengaturan batal() { pinMode(vccPin, OUTPUT); digitalWrite(vccPin, RENDAH); Serial.begin(9600); while (!Serial);}int readHumidity() { digitalWrite(vccPin, HIGH); penundaan (500); // Anda perlu menguji berapa lama Anda melakukan pra-daya sebelum pengukuran int value =analogRead(dataPin); digitalWrite(vccPin, RENDAH); return 1023 - nilai;}void loop() { Serial.print("Level Kelembaban (0-1023):"); Serial.println(readHumidity()); delay(10000);}
Langkah Kedua:Relai untuk Pompa dan Lampu
Tujuan selanjutnya adalah memasang relay shield (4 relais) untuk memisahkan rangkaian lampu, pompa dan arduino. Arduino berjalan pada 5V, pompa menggunakan 12V dan lampu tanam 230V. Perisai harus terhubung ke pin 5V dan Ground pada Arduino. Setiap relai selanjutnya membutuhkan pin GPIO pilihan Anda untuk menghidupkan dan mematikan. Terakhir, Anda dapat menggunakan jumper untuk VCC JC ke VCC pada pelindung, atau menggunakan baterai ekstra (yang akan lebih baik, tetapi saya belum memiliki baterai di dalam proyek saya).
Penting untuk dipahami, bahwa perisai saya mengaktifkan "Aktif" dengan "RENDAH" pada pin. Segera setelah pin saya ditetapkan sebagai OUTPUT, pin tersebut secara otomatis beralih ke aktif. Dalam kode Anda harus selalu beralih ke INPUT dan LOW, jika Anda ingin relai mati. Secara default, pin Arduino adalah INPUT dan LOW.
Menghubungkan espressif ESP8266 ESP-01 ke Arduino untuk WiFi adalah bagian yang paling sulit. Butuh waktu berjam-jam untuk menjalankan wifi di skrip saya.
ESP terhubung ke:VCC =3.3V, GND =GND, CH_PD =3.3V, TX =Pin 02, RX =Pin 03. Untuk penggunaan yang produktif, Anda harus menggunakan setidaknya konverter level dari 5V ke 3.3V untuk pin 02 dan pin 03 juga. Dalam kasus saya, ini bekerja dengan baik.
Mirip dengan Arduino, ESP-01 adalah mikrokontroler lain. Jika Anda ingin kedua pengontrol berkomunikasi, Anda harus menggunakan komunikasi serial. Arduino UNO secara default menggunakan pin 01 dan 02 untuk RX dan TX. Tetapi mereka juga digunakan untuk debugging USB dan oleh karena itu disarankan untuk menyertakan SoftwareSerial.h dan menentukan pin khusus.
#include SoftwareSerial espSerial(3,2); // RX, TXvoid setup() { Serial.begin(9600); espSerial.begin(115200); // beralih ke 9600 setelah AT+UART_DEF=9600,8,1,0,0 while (!Serial);}void loop() { if (espSerial.available()) { Serial.write(espSerial.read()); } if (Serial.available()) { espSerial.write(Serial.read()); }}
Menjalankan script di atas, Anda bisa memasukkan AT-commands ke serial monitor dan lihat hasilnya. Komunikasi serial rentan terhadap kegagalan, oleh karena itu saya menurunkan baud rate komunikasi yang digunakan oleh ESP dari 115200 menjadi 9600.
Kelas pembantu yang berguna (tetapi menggunakan terlalu banyak memori):Perpustakaan:WiFiEsp
Alat pemeriksaan memori:Perpustakaan:MemoryFree
Script menggunakan HTTP 1.0, karena dengan HTTP 1.1 byte adalah bagian dari respon. Penting untuk berhati-hati dengan jeda baris agar perintah dikirim setelah AT+CIPSEND. Jika salah, Anda akan menerima kesalahan pengiriman byte.
#include SoftwareSerial espSerial(3,2); // RX, TXconst char* ssid ="";const char* pass ="";void setup() { Serial.begin(9600); espSerial.begin(9600); while(!Serial); while(!koneksikeWiFi()); // request website dan print hasil if (httpRequest("my.server.com", "/site/subsite/index.php")) { while (espSerial.available()) { Serial.write(espSerial.read() ); } }}void loop() { // dijalankan berulang-ulang if (espSerial.available()) { Serial.write(espSerial.read()); } if (Serial.available()) { espSerial.write(Serial.read()); }}bool connectToWiFi() { delay(2000;) espSerial.setTimeout(3000); while (espSerial.available()) Serial.write(espSerial.read()); Serial.println(F("[ESP] Menghubungkan ke WiFi")); espSerial.println(F("AT+CIPSTATUS=2")); if (!espSerial.find("OK")) { espSerial.setTimeout(10000); Serial.println(F("[ESP] Atur Ulang Modul")); espSerial.println(F("AT+RST")); if (!espSerial.find("ready")) { Serial.println(F("[ESP] Reset gagal")); kembali salah; } Serial.println(F("[ESP] Setel CWMode")); espSerial.println(F("AT+CWMODE=1")); if (!espSerial.find("OK")) { Serial.println(F("[ESP] Mode gagal")); kembali salah; } Serial.println(F("[ESP] Hubungkan ke Router")); espSerial.print(F("AT+CWJAP=\"")); espSerial.print(ssid); espSerial.print(F("\",\"")); espSerial.print(lulus); espSerial.println ("\""); if (!espSerial.find("OK")) { Serial.println(F("[ESP] koneksi WiFi gagal")); kembali salah; } } espSerial.setTimeout(3000); Serial.println(F("[ESP] WiFi terhubung")); return true;}bool httpRequest(String server, String site) { String cmd =""; cmd +="DAPATKAN " + situs + " HTTP/1.0\r\n"; cmd +="Tuan rumah:" + server + "\r\n"; cmd +="Koneksi:tutup"; int cmdPanjang =cmd.panjang() + 4; // Serial.println(cmd); espSerial.print(F("AT+CIPSTART=\"TCP\",\"")); espSerial.print(server); espSerial.println(F("\",80")); if (!espSerial.find("OK")) { Serial.println(F("[ESP] TCP Connection Error")); kembali salah; } espSerial.print(F("AT+CIPSEND=")); espSerial.println(cmdLength); if (!espSerial.find(findGT)) { Serial.println(F("[ESP] Kirim Kesalahan Status")); kembali salah; } espSerial.print(F("DAPATKAN")); espSerial.print(situs); espSerial.print(F("HTTP/1.0\r\n")); espSerial.print(F("Host:")); espSerial.print(server); espSerial.print(F("\r\n")); espSerial.print(F("Koneksi:tutup\r\n")); espSerial.println(); if (!espSerial.find(":")) { Serial.println(F("Byte tidak terkirim")); espSerial.print(F("AT+CIPCLOSE")); kembali salah; } status karakter[32] ={0}; espSerial.readBytesUntil('\r', status, sizeof(status)); if (strcmp(status, "HTTP/1.1 200 OK") !=0) { Serial.print(F("[ESP] Respons tak terduga:")); Serial.println(status); kembali salah; } if (!espSerial.find("\r\n\r\n")) { Serial.println(F("[ESP] Respons salah")); kembali salah; } // Lewati header HTTP // if (!espSerial.find(\r\n)) { Serial.println(F("[ESP] Bytes tidak ditemukan")); kembali; } // lewati byte (untuk http 1.1) mengembalikan true;i}
Langkah Empat:Kotak Kayu
Bingkai itu direncanakan untuk menyimpan semua barang elektronik dan tiga pot herbal dari supermarket. Saya mengukur ukuran semua komponen dan menyusun posisinya. Empat sensor kelembapan, dua pompa, pelindung Arduino +, pelindung relai 4x, dan colokan USB, serta beberapa kabel harus masuk ke dalam kotak. Itu terbuat dari kayu beech, untuk membuatnya kuat dan tahan tetesan air tanpa glasir tambahan.
Lingkaran digergaji dengan jig saw di atas meja jig saw buatan sendiri. Tunggangan tanaman direkatkan di dalam lingkaran dengan lem panas. Sisi-sisi kotak direkatkan dengan lem kayu (D3 untuk tahan air). Selain elektronik, saya tidak menggunakan sekrup atau paku di samping pemasangan panel bawah.
Saya meletakkan semua sirkuit, kabel dan tabung air di dalam kotak, menarik sensor keluar dan tabung untuk tangki air tambahan. Sebelum menutup kotak, saya menambahkan piring untuk mencegah air tenggelam di dalam kotak untuk melindungi barang elektronik.
Langkah Kelima:API Situs Web
API dan situs web didasarkan pada jQuery, Bootstrap, X-editable (untuk formulir ajax sebaris) dan Chart.js (untuk bagan kelembapan), dikodekan dalam php. Di situs web Anda dapat menentukan pengaturan untuk Arduino (misalnya pin sensor, interval pemeriksaan kelembaban, pompa per tanaman, pin VCC pompa, pin VCC ringan) dan menemukan grafik + kelembaban saat ini.
Konfigurasi disediakan oleh JSON untuk Arduino. Setelah memulai dan dalam interval yang sering, kotak ramuan memeriksa pengaturan baru. Untuk parsing JSON dengan Arduino, saya menggunakan library ArduinoJson. Untuk interval polling saya menggunakan StensTimer.
Situs web menyediakan API untuk komunikasi Alexa. Ini berfungsi sebagai hub untuk menerima permintaan JSON oleh Alexa dan menerjemahkannya ke dalam JSON khusus yang digunakan oleh Arduino (misalnya lampu menyala, mengairi tanaman 1, ...). Arduino melakukan polling untuk tindakan baru dan mengeksekusinya.
Karena permintaan suara lebih dari sekedar on/off, saya menerapkan Alexa Skill dan tidak ada Alexa Smart Home. AWS Lampda meneruskan permintaan JSON ke API saya, yang mengurai maksud.
var https =require('https');exports.handler =(event, konteks, callback) => { var postData =JSON.stringify(event); var options ={ Host:'', path:'', port:443, metode:'POST', header:{ 'Content-Type':'application/json' , 'Content-Length':postData.length, } }; // mengatur permintaan var postRequest =https.request(options, function(res) { res.setEncoding('utf8'); res.on('data', function (chunk) { console.log('Response:' + potongan); // console.log(potongan); callback(null, JSON.parse(potongan)); }); }); // posting data postRequest.write(postData); postRequest.end();};
Kutipan maksud yang saya gunakan oleh keahlian saya:
ReadHumidityIntent Bagaimana kabar tanaman saya
ReadHumidityIntent Bagaimana {plantName}
my saya
IrigasiPlantIntent Mengairi tanaman saya
IrigatePlantIntent Mengairi {plantName} saya selama {durationSeconds} detik
SwitchIntent Mengalihkan lampu {switchState}
ReadIrigateIntent Tanaman mana yang membutuhkan air
ReadLastIrrigationIntent Kapan irigasi terakhir {plantName}
my saya
Terakhir, namun tidak kalah pentingnya, saya menambahkan dukungan lokal untuk penggunaan bahasa Jerman dan Inggris.
Hasilnya
Hasilnya, saya memiliki kotak kayu untuk menaruh pot herbal supermarket, mengambil tabung air dan sensor kelembaban di tanah dan tabung di tangki air eksternal. Dengan integrasi Alexa, saya dapat mengucapkan kalimat berikut:
"Alexa, tanya kotak ramuan bagaimana tanaman saya " - Response:"Tanaman 1 baik-baik saja, Tanaman 2 kering, ..."
"Alexa, beri tahu kotak ramuan untuk mengairi basil saya selama 5 detik " - Response:"Mengirigasi kemangi selama 5 detik"
"Alexa, tanyakan kotak ramuan tanaman mana yang membutuhkan irigasi " - Respon:"Tanaman 1 kering, Tanaman 3 kering, ..."
"Alexa, tanyakan kotak ramuan kapan irigasi terakhirkemangi saya " - Response:"Irigasi terakhir kemangi adalah 36 jam yang lalu"
"Alexa, beri tahu kotak ramuan untuk menyalakan lampu " - Response:"Menyalakan lampu tanam tanaman"
Menanyakan kelembapan tanaman saya kepada Alexa dan mengairinya setelah itu (Jerman):
Meminta Alexa untuk menyalakan lampu tanam:
GIF yang menampilkan hasil tanpa video:
Fitur yang Direncanakan
Fitur berikut belum diterapkan tetapi direncanakan untuk masa mendatang:
Mode hemat daya untuk kode sumber Arduino
Tambahkan Arduino Nano eksternal dengan komunikasi nirkabel (2,4 GHz) untuk pengukuran kelembapan tanaman lain di rumah (kotak adalah hub untuk WiFi) - hanya menggunakan baterai
Perluas API untuk beberapa contoh kotak ramuan, untuk teman (dan siapa pun, jika Anda tertarik?!)
Tambahkan tombol untuk mengairi dan menyalakan lampu di kotak tanpa situs web atau Alexa
Gambar Alexa (kartu dalam respons keterampilan)
Pembaruan 23.03.2018
Saya telah menambahkan dua maksud baru. Salah satunya penting untuk fitur terencana dari Adruino Nanos eksternal yang baru saja mencatat kelembapan.
Tanaman apa yang kering
Kapan irigasi terakhir
Kode
EcoActionBuffer.h
EcoActionBuffer.cpp
Plant.cpp
Plant.h
WhiteWalnut.ino
WhiteWalnutApi.cpp
WhiteWalnutApi.h
EcoActionBuffer.hArduino
#ifndef ECOACTIONBUFFER_H#menentukan ECOACTIONBUFFER_H#menyertakan "Arduino.h"#menyertakan "StensTimer.h"struct EcoActionBuffer :public IStensTimerListener { long entryNo; tindakan int; int pin; durasi panjang; void timerCallback(Pewaktu* pengatur waktu); void switchPin(pin int, nilai bool); batal readStack(); proses batal(); batal keSerial(); void reset();};#endif
Chart about the communication and interfaces All implemented intents you can ask Alexa, including the response. (multilingual) If you are interested in the entrance step of your alexa json parsing.