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

Papan Sensor Lingkungan Multi-Mode MKR1000 – Petir, Gas, UV, Suhu, Kelembaban & Tekanan

Komponen dan Perlengkapan

Berikut adalah komponen yang dibutuhkan untuk papan sensor lingkungan multi-mode ini:

Tentang Proyek Ini

Saya suka memantau cuaca, dan saya ingin mencoba untuk menangkap dan menggambarnya. Stasiun cuaca rumah memungkinkan saya melihat detail untuk "sekarang", dan terkadang total untuk jam atau hari yang lalu. Saya ingin melakukan lebih, dan menggunakan Arduino untuk pekerjaan itu. Semua orang memulai dengan Suhu dan Kelembaban, terkadang Tekanan Barometrik, tetapi saya ingin lebih! Kecepatan angin dan pengukuran hujan masing-masing membutuhkan input perangkat keras. Setelah saya menguasai penggunaan i2c, saya menemukan hal-hal seperti Detektor Petir AS3935! Dan kemudian kesedihan datang... Saya tidak memiliki cukup interupsi hardware untuk melakukan pekerjaan dengan Arduino dasar Anda. Sparkfun bahkan memiliki papan sensor cuaca untuk Photon, tetapi masih terbatas. Saya harus memilih, dan melakukannya tanpa beberapa sensor. :-(

Kemudian saya melihat MKR1000, dan saya menemukan FITUR TERBAIK, itu memiliki 8 interupsi hardware! Sekarang saya bisa memilikinya semua!

Memilih Sensor Anda

Sensor datang dalam tiga rasa dasar:

MKR1000 memiliki cukup I/O untuk semua ini!

PERHATIKAN TEGANGAN YANG ANDA PERLUKAN UNTUK I/O ANDA pada I2C dan Interupsi! Misalnya, MKR1000, Photon, dan banyak varian Arduino menggunakan I/O 3.3v alih-alih 5v. Jika CPU dan sensor(s) yang Anda inginkan menggunakan tegangan berbeda, Anda juga akan perlu menggunakan level-shifter di antara perangkat tersebut.

Semua sensor yang saya gunakan cukup umum, tersedia dari Adafruit, SparkFun, Element-14 dan lainnya, dan biasanya berjarak antara $5-10(US). Sensor gas biasanya berjarak $10-$20. Untuk detektor petir (chip AS3935), saya memilih MOD-1016 dari Embedded Adventures, yang berjarak $26 (US) untuk mendapatkan antena di papan tersebut juga. Saya juga membeli Sparkfun Photon Weather Shield, karena saya memiliki Photon, dan saya mungkin akan membeli "meter cuaca" mereka (instrumen kecepatan dan arah angin). Mungkin saya akan menambahkan Sensor Kelembaban Tanah, setelah saya mengetahui di mana saya akan memasang MKR1000. Beberapa sensor tidak suka memiliki kabel panjang.

Atribusikan Sensor Anda ke Pin

Setelah Anda mengetahui sensor mana yang Anda inginkan, Anda akan mengetahui jenis input yang Anda butuhkan, langkah selanjutnya adalah memutuskan sensor mana yang akan ditempatkan di pin mana. Saya memulai di kertas, tetapi saya juga akan menambahkan daftar ini sebagai komentar blok dalam kode saya, sebagai pengingat.

Berikut adalah atribusi pin MKR1000 yang saya buat untuk papan sensor saya.

Memulai...

Untuk pemula di antara Anda, saya menyarankan memulai dengan setiap sensor yang akan Anda gunakan, satu per satu, dan mulai dengan memuat contoh kode, dan menginstal perpustakaan yang diperlukan. Ingatlah untuk mengubah pin sensor, agar sesuai dengan atribusi pin pilihan Anda, dan simpan salinan kode demo di folder proyek Anda.

Ketika Anda dapat menjalankan kode uji, dan membaca hasil dari Serial Monitor, Anda siap untuk mencoba menambahkan yang lain. Dan ketika Anda selesai menguji setiap sensor, mereka sekarang semua terhubung dan siap untuk mulai membangun sketsa yang lebih besar Anda!

Tinkering asli saya dengan sensor termasuk menggunakan Reat-Time Clock (RTC) berbasis i2c, sehingga saya dapat mencatat ke kartu memori SD. Meskipun MKR1000 memiliki RTC dan baterai sendiri, saya tidak bisa membuat jam tetap menjaga waktu hanya dengan baterai, jadi saya akan tetap menggunakan ChronoDot v2.1 i2c RTC juga.

Melihat papan pemancar dalam gambar saya di bawah, Anda dapat melihat berbagai jumper yang digunakan. Yang orange adalah untuk daya 3.3v ke setiap sensor, sehingga saya hanya dapat memasangnya saat saya siap untuk bekerja dengan mereka. (Mudah untuk menonaktifkan sensor dengan mencabut jumper oranye.)

Catatan tentang Perpustakaan

Saya menemukan bahwa beberapa perpustakaan yang dapat Anda instal, TIDAK berfungsi sempurna dengan MKR1000, dan/atau dengan versi Arduino.cc IDE 1.6.7, dan Anda mungkin perlu melakukan beberapa penyesuaian, tergantung seberapa tua sensor Anda. Salah satu contoh ini adalah makro ATOMIC_* yang lebih lama dalam perpustakaan AVR libc yang lebih lama (mereka dihapus di Arduino IDE 1.6.5), dan ada thread yang bagus tentang masalah dan solusi yang disarankan di thread forum pada Arduino.cc. Membuat beberapa perubahan yang disarankan adalah sesuatu bagi hacker Arduino menengah, tetapi mungkin akan menakutkan bagi hacker baru. Dan, untuk perpustakaan yang sedikit lebih lama, penulis asli mungkin tidak ada lagi untuk memperbarui perpustakaan dan menghilangkan ketergantungan.

Sayangnya, Anda biasanya tidak akan dapat mengetahui perpustakaan mana yang perlu disesuaikan sebelum Anda membeli sensor dan mengujinya. Pada titik itu, saya merekomendasikan Anda untuk melihat pesan kesalahan yang muncul di warna oranye saat Anda mencoba mengunggah sketsa Anda dengan hati-hati, untuk melihat apakah masalah ada di kode Anda, atau di perpustakaan, sebelum Anda mulai mengubah kode Anda. Jika masalahnya ada di perpustakaan, cari di web untuk "arduino" dan pesan kesalahan. Jika Anda tidak dapat menemukan solusi, coba kirim email ke penulis, dan beri tahu mereka tentang kesalahan, dan mungkin mereka akan memperbarui perpustakaan.

Saya membeli chip individual, mencoba untuk menghemat uang. Saya telah memutuskan bahwa, sampai saya siap dan mampu untuk membuat papan sirkuit sendiri (mungkin menggunakan EagleCAD dan OSHPark), lebih mudah untuk membeli modul sensor dari Adafruit dan SparkFun, karena mereka hebat dalam menjaga perpustakaan mereka diperbaiki.

Sebentar tentang WiFi dan Enkripsi

Saya juga memikirkan wifi untuk membuat sensor cuaca saya melaporkan ke situs web. Kami bahkan memiliki mesin enkripsi pada MKR1000, untuk membantu menjaga data kami aman dalam transit melalui Internet! Namun, itu lebih dari apa yang akan saya dapatkan dalam proyek pertama ini. Ini ada di daftar saya untuk dilakukan, karena membuat keamanan data sebagai bagian dari desain Anda penting untuk Internet of Things, tetapi saya kehabisan waktu untuk menambahkan entri saya untuk kontes MKR1000. Perhatikan "versi 2" saya dari proyek ini. Berikut adalah diagram blok modul SAMD yang merupakan jantung papan Anda.

Saya dapat memberikan satu tips untuk memulai dengan WiFi papan: Pastikan Anda menggunakan versi terbaru dari perpustakaan WiFi101! Jika tidak, sketsa Anda tidak akan mengenali modul wifi, dan sketsa wifi Anda hanya akan melaporkan bahwa jika ada pemeriksaan kesalahan pada panggilan ke modul wifi.) Saya perlu mengucapkan terima kasih kepada Charif Mahmoudi untuk menyebutkan hal itu dalam tutorial bagusnya "Memulai dengan MKR1000" di sini di Hackster! Pada saat saya hacking, Anda dapat menemukan WiFi101 Github di sini.

