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

Sensor Tekanan IoT:MKR GSM + Arduino Cloud + Google Spreadsheet

Komponen dan persediaan

Arduino UNO
× 1
Arduino MKR GSM 1400
× 1
Transduser Tekanan (0-150 psi)
× 1
Sensor Suhu &Kelembaban Adafruit DHT22
× 1
Modul RTC DS3231
× 1
Adafruit Logic Level Converter - BSS138 - 4-channel I2C-safe Dua arah
× 1
Baterai LiPo 3.7V Adafruit (2000 mAh atau lebih besar)
× 2
Konverter Peningkatan Tegangan
× 1
Kit Pemula Dasar dengan Berbagai Macam LED &Resistor
× 1
Breadboard (generik)
× 1

Aplikasi dan layanan online

Google Spreadsheet
Arduino IoT Cloud
Editor Web Arduino
Arduino IDE

Tentang proyek ini

Tujuan

Tujuan dari proyek ini adalah untuk membuat prototipe perangkat murah untuk memantau tekanan pada peralatan industri di lokasi terpencil menggunakan data seluler.

Panduan Proyek

Berikut ini adalah panduan langkah demi langkah proyek mengikuti aliran data dari transduser tekanan ke pemberitahuan email yang dihasilkan oleh skrip yang dilampirkan ke Google Sheet.

Langkah 1:Transduser Tekanan ke Uno

Transduser tekanan mengubah tekanan menjadi sinyal listrik analog.

Arduino Uno mengubah sinyal analog dari transduser tekanan menjadi tekanan (psi).

Langkah 2:Uno ke MKR GSM 1400 melalui Serial

Saat berkomunikasi antara dua perangkat Arduino melalui Serial:

  • Hubungkan RX di Perangkat #1 ke TX di Perangkat #2
  • Hubungkan TX di Perangkat #1 ke RX di Perangkat #2
  • Perangkat harus memiliki kesamaan

Frekuensi Transmisi Data (Uno ke MKR GSM 1400)

  • NORMAL: Setiap 30 menit (transmitFrequency) Uno akan serial.print data ke MKR GSM 1400 yang akan mengirimkan data ke cloud.
  • PICU TINGGI/RENDAH: Jika tekanan di atas 40 psi (highTrigger) atau di bawah 20 psi (lowTrigger) dan tetap di sana selama lebih dari 2 menit (dtLastTriggerLimit) Uno akan serial.print data ke MKR GSM 1400 yang akan mengirimkan data ke cloud.
  • POLL PERMINTAAN: Jika pin A1 pada Uno ditekan tinggi maka akan serial.print data ke MKR GSM 1400 yang akan mengirimkan data ke cloud. Catatan:pin A1 diberi nama "buttonPin" dalam sketsa untuk Uno. Ada 2 cara agar pin A1 pada Uno bisa terdorong tinggi. (1) Ada tombol tekan di papan tempat memotong roti. (2) Jika pin A3 pada MKR GSM 1400 tinggi maka akan mendorong pin A1 tinggi. Karena pin A3 dikendalikan oleh input di Arduino Cloud, tekanan saat ini dapat diperoleh dari jarak jauh kapan saja tanpa harus menunggu transmisi data yang dijadwalkan secara rutin.

Catatan

  • Sketsa untuk Uno dapat dimodifikasi sehingga beberapa input seperti suhu, kelembaban, tegangan baterai, dll. dapat dipantau dengan setpoint tinggi dan rendah selain tekanan dalam versi saat ini.
  • Kode yang digunakan untuk mengubah sinyal analog dari transduser tekanan menjadi tekanan (psi) didasarkan pada instruksi yang diberikan dalam video YouTube berikut:https://www.youtube.com/watch?v=AB7zgnfkEi4
  • Postingan berikut di Forum Arduino yang membahas "Dasar-dasar Input Serial" sangat membantu dalam menulis kode untuk berkomunikasi dari satu perangkat ke perangkat lain menggunakan data serial:https://forum.arduino.cc/index. php?topic=288234.0

Kode yang digunakan untuk Arduino Uno dalam proyek ini dilampirkan dengan komentar yang menjelaskan informasi penting.

Nama File:"InstrumentReader"

Langkah 3:MKR GSM 1400 ke Arduino Cloud melalui Seluler

MKR GSM 1400 memproses data serial dari Arduino Uno dan mengirimkan data ke Arduino Cloud menggunakan data seluler.

Perlu dicatat bahwa dalam kode untuk MKR GSM 1400 Anda akan melihat Serial1.read sebagai lawan dari Serial.read. Materi referensi di website Arduino memberikan penjelasan yang baik. Tabel pada gambar di bawah ini menunjukkan bahwa pin TX/RX pada papan MKR diakses melalui Serial1.

