Manufaktur industri
Industri Internet of Things | bahan industri | Pemeliharaan dan Perbaikan Peralatan | Pemrograman industri |
home  MfgRobots >> Manufaktur industri >  >> Manufacturing Technology >> Proses manufaktur

ArduFarmBot - Bagian 2:Stasiun Jarak Jauh Implementasi IoT

Komponen dan persediaan

Arduino Nano R3
× 1
Espressif ESP8266 ESP-01
× 1
Sensor Suhu DHT22
× 1
ky18
× 1
hidrometer
× 1
Relai (umum)
× 2
lcd 4X20
× 1
Sakelar Tombol Tekan SparkFun 12mm
× 3
LED (generik)
× 3

Aplikasi dan layanan online

ThingSpeak API

Tentang proyek ini

Tutorial ini merupakan lanjutan dari ArduFarmBot:Mengontrol Home Farm Tomat menggunakan Arduino dan IoT

Pada bagian pertama kami membuat stasiun kontrol lokal, menangkap informasi dari perkebunan tomat, seperti suhu, kelembaban udara relatif, luminositas, dan kelembaban tanah. Berdasarkan data tersebut, ArduFarmBot memutuskan secara otomatis jumlah yang tepat (dan kapan) perkebunan harus menerima panas dan air. Stasiun lokal yang dikembangkan di Bagian 1, juga memungkinkan intervensi manual dari operator untuk mengontrol pompa air dan lampu listrik. Pada Bagian 2 ini, kami akan menerapkan pendekatan IoT jika "intervensi manual" ini juga dapat dilakukan dari jarak jauh melalui Internet. Diagram blok menunjukkan bagaimana kita akan melakukan ini.

Perhatikan bahwa data yang diambil akan dikirim ke "layanan Cloud Storage" (dalam kasus kami Thinkspeak.com). Juga situs web khusus, "Halaman Kontrol Jarak Jauh" akan memantau dan menampilkan data tersebut hampir secara waktu nyata. Halaman web ini juga akan mengizinkan aktivasi jarak jauh pompa dan lampu.

Langkah 1:Daftar Bahan

  • Arduino Nano - ($7,50)
  • Sensor Suhu dan Kelembaban DHT22 atau DHT11 - ($3,66)
  • Sensor Luminositas - Modul resistor foto AD-018. atau yang setara - ($0,71)
  • 2X Sensor Kelembaban Tanah - ($1,99) (Opsional, bisa DIY)
  • LCD I2C 20X4 ($13,99)
  • LED (1X) ($0,20)
  • Modul Transceiver Nirkabel Wifi Serial Esp8266 Esp-01 - ($5,96)
  • Buzzer Aktif - Ky-12 atau setara ($0,60)
  • Modul Relai 2 X 5v ($11,60)
  • Melompat kabel (S1.00)
  • Resistor 10KOhm - ($0,03)
  • Resistor 2,2K Ohm - ($0,03)
  • Resistor 1,0K Ohm - ($0,03)
  • Resistor 220 Ohm - ($0,03)
  • Arduino Nano Shield ("Funduino") - ($7.28)
  • Keyboard membran (4 Tombol) - ($6.65)
  • Kotak Plastik

Langkah 2:Melengkapi Perangkat Keras

Mulai dari Local Station yang dikembangkan pada Part 1, satu-satunya tambahan HW yang dibutuhkan adalah ESP8266. Diagram Blok di atas, menunjukkan semua koneksi PIN Arduino dan komponen utama. Satu-satunya perawatan yang harus Anda miliki terkait dengan level tegangan. ESP8266 bekerja dengan 3.3V, jadi Pin Rx yang seharusnya tidak terhubung langsung ke Pin Nano Tx (D3). Level tegangan harus digunakan. Dalam kasus kami, kami akan membangun pembagi tegangan untuk digunakan sebagai konverter level tegangan. Diagram di atas menunjukkan lebih detail cara menghubungkan ESP8266. Jika Anda ingin tahu lebih banyak tentang ESP8266, silakan lihat tutorial saya:

  • ESP8266 Bagian 3 - Memicu LED Arduino dari Jarak Jauh
  • ESP8266 Bagian 1 - Modul WIFI Serial untuk Arduino
  • ESP8266 Bagian 2 - Server Web Arduino

Perhatikan bahwa kami menggunakan ESP8266 yang terhubung ke Nano Pin 2 (Tx) dan Pin 3 (Rx), menggunakan perpustakaan SoftSerial. Jika Anda ingin "membebaskan" pin digital tersebut, Anda dapat menggunakan pin Nano Serial 0 dan 1. Secara bergantian, hanya perlu diingat bahwa Anda harus melepaskannya saat mengunggah kode ke Nano.

CATATAN:Jika Anda ingin menghubungkan BUZZER, Anda harus melakukannya di pin D17 (sama dengan pin A3). Adalah baik untuk memiliki suara ketika Anda memiliki kesalahan komunikasi. Saya menggunakannya selama fase pengujian, meninggalkan proyek akhir (hw, tetapi kodenya disiapkan untuk itu). Terserah Anda memilikinya atau tidak.

Anda dapat menggunakan kode di bawah ini untuk menguji dan/atau menyiapkan ESP8266 Anda:

FC9DBPKIT682FY7.ino

Langkah 3:Koneksi ESP8266