Tips untuk Sensor Analog

Sebagian besar modul sensor "output analog" akan menghasilkan output tegangan analog sederhana, dan ini mudah dibaca menggunakan analogRead dari pin sensor. Namun, kemudian Anda perlu mengetahui apa artinya. Biasanya, Anda akan perlu menggunakan perintah map , atau Anda mungkin perlu melakukan sedikit matematika. Elemen resistif biasanya akan memerlukan rangkaian tambahan. Anda mungkin ingin menambahkan potensiometer untuk "menyesuaikan halus" tegangan.

Dalam kasus lain, Anda akan perlu persamaan untuk mengubah output tegangan menjadi sesuatu yang akan dipahami manusia. Sensor suhu TMP36 adalah salah satu contoh yang baik terdokumentasi ini. Bagian ini dirancang untuk membaca dalam derajat Celsius, jadi Anda perlu mengukur tegangan, dan melakukan matematika untuk mendapatkan C, dan jika Anda ingin Fahrenheit, Anda akan perlu mengonversi C ke F. Membaca datasheet komponen akan menjelaskan bagaimana bagian itu bekerja, tetapi Anda akan menemukan lebih mudah untuk mengikuti jejak orang lain saat Anda membangun pengalaman Anda.

Sensor lain membutuhkan penguat, untuk membuat goyakan tegangan yang kecil cukup besar untuk ADC Anda mendapatkan rentang yang baik dari tinggi ke rendah. Jenis sensor ini (sel beban, kelembaban, akselerometer) adalah tempat saya menemukan paling baik untuk menaruh sedikit uang, dan membeli modul yang sudah memiliki amp, dan perpustakaan untuk membantu memahami rentang output.

Tips untuk Menggunakan Perangkat I2C

I2C terkadang disebut "antarmuka dua kabel", karena Anda perlu sinyal jam, serta sinyal data. (Anda hanya perlu satu kabel data, karena "master" dan "slave(s)" akan bergantian mengirim data padinya.) Tentu saja, sensor I2C Anda juga akan perlu kabel tanah dan kabel daya, dan kabel tanah itu perlu dihubungkan kembali ke CPU Anda.