https://www.arduino.cc/reference/en/language/functions/communication/serial/

Arduino Cloud

Proyek ini diatur dengan 2 variabel di Arduino Cloud. Gambar di bawah ini menunjukkan bagaimana variabel-variabel ini ditampilkan di dasbor di Arduino Cloud.

Variabel pertama bernama "dataStringCloud" secara efektif merupakan paket semua data dari perangkat. Pendekatan ini diambil sebagai lawan dari satu variabel untuk setiap nilai untuk menyederhanakan pemrosesan data di Google Spreadsheet. Dengan nama variabel individual, sulit untuk membedakan antara nilai yang tetap sama dan nilai yang tidak diperbarui. Data dari paket ini diuraikan di Google Spreadsheet.

Variabel kedua bernama "pinCloud" digunakan untuk mengontrol MKR GSM 1400 dari Arduino Cloud. Ada fungsi sakelar dalam sketsa yang mengontrol tindakan berdasarkan nilai pinCloud. Ketika pinCloud =1, pin A1 didorong tinggi menyebabkan LED di papan menyala. Ketika pinCloud =2, pin A3 didorong tinggi yang mengarah ke Arduino Uno mengirimkan data saat ini seperti dijelaskan di atas.

Kode yang digunakan untuk Arduino MKR GSM 1400 dalam proyek ini dilampirkan dengan komentar yang menjelaskan informasi penting.

Nama File:"Perangkat Komunikasi"

Langkah 4:Arduino Cloud ke Google Spreadsheet melalui Webhook

Data ditransfer dari Arduino Cloud ke Google Spreadsheet menggunakan webhook.

Inti dari webhook adalah fungsi doPost yang ditulis dalam skrip file Google Spreadsheet.

Berikut adalah ringkasan singkat tentang cara menyiapkan webhook. Perhatikan bahwa prosesnya dimulai di Google Spreadsheet. Anda tidak sampai ke Arduino Cloud sampai akhir. Untuk pergi dari A ke B, mulai dari B.

  • Buat file Google Spreadsheet Baru
  • Klik "Alat" pada bilah alat &pilih "Editor skrip" di tarik-turun
  • Tulis kode dengan fungsi doPost (lihat GoogleSheetsScript.js yang dilampirkan pada proyek ini)
  • Klik "Publikasikan" pada bilah alat &pilih "Terapkan sebagai aplikasi web..." di tarik-turun
  • Sebuah kotak dialog akan muncul dengan 3 bidang.
  • (1) Versi Proyek: Selalu gunakan dropdown untuk memilih "Baru". Setelah pembaruan pertama, itu akan default ke # dari versi saat ini; jika Anda tidak menggunakan dropdown untuk memilih "Baru", perubahan tidak akan berlaku.
  • (3) Siapa yang memiliki akses ke aplikasi: "Siapa saja, bahkan anonim"
  • Tekan terapkan setelah memverifikasi nilai di 3 bidang
  • Kotak dialog kedua akan muncul dengan "URL aplikasi web saat ini". Ini adalah URL yang akan Anda salin &tempel ke tab webhook di Arduino Cloud. Perlu dicatat, URL ini tetap sama terlepas dari versi proyeknya.
  • Klik ok, dan selesai!

Sebagian besar kode JavaScript yang digunakan dalam proyek ini dimodelkan setelah kode yang digunakan dalam proyek lain bernama "Arduino IoT Cloud Google Sheets Integration". Tautan ke proyek ada di bawah. Saya sarankan untuk memeriksanya.

https://create.arduino.cc/projecthub/Arduino_Genuino/arduino-iot-cloud-google-sheets-integration-71b6bc?ref=part&ref_id=64347&offset=9

Langkah 5:Gunakan Google Spreadsheet untuk Mengurai Data

Gunakan Google Spreadsheet untuk mengurai nilai individual dari dataStringCloud dan menampilkan catatan unik yang ditransfer dari Arduino Cloud

Tautan di bawah adalah ke file Google Sheets yang digunakan untuk pengujian perangkat terbaru. Sel-sel dalam file ini diwarnai berdasarkan bagaimana mereka diisi seperti yang ditunjukkan dalam legenda di setiap lembar.

https://docs.google.com/spreadsheets/d/1XwCir2Llw8RvGPGgZI3Yk6U5a3LeIfUACNuO1Gr_LFQ/edit?usp=sharing

Langkah 6:Gunakan Google Spreadsheet untuk Mengirim Notifikasi