Untuk menghubungkan ArduFarmBot ke Internet, kami akan menggunakan ESP8266, modul program yang sederhana, murah, dan mudah untuk proyek IoT. Setelah modul terpasang, hal pertama yang harus dilakukan adalah menerapkan "Reset" pada Pin CH-PD-nya.

/****************************************** ********* Atur ulang fungsi untuk menerima komunikasi************************************ ****************/void reset8266(void){ pinMode(CH_PD, OUTPUT); digitalWrite(CH_PD, RENDAH); penundaan (300); digitalWrite(CH_PD, TINGGI); Serial.print("Reset 8266 Oke"); lcd.clear(); lcd.println("8266 reset OK ");}  

Setelah mengatur ulang, mari sambungkan ke jaringan lokal Anda menggunakan kredensial Anda (dalam kode, ubah:USERNAME dan PASSWORD) dan untuk memulai modul sebagai "STA:Mode Stasiun" (CWMODE =1):

/****************************************** ********* Hubungkan WiFi*************************************** *************/void connectWiFi(void){ sendData("AT+RST\r\n", 2000, DEBUG); // reset sendData("AT+CWJAP=\"USERNAME\",\"PASSWORD\"\r\n", 2000, DEBUG); //Hubungkan penundaan jaringan(3000); sendData("AT+CWMODE=1\r\n", 1000, DEBUG); sendData("AT+CIFSR\r\n", 1000, DEBUG); // Tampilkan Alamat IP lcd.clear(); lcd.print("8266 Terhubung"); Serial.println("8266 Terhubung");} 

Untuk mengirim data ke ESP8266, fungsi sendData() digunakan:

/****************************************** ********* Kirim perintah AT ke modul************************************ ****************/String sendData(String command, const int timeout, boolean debug){ String response =""; esp8266.print(perintah); waktu int panjang =milis(); while ( (waktu + batas waktu)> milis()) { while (esp8266.available()) { // esp memiliki data jadi tampilkan outputnya ke jendela serial char c =esp8266.read(); // membaca karakter berikutnya. tanggapan +=c; } } if (debug) { Serial.print(respon); } kembalikan tanggapan;} 

Fungsi-fungsi di atas akan dipanggil selama "Fase Pengaturan" dari Kode kita. Jika semuanya dilakukan dengan benar, Anda akan melihat di Serial Monitor pesan serupa seperti di atas.

Langkah 4:Data Penyimpanan Cloud:ThinkSpeak.com

Semua data yang diambil oleh ArduFarmBot akan diunggah ke cloud, menggunakan layanan gratis "ThinkSpeak.com".

Pada fungsi "Loop()" (setelah kita menangkap data dengan readSensors() ), kita akan memanggil fungsi tertentu untuk mengunggah data yang diambil:updateDataThingSpeak();

/****************************************** ******** Mengirimkan data ke thingspeak.com************************************ *****************/void updateDataThingSpeak(void){ startThingSpeakCmd(); cmd =pesan; cmd +="&bidang1="; //bidang 1 untuk suhu DHT cmd +=tempDHT; cmd +="&bidang2="; //bidang 2 untuk kelembaban DHT cmd +=humDHT; cmd +="&bidang3="; //bidang 3 untuk luminositas LDR cmd +=lumen; cmd +="&field4="; //bidang 4 untuk data Kelembaban Tanah cmd +=soilMoist; cmd +="&bidang5="; //bidang 5 untuk Status PUMP cmd +=pumpStatus; cmd +="&bidang6="; //bidang 6 untuk LAMP Status cmd +=lampStatus; cmd +="\r\n"; sendThingSpeakCmd();}  

Untuk mengirim data tersebut, hal pertama yang harus dilakukan adalah memulai komunikasi dengan ThingSpeak. Kami akan melakukan ini, menggunakan finction:startThingSpeakCmd ();

/****************************************** ******** Mulai komunikasi dengan ThingSpeak.com************************************ *****************/void startThingSpeakCmd(void){ cmd ="AT+CIPSTART=\"TCP\",\""; cmd +=IP; cmd +=" \",80"; esp8266.println(cmd); penundaan(2000); if(esp8266.find("Kesalahan")) { Serial.println("ESP8266 MULAI KESALAHAN"); kembali; } Serial.println("Thinkspeak Comm Dimulai"); cmd="";} 

Setelah saluran terbuka dengan ThingSpeak dan string "cmd" digabungkan dengan data, sekarang saatnya untuk mengunggah semuanya ke saluran koresponden di ThingSpeak menggunakan fungsi:sendThingSpeakCmd();

/****************************************** ******** * Perbarui saluran ThingSpeak.com************************************ ****************/String sendThingSpeakCmd(void){ esp8266.print("AT+CIPSEND="); esp8266.println(cmd.length()); if(esp8266.find(">")){ esp8266.print(cmd); Serial.println(""); Serial.println(""); Serial.println(cmd); penundaan (500); String pesanBody =""; while (esp8266.available()) { String baris =esp8266.readStringUntil('\n'); if (line.length() ==1) { //konten aktual dimulai setelah baris kosong (yang memiliki panjang 1) messageBody =esp8266.readStringUntil('\n'); Serial.print("Pesan diterima:"); Serial.println(messageBody); } } kembalikan messageBody; } else{ esp8266.println("AT+CIPCLOSE"); Serial.println("ESP8266 CIPSEND ERROR:MENGIRIM ULANG"); //Kirim ulang... error=1; kembalikan "kesalahan"; }} 

Fungsi-fungsi di atas didasarkan pada tutorial hebat dan terperinci yang dikembangkan oleh Michalis Vasilakis. Untuk lebih jelasnya, silakan lihat tutorialnya:Arduino IOT:Suhu dan Kelembaban (dengan WiFi ESP8266).

Foto menunjukkan saluran ArduFarmBot di ThingSpeak.com.

Langkah 5:Memerintahkan aktuator dari web

Saat ini kami sedang mengunggah semua data yang dikumpulkan dan menyimpannya di cloud. Ini sangat bagus dan berguna untuk pemantauan jarak jauh, tetapi apa yang terjadi jika berdasarkan data tersebut kita juga ingin menyalakan Pompa atau Lampu, terlepas dari program otomatis lokal? Untuk melakukan itu, kita juga perlu "Mengunduh" data dari Cloud dan memerintahkan pengontrol untuk bertindak berdasarkan perintah tersebut.

Kami akan membuat bidang spesifik di saluran ThinkSpeak kami untuk memerintahkan aktuator:

Bidang 7:

  • Data =1 ==> POMPA harus AKTIF
  • Data =0 ==> POMPA harus DIMATIKAN

Bidang 8:

  • Data =1 ==> LAMPU harus NYALA
  • Data =0 ==> LAMPU harus DIMATIKAN

Oke, tetapi bagaimana cara mengatur bidang-bidang itu secara langsung di ThingSpeak? Kita bisa melakukannya, misalnya menulis "PlugIn" langsung di ThinksPeak, atau kita bisa menggunakan situs web eksternal untuk melakukannya (ini akan menjadi pilihan kita). Bagaimanapun, pada kedua kasus Anda harus menggunakan perintah seperti:

api.thingspeak.com/update?key=YOUR_WRITE_KEY&field7=1 

Dengan perintah di atas, misalnya (dan menggunakan saluran Anda Write Key), Anda akan menulis "1" di kolom 7, artinya POMPA harus dihidupkan. Anda dapat dengan mudah mengujinya, menulis baris perintah di atas di browser Anda, bidang koresponden di saluran Anda akan diubah. Sebagai gantinya, browser akan menampilkan halaman putih dengan satu nomor di sudut kiri atas, sesuai dengan entri data berurutan di saluran Anda.

50% dari pekerjaan selesai, sekarang Anda harus membaca "perintah" ini (data di lapangan), di stasiun ArduFarmBot lokal.

Perintah untuk melakukan ini ditunjukkan di bawah ini. Ini akan mendapatkan data terakhir yang ditulis di bidang tertentu (yang dalam kasus kami akan menjadi "perintah".

api.thingspeak.com/channels/CHANNEL_ID/fields/7/last 

Cara yang sama seperti yang kami lakukan sebelumnya, Anda dapat menguji baris perintah, menggunakan browser web Anda. Dalam hal ini, browser akan menampilkan data pada bidang tertentu itu. Lihat Foto di atas.

Kembali ke "bumi", mari kita tulis fungsi yang akan membaca "bidang terakhir" ini:

/****************************************** ********* Baca data dari field7 dari thingspeak.com********************************* *******************/int readLastDataField7(){ startThingSpeakCmd(); // "DAPATKAN /channels/CHANNEL_ID/fields/7/last"; cmd =msgReadLastDataField7; cmd +="\r\n"; String messageDown =sendThingSpeakCmd(); Serial.print("Perintah diterima:"); Serial.println(messageDown[7]); perintah int =messageDown[7]-48; kembalikan perintah;} 

Fungsi di atas akan mengembalikan data pada field 7 ("1" atau "0"). Fungsi serupa harus ditulis untuk Field 8.

Setelah kami memiliki konten dari kedua bidang, kami harus menggunakannya pada fungsi yang akan memerintahkan aktuator dengan cara yang sama seperti yang kami lakukan dengan "fungsi perintah manual":

/****************************************** ******** Terima Perintah dari thingSpeak.com********************************* *****************/void acceptCommands(){ field7Data =readLastDataField7(); if (bidang7Data ==1) { digitalWrite(PUMP_PIN, TINGGI); status pompa =1; showDataLCD(); } if (bidang7Data ==0) { digitalWrite(PUMP_PIN, RENDAH); status pompa =0; showDataLCD(); } penundaan (500); field8Data =readLastDataField8(); if (bidang8Data ==1) { digitalWrite(LAMP_PIN, HIGH); status lampu =1; showDataLCD(); } if (bidang8Data ==0) { digitalWrite(LAMP_PIN, RENDAH); status lampu =0; showDataLCD(); } penundaan (500); } 

Jadi, mulai sekarang Anda dapat menggunakan baris perintah di browser Anda untuk Menghidupkan/Mematikan Pompa dan Lampu dari jarak jauh. Foto di atas menunjukkan bagaimana perintah yang diterima akan muncul di monitor Serial Anda.

Pertimbangan penting lainnya adalah "koordinasi" antara komando lokal dan remote. Kita harus mengubah fungsi readLocalCmd() untuk juga memperbarui Thinkspeak Field 7 dan 8 masing-masing dengan status Pompa dan lampu (pada "pernyataan JIKA" korespondennya. Lihat kode lengkap di akhir tutorial ini):

field7Data =pumpStatus;field8Data =lampStatus; 

Sekarang "filed7Data" dan "field8Data" sinkron dengan perintah halaman web dan juga dengan tindakan perintah lokal saat Anda menekan tombol. Jadi, mari perbarui aplyCmd() fungsi, yaitu yang bertanggung jawab untuk menghidupkan/mematikan aktuator:

/****************************************** ******** Menerima Perintah dan bertindak berdasarkan aktuator********************************* *****************/void aplyCmd(){ if (field7Data ==1) digitalWrite(PUMP_PIN, HIGH); if (bidang7Data ==0) digitalWrite(PUMP_PIN, RENDAH); if (field8Data ==1) digitalWrite(LAMP_PIN, HIGH); if (field8Data ==0) digitalWrite(LAMP_PIN, LOW);} 

Saat Anda memulai pengujian, Anda akan menyadari bahwa setiap perintah yang Anda lakukan secara manual di lokal atau melalui web akan diatasi oleh tindakan otomatis yang ditentukan oleh fungsi autoControlPlantation() ; Pada titik ini Anda harus mempertimbangkan siapa yang akan menjadi "bos", memiliki kata terakhir! Dalam kasus kami di sini, kami akan mendefinisikan yang berikut:

  • Setiap siklus loop, yang hampir "selalu", kita akan melihat jika tombol ditekan
  • Sekitar setiap menit, kita harus melakukan "penggabungan" di ThingSpeak dan melihat apakah kita telah menerima pesanan dari sana.
  • Sekitar setiap 10 menit, kami akan membaca sensor, memperbarui data di ThingSpeak, dan yang lebih penting mengambil tindakan otomatis. Tindakan tersebut akan diambil terlepas dari apa yang dipilih secara manual dan tindakan yang akan disimpan.

Anda dapat mengubahnya, seperti yang Anda inginkan. Itu adalah hal yang baik tentang menggunakan prosesor yang dapat diprogram untuk mengendalikan berbagai hal!

Jadi, 2 timer akan digunakan sekarang, satu untuk mengumpulkan perintah jarak jauh dan satu lagi untuk membaca sensor (yang sama yang telah kita gunakan sebelumnya:

sampel panjangTimingSeconds =75; // ==> ******** Tentukan Waktu sampel dalam detik untuk membaca sensor *********int reverseElapsedTimeSeconds =0;waktu mulai lama =0;waktu berlalu lama =0;pengumpulan lamaRemoteCmdSeconds =20; // ==> ******** Tentukan waktu Pooling dalam hitungan detik untuk perintah ThingSpeak baru ********* long startRemoteCmdTiming =0; long elapsedRemoteCmdTime =0; 

Jadi, loop() fungsi sekarang harus ditulis ulang seperti di bawah ini:

void loop() { elapsedRemoteCmdTime =milis()-startRemoteCmdTiming; // Mulai timer untuk menggabungkan perintah jarak jauh elapsedTime =millis()-startTiming; // Mulai pengatur waktu untuk pengukuran reverseElapsedTimeSeconds =putaran (sampleTimingSeconds - elapsedTime/1000); readLocalCmd(); //Baca status tombol lokal showDataLCD(); if (elapsedRemoteCmdTime> (poolingRemoteCmdSeconds*1000)) { acceptCommands(); updateDataThingSpeak(); startRemoteCmdTiming =milis(); } if (Waktu berlalu> (sampleTimingSeconds*1000)) { readSensors(); autoControlPerkebunan(); updateDataThingSpeak(); startTiming =milis(); }} 

Langkah 6:Menerapkan Halaman Web khusus

Pada titik ini ArduFarmBot kami beroperasi dan dapat dikontrol dari web. Anda dapat memantau data di situs Thinkspeak dan juga mengirim perintah menggunakan browser, tetapi tentu saja "solusi web" ini tidak dapat dianggap sebagai "elegan"! Cara terbaik untuk menerapkan solusi IoT lengkap adalah dengan mengembangkan halaman web lengkap yang akan menampilkan semua data, juga memiliki tombol untuk mengaktifkan aktuator.

Saya memilih Byethost, hosting gratis, sangat mudah dan sederhana untuk menangani halaman Anda. Saya juga menggunakan kesempatan untuk melamar proyek ini, apa yang telah saya pelajari tentang spesialisasi online yang fantastis di Coursera/University of Michigan:Belajar Merancang dan Membuat Situs Web (Bangun portofolio web yang responsif dan dapat diakses menggunakan HTML5, CSS3, dan JavaScript ).

Saya tidak akan memasukkan secara detail bagaimana mengembangkan halaman tersebut, karena ini bukan tujuan utama dari tutorial ini, tetapi saya akan menyertakan kode sumber HTML, CSS dan JavaScript di sini. Dan begitu seseorang tertarik pada bagaimana saya mendapatkan hasilnya, kita dapat mendiskusikannya selain menggunakan Papan Komentar di akhir proyek.

Penting untuk menegaskan bahwa halaman ini tidak bekerja secara langsung dengan Stasiun Kontrol Lokal ArduFarmBot. Apa yang sebenarnya dilakukan adalah berinteraksi dengan saluran ThinkSpeak seperti di bawah ini:

  • Membaca data sensor pada bidang 1, 2, 3, 4
  • Membaca status aktuator pada kolom 5 dan 6
  • Menulis data pada kolom 7 dan 8
  • Membaca data cuaca lokal dari layanan Yahoo

Butir 4 di atas tidak terlalu penting untuk proyek, tetapi selalu merupakan data tambahan yang tersedia jika Anda ingin mengambil beberapa tindakan jarak jauh terlepas dari apa yang terjadi secara lokal dengan perkebunan tomat Anda. Pertimbangan lainnya adalah Anda dapat, misalnya, menyimpan data tersebut di Saluran ThingSpeak lain dan mengunduhnya ke Arduino Anda, menampilkan data cuaca pada layar LCD lokal (Saya mengembangkan ini pada proyek keren lain yang berfungsi dengan baik! Saya meninggalkannya di sini sebagai saran untuk Anda).

FQOK9ENIT653YX5.zip

Langkah 7:Kembali ke otak. Pendekatan Matriks Sensor-Aktuator:

Pada bagian pertama dari proyek ini, kami telah menetapkan beberapa pertimbangan awal tentang bagaimana aktuator harus bertindak tergantung pada pembacaan sensor. Kami hanya melakukan pilihan sederhana, tetapi apa yang akan terjadi jika kami memiliki situasi yang lebih kompleks? Beberapa kondisi berbeda? Yang akan kami kembangkan adalah “pendekatan matriks Sensor – Aktuator”.

Pada Matriks didefinisikan untuk setiap sensor, kondisinya dan bagaimana seharusnya output dari aktuator. Hasilnya dapat dilihat pada spreadsheet Excel yang disertakan di bawah ini. Pada file Excel ada dua spreadsheet. Tabel dengan filter dan versi di mana Anda dapat memilih beberapa kondisi sensor dan melihat bagaimana aktuator akan bekerja karena pemilihan ini.

Setelah Matriks didefinisikan, kita harus menerjemahkannya ke kode kita. Sebuah larik 18 baris dan 10 kolom dibuat untuk "menyalin" kondisi Matriks Sensor-Aktuator:

 // +---SOIL----+-LIGHT-+---TEMP---+---ACTUAT----+ // SL SM SH LL LH TL TM TH Pump Lampboolean SDf [18] [10] ={{ 1, 0, 0, 0, 1, 0, 0, 1, 1, 0 }, { 1, 0, 0, 0, 1, 0, 1, 0, 1 , 0 }, { 1, 0, 0, 0, 1, 1, 0, 0, 1, 1 }, { 1, 0, 0, 1, 0, 0, 0, 1, 1, 0 }, { 1 , 0, 0, 1, 0, 0, 1, 0, 1, 0 }, { 1, 0, 0, 1, 0, 1, 0, 0, 0, 1 }, { 0, 1, 0, 0 , 1, 0, 0, 1, 0, 0 }, { 0, 1, 0, 0, 1, 0, 1, 0, 0, 0 }, { 0, 1, 0, 0, 1, 1, 0 , 0, 0, 1 }, { 0, 1, 0, 1, 0, 0, 0, 1, 0, 0 }, { 0, 1, 0, 1, 0, 0, 1, 0, 0, 1 }, { 0, 1, 0, 1, 0, 1, 0, 0, 0, 1 }, { 0, 0, 1, 0, 1, 0, 0, 1, 0, 0 }, { 0, 0 , 1, 0, 1, 0, 1, 0, 0, 0 }, { 0, 0, 1, 0, 1, 1, 0, 0, 0, 1 }, { 0, 0, 1, 1, 0 , 0, 0, 1, 0, 0 }, { 0, 0, 1, 1, 0, 0, 1, 0, 0, 1 }, { 0, 0, 1, 1, 0, 1, 0, 0 , 0, 1 }, }; 

Untuk bekerja dengan Matrix, kami membuat fungsi defSensorStatus () . Fungsi ini menguji setiap baris jika kondisi 8 kolom pertama adalah TRUE. Jika Ya, kondisi 2 kolom terakhir dijalankan.

Misalnya:

if (1 dan 0 dan 0 dan 0 dan 1 dan 0 dan 0 dan 1) { pumpStatus =1; lampStatus =0}else if (1 dan 0 dan 0 dan 0 dan 1 dan 0 dan 1 dan 0) { pumpStatus =1; lampStatus =0} 

dan seterusnya.

Di dalam fungsi di atas, array lain dibuat dengan status setiap pembacaan sensor:

boolean snsSts[8]={0, 0, 0, 0, 0, 0, 0, 0}; // SL, SM, SH, LL, LH, TL, TM, TH 

Array variabel ini juga akan digunakan untuk register LOG.

F2HWXBYITA8WIN1.xlsx

Langkah 8:Pengoptimalan Kode

Selama proses pengembangan ArduFarmBot kami menyadari bahwa beberapa perubahan pada spesifikasi asli harus dilakukan:

Tampilan:

Layar LCD harus MATI secara default dan setiap kali pembacaan sensor diperlukan, kami dapat secara manual menyalakannya "ON". Kondisi ini diterapkan pada kode dan tombol "Sensors Read" harus digunakan seperti dalam mode "toggle" untuk Menghidupkan/mematikan LCD setiap saat. AKTIFKAN atau MATI layar akan memperbarui pembacaan sensor untuk ditampilkan, tetapi tidak digunakan oleh ArduFarmBot pada fungsi regulernya.

Penyiapan Awal:

Ketika ArduFarmBot ON (atau direset), LCD akan menampilkan "Initial Set-up". Untuk memulai menjalankan program, tombol "Sensor" harus ditekan. Informasi awal (lihat foto di atas) yang ditampilkan adalah:

  • Suhu DINGIN (yaitu 12oC)
  • Kelembaban Tanah KERING (yaitu 30%)
  • Kelembaban Tanah BASAH (yaitu 60%)
  • Terang GELAP (yaitu 40%)
  • P_ON Waktu pompa AKTIF (yaitu 10 detik)
  • SCAN Waktu untuk membaca sensor (yaitu 600 detik)
  • Versi SW_ (yaitu 4.1)

Catatan Log:

Untuk tujuan audit, kami telah membuat LOG dengan pembacaan dan aktuasi ArduFarmBot kami. Pada setiap siklus pembacaan, fungsi:storeDataLogEEPROM() dieksekusi.

/****************************************** ********* Penyimpanan data Log di Arduino EEPROM********************************* ******************/void storeDataLogEEPROM(void){ for (int i =0; i<8; i++) { logData =logData + (snsSts[i])<<1; } EEPROM.write (memoAddr, logData); memoAddr++; logData =0; logData =logData + pumpStatus; logData =logData <<1; logData =logData + lampStatus; EEPROM.write (memoAddr, logData); EEPROM.tulis (0, memoAddr+1); logData =0; if ((memoAddr+1) ==1023) memoAddr=1; else memoAddr++;}  

Seperti yang dikomentari di Langkah terakhir, apa yang akan disimpan di Arduino EEPROM adalah konten, sedikit dari array snsSts[] ditambah status Pompa dan Lampu. Di atas Anda dapat melihat LOG di Serial Monitor.

Semua kode ArduFarmBot dibagi dalam file yang berbeda agar lebih mudah dipahami. Perhatikan bahwa 2 file baru ditambahkan pada bagian kedua ini:

  • communication.ino (Fungsi khusus ThingSpeak dan ESP8266)
  • stationCredentials.h (ID Saluran ThingSpeak dan Tombol khusus untuk menulis di saluran)

Last but not least, setelah kode diakhiri dengan ukuran yang wajar, kami memutuskan untuk menyimpan data konstan dalam memori flash (program) alih-alih SRAM. Untuk itu, kami menggunakan kata kunci PROGMEM yang merupakan pengubah variabel. Misalnya, alih-alih menggunakan:

#define DHTPIN 5 

Kami menggunakan:

const PROGMEM byte DHTPIN =5; 

Kata kunci PROGMEN memberitahu kompilator "memasukkan informasi ini ke dalam memori flash", bukan ke SRAM, di mana biasanya akan pergi. Anda juga harus menyertakan perpustakaan avr/pgmspace.h di file utama kode Anda.

Prosedur lain yang baik untuk mengurangi penggunaan SRAM adalah mengomentari (atau menghapus) semua baris Serial.Print () yang Anda gunakan untuk debugging selama pengembangan. Anda akan menyadari bahwa kode yang digunakan misalnya untuk menampilkan LOG di Serial Monitor akan dikomentari pada file di bawah ini.

Di bawah ini Anda dapat menemukan kode Arduino ArduFarmBot lengkap. Jangan lupa untuk mengganti data dummy pada credential.h dengan Channel Id dan Write Key Anda. Juga di communication.ino, gunakan Nama Pengguna dan kata sandi asli Anda untuk menghubungkan ESP 8266 di Internet.

FTUT5VIIT67U8ME.ino FWMIPSSIT67U8MG.ino FJPGZNKIT67U8MK.ino FQH3X9VIT67U8NA.ino F15MY4YIT67U8NB.ino FVU64X1IT67U8NC.h FZ057E3IT67U8P5.h

Langkah 9:Peternakan Rumah MJRovai

Foto-foto di bawah ini menunjukkan foto berurutan ArduFarmBot mengendalikan Perkebunan Tomat Pertama saya.

The below photo sequence, shows my 2nd plantation evolution from seed plantation until the time to select the best plants (around 45 days) and the transplantations of best 6 plants.

Step 10:Conclusion

That's all folks! ...For now!

As always, I hope this project can help others find their way in the exciting world of electronics, IoT and Robotics!

Soon we probably will publish the third and last part of our project that I hope will be a very good recipe of a organic tomato sauce pasta.

By the way, on the above photo you can see the first sighs of life on Mauricio's plantation! And before you go, please give a look and the new ArduFarmBot, the book!, where I pack all project on a more friendly format:

ArduFarmBot, the Book!

"ArduFarmBot, the book" is also at Amazon.com! You can get it, by clicking hereThe book uses the electronic controller ArduFarmBot as a basis for teaching how to work in both HW and SW, with:

  • LCD and OLED type displays;
  • LEDs and buttons;
  • Activation of pumps and lamps via relays and
  • Sensors such as:DHT22 (temperature and relative air humidity), DS18B20 (soil temperature), YL69 (soil moisture) and LDR (luminosity).

All key stages of the project are documented in detail through explanatory texts, block diagrams, high-resolution color photos, electrical diagrams using Fritzing application, complete codes stored in GitHub and YouTube videos.

Two versions of the electronic controller ArduFarmBot are developed in detail in the book. From capture of data coming from a garden, such as air and soil temperature, relative humidity, soil moisture and luminosity, the ArduFarmBot helps to control when a crop should receive heat and water. Control will happen automatically, locally and remotely via internet. The book is divided into 3 parts. In the first part, the Arduino Nano is the starting point for development of a local version of ArduFarmBot , that can be controlled both, manually and automatically.

In the second part, the book dives into automation design, introducing remote operation through the creation of a webpage. The ESP8266-01 is used for Wi-Fi connection, sending data to an important web service in the field of IoT, the ThingSpeak.com .

In the third part, a second version of ArduFarmBot is developed, introducing the NodeMCU ESP8266-12E , a powerful and versatile IoT device, which replaces both the Arduino Nano and the ESP8266-01 , used in the earlier parts of the book.

In this last part of the book, a new service platform of the IoT universe, the Blynk , is also explored.

Download the book, give it a review and please use the message board here to give us any comment, suggestion or critic!

For more projects, please visit my blog:MJRoBot.org

Saludos from the south of the world!

See you at my next project!

Thank you

Marcelo

Kode

  • Cuplikan kode #1
  • Cuplikan kode #2
  • Code snippet #3
  • Code snippet #4
  • Code snippet #5
  • Code snippet #6
  • Code snippet #9
  • Code snippet #10
  • Code snippet #11
  • Code snippet #12
  • Code snippet #13
  • Code snippet #14
  • Code snippet #15
Cuplikan kode #1Teks biasa
/**************************************************** Reset funtion to accept communication****************************************************/void reset8266(void){ pinMode(CH_PD, OUTPUT); digitalWrite(CH_PD, LOW); delay(300); digitalWrite(CH_PD, HIGH); Serial.print("8266 reset OK"); lcd.clear(); lcd.println("8266 reset OK ");}
Cuplikan kode #2Teks biasa
/**************************************************** Connect WiFi****************************************************/void connectWiFi(void){ sendData("AT+RST\r\n", 2000, DEBUG); // reset sendData("AT+CWJAP=\"USERNAME\",\"PASSWORD\"\r\n", 2000, DEBUG); //Connect network delay(3000); sendData("AT+CWMODE=1\r\n", 1000, DEBUG); sendData("AT+CIFSR\r\n", 1000, DEBUG); // Show IP Adress lcd.clear(); lcd.print("8266 Connected"); Serial.println("8266 Connected");}
Code snippet #3Plain text
/**************************************************** Send AT commands to module****************************************************/String sendData(String command, const int timeout, boolean debug){ String response =""; esp8266.print(command); long int time =millis(); while ( (time + timeout)> millis()) { while (esp8266.available()) { // The esp has data so display its output to the serial window char c =esp8266.read(); // read the next character. response +=c; } } if (debug) { Serial.print(response); } return response;}
Code snippet #4Plain text
/**************************************************** Transmit data to thingspeak.com****************************************************/void updateDataThingSpeak(void){ startThingSpeakCmd (); cmd =msg; cmd +="&field1="; //field 1 for DHT temperature cmd +=tempDHT; cmd +="&field2="; //field 2 for DHT humidity cmd +=humDHT; cmd +="&field3="; //field 3 for LDR luminosity cmd +=lumen; cmd +="&field4="; //field 4 for Soil Moisture data cmd +=soilMoist; cmd +="&field5="; //field 5 for PUMP Status cmd +=pumpStatus; cmd +="&field6="; //field 6 for LAMP Status cmd +=lampStatus; cmd +="\r\n"; sendThingSpeakCmd();}
Code snippet #5Plain text
/**************************************************** Start communication with ThingSpeak.com****************************************************/void startThingSpeakCmd(void){ cmd ="AT+CIPSTART=\"TCP\",\""; cmd +=IP; cmd +="\",80"; esp8266.println(cmd); delay(2000); if(esp8266.find("Error")) { Serial.println("ESP8266 START ERROR"); kembali; } Serial.println("Thinkspeak Comm Started"); cmd ="";}
Code snippet #6Plain text
/*************************************************** * Update channel ThingSpeak.com****************************************************/String sendThingSpeakCmd(void){ esp8266.print("AT+CIPSEND="); esp8266.println(cmd.length()); if(esp8266.find(">")){ esp8266.print(cmd); Serial.println(""); Serial.println(""); Serial.println(cmd); penundaan (500); String messageBody =""; while (esp8266.available()) { String line =esp8266.readStringUntil('\n'); if (line.length() ==1) { //actual content starts after empty line (that has length 1) messageBody =esp8266.readStringUntil('\n'); Serial.print("Message received:"); Serial.println(messageBody); } } return messageBody; } else{ esp8266.println("AT+CIPCLOSE"); Serial.println("ESP8266 CIPSEND ERROR:RESENDING"); //Resend... error=1; return "error"; }}
Code snippet #9Plain text
/**************************************************** Read data from field7 of thingspeak.com****************************************************/int readLastDataField7(){ startThingSpeakCmd (); // "GET /channels/CHANNEL_ID/fields/7/last"; cmd =msgReadLastDataField7; cmd +="\r\n"; String messageDown =sendThingSpeakCmd(); Serial.print("Command received:"); Serial.println(messageDown[7]); int command =messageDown[7]-48; return command;}
Code snippet #10Plain text
/**************************************************** Receive Commands from thingSpeak.com****************************************************/void receiveCommands(){ field7Data =readLastDataField7(); if (field7Data ==1) { digitalWrite(PUMP_PIN, HIGH); pumpStatus =1; showDataLCD(); } if (field7Data ==0) { digitalWrite(PUMP_PIN, LOW); pumpStatus =0; showDataLCD(); } delay (500); field8Data =readLastDataField8(); if (field8Data ==1) { digitalWrite(LAMP_PIN, HIGH); lampStatus =1; showDataLCD(); } if (field8Data ==0) { digitalWrite(LAMP_PIN, LOW); lampStatus =0; showDataLCD(); } delay (500); }
Code snippet #11Plain text
/**************************************************** Receive Commands and act on actuators****************************************************/void aplyCmd(){ if (field7Data ==1) digitalWrite(PUMP_PIN, HIGH); if (field7Data ==0) digitalWrite(PUMP_PIN, LOW); if (field8Data ==1) digitalWrite(LAMP_PIN, HIGH); if (field8Data ==0) digitalWrite(LAMP_PIN, LOW);}
Code snippet #12Plain text
long sampleTimingSeconds =75; // ==> ******** Define Sample time in seconds to read sensores *********int reverseElapsedTimeSeconds =0;long startTiming =0;long elapsedTime =0;long poolingRemoteCmdSeconds =20; // ==> ******** Define Pooling time in seconds for new ThingSpeak commands *********long startRemoteCmdTiming =0; long elapsedRemoteCmdTime =0;
Code snippet #13Plain text
void loop() { elapsedRemoteCmdTime =millis()-startRemoteCmdTiming; // Start timer for pooling remote commands elapsedTime =millis()-startTiming; // Start timer for measurements reverseElapsedTimeSeconds =round (sampleTimingSeconds - elapsedTime/1000); readLocalCmd(); //Read local button status showDataLCD(); if (elapsedRemoteCmdTime> (poolingRemoteCmdSeconds*1000)) { receiveCommands(); updateDataThingSpeak(); startRemoteCmdTiming =millis(); } if (elapsedTime> (sampleTimingSeconds*1000)) { readSensors(); autoControlPlantation(); updateDataThingSpeak(); startTiming =millis(); }}
Code snippet #14Plain text
 // +---SOIL----+-LIGHT-+---TEMP---+---ACTUAT----+ // SL SM SH LL LH TL TM TH Pump Lampboolean SDf [18] [10] ={{ 1, 0, 0, 0, 1, 0, 0, 1, 1, 0 }, { 1, 0, 0, 0, 1, 0, 1, 0, 1, 0 }, { 1, 0, 0, 0, 1, 1, 0, 0, 1, 1 }, { 1, 0, 0, 1, 0, 0, 0, 1, 1, 0 }, { 1, 0, 0, 1, 0, 0, 1, 0, 1, 0 }, { 1, 0, 0, 1, 0, 1, 0, 0, 0, 1 }, { 0, 1, 0, 0, 1, 0, 0, 1, 0, 0 }, { 0, 1, 0, 0, 1, 0, 1, 0, 0, 0 }, { 0, 1, 0, 0, 1, 1, 0, 0, 0, 1 }, { 0, 1, 0, 1, 0, 0, 0, 1, 0, 0 }, { 0, 1, 0, 1, 0, 0, 1, 0, 0, 1 }, { 0, 1, 0, 1, 0, 1, 0, 0, 0, 1 }, { 0, 0, 1, 0, 1, 0, 0, 1, 0, 0 }, { 0, 0, 1, 0, 1, 0, 1, 0, 0, 0 }, { 0, 0, 1, 0, 1, 1, 0, 0, 0, 1 }, { 0, 0, 1, 1, 0, 0, 0, 1, 0, 0 }, { 0, 0, 1, 1, 0, 0, 1, 0, 0, 1 }, { 0, 0, 1, 1, 0, 1, 0, 0, 0, 1 }, };
Code snippet #15Plain text
/**************************************************** Storage of Log data at Arduino EEPROM****************************************************/void storeDataLogEEPROM(void){ for (int i =0; i<8; i++) { logData =logData + (snsSts[i])<<1; } EEPROM.write (memoAddr, logData); memoAddr++; logData =0; logData =logData + pumpStatus; logData =logData <<1; logData =logData + lampStatus; EEPROM.write (memoAddr, logData); EEPROM.write (0, memoAddr+1); logData =0; if ((memoAddr+1) ==1023) memoAddr=1; else memoAddr++;} 
ArduFarmBot GitHub
https://github.com/Mjrovai/ArduFarmBot

Skema

ardufarmbot_qpNcBDX6Jr.fzz

Proses manufaktur

  1. Tren Implementasi IoT
  2. 6-Shooter:Stasiun Pencampur Minuman Arduino
  3. Sensor Multi Suhu
  4. MotionSense
  5. Keselamatan Kebakaran Printer 3D
  6. Pengukur IoT dengan Arduino, Yaler &IFTTT
  7. Arduino Repulsive Electromagnetic Levitation
  8. Bot Gripper Kontrol Jarak Jauh
  9. Datalogger Balon Cuaca Bertenaga Arduino
  10. CoroFence - Detektor Termal🖖