Setiap perangkat I2C akan memiliki alamat heksadesimal pada bus. Sebaiknya hindari menggunakan beberapa perangkat dengan alamat yang sama. (Jika Anda ingin memiliki beberapa, Anda perlu mengelola mereka dengan rangkaian tambahan, untuk "mengaktifkan" yang ingin Anda berkomunikasi, dan kemudian menonaktifkannya ketika selesai, sebelum Anda mengaktifkan yang lain untuk berkomunikasi.) Dokumentasi seharusnya memberi tahu Anda alamat mana yang dapat dimiliki perangkat. (CATATAN: Jika Anda memiliki dua perangkat pada bus I2C dengan alamat yang sama, dan keduanya memiliki pin "Enable" atau "Shutdown", Anda akan dapat menonaktifkan satu saat yang lain aktif. Namun, Anda tidak dapat hanya mematikan daya ke pin vdd, karena sensor dapat mengambil beberapa daya dari pin SDA dan SCL, dan akan menghasilkan pembacaan yang buruk untuk alamat itu. Pemeriksaan kesalahan untuk I2C tidak cukup baik untuk mendeteksi/memperbaiki kasus ini.)

Spesifikasi I2C memberi tahu kita bahwa kita harus memiliki resistor "kuat" pull-up pada kedua kabel jam dan data, pada sensor yang paling jauh pada kabel. Karena ini, beberapa modul sensor sudah memiliki resistor di papan, dan Anda mungkin hanya perlu menambahkan beberapa jumper, jadi pastikan untuk membaca dokumentasi untuk modul(-modul).

Selain "resistor penghenti bus", saya juga telah menemukan petunjuk dari seorang hacker dari waktu yang lalu, untuk menambahkan resistor inline pada kedua kabel data (SDA) dan jam (SCL). Ini sangat meningkatkan keandalan pembacaan data dari beberapa sensor. Dengan MKR1000, menggunakan sinyal 3.3v, saya menggunakan resistor 220 ohm. Pada CPU 5-v, Anda mungkin ingin mencoba 330 ohm. Lihat skematik di bawah untuk melihat perbedaan dalam penempatannya.

Apa yang akan Anda lakukan dengan data?

Saat ini, saya hanya mengirimnya ke Serial Monitor. Anda dapat menambahkan LCD. Saya akan menambahkan kartu SD, tetapi sekarang setelah saya memiliki wifi bawaan, saya ingin mengunggah data ke cloud... bayangkan memiliki beberapa papan sensor ini di sekitar, mengetahui lintang dan bujur mereka, dan mampu mensusulkan colokan petir dengan membandingkan pembacaan daya dari setiap stasiun untuk suatu colokan petir!

CATATAN: 2017-11-29; Saya tidak bisa membuat interupsi hardware bekerja pada MKR1000. Saya membuat catatan dan eksperimen sensor untuk kelas 9 (usia 13-14), dan mungkin Anda akan menemukan sketsa menarik. Kelas ini dibangun di sekitar papan Adalogger M0, dan menyimpan data ke kartu SD, dan masih ada cukup pin untuk modul WiFi. https://arduinoclass.pbworks.com

Sementara saya bekerja pada sensor, saya juga menemukan lampu SODERSVIK di IKEA (Lihat gambar di bawah.). Bayangkan mengganti LED putih di dalam lampu ini dengan 20 Neopixels, dan menambahkan penerima remote IR. Angin yang berhembus bisa terlihat seperti awan yang melintas, dan warna dapat menunjukkan suhu. Remote juga dapat memilih untuk menunjukkan informasi lain untuk sementara waktu, seperti perubahan suhu selama 12 jam terakhir.

Apa yang ingin Anda pantau dan tampilkan?

Kode

Sketsa pemantauan lengkapArduino

Ada banyak sensor yang melaporkan dalam sketsa ini, dan perpustakaan bekerja sama dengan baik. Namun, metode penguncian interupsi klasik di AVR-libc telah dihapus dalam versi terbaru Arduino IDE, yang telah menonaktifkan perpustakaan untuk NeoPixel dan untuk sensor Petir. Saya harap ini akan diselesaikan pada tahun ini suatu saat, tetapi berarti bahwa saya telah mengecualikannya dari sketsa akhir.

/* RTC-Weather-Sensors_v6_MKR1000 by Zonker Harris Spring 2016 * Hooray! A small board, with more than 2 hardware interrupts! * Plus WiFi, *and* crypto (VERY necessary for IoT applications!) * * Note to newer hackers: I put MANY comments in my code, as you see. * When you click upload, *comments are IGNORED*, and do not eat memory! * I recommend that you also add plenty of comments when you make changes * and additions, to help you remember WHY you did what you did months ago. * They will also help those who come after you, to learn a thing or two. * * Now, libraries *DO* count against your program memory... */ #include <Wire.h> #include <Adafruit_Sensor.h> #include <Adafruit_BMP085_U.h> #include <Adafruit_HTU21DF.h> // Including neopixels as a placeholder, but the library interrupt vector needs updating. // Include the Adafruit_NeoPixel library https://github.com/adafruit/Adafruit_NeoPixel //#include <Adafruit_NeoPixel.h> //const int numLeds = 1; // How many neopixels in the string? used to set the NeoPixel library // Parameter 1 = number of pixels in strip // Parameter 2 = pin number (most are valid) // Parameter 3 = pixel type flags, add together as needed: // NEO_RGB Pixels are wired for RGB bitstream // NEO_GRB Pixels are wired for GRB bitstream // NEO_KHZ400 400 KHz bitstream (e.g. FLORA pixels) // NEO_KHZ800 800 KHz bitstream (e.g. High Density LED strip) //Adafruit_NeoPixel strip = Adafruit_NeoPixel(numLeds, 6, NEO_GRB + NEO_KHZ800); /* The BMP085_U driver uses the Adafruit unified sensor library (Adafruit_Sensor), which provides a common 'type' for sensor data and some helper functions. (The BMP180 is comptible with this library, and gives the same output, but the library will identify the BMP180 as a BMP085.) To use this driver you will also need to download the Adafruit_Sensor library and include it in your libraries folder. You should also assign a unique ID to this sensor for use with the Adafruit Sensor API so that you can identify this particular sensor in any data logs, etc. To assign a unique ID, simply provide an appropriate value in the constructor below (12345 is used by default in this example). */ Adafruit_BMP085_Unified bmp = Adafruit_BMP085_Unified(10180); /* This sketch also designed to work with the HTU21D-F sensor from Adafruit ----> https://www.adafruit.com/products/1899 */ Adafruit_HTU21DF htu = Adafruit_HTU21DF(); /* Macetech Chronodot v2.1 Battery-backed Real-Time Clock (RTC)... https://docs.macetech.com/doku.php/chronodot (because the battery on my MKR1000 doesn't seem to keep the on-board RTC alive) The Adafruit Real-Time Clock (RTC) Library info https://learn.adafruit.com/adafruit-data-logger-shield/using-the-real-time-clock Analog Devices TMP36 analog calibrated temperature sensor. This requires some math https://learn.adafruit.com/tmp36-temperature-sensor https://www.analog.com/media/en/technical-documentation/data-sheets/TMP35_36_37.pdf ML8511 UV sensor... This sensor detects 280-390nm light most effectively. This is categorized as part of the UVB (burning rays) spectrum and most of the UVA (tanning rays) spectrum. MOD-1016 (AS3935 Lightning Sensor) i2c address 0x03 - AS3935 Lightning Sensor Adafruit has an anemometer which provides a DC voltage out (0.4-2.0v) https://www.adafruit.com/products/1733 https://www.instructables.com/id/Breezefinder-Citizen-Science-Windpower-Tool/step2/Build-the-housing/ Soil Moisture Detector (YL-69 sensor or similar) requires analog input... https://www.instructables.com/id/Arduino-LCD-Soil-Moisture-Sensor/step3/Connect-moisture-sensor/ My MKR1000 Connections (All sensors must be 3.3v signalling!) =========== */ int UVOUT = A1; // Output from the MV8511 UV sensor int lightOut = A2; // Output from the TEMT6000 visible light sensor int tmp36out = A3; // Output from the TMP36 local temperature sensor int mq9out = A4; // Output from DFrobot MQ-9 CO/Combustable Gs sensor /* A5 Moisture Sensor A6 Wind speed sensor? 0 (HW INT) pushbutton 1 (HW INT) AS Lightning Detector 2 (HW INT) wind speed anemometer? (interrupt per rotation) 3 (HW INT) Rain Tipper… 4 5 */ int sounderPin = 6; // Piezo Sounder output (shared with on-board LED) // (You can use a jumper to disable the sounder, but the on-board LED will blink) int neopixelPin = 7; // NeoPixel output, for visualization using shift-register-based LEDs /*11 i2c SDA 12 i2c SCL */ // Decalring variables for the Chronodot i2c RTC... int addrRTC = (0x68); // RTC i2c address int seconds; //combined BCD from the RTC (00h) int seconds1; //0-9 int seconds10; //0-5 int minutes; //combined BCD from the RTC (01h) int minutes1; //0-9 int minutes10; //0-6 int hours; //combined BCD from the RTC (02h) int hours1; //0-9 int hours10; //0-2 int day; //1-7 (03h) int date; //01-31 (04h) int month; //01-12 (05h) int years; //0-99; (06h) int a1secs; // (07h) get Alarm 1 seconds int a1mins; // (08h) get Alarm 1 minutes int a1hrs; // (09h) get Alarm 1 hours int a1daydate; // (0Ah) get Alarm 1 day and date bits int a2mins; // (0Bh) get Alarm 2 minutes int a2hrs; // (0Ch) get Alarm 2 hours int a2daydate; // (0Dh) get Alarm 2 day and date bits int rtcstatus; // (0Eh) get RTC status bits int aginginfo; // (0Fh) get aging offset info // what is 10h? int temprtc; //combined BCD from the RTC (11h) int tempfrtc; //combined BCD from the RTC (12h) /**************************************************************************/ // Arduino setup function (automatically called at startup) /**************************************************************************/ void setup(void) { Serial.begin(9600); delay(1000); Serial.println("i2c Sensor Deck"); // Remember to set up your inputs and output pins! pinMode(UVOUT, INPUT); // the ML8511 UV sensor pinMode(lightOut, INPUT); // the TEMT6000 visible light sensor pinMode(tmp36out, INPUT); // the Analog Devices TMP36 temperature sensor pinMode(sounderPin, OUTPUT); // HIGH will cause the sounder to emit noise pinMode(neopixelPin, OUTPUT); // Use a 220-ohm resistor in-line to the strip /* Initialize the BMP085/BMP180 sensor */ if(!bmp.begin()) { /* There was a problem detecting the BMP085/180 ... check your connections */ Serial.print("Ooops, no BMP085/180 detected ... Check your wiring or I2C ADDR!"); while(1); } /* Display some basic information on this sensor, BMP180 reports as BMP085 */ displaySensorDetails(); /* Initialise the HTU21D sensor */ if (!htu.begin()) { Serial.println("Couldn't find the HTU21-DF sensor!"); while (1); } // Initialize the Chronodot RTC clock //(change the values, uncomment, then upload to set the time, then comment it out again) /* seconds = 0; minutes = 41; hours = 20; day = 7; date = 3; month = 1; years = 16; initChrono(); */ } void loop(void) { beep(50, 2); // announce the start of the loop on the sounder // Set the neopixel to Teal... //int red = 0; int green = 45; int blue = 30; //strip.setPixelColor(0, (red, green, blue)); //strip.show(); /**********************************************************************/ /* Pull the Chronot info i2c address 0x68 - DS1307 RTC */ /* Board info: https://docs.macetech.com/doku.php/chronodot */ /* DS3231 datasheet: https://datasheets.maxim-ic.com/en/ds/DS3231.pdf */ /**********************************************************************/ int temprtc; /* Get a new timestamp */ Wire.beginTransmission(0x68); // 0x68 is DS3231 device address Wire.write((byte)0); // start at register 0 Wire.endTransmission(); Wire.requestFrom(0x68, 13); // request 19 bytes (is the # of bytes DEC or HEX?) // (seconds, minutes, hours, day, date, month, hrs, // a1secs, a1mins, a1hrs // a1secs, a1mins, a1hrs // Aging offset, Temp integer, temp fraction) while(Wire.available()) { seconds = Wire.read(); // (00h) get seconds minutes = Wire.read(); // (01h) get minutes hours = Wire.read(); // (02h) get hours day = Wire.read(); // (03h) get day of the week date = Wire.read(); // (04h) get date of the month month = Wire.read(); // (05h) get the month, and century bit years = Wire.read(); // (06h) get the year int a1secs = Wire.read(); // (07h) get Alarm 1 seconds int a1mins = Wire.read(); // (08h) get Alarm 1 minutes int a1hrs = Wire.read(); // (09h) get Alarm 1 hours int a1daydate = Wire.read(); // (0Ah) get Alarm 1 day and date bits int a2mins = Wire.read(); // (0Bh) get Alarm 2 minutes int a2hrs = Wire.read(); // (0Ch) get Alarm 2 hours int a2daydate = Wire.read(); // (0Dh) get Alarm 2 day and date bits int rtcstatus = Wire.read(); // (0Eh) get RTC status bits int aginginfo = Wire.read(); // (0Fh) get aging offset info temprtc = Wire.read(); // (11h) get integer portion of the temp, and sign tempfrtc = Wire.read(); // (12h) get the fractional portion of the temp // Read our bits, and normalize the data with leading-zero padding // NOTE: The Chronodot doesn't know about Daylight Savings, shoulod your code? seconds10 = ((seconds & 0b11110000)>>4); seconds1 = ((seconds & 0b00001111)); // convert BCD to decimal minutes10 = ((minutes & 0b11110000)>>4); minutes1 = (minutes & 0b00001111); // convert BCD to decimal hours10 = (((hours & 0b00100000)>>5)*2 + ((hours & 0b00010000)>>4)*1); hours1 = (hours & 0b00001111); // convert BCD to decimal (assume 24 hour mode) years = (years + 2000); temprtc = ((temprtc & 0b01111111) + (((tempfrtc & 0b11000000)>>6)*0.25)); } get_date(); // This is one place you could add Dayligh Savings Time decisions to alter hours... Serial.print("ChronoDot - "); Serial.print(hours10); Serial.print(hours1); Serial.print(":"); Serial.print(minutes10); Serial.print(minutes1); Serial.print(":"); Serial.print(seconds10); Serial.print(seconds1); Serial.print(" 20"); Serial.print(years); Serial.print(" "); Serial.print(month); Serial.print(" "); Serial.print(date); Serial.print(" \t"); Serial.print(temprtc); Serial.println(" C"); delay(100); // so this will finish printing, in case the next sensor is stalled /**********************************************************************/ /* Get BMP180 data i2c address 0x77 - BMP180 Baro Pres and Temp */ /* data: https://www.adafruit.com/datasheets/BST-BMP180-DS000-09.pdf */ /**********************************************************************/ sensors_event_t event; bmp.getEvent(&event); /* First we get the current temperature from the BMP085/BMP180 */ float BMPtemperature; bmp.getTemperature(&BMPtemperature); float BMPtempF = (BMPtemperature * 1.8 + 32); Serial.print("Temp: "); Serial.print(BMPtemperature); Serial.print(" C ("); Serial.print(BMPtempF); Serial.print(" F) \t"); /* Display the results (barometric pressure is measure in hPa) */ if (event.pressure) { /* Display atmospheric pressue in hPa */ Serial.print("BMP180 - Pres: "); Serial.print(event.pressure); Serial.print(" hPa\t"); /* Calculating altitude with reasonable accuracy requires pressure * * sea level pressure for your position at the moment the data is * * converted, as well as the ambient temperature in degress * * celcius. If you don't have these values, a 'generic' value of * * 1013.25 hPa can be used (defined as SENSORS_PRESSURE_SEALEVELHPA * * in sensors.h), but this isn't ideal and will give variable * * results from one day to the next. * * * * You can usually find the current SLP value by looking at weather * * websites or from environmental information centers near any major * * airport. * * * * convert inches-mercury https://www.csgnetwork.com/pressinmbcvt.html * * * For example, for Paris, France you can check the current mean * * pressure and sea level at: https://bit.ly/16Au8ol */ /* Then convert the atmospheric pressure, and SLP to altitude */ /* Update this next line with the current SLP for better results */ float seaLevelPressure = SENSORS_PRESSURE_SEALEVELHPA; Serial.print("Alt: "); Serial.print(bmp.pressureToAltitude(seaLevelPressure, event.pressure)); Serial.println(" m"); delay(100); // so this will finish printing, in case the next sensor is stalled } else { Serial.println("Sensor error"); } /********************************************************************** /* Get HTU21-DF data i2c address 0x40 - Humidity and Temp Sensor * /* Then convert the atmospheric pressure, and SLP to altitude * /* Update this next line with the current SLP for better results * /* https://learn.adafruit.com/adafruit-htu21d-f-temperature-humidity-sensor/overview /**********************************************************************/ float HTUtemperature = htu.readTemperature(); float HTUtempF = (HTUtemperature * 1.8 + 32); Serial.print("HTU21-DF - Temp: "); Serial.print(HTUtemperature); Serial.print(" C ("); Serial.print(HTUtempF); Serial.print(" F)\tHum: "); Serial.print(htu.readHumidity()); Serial.println("%"); delay(100); // so this will finish printing, in case the next sensor is stalled /********************************************************************** /* Analog Devices venerable TMP36 precision temperature sensor /* this requires a bit of math after reading the output... /* https://learn.adafruit.com/tmp36-temperature-sensor/using-a-temp-sensor /**********************************************************************/ //getting the voltage reading from the temperature sensor int reading = averageAnalogRead(tmp36out); // 0.0032258064516129 are the DAC unit for 3.3v float tmp36voltage = 0.0032258064516129 * reading; // print out the voltage Serial.print("TMP36 - temp: "); float tmp36temperatureC = (tmp36voltage - 0.5) * 100 ; //converting from 10 mv per degree with 500 mV offset to degrees ((voltage - 500mV) times 100) Serial.print(tmp36temperatureC); Serial.print(" C \t"); // now convert to Fahrenheit float tmp36temperatureF = (tmp36temperatureC * 9.0 / 5.0) + 32.0; Serial.print(tmp36temperatureF); Serial.print(" F, out: "); Serial.print(tmp36voltage); Serial.println("v"); delay(100); // so this will finish printing, in case the next sensor is stalled /********************************************************************** * Vishay TEMT6000 Visible Light sensor - analog reading * https://www.sparkfun.com/products/8688 /**********************************************************************/ int vLevel = averageAnalogRead(lightOut); // 0.0032258064516129 is (3.3v (the DAC ref voltage) \ 1023 * uvLevel) float newVOutVolts = 0.0032258064516129 * vLevel; Serial.print("TEMT6000 out: "); Serial.println(vLevel); delay(100); // so this will finish printing, in case the next sensor is stalled /********************************************************************** * ML8511 UV Sensor - analog reading * https://learn.sparkfun.com/tutorials/ml8511-uv-sensor-hookup-guide * /**********************************************************************/ int uvLevel = averageAnalogRead(UVOUT); // 0.0032258064516129 is (3.3v (the DAC ref voltage) \ 1023 * uvLevel) float newOutVolts = 0.0032258064516129 * uvLevel; //Convert the voltage to a UV intensity level float uvIntensity = mapfloat(newOutVolts, 0.99, 2.8, 0.0, 15.0); Serial.print("ML8511 UV out: "); Serial.print(uvLevel); Serial.print(" / UV Intensity (mW/cm^2): "); Serial.println(uvIntensity); delay(100); // so this will finish printing, in case the next sensor is stalled /********************************************************************** * DFrobot MQ-9 CO/Combustable Gas sensor - analog reading * https://www.dfrobot.com/wiki/index.php/Analog_Gas_Sensor(MQ9)_(SKU:SEN0134) * https://www.pololu.com/category/83/gas-sensors There are many available * But, deciphering what the output levels mean is an exercise for the buyer. :-( /**********************************************************************/ int MQ9volts = analogRead(mq9out); // Read Gas value from the MQ-9 sensor Serial.print("MQ-9 Gas: "); Serial.println(MQ9volts,DEC); delay(100); // so this will finish printing, in case the next sensor is stalled Serial.println(""); delay(3500); // looking to time the loop at about 5 seconds... // End of the main loop... } /**************************************************************************/ /* The code below are supporting subroutines * /**************************************************************************/ /* Chronodot-related subroutines * * initChrono, set_date, get_date, set_time, get_time, get_temp, * * setHour, SetMinutes, decToBcd, bcdToDec */ /**************************************************************************/ void initChrono() { set_time(); set_date(); } void set_date() { Wire.beginTransmission(104); Wire.write(4); Wire.write(decToBcd(day)); Wire.write(decToBcd(date)); Wire.write(decToBcd(month)); Wire.write(decToBcd(years)); Wire.endTransmission(); } void get_date() { Wire.beginTransmission(104); Wire.write(3);//set register to 3 (day) Wire.endTransmission(); Wire.requestFrom(104, 4); //get 4 bytes(day,date,month,year); day = bcdToDec(Wire.read()); date = bcdToDec(Wire.read()); month = bcdToDec(Wire.read()); years = bcdToDec(Wire.read()); } void set_time() { Wire.beginTransmission(104); Wire.write((byte)0); Wire.write(decToBcd(seconds)); Wire.write(decToBcd(minutes)); Wire.write(decToBcd(hours)); Wire.endTransmission(); } void get_time() { Wire.beginTransmission(104); Wire.write((byte)0);//set register to 0 Wire.endTransmission(); Wire.requestFrom(104, 3);//get 3 bytes (seconds,minutes,hours); seconds = bcdToDec(Wire.read() & 0x7f); minutes = bcdToDec(Wire.read()); hours = bcdToDec(Wire.read() & 0x3f); } void get_temp() { Wire.beginTransmission(104); Wire.write((byte)0); //set register to 0 Wire.endTransmission(); Wire.requestFrom(104, 3);//get 3 bytes (seconds,minutes,hours); seconds = bcdToDec(Wire.read() & 0x7f); minutes = bcdToDec(Wire.read()); hours = bcdToDec(Wire.read() & 0x3f); } void setHour() { hours++; if (hours > 23) { hours = 0; seconds = 0; minutes = 0; } set_time(); } void setMinutes() { minutes++; if (minutes > 59) { minutes = 0; } seconds = 0; set_time(); } byte decToBcd(byte val) { return ( (val / 10 * 16) + (val % 10) ); } byte bcdToDec(byte val) { return ( (val / 16 * 10) + (val % 16) ); } /**************************************************************************/ /* Displays some basic information on this sensor from the unified sensor API sensor_t type (see Adafruit_Sensor for more information) */ /**************************************************************************/ void displaySensorDetails(void) { sensor_t sensor; // bmp.getSensor(&sensor); Serial.println("------------------------------------"); Serial.print ("Sensor: "); Serial.println(sensor.name); Serial.print ("Driver Ver: "); Serial.println(sensor.version); Serial.print ("Unique ID: "); Serial.println(sensor.sensor_id); Serial.print ("Max Value: "); Serial.print(sensor.max_value); Serial.println(" hPa"); Serial.print ("Min Value: "); Serial.print(sensor.min_value); Serial.println(" hPa"); Serial.print ("Resolution: "); Serial.print(sensor.resolution); Serial.println(" hPa"); Serial.println("------------------------------------"); Serial.println(""); delay(500); } /**************************************************************************/ /* Takes an average of readings on a given pin, Returns the average * /* used for the TMP36 and ML8511 UV Sensor readings. /**************************************************************************/ int averageAnalogRead(int pinToRead) { byte numberOfReadings = 8; unsigned int runningValue = 0; for(int x = 0 ; x < numberOfReadings ; x++) runningValue += analogRead(pinToRead); runningValue /= numberOfReadings; return(runningValue); } //The Arduino Map function but for floats //From: https://forum.arduino.cc/index.php?topic=3922.0 float mapfloat(float x, float in_min, float in_max, float out_min, float out_max) { return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; } void beep(int duration, int count) { for(int loop = 0 ; loop < count ; loop++) { digitalWrite(sounderPin, HIGH); delay(duration); digitalWrite(sounderPin, LOW); delay(duration); } } 
Membaca Rata-Rata AnalogArduino

Ini adalah hack cerdas yang saya temukan di perpustakaan SparkFun untuk Sensor UV ML8511, tetapi saya menyebutnya secara khusus, karena Anda dapat menggunakannya untuk pembacaan analog apa pun! Jika Anda pernah bertemu Nathan Seidl, silakan belikan dia bir (lisensi Beerware.)

//Takes an average of readings on a given pin //Returns the average int averageAnalogRead(int pinToRead) { byte numberOfReadings = 8; unsigned int runningValue = 0; for(int x = 0 ; x < numberOfReadings ; x++) runningValue += analogRead(pinToRead); runningValue /= numberOfReadings; return(runningValue); } 
Scanner Bus I2CArduino

Jika Anda tidak mengetahui alamat dasar untuk perangkat i2c Anda, gunakan ini untuk memindai rentang alamat yang valid. Ini mengetahui tentang sensor yang saya kerjakan. Anda dapat menambahkan bagian untuk sensor lainnya Anda.

// -------------------------------------- // i2c_scanner // // Found at https://playground.arduino.cc/Main/I2cScanner?action=sourceblock&num=1 // 26 OCT 2015 // // Version 1 // This program (or code that looks like it) // can be found in many places. // For example on the Arduino.cc forum. // The original author is not know. // Version 2, Juni 2012, Using Arduino 1.0.1 // Adapted to be as simple as possible by Arduino.cc user Krodal // Version 3, Feb 26 2013 // V3 by louarnold // Version 4, March 3, 2013, Using Arduino 1.0.3 // by Arduino.cc user Krodal. // Changes by louarnold removed. // Scanning addresses changed from 0...127 to 1...119, // according to the i2c scanner by Nick Gammon // https://www.gammon.com.au/forum/?id=10896 // Version 5, March 28, 2013 // As version 4, but address scans now to 127. // A sensor seems to use address 120. // // This sketch tests the standard 7-bit addresses // Devices with higher bit address might not be seen properly. // // Zonker Harris added device descriptions, comments. OCT 10 2015 // #include <Wire.h> void setup() { Wire.begin(); Serial.begin(9600); Serial.println("\nI2C Scanner"); } void loop() { byte error, address; int nDevices; Serial.println("Scanning..."); nDevices = 0; for(address = 1; address < 127; address++ ) { // The i2c_scanner uses the return value of // the Write.endTransmisstion to see if // a device did acknowledge to the address. Wire.beginTransmission(address); error = Wire.endTransmission(); if (error == 0) { Serial.print("I2C device found at address 0x"); if (address<16) Serial.print("0"); Serial.print(address,HEX); // Serial.print(address); If needed, print the address in decimal // // Now, detail sensors that we know about or expect... if (address == 3) { // DEC 3 = 0x03 HEX = AS3935 Lightning Sensor Serial.print(" - AS3935 Lightning Sensor"); } if (address == 64) { // DEC 64 = 0x40 HEX = HTU21D Humidity and Temp Sensor Serial.print(" - HTU21D Humidity and Temp Sensor"); } if (address == 104) { // DEC 104 = 0x68 HEX = DS1307 (Chrono-Dot?) RTC Serial.print(" - DS1307 RTC (Chrono-Dot?)"); } if (address == 119) { // DEC 119 = 0x77 HEX = BMP180 Barometric Pressure and Tem Sensor Serial.print(" - BMP180 Barometric Pressure and Tem Sensor"); } Serial.println(" "); nDevices++; } else if (error==4) { Serial.print("Unknow error at address 0x"); if (address<16) Serial.print("0"); Serial.println(address,HEX); if (address == 3) { // DEC 3 = 0x03 HEX = AS3935 Lightning Sensor Serial.print(" - AS3935 Lightning Sensor"); } if (address == 64) { // DEC 64 = 0x40 HEX = HTU21D Humidity and Temp Sensor Serial.print(" - HTU21D Humidity and Temp Sensor"); } if (address == 104) { // DEC 104 = 0x68 HEX = DS1307 (Chrono-Dot?) RTC Serial.print(" - DS1307 RTC (Chrono-Dot?)"); } if (address == 119) { // DEC 119 = 0x77 HEX = BMP180 Barometric Pressure and Tem Sensor Serial.print(" - BMP180 Barometric Pressure and Tem Sensor"); } } } if (nDevices == 0) Serial.println("No I2C devices found\n"); else Serial.println("done\n"); delay(5000); // wait 5 seconds for next scan } /* The output looks like this... * * Scanning... * I2C device found at address 0x03 - AS3935 Lightning Sensor * I2C device found at address 0x40 - HTU21D Humidity and Temp Sensor * I2C device found at address 0x68 - DS1307 RTC (Chrono-Dot?) * I2C device found at address 0x77 - BMP180 Barometric Pressure and Tem Sensor * done * */ 
Kode Demo ML8511Arduino