Anda mungkin telah memperhatikan bahwa ada dua fungsi dalam file JavaScript untuk proyek ini (GoogleSheetsScript.js) yang dirujuk di atas pada langkah 4.

  • Fungsi doPost - Mengirim data dari Arduino Cloud Webhook. Ini berjalan ketika ada data baru di Arduino Cloud.
  • fungsi sendEmail - Mengirim email berdasarkan nilai yang diekstrak dari lembar bernama "Data" di file Google Spreadsheet untuk proyek tersebut. Ini berjalan sekali setiap menit berdasarkan pengaturan di pengaturan pemicu.

Langkah-langkah untuk Menyiapkan Pemicu untuk fungsi sendEmail

  • Buka file Google Spreadsheet
  • Klik "Alat" di bilah alat
  • Pilih "Editor Skrip" di tarik-turun
  • Dari jendela Script editor lanjutkan ke:
  • Klik "Edit" di bilah alat
  • Pilih "Pemicu proyek saat ini" di tarik-turun
  • Dari jendela G Suite Developer Hub, lanjutkan ke:
  • Pilih "Tambahkan Pemicu" di pojok kanan bawah jendela
  • Pada kotak dialog yang muncul, buat pilihan untuk menjalankan fungsi sendEmail.
  • Catatan:menjalankan pemicu berdasarkan Time-Driven memungkinkan untuk menghasilkan notifikasi email saat perangkat berhenti memperbarui.

Masa Pakai Baterai

~24 jam

Ini dapat dioptimalkan dengan mematikan atau menghapus tampilan. Pilihan lain adalah menghapus sensor yang tidak penting seperti DHT22 dan DS3231.

Penggunaan Data

~0,7 megabyte/hari

Ini dapat dioptimalkan dengan mengurangi ukuran atau frekuensi transmisi data. Misalnya:Untuk mengurangi ukuran, hanya mengirim tekanan sebagai lawan tekanan, suhu, kelembaban, dan waktu. Untuk mengurangi frekuensi, hanya pembaruan per jam, bukan setiap 30 menit.

Biaya Proyek

Total =$241

  • Arduino MKR GSM 1400 ($70)
  • Arduino Uno ($22)
  • Baterai LiPo 2 x 3,7V ($30)
  • 2 x Tampilan LED ($29)
  • Kotak Plastik Tahan Cuaca ($22)
  • Sensor Tekanan ($19)
  • Sensor Suhu / Kelembaban - DHT22 ($10)
  • Modul RTC - DS3231 ($5)
  • Konverter Kenaikan Tegangan ($5)
  • Konverter Tingkat Logika ($4)
  • Lain-lain - LED, Resistor, Pengkabelan, dll. ($25)

Perangkat Keras / Alat

Semua perangkat keras dan alat yang digunakan untuk proyek ini dibeli dari berikut ini:

  • Arduino Online Store (https://store.arduino.cc/)
  • Adafruit (https://www.adafruit.com/)
  • Amazon (https://www.amazon.com/)
  • Pengangkutan Pelabuhan
  • Rumah Depot

Kesimpulannya...

Terima kasih telah meluangkan waktu untuk meninjau proyek ini.

Setiap dan semua pertanyaan / umpan balik / komentar / saran dipersilahkan / dihargai.

Kode

  • InstrumentReader - Sketsa untuk Arduino Uno
  • GoogleSheetsScript.js
InstrumentReader - Sketsa untuk Arduino UnoArduino
// Sketsa 1 dari 2// Arduino Uno // Data dikumpulkan oleh perangkat ini dan dikirimkan ke MKR 1400 melalui serial// Sensor DHT22 Memerlukan 2 pustaka, tetapi hanya satu yang dipanggil dalam kode. // (1):DHT Sensor Library:https://github.com/adafruit/DHT-sensor-library // (2):Adafruit Unified Sensor Lib:https://github.com/adafruit/Adafruit_Sensor #include #include #include  // RTC module#include  // DHT22#include "U8glib.h" // Velleman 128 x 64 OLED SPI Display // Catatan:Pustaka U8glib standar lainnya tidak berfungsi ketika saya mencoba menggunakannya untuk tampilan ini. Itu berhasil ketika saya menggunakan perpustakaan yang direkomendasikan oleh pabrikan. // Perpustakaan:https://www.velleman.eu/support/downloads/?code=VMA437 // Sintaks:https://github.com/olikraus/u8glib/wiki/userreference &https://github.com/ olikraus/u8glib/wiki/thelloworld//#include  // Opsi untuk menyimpan ke kartu SD di Ethernet Shield untuk Arduino UnoRTClib RTC;#define DHTPIN 11 // Pin digital terhubung ke sensor DHT#define DHTTYPE DHT22 / / DHT 22 (AM2302), AM2321DHT dht(DHTPIN, DHTTYPE);U8GLIB_SH1106_128X64 u8g(3, 4, 6, 7); // (CLK/SCK:3, MOSI:4, CS:6, DC(A0):7) // u8g(sck, mosi, cs, a0 [, reset]) int y_pos =0; // variabel global//const int chipPilih =10; // Opsi untuk menyimpan ke kartu SD di Ethernet Shield untuk Arduino Uno//float fileSizeSD =0.0; // Opsi untuk menyimpan ke kartu SD di Ethernet Shield untuk Arduino Unoint i =0; // Hitung # pembacaan yang dilakukan oleh Uno (sama seperti # loop dalam program) const int ledPin =9; // indikator transmisi (berkedip saat transmisi data terjadi)const int ledPin2 =8; // indikator push transmit (ditekan tinggi oleh tombol manual pada papan tempat memotong roti atau output dari MKR 1400 diaktifkan dari cloud)const int buttonPin =A1;int buttonState =0;int transmitFrequency =30; // Frekuensi Serial Print dataString untuk mengirim data ke perangkat kedua (menit)String pTransmitDateTime ="";int transmitCounter =0;int pTransmitMinute =0;int ptriggerTransmitAlertIndicator;float cRuntimeAtTriggerStart =0.0;float dtLastTrigger =0.0;int triggerCounter =0.0;int triggerTransmitAlertCounter =0;// Variabel Input untuk Mengontrol Triggerfloat lowTrigger =20.0;float highTrigger =40.0;float dtLastTriggerLimit =2.0; // Jika kondisi terpenuhi untuk jangka waktu ini, peringatan akan dibuatvoid setup (void) { Serial.begin(9600); Kawat.mulai(); dht.mulai(); pinMode(ledPin, OUTPUT); pinMode(ledPin2, OUTPUT); pinMode(tombolPin, INPUT); u8g.setRot180(); // flip screen, jika diperlukan (tambah/hapus komentar pada baris ini untuk memutar) // Opsi untuk menyimpan ke kartu SD di Ethernet Shield untuk Arduino Uno // Serial.print("Inisialisasi kartu SD..."); // if (!SD.begin(chipSelect)) // melihat apakah kartu ada dan dapat diinisialisasi // { // Serial.println("Kartu gagal, atau tidak ada"); //sementara (1); // jangan lakukan apa-apa lagi // } // Serial.println("card initialized.");}void loop (void) { delay(5000); DateTime sekarang =RTC.now(); float cRuntime =milis()/60000; float p =getPressure();// Serial.println(p); buttonState =digitalRead(buttonPin);// Serial.print("Button:");// Serial.println(buttonState); if(buttonState ==1) { digitalWrite(ledPin2, HIGH); penundaan (30000); // tunda untuk mengizinkan MKR1400 bersiap menerima data jika Uno:buttonPin didorong TINGGI oleh MKR1400:pingPin } else { digitalWrite(ledPin2, LOW); } float h =dht.readHumidity(); float t =dht.readTemperature(true); // t =dht.readTemperature(true) --> temp if derajat F &t =dht.readTemperature() --> temp if derajat C int transmitIndicator =0; if(now.minute() % transmitFrequency ==0 &&now.minute() !=pTransmitMinute) { transmitIndicator =1; pTransmitMinute =sekarang.menit(); pTransmitDateTime =String(now.hour())+String(":")+String(now.minute())+String(":")+String(now.second()); } int triggerStatus =0; if(p <=lowTrigger || p>
=highTrigger) { // Catatan:variabel yang direferensikan dalam kondisi untuk pernyataan if ini dievaluasi terhadap setpoint tinggi &rendah // Cepat untuk mengubah variabel mana yang dievaluasi - ini adalah hanya lokasi di mana variabel ditentukan triggerStatus =1; triggerCounter++; } else { triggerCounter =0; } if(triggerStatus ==1 &&triggerCounter ==1) { cRuntimeAtTriggerStart =cRuntime; } dtLastTrigger =cRuntime - cRuntimeAtTriggerStart; int triggerTransmitAlertIndicator =0; if((dtLastTrigger> dtLastTriggerLimit) &&triggerStatus ==1) { triggerTransmitAlertIndicator =1; triggerTransmitAlertCounter++; } else { triggerTransmitAlertCounter =0; } if(triggerTransmitAlertCounter> 0 &&triggerTransmitAlertCounter % 10 ==0) { flashLED(2,500); } int triggerPushTransmitAlertIndicator =0; if((triggerTransmitAlertIndicator ==1 &&triggerTransmitAlertCounter ==1) || ptriggerTransmitAlertIndicator !=triggerTransmitAlertIndicator) // if(TriggerStatus ada selama min waktu yang ditentukan untuk Alert &Count =1 artinya ini adalah loop pertama di mana waktu melebihi min yang ditentukan time // ATAU status triggerAlert berubah -- ini akan menghasilkan Push Alert jika TriggerStatus kembali ke 0 yang berarti kondisi Trigger tidak lagi terpenuhi.) { triggerPushTransmitAlertIndicator =1; flashLED (5.500); penundaan(5000); } ptriggerTransmitAlertIndicator =triggerTransmitAlertIndicator; // indikator saat ini disimpan ke indikator sebelumnya. Pada loop berikutnya nilai yang ditransfer di sini akan dibandingkan dengan nilai yang dihasilkan berdasarkan nilai baru. // Buat string String dataString =""; String cDateTime =""; String cHumTemp =""; String cP =""; dataString +="<"+String(i)+","+String(triggerTransmitAlertIndicator)+","+String(dtLastTrigger,0)+","+String(buttonState)+", "+String(sekarang.bulan ())+","+String(sekarang.hari())+","+String(sekarang.tahun())+", "+String(sekarang.jam())+","+String(sekarang .menit())+","+String(sekarang.detik())+", "+String(h)+","+String(t)+","+String(p)+">"; cDateTime +=String(now.month())+"/"+String(now.day())+"/"+String(now.year())+" "+String(now.hour())+ ":"+String(sekarang.menit())+":"+String(sekarang.detik()); cHumTemp +="H:"+String(h)+"% T:"+String(t)+"degF"; cP +="P:"+String(p)+"psi"; if(transmitIndicator ==1 || triggerPushTransmitAlertIndicator ==1 || buttonState ==1) { char dataArray[100]; dataString.toCharArray(dataArray, 100); Serial.println(dataArray); flashLED (10.500); mengirimkanPenghitung++; } // Serial.print("T:");// Serial.println(triggerStatus); penundaan(100); // tunggu sebentar hingga seluruh pesan tiba // loop gambar u8g.firstPage(); lakukan { draw(cDateTime,cHumTemp, cP,i,transmitCounter,now.minute(),transmitFrequency,pTransmitMinute); } while(u8g.nextPage()); penundaan (1000); // writeToSD(dataString); // Opsi untuk menyimpan ke kartu SD di Ethernet Shield untuk Arduino Uno i++;}void draw(String DcDateTime,String DcHumTemp, String DcP, int Di, int DtransmitCounter,int DnowMinute,int DtransmitFrequency, int DpTransmitMinute) { u8g.begin(); u8g.setFont(u8g_font_5x7); //u8g_font_micro //u8g_font_5x7 //u8g_font_5x8 //u8g_font_6x10 u8g.setFontPosTop(); u8g.setPrintPos(0,0); u8g.print(DcDateTime); u8g.setPrintPos(0,8); u8g.print(2); u8g.setPrintPos(10,8); u8g.print(DcHumTemp); u8g.setPrintPos(0,16); u8g.print("3#:"); u8g.setPrintPos(30,16); u8g.print(Di); u8g.setPrintPos(50,16); u8g.print(DcP); u8g.setPrintPos(0,24); u8g.print("4#t:"); u8g.setPrintPos(30,24); u8g.print(DtransmitCounter); u8g.setPrintPos(50,24); u8g.print("tFreq:"); u8g.setPrintPos(83,24); u8g.print(DtransmitFrequency); u8g.setPrintPos(0,32); u8g.print(5); u8g.setPrintPos(10,32); u8g.print("SekarangMenit:"); u8g.setPrintPos(70,32); u8g.print(DnowMinute); u8g.setPrintPos(0,40); u8g.print(6); u8g.setPrintPos(10,40); u8g.print("pTransmitMenit:"); u8g.setPrintPos(95,40); u8g.print(DpTransmitMinute); u8g.setPrintPos(0,48); u8g.print(7); u8g.setPrintPos(10,48); u8g.print("Sisa:"); u8g.setPrintPos(70,48); u8g.print(DnowMinute % DtransmitFrequency);}float getPressure(){ int sensorVal=analogRead(A2);// Serial.print("Nilai Sensor:");// Serial.print(sensorVal); tegangan float =(sensorVal*5.0)/1023.0;// Serial.print(" Volt:"); // Serial.print(tegangan); // Saat Tekanan =0, Input Analog =100 // Konversi Input Analog ke Tegangan:Input Analog =100 -> Tegangan =100*(5/1023) =0,4889 float m =((150-0)/(4,5- 0,4889); float b =150 - (m*4.5);// Serial.print(" m =");// Serial.print(m);// Serial.print(" b =");// Serial.print( B); float pressure_psi =((m*voltage)+ b);// Serial.print(" Pressure =");// Serial.print(pressure_psi);// Serial.println(" psi"); // tunda(200); return pressure_psi;}void flashLED(int num, int t){ for (int z =1; z <=num; z++) { digitalWrite(ledPin, HIGH); penundaan (t); digitalWrite(ledPin, RENDAH); penundaan (t); }}// Opsi untuk menyimpan ke kartu SD di Ethernet Shield untuk Arduino Uno //void writeToSD(String dataToWrite) //{ // // buka file. perhatikan bahwa hanya satu file yang dapat dibuka pada satu waktu, // // jadi Anda harus menutup yang ini sebelum membuka yang lain. // File dataFile =SD.open("datalog4.txt", FILE_WRITE); // fileSizeSD =dataFile.size(); // Mengembalikan ukuran file dalam byte // fileSizeSD =fileSizeSD / 1000000; // Mengonversi byte ke MB. 1 MB =1e6 byte // // jika file tersedia, tulis ke file tersebut:// if (dataFile) // { // dataFile.println(dataToWrite); // dataFile.close(); // // cetak juga ke port serial:// // Serial.println(dataToWrite); // } // // jika file tidak terbuka, muncul error:// else // { // Serial.println("error membuka datalog1.txt"); // } //}
GoogleSheetsScript.jsJavaScript
// Ada 2 fungsi dalam kode ini// fungsi doPost - Mengirim data dari Arduino Cloud Webhook. Ini berjalan ketika ada data baru di Arduino Cloud.// fungsi sendEmail - Mengirim email berdasarkan nilai yang diekstraksi dari lembar bernama "Data" di file Google Spreadsheet untuk proyek tersebut. Ini berjalan sekali setiap menit berdasarkan pengaturan di pengaturan pemicu. Untuk instruksi, lihat bagian fungsi sendEmail dari pos hub proyek.// Sebagian besar kode ini (selain fungsi sendEmail) dimodelkan setelah proyek berikut di Arduino Project Hub// https://create.arduino. cc/projecthub/Arduino_Genuino/arduino-iot-cloud-google-sheets-integration-71b6bc?f=1// Ini tautan ke repositori GitHub dengan Google Script yang digunakan untuk proyek yang disebutkan di atas di Project Hub. // Tautan ini disalin dari deskripsi proyek di Hub Proyek.// https://github.com/arduino/arduino-iot-google-sheet-script/blob/master/Code.gs// get active spreasheetvar ss =SpreadsheetApp.getActiveSpreadsheet();// dapatkan sheet bernama RawDatavar sheet =ss.getSheetByName("RawData");var sd =ss.getSheetByName("Data");var sref =ss.getSheetByName("Referensi"); var MAX_ROWS =1440; // jumlah maksimum baris data untuk ditampilkan// 3600s / cloud_int(30s) * num_ore(12h) =(60*60*12)/30 =(3600*12)/30 =1440 pembacaan dalam 12 jam pada pembaruan 30 detik interval// (60*24)/15 =96 pembacaan dalam periode 24 jam pada interval pembaruan 15 menit// 15 hari * 96 pembacaan/hari =1440 pembacaan// 90 hari * 96 pembacaan/hari =8640 pembacaan// 365 hari * 96 bacaan/hari =35040 bacaanvar HEADER_ROW =1; // indeks baris headervar TIMESTAMP_COL =1; // indeks kolom stempel waktu fungsi kolom doPost(e) { var cloudData =JSON.parse(e.postData.contents); // ini adalah objek json yang berisi semua info yang berasal dari IoT Cloud console.log(cloudData); //var webhook_id =cloudData.webhook_id; // benar-benar tidak menggunakan ketiganya //var device_id =cloudData.device_id; //var thing_id =cloudData.thing_id; nilai var =cloudData.values; // ini adalah larik objek json console.log(nilai); // Menyimpan nama dan nilai dari larik nilai // Setiap properti yang masuk memiliki:// nama yang akan menjadi nama kolom // nilai yang akan ditulis ke dalam baris di bawah header kolom var incLength =values.length; var incNama =[]; var incValues ​​=[]; for (var i =0; i  2018) { // buang semua pesan yang datang 'late' if (sheet.getRange(HEADER_ROW+1, 1).getValue() !='') { // HEADER_ROW + 1 =Row #2 &Column #1 --> ini adalah lokasi timestamp terbaru di lembar // Jika stempel waktu terbaru tidak kosong =(''), maka bandingkan waktu saat ini dengan stempel waktu data yang masuk // Jika stempel waktu terbaru kosong, kemungkinan besar pertama kali skrip dijalankan. // Dalam hal ini lewati pernyataan if ini dan lanjutkan untuk menulis di header kolom dan data. // Tidak masalah jika data datang terlambat (waktu saat ini vs stempel waktu data masuk). var sekarang =Tanggal baru(); // sekarang var COMM_TIME =120; // Catatan:diubah menjadi 120 untuk memungkinkan lebih banyak pesan masuk, sebelumnya ditetapkan pada 5 detik &berfungsi dengan baik // perkiraan waktu komunikasi yang terlalu tinggi antara cloud dan aplikasi jika (now.getTime() - date.getTime()> COMM_TIME * 1000) { // Jika perbedaan antara waktu sekarang dan waktu lebih besar dari 5 detik, buang datanya. // Ketika kondisi dalam pernyataan If ini bernilai benar, fungsi akan berhenti karena pernyataan kembali. kembali; // "Pernyataan return menghentikan eksekusi suatu fungsi dan mengembalikan nilai dari fungsi itu." } } // Bagian ini menulis nilai ke baris header berdasarkan nama properti yang masuk // Dengan kata lain, bagian ini membuat nama kolom // Menetapkan nama ke sel yang ada di baris header &di baris pertama kolom =lembar stempel waktu.getRange(HEADER_ROW, 1).setValue('stempel waktu'); for (var i =0; i  ini adalah 2 // kolom 1 adalah kolom stempel waktu. if (lastCol ==1) { // tulis nama kolom yang diawali dengan kolom setelah lastCol ==1 yang merupakan kolom timestamp // incNames adalah array yang berisi nama semua properti yang masuk // If lastCol ==1 , tulis nilai dari 'lokasi ke-i dalam larik incNames ke baris header di kolom #2 =lastCol + 1 sheet.getRange(HEADER_ROW, lastCol + 1).setValue(incNames[i]); } else { // dievaluasi jika lastCol !=1 // periksa apakah nama sudah ada di header var found =0; for (var col =2; col <=lastCol; col++) { // dimulai dengan kolom 2, ulangi semua kolom hingga lastCol mengevaluasi pernyataan if terlampir if (sheet.getRange(HEADER_ROW, col).getValue( ) ==incNames[i]) { // the condition of this If statement compares the value in the header row &column # =col to the 'i'th value in the array of incoming property names // This if statement is evaulated for each iteration of the for loop that it is enclosed in. // The condition is evaluated for all of the columns from column #2 to the last column. // It is checking to see if the 'i'th value in the incNames array exists in any of the columns in the header row. // If the 'i'th value in the incNames array finds a match to any of the values in the header row, set found =1 &exit the for loop with the break statment. found =1; merusak; // "The break statement breaks the loop and continues executing the code after the loop" } // close if statement evaluated for each iteration of the for loop that it is enclosed in. } // close for loop to check the 'i'th value in the incNames array to the values in the header row. if (found ==0) { // This If statemnt will be evaluated after the preceeding for loop has completed. // If found ==0 it means that the 'i'th value in the incNames array did not match any of the existing values in the header row. // If found ==0, write the 'i'th value in the incNames array to the column after the last column. // If new properties are added to the incoming data over time, the existing columns will not be impacted. The new property will be added to the column after the last column. sheet.getRange(HEADER_ROW, lastCol+1).setValue(incNames[i]); } // close if statement } // close else, since this is the end of the code block inside the main for loop, the next i will be evaluated up to i =incLength // The block of code inside this for loop is evaluated for each value at location i in the incNames array. // The values of i range from 0 to incLength (the number of values in the names array) // In JavaScript the index in arrays starts at 0. In other words, the 1st value in the array is at location =0. } // close main for loop used to write column names (assigning values from names array to header row) // redefine last coloumn and last row since new names could have been added var lastCol =sheet.getLastColumn(); var lastRow =sheet.getLastRow(); // delete last row to maintain constant the total number of rows if (lastRow> MAX_ROWS + HEADER_ROW - 1) { sheet.deleteRow(lastRow); } // insert new row after deleting the last one sheet.insertRowAfter(HEADER_ROW); // reset style of the new row, otherwise it will inherit the style of the header row var range =sheet.getRange('A2:Z2'); //range.setBackground('#ffffff'); range.setFontColor('#000000'); range.setFontSize(10); range.setFontWeight('normal'); // write the timestamp sheet.getRange(HEADER_ROW+1, TIMESTAMP_COL).setValue(date).setNumberFormat("yyyy-MM-dd HH:mm:ss"); // write values in the respective columns for (var col =1+TIMESTAMP_COL; col <=lastCol; col++) { // for loop to assign the value from incValues to the approrpriate column // This block of code was replaced by an if statement checking for blank values after the incoming data is populated. // Copy previous values // This is to avoid empty cells if not all properties are updated at the same time // sheet.getRange(HEADER_ROW+1, col).setValue(sheet.getRange(HEADER_ROW+2, col).getValue()); for (var i =0; i  2018), used to eliminate dupicate messages from the Arduino Cloud} // close doPost functionfunction sendEmail (){ var emailAddress =sd.getRange("V3").getValue(); var lastPressure =sd.getRange("K3").getValue(); // pressure at last update var lastUpdate =sd.getRange("A3").getValue(); // datetime of last update var ssLink ="https://docs.google.com/spreadsheets/d/1XwCir2Llw8RvGPGgZI3Yk6U5a3LeIfUACNuO1Gr_LFQ/edit#gid=1123486497"; var triggerAlertCount =sd.getRange("L6").getValue(); var triggerMonitor =sd.getRange("M3").getValue(); var dtLastStatusChange =sd.getRange("P3").getValue(); var dtLastDeviceUpdate1 =sd.getRange("S3").getValue(); var dtLastDeviceUpdate2 =sd.getRange("S4").getValue(); var emailSentNoUpdate =sd.getRange("T3").getValue(); var emailSentStartedReading =sd.getRange("U3").getValue(); var message ="Last Device Update:" + "\n" + lastUpdate + "\n\n" + " Last Pressure:" + "\n\t" + lastPressure.toFixed(2) + " psi" + "\n\n" + " Link to Spreadsheet:" + "\n\t" + ssLink; if(triggerMonitor ==0){ sd.getRange("L5").setValue(0); sd.getRange("L6").setValue(0); } if(triggerMonitor ==-1 &&triggerAlertCount <=4){ sd.getRange("L3").setValue(lastUpdate); // emailSent sd.getRange("L5").setValue(-1); sd.getRange("L6").setValue(triggerAlertCount + 1); var subject ="Status Change Alert - Outside Setpoints"; MailApp.sendEmail(emailAddress, subject, message); } if(triggerMonitor ==1 &&triggerAlertCount <=4){ sd.getRange("L3").setValue(lastUpdate); // emailSent sd.getRange("L5").setValue(1); sd.getRange("L6").setValue(triggerAlertCount + 1); var subject ="Status Change Alert - Normal"; MailApp.sendEmail(emailAddress, subject, message); } if(emailSentNoUpdate ==0 &&dtLastDeviceUpdate1> 60 &&dtLastDeviceUpdate2> 60){ sd.getRange("T3").setValue(1); // emailSentNoUpdate sd.getRange("U3").setValue(0); // emailSentStartedReading sd.getRange("T4").setValue(now.getTime()); // emailSentNoUpdate var subject ="Alert - Over 60 minutes Since Last Device Update"; MailApp.sendEmail(emailAddress, subject, message); } if(emailSentNoUpdate ==1 &&dtLastDeviceUpdate1 <60){ // removed the following from the condition:&&dtLastDeviceUpdate2> 60 sd.getRange("T3").setValue(0); // emailSentNoUpdate sd.getRange("U3").setValue(1); // emailSentStartedReading sd.getRange("U4").setValue(now.getTime()); // emailSentStartedReading var subject ="Alert - Device Started Updating"; MailApp.sendEmail(emailAddress, subject, message); }} 
CommunicationsDevice - Sketch for MKR 1400

Skema


Proses manufaktur

  1. ADLINK bermitra dengan Google Cloud untuk menawarkan solusi siap IoT
  2. IoT Dasar – RaspberryPI HDC2010 cara
  3. BMP180 I2C Digital Barometric Pressure Sensor
  4. Python/MicroPython Sensor Logger dengan Google Spreadsheet
  5. Windows 10 IoT Core pada Raspberry Pi 2 – Data Adafruit Sensor
  6. Windows 10 IoT Core dan SHT15
  7. UnifiedWater v1
  8. IOT - Smart Jar Menggunakan ESP8266, Arduino dan Sensor Ultrasonik
  9. Arduino Cloud Sensor Tower
  10. Arduino Apple Watch