Stasiun cuaca di Arduino dari A hingga Z. Bagian 5

Bagian akhir. Bagian sebelumnya .


Daftar isi:



Sensor tempel. Perangkat lunak


Bicara tentang perangkat lunak untuk sensor luar negeri. Setelah itu, Anda akan mendapatkan sistem lengkap yang sudah dapat Anda coba.


Biarkan saya mengingatkan Anda bahwa server adalah unit rumah pusat yang dapat berkomunikasi dengan Internet melalui WiFi, dan klien adalah sensor jarak jauh yang out-of-the-box yang mentransmisikan data ke server melalui udara.


Kode sumber untuk server dan klien ada di sini .
Teks sumber dilengkapi dengan komentar terperinci.


Hampir tidak ada yang perlu dikonfigurasi pada klien.


Pemancar radio nRF24L01 +, lebih tepatnya perpustakaan RadioHead, membutuhkan alamat server dan klien untuk ditentukan. Alamat disediakan jika Anda memiliki lebih dari satu server dan klien. Sebuah alamat hanyalah sembarang bilangan bulat. Ketika klien mengirim paket data ke server, itu menunjukkan server mana paket ini untuk. Server, mengetahui alamatnya sendiri, pada gilirannya, menentukan apakah paket ini ditujukan untuknya.


Karenanya, SERVER_ADDRESS di server dan di klien harus sama, tetapi CLIENT_ADDRESS untuk klien yang berbeda harus berbeda. Dengan kata lain, jika Anda menghubungkan sensor baru lain ke sistem kami di masa depan, maka CLIENT_ADDRESS perlu diubah untuk itu.


 //     #define SERVER_ADDRESS 10 #define CLIENT_ADDRESS 20 //     !!! 

RF_CHANNEL saluran radio RF_CHANNEL harus sama untuk semua orang. Secara default adalah 2. Saya mengubah nomor default, Anda dapat memilih yang lain.


 //  .       #define RF_CHANNEL 73 

Pengaturan voltmeter untuk mengukur tegangan pasokan baterai harus diubah:


 //   ,   const float r1 = 100400; // 100K const float r2 = 9960; // 10K //      //    http://localhost/arduino-secret-true-voltmeter/ const float typVbg = 1.082; //    1.0 -- 1.2  

Untuk menghemat energi, pustaka daya rendah Ringan untuk Arduino digunakan .


Berikut ini adalah pengukuran konsumsi aktual saya untuk Arduino Pro Mini dengan Lib ini:


  • biasanya 25mA
  • ketika bekerja dengan DHT sama
  • dengan transmisi radio 38 mA
  • di LowPower.idle 15 mA
  • di LowPower.powerdown 7,5 mA

Klien melakukan pengukuran suhu, kelembaban dan tegangan suplai, mengemas semua ini ke dalam struktur data, mengirimkan data ke server dan “tertidur”. Jika kesalahan terjadi selama transfer, transfer segera diulang.


Server (pusat, unit rumah), pada gilirannya, menerima data, mengonfirmasi penerimaan dan memprosesnya.


Database, MySQL, PHP, WWW-server


Setelah pekerjaan selesai, kami memiliki desain stasiun cuaca yang berfungsi penuh. Tapi sekarang ada selusin sepeser pun stasiun cuaca seperti itu, kerajinan lokal tidak lagi modis. Lagipula, kita punya internet.


Oleh karena itu, kami akan berbicara tentang bagaimana akses ke Internet ini dilakukan, kami akan melampirkan database dan tampilan web ke stasiun cuaca kami.


Pernyataan masalah untuk "webcam":


  • menerima dan menyimpan data stasiun cuaca: suhu, kelembaban, tekanan atmosfer, tegangan suplai
  • tampilkan data ini
  • membangun grafik.

Dalam hal ini, kita perlu hosting dengan dukungan untuk Apache, PHP dan MySQL dengan modul mysqli. Dan kondisi ini dipenuhi oleh hampir semua hosting di planet Bumi. Atau alih-alih hosting akan ada komputer Anda memainkan peran server yang terhubung ke router jaringan rumah dan memiliki akses Internet.


Pembuatan basis data


Mari kita mulai dari awal, yaitu dengan desain dan pembuatan database.


Basis data adalah dunia Anda dan Anda dapat mempelajarinya untuk waktu yang lama, jadi kami akan menyentuh secara singkat hanya hal-hal yang secara langsung kami butuhkan.


Semua skrip SQL berada di direktori weather-station/server/php-sql/


Di mana desain database dimulai? Dengan representasi logis dan fisik.


Tampilan logis atau skema basis data:


  • Tabel suhu dan kelembaban DHT
  • tabel data tekanan dan suhu sensor BMP
  • tabel yang ditunjukkan tidak memiliki hubungan satu sama lain, lebih tepatnya, tidak ada tautan yang diperlukan.

Skema fisik bergantung pada DBMS dan tipe data tertentu. Lebih mudah dibongkar dengan contoh tertentu. make_tables.sql SQL make_tables.sql skema logis dan fisik.


Setiap tabel harus memiliki bidang tipe


 id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT 

Nama bidang mungkin berbeda di basis data yang berbeda, tetapi hanya ada satu pengertian - ini adalah pengidentifikasi unik, kunci rekaman. Untuk masa depan, jika Anda melihat database dalam tabel yang tidak memiliki counter seperti itu, Anda harus tahu bahwa database ini dirancang oleh seseorang yang sangat jauh dari pemrograman, kemungkinan besar humaniora.


Kami menyimpan data dari sensor dari tipe yang sama dalam satu tabel, untuk sensor dari tipe lain, kami membuat tabel lain. Ini sedikit menyulitkan database dan PHP mengikatnya, tetapi menyederhanakan ekstensi atau modifikasi seluruh sistem di masa depan.


Ada dua tabel di proyek kami. Tabel arduino_dht menyimpan data dari sensor tipe DHT (suhu, kelembaban), tabel arduino_bmp menyimpan data dari sensor tipe BMP (suhu, tekanan). Jika di masa depan Anda ingin memiliki, misalnya, sensor gas atau detektor gerakan, kemudian buat tabel tambahan, jangan malas. Jika Anda menghubungkan sensor lain dari tipe DHT11 atau DHT22, maka Anda tidak perlu membuat tabel tambahan, gunakan tabel arduino_dht . Saya harap prinsipnya jelas: entitas fisik yang terpisah adalah tabel yang terpisah.


Jika data dari beberapa sensor dari jenis yang sama akan disimpan dalam sebuah tabel, lalu bagaimana mereka dapat dibedakan? Untuk melakukan ini, masukkan bidang di setiap tabel


 idSensor INTEGER 

Sebenarnya, ini adalah CLIENT_ADDRESS yang kami daftarkan di file client/client.ino untuk setiap instance klien-klien jarak jauh dan di server/server.ino untuk sensor yang terhubung langsung ke server - unit pusat.


Dalam sistem industri, harus ada tabel lain - korespondensi idSensor dan idSensor verbal yang dapat dibaca manusia. Sebagai contoh, sensor dengan idSensor = 2 adalah "Suhu, kelembaban di apartemen" , dll. Tetapi dalam proyek kami, kami tidak akan menyulitkan, hanya ingat bahwa:


  • sensor dengan idSensor , itu adalah CLIENT_ADDRESS , sama dengan 11 - ini adalah sensor rumah di server - unit pusat,
  • sensor dengan idSensor , juga CLIENT_ADDRESS , sama dengan 20 - ini adalah yang pertama (di proyek kami dan satu-satunya) klien sensor luar negeri.

Selanjutnya Tabel menyimpan data berikut:


  • ipRemote - alamat IP stasiun cuaca (server) dari mana data berasal, berguna untuk debugging dan pemantauan,
  • dateCreate - tanggal saat catatan dibuat,
  • milis - berguna untuk debugging, ini adalah waktu dalam milidetik sejak awal sketsa di Arduino,
  • suhu - suhu
  • kelembaban - kelembaban
  • tegangan - tegangan suplai,
  • tekanan - tekanan
  • kesalahan - jumlah kesalahan (tidak digunakan). Itu dimaksudkan untuk menyimpan jumlah kesalahan transmisi, dll., Sehingga Anda bisa mengevaluasi keadaan keseluruhan sistem dari jarak jauh.

Seperti yang Anda lihat, arduino_bmp dan arduino_bmp sangat mirip, perbedaannya hanya di bidang tekanan dan kelembaban, dan ada keinginan untuk membuang semuanya menjadi satu tumpukan (tabel). Tetapi bentuk normal pertama tidak memerintahkan untuk melakukan ini, banyak programmer pemula mencoba untuk mengatasinya, tetapi tidak satupun dari mereka yang berhasil, dan kami tidak akan melakukannya. Ini adalah bagaimana tidak memperhatikan hukum gravitasi universal, untuk saat ini mungkin akan berubah.


Tabel arduino_error_log berguna untuk debugging - ini adalah log kesalahan dan pesan sistem lainnya.


Membuat database dan penggunanya dengan hak dijelaskan di make_db.sql


 -- .  config.php --   CREATE DATABASE IF NOT EXISTS db_weather; --   CREATE USER 'u_weather'@'localhost' IDENTIFIED BY '***PASSWORD***'; GRANT ALL ON db_weather.* TO 'u_weather'@'localhost'; 

Ini dilakukan sekali, nama database dan nama pengguna dapat muncul dengan Anda sendiri. Dan apa yang sebenarnya perlu dilakukan adalah mengatur kata sandi Anda.


PHP dan server web


Semua pengaturan antarmuka web disimpan dalam config.php . Ubah sesuai dengan pengaturan basis data Anda.


Tetapkan zona waktu Anda dalam format PHP


 date_default_timezone_set('Europe/Prague'); 

Semua zona waktu yang tersedia dijelaskan di sini .


Tetapkan kunci rahasia Anda untuk akses (sebagai angka) yang harus cocok dengan SOURCE_KEY konstan dari sketsa server.ino


 $access_key = '***KEY***'; 

Di server web kami tidak ada otorisasi, entri kata sandi, ini akan menyulitkan seluruh desain. Untuk prototipe, ini tidak perlu. Oleh karena itu, semua perlindungan dibangun di atas file robots.txt , tidak adanya index.php dan kunci rahasia ini untuk diakses.


Script PHP utama weather.php menerima permintaan HTTP GET sederhana dengan data dan menyimpannya dalam tabel database yang sesuai. Jika kunci $access_key tidak cocok, maka permintaan akan ditolak.


weather-view.php digunakan untuk melihat tabel data dan berisi hyperlink ke skrip antarmuka web lainnya. Panggil dia seperti itu


 http:// / /weather-view.php?k= access_key 

Sebagai contoh


 http://yourhost/iot/weather-view.php?k=12345 

weather-view.php menampilkan label sederhana di mana Anda perlu mengingat bahwa:


  • sensor dengan id 11 adalah sensor rumah di server,
  • Sensor dengan id 20 adalah sensor jendela.

Skrip function.php berisi fungsi-fungsi yang umum untuk semua skrip PHP.


chart-dht.php bertanggung jawab untuk membuat chart menggunakan Google Charts . Di sini, misalnya, adalah grafik dari tegangan suplai sensor luar negeri. Tegangan naik pada hari yang cerah karena baterai surya, dan kemudian catu daya pada baterai secara bertahap habis.


Grafik


export-dht.php mengekspor data dari tabel database MySQL ke file CSV. Untuk impor dan analisis lebih lanjut dalam spreadsheet.


export-voltage.php mengekspor data pada tegangan suplai dari sensor jendela dari database MySQL ke file CSV. Berguna untuk debugging.


truncate.php menghapus semua tabel, mis. menghapus semua data kami. Berguna untuk debugging. Tidak ada tautan ke skrip ini dari weather-view.php , jadi Anda perlu menyebutnya melalui tautan langsung di bilah alamat browser Anda dengan $access_key .


Saat menerima data, fungsi mysqli_real_escape_string() umumnya digunakan untuk mencegah nilai yang salah dari memasuki database.


Jangan lupa untuk meletakkan robots.txt di root situs Anda untuk mencegahnya masuk ke mesin pencari.


ESP8266, WiFi dan transfer data


Dan sekarang kembali ke sketsa server.ino , ke bagian yang menghubungkan titik akses WiFi dan mengirimkan data ke server web.


Seperti yang sudah saya tulis, saya tidak dapat menemukan perpustakaan normal untuk Arduino untuk mengontrol modul ESP8266 menggunakan perintah AT, saya harus "pertanian kolektif" sendiri. Biarkan saya juga mengingatkan Anda bahwa Anda harus menginstal versi firmware tertentu di ESP8266-01. Dan sekarang ketika semuanya sudah siap, mari kita lihat cara kerjanya.


Untuk mengakses server web dalam sketsa server.ino , server.ino perlu mengubah konstanta ini


 const String DEST_HOST = " "; //  habr.com const String DEST_PORT = " "; //  80 const String DEST_URL = "/ /weather.php"; const String SOURCE_KEY= "  "; //    $access_key  config.php 

Di server.ino dalam fungsi void setup() , ESP8266 pertama kali beralih ke mode Station, mis. itu mulai bekerja sebagai klien WiFi


 espSendCmd(«AT+CWMODE_CUR=1», «OK», 3000); 

dan kemudian terhubung ke titik akses


 espState = espConnectToWiFi(); 

Jika koneksi tidak terjadi, maka upaya diulangi (satu kali)


 if ( espState != ESP_SUCCESS ) { delay(5000); Serial.println("WiFi not connected! Try again ..."); espConnectToWiFi(); } 

Kemudian pilih mode koneksi tunggal TCP / IP


 espSendCmd("AT+CIPMUX=0", "OK", 2000); 

Saat mengirim data dari sensor tipe DHT ke server web, fungsi digunakan yang menunjukkan type=dht data sebagai type=dht


 espSendData( "type=dht&t=" + String(dhtData.temperature) + "&h=" + String(dhtData.humidity) + "&v=" + String(dhtData.voltage) + "&s=" + String(CLIENT_ADDRESS) ); 

Saat mengirim data dari sensor BMP ke server web, fungsi yang sama digunakan dengan tipe data yang ditunjukkan sebagai type=bmp


 espSendData( "type=bmp&t=" + String(temperature_bmp) + "&p=" + String(pressure_bmp) + "&s=" + String(CLIENT_ADDRESS) ); 

Fungsi espSendData() menerima string permintaan HTTP GET dan mengirimkannya ke server web sebagaimana dimaksud.


Di dalam dirinya sendiri, espSendData() memeriksa ketersediaan modul ESP dengan mengirimkannya perintah "AT", lalu memeriksa koneksi WiFi dan menghubungkan kembali jika perlu. Kemudian data dikirim dan koneksi TCP ditutup.


Aplikasi Android


Saat ini, ketika semua orang bisa berkedip LED, Anda tidak akan mengejutkan siapa pun dengan stasiun cuaca. Tetapi jika pesawat tahu bagaimana berkomunikasi dengan server melalui WiFi, memiliki wajah web dan aplikasi mobile, maka ini adalah sesuatu! Dengan server di sini yang kami maksud tentu saja server aplikasi, mis. dalam kasus kami, ini adalah pengikatan PHP dan DBMS MySQL. Tidak ada ceri pada kue, yaitu aplikasi Android, yang akan kita tulis sekarang.


Arsitektur


Arsitektur seluruh platform perangkat lunak stasiun cuaca sederhana:


  • bagian server (unit pusat) stasiun cuaca mengumpulkan data dari klien sensor jarak jauh
  • kemudian mentransfer data ke server web aplikasi, yang menyimpan data ini ke database
  • Aplikasi Android (atau aplikasi jarak jauh lainnya: iOS, browser) meminta data dari server web dan menampilkannya di layar.

Pada layar perangkat Android, kami akan menampilkan pembacaan sensor terbaru saat ini.


HTTP DAPATKAN dan JSON


Pertanyaan yang perlu diselesaikan di tempat pertama adalah bagaimana data akan ditransfer dari server web ke aplikasi Android.


Tidak perlu menemukan apa pun di sini, semuanya telah diciptakan untuk kita - ini adalah HTTP GET dan JSON.


Dalam kasus kami, permintaan GET sederhana ke server web dapat dikompilasi dan didebug secara manual sementara aplikasi Android belum siap.


Di Jawa dan Android, ada pustaka siap pakai untuk memproses data dalam format JSON. JSON adalah format teks yang dapat dibaca manusia, yang berguna untuk debugging.


Untuk menghasilkan data saat ini dari sensor stasiun cuaca, buat skrip PHP baru data terakhir ke json.php di server web.


Panggilan skrip:


 http://<>/last-data-to-json.php?k=<access_key> 

di mana <access_key> , seingat kami, adalah kunci akses basis data rahasia.


Contoh respons dalam format JSON:


 { "DHT 11":{ "idSensor":"11", "dateCreate":"2016-04-20 18:06:03", "temperature":"19", "humidity":"26", "voltage":"5.01" }, "DHT 20":{ "idSensor":"20", "dateCreate":"2016-04-18 07:36:26", "temperature":"10", "humidity":"26", "voltage":"3.7" }, "BMP 11":{ "idSensor":"11", "dateCreate":"2016-04-20 18:06:22", "temperature":"19", "pressure":"987.97" } } 

Harus diingat bahwa kita memiliki 3 sensor. ID dan tipe mereka (DHT atau BMP) di-hardcode di seluruh kode stasiun cuaca. Metode pengkodean hardcore ini secara ideologis salah, tetapi untuk prototipe berlutut (di mana solusi cepat dan mudah diperlukan) ini adalah kompromi yang masuk akal.


 $idSensor = 11; //  DHT  $idSensor = 11; //  BMP  $idSensor = 20; //  DHT  

last-data-to-json.php mengambil data terbaru dari sensor heterogen ini dari basis data dan mengemasnya dalam format JSON. Pemilihan data dari database "dari akhir" berlangsung dengan cara ini:


 SELECT <> FROM <> ORDER BY id DESC LIMIT 1; 

Android


Sekarang kami akan menulis aplikasi Android sederhana yang meminta, menerima, menerjemahkan data JSON dan menampilkan informasi di layar.


Aplikasi Android kami akan sesederhana mungkin, hanya inti dari teknologinya. Lebih jauh di sekitar "kerangka" ini sudah mungkin untuk menghasilkan berbagai "keindahan".


Berikut adalah tangkapan layar dari apa yang harus dihasilkan


Android


Seperti yang Anda lihat, UI hanya sederhana, berdasarkan LinearLayout, tidak lebih.


Di bagian atas TextView menunjukkan ID sensor dan data cuaca mereka. Tombol Refresh memulai permintaan kedua ke server web. Berikutnya di EditText adalah satu-satunya pengaturan program - ini adalah URL permintaan dalam formulir


 http://< >/last-data-to-json.php?k=<access_key> 

Apa yang harus diperhatikan?


Dalam manifes, tambahkan baris yang memungkinkan Internet dan memeriksa status koneksi jaringan:


 <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.INTERNET" /> 

Bekerja dengan jaringan dan menerima data dari situs web adalah sebagai berikut.


Kami menggunakan AsyncTask untuk membuat tugas latar belakang terpisah dari utas UI utama. Tugas latar belakang ini mengambil URL permintaan dan menggunakannya untuk membuat HttpURLConnection .


Setelah koneksi dibuat, AsyncTask memuat konten halaman web (JSON) sebagai InputStream. Selanjutnya, InputStream dikonversi menjadi string, yang didekodekan menggunakan JSONObject dan ditampilkan di antarmuka pengguna menggunakan metode onPostExecute() .


Di MainActivity.java, ubah URL ke:


 private static final String defUrl = "http://host/dir/last-data-to-json.php?k=< >"; 

itu akan digunakan secara default saat pertama kali Anda menjalankan aplikasi Android.


Epilog


Ya, sesuatu sudah bekerja. Kemudian Anda dapat mengoptimalkan sesuatu, mengganti sesuatu, Anda dapat membuang semuanya, tetapi juga meminjam sesuatu.


Titik sakit besar yang terpisah adalah konsumsi energi . Saya merekomendasikan membaca komentar pada posting di mana ada banyak tips praktis.


Hingga tak terbatas ... dan seterusnya.

Source: https://habr.com/ru/post/id426019/


All Articles