Dimodifikasi untuk digunakan dengan CPU 3.3v-native (untuk unit referensi DAC).

/* * From https://learn.sparkfun.com/tutorials/ml8511-uv-sensor-hookup-guide 19 MAR 2016 * (Adapted for MKR1000 by Zonker Harris, MAR 2016) ML8511 UV Sensor Read Example By: Nathan Seidle SparkFun Electronics Date: January 15th, 2014 License: This code is public domain but you buy me a beer if we meet someday (Beerware license). The ML8511 UV Sensor outputs an analog signal in relation to the amount of UV light it detects. Connect the following ML8511 breakout board to Arduino: 3.3V = 3.3V OUT = A1 GND = GND EN = 3.3V * The Sparkfun demo presumes 5v VCC, but the MKR1000 is 3.3v native. * Because of this, the second reference voltage value will always be "1023". * As a result of testing, I cut that part out... -Z- Test your sensor by shining daylight or a UV LED: https://www.sparkfun.com/products/8662 This sensor detects 280-390nm light most effectively. This is categorized as part of the UVB (burning rays) spectrum and most of the UVA (tanning rays) spectrum. There's lots of good UV radiation reading out there: https://www.ccohs.ca/oshanswers/phys_agents/ultravioletradiation.html https://www.iuva.org/uv-faqs */ //Hardware pin definitions int UVOUT = A1; //Output from the sensor void setup() { Serial.begin(9600); pinMode(UVOUT, INPUT); Serial.println("ML8511 example"); } void loop() { int uvLevel = averageAnalogRead(UVOUT); float newOutVolts = 0.0032258064516129 * uvLevel; // This is 3.3v \ 1023 * uvLevel float uvIntensity = mapfloat(newOutVolts, 0.99, 2.8, 0.0, 15.0); //Convert the voltage to a UV intensity level Serial.print("ML8511 out: "); Serial.print(uvLevel); Serial.print(" / UV Intensity (mW/cm^2): "); Serial.print(uvIntensity); Serial.println(); delay(100); } //Takes an average of readings on a given pin //Returns the average int averageAnalogRead(int pinToRead) { byte numberOfReadings = 8; unsigned int runningValue = 0; for(int x = 0 ; x < numberOfReadings ; x++) runningValue += analogRead(pinToRead); runningValue /= numberOfReadings; return(runningValue); } //The Arduino Map function but for floats //From: https://forum.arduino.cc/index.php?topic=3922.0 float mapfloat(float x, float in_min, float in_max, float out_min, float out_max) { return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; } 

Skematik

Saya masih baru dalam Fritzing, dan tidak dapat menemukan banyak bagian di perpustakaan, jadi saya membuat tiruan ini sebagai gantinya.

Papan Sensor Lingkungan Multi-Mode MKR1000 – Petir, Gas, UV, Suhu, Kelembaban & Tekanan

Proses manufaktur

  1. Mengintegrasikan Data Sensor ke Raspberry Pi: Panduan Praktis
  2. Sensor Pelacakan Garis dengan Raspberry Pi – Detektor Pintu/Garis Sederhana KY-033
  3. Membuat API Suhu & Sensor Kuat di Raspberry Pi dengan Modul GY-91
  4. Membangun Sistem Aeroponik Otomatis dengan Raspberry Pi dan Sensor Kelembaban
  5. Menguasai GPIO Raspberry Pi: Menghubungkan Sensor Gerak PIR pada B+/Model 2
  6. Integrasi Radar Pulse Acconeer A111 dengan Raspberry Pi: Panduan Praktis
  7. Cara Menghubungkan, Mengkalibrasi, dan Memprogram Sensor Gerakan PIR HC-SR501 dengan Raspberry Pi
  8. Pencatat Sensor Python/MicroPython: Simpan Data Sensor ke Google Sheets
  9. Kirim Data IMU Adafruit 10DOF dari Raspberry Pi 2 ke Azure Event Hubs dengan Windows 10 IoT Core
  10. Penghentian Halus & Mode Tidur untuk Raspberry Pi – Rangkaian Manajemen Daya DIY