Mata Ultrasonik: Sensor Jarak Interaktif Matriks LED 8x8
Komponen dan Perlengkapan
Sensor Ultrasonik - HC-SR04 (Generik) × 2
Arduino Nano R3 × 1
Photo resistor × 1
Matriks LED 8x8 MAX7219 (Maxim Integrated) × 2
Papan roti setengah ukuran tanpa solder × 1
Kabel jumper (generik) × 1
Resistor 330 ohm × 1
Aplikasi dan Layanan Online
Arduino IDE
Tentang Proyek Ini
Saya ingin membuat proyek unik menggunakan beberapa matriks LED 8x8 dan sensor ultrasonik... sesuatu yang berbeda dari yang biasanya dibuat orang lain dengan ultrasonik — dan saya ingin proyek ini menyenangkan dan ceria.
Jadi saya membuat yang disebut UltrasonicEyes — proyek menyenangkan yang Anda tempatkan di dekat area orang bergerak, dan ia akan melihat ke arah orang-orang, berkedip, dan membuat Anda merasa aneh dengan cara menyenangkan serta sedikit menakutkan!
Apa yang Akan Kita Butuhkan?
Modul sensor ultrasonik dirancang untuk mendeteksi halangan dan menentukan seberapa jauh halangan tersebut, jadi umumnya memiliki jarak deteksi hingga 3–4 meter, yang merupakan jarak yang baik untuk proyek ini ditempatkan di dalam ruang tamu atau area kantor.
Saya menggunakan 2 modul HC-SR04 yang dibeli dari e-Bay. Anda bisa menemukannya dengan harga sangat murah.
Modul-modul ini cukup mudah digunakan, dan hanya membutuhkan 3 atau 4 kabel untuk terhubung ke mikrokontroler Arduino.
Modul matriks LED 8x8 yang saya pilih memungkinkan rantai, jadi hanya satu yang perlu terhubung ke Arduino, dan modul kedua terhubung ke yang pertama.
Modul-modul menggunakan SPI, jadi kita hanya membutuhkan 5 kabel ke Arduino untuk mengontrol gambar mata di kedua layar. Tentu kita membutuhkan dua modul!
CATATAN: Kode yang disediakan menggunakan Hardware SPI, jadi jika Anda menggunakan papan Arduino yang berbeda dari Nano, periksa pin mana yang merupakan pin Hardware SPI untuk MOSI dan SCK dan sambungkan sesuai dengan itu!
Anda juga memerlukan mikrokontroler kompatibel Arduino tipe apa pun. Saya menggunakan Nano (kompatibel) karena cukup kecil untuk muat di dalam casing, memiliki USB untuk daya/pemrograman firmware dan memiliki banyak GPIO untuk menghubungkan semuanya.
Saya telah menempel semuanya pada papan proto yang berukuran sama dengan papan roti setengah, tapi saya merekomendasikan Anda membangun semuanya pada papan roti setengah ukuran terlebih dahulu, karena dengan cara itu proyek tidak memerlukan solder dan dapat dengan mudah diurai atau diubah.
Beberapa hal terakhir yang Anda butuhkan adalah LDR (Photo resistor) untuk mendeteksi cahaya, resistor 330ohm dan sekumpulan kabel papan roti, baik macho ke betina, dan betina ke betina.
CATATAN: Anda dapat menggunakan warna kabel apa pun dalam proyek ini... tidak ada persyaratan untuk menggunakan warna yang sama yang saya tentukan, tetapi, selalu merupakan praktik baik untuk menggunakan merah dan hitam untuk DAYA dan GND, dan menggunakan warna lain untuk kabel lain karena membuatnya sangat mudah untuk mengidentifikasi kabel mana yang memiliki daya mengalir di dalamnya dan kabel mana yang digunakan untuk data & sinyal.
Menggabungkan Semuanya
Mari kita mulai dengan memasukkan Nano ke papan roti di ujung sangat jauh sehingga USB tergantung di tepi, tetapi tetap memastikan semua pin terhubung ke papan.
Koneksi POWER dan GND
Sambungkan kabel hitam dari koneksi GND pada Nano ke rel GND pada papan roti. Lakukan hal yang sama dengan kabel merah, menghubungkan 3V (atau 5V jika itu yang Anda miliki) ke rel DAYA pada papan roti.
Sedang bekerja pada GND dan DAYA, mari kita sambungkan kabel hitam antara dua rel GND di setiap sisi papan roti. Lakukan hal yang sama dengan kabel merah dan dua rel DAYA.
*Catatan: Beberapa panel matriks LED mungkin memerlukan 5V alih-alih 3.3V tergantung merek. Jika Anda menemukan hasil yang tidak stabil, coba gunakan pin 5V dari Arduino.
Mengkabeli Sensor Ultrasonik
Sambungkan kabel hitam antara pin GND pada setiap sensor Ultrasonik ke rel GND pada papan roti. Lakukan hal yang sama dengan kabel merah dan pin VCC (DAYA) pada sensor dan rel DAYA pada papan roti.
Sekarang mari kita hubungkan kabel putih dan biru berikut:
Kabel putih dari pin TRIG pada sensor 1 ke pin Digital 2 pada Arduino
Kabel biru dari pin ECHO pada sensor 1 ke pin Digital 3 pada Arduino
Kabel putih dari pin TRIG pada sensor 2 ke pin Digital 4 pada Arduino
Kabel biru dari pin ECHO pada sensor 2 ke pin Digital 5 pada Arduino
Kerja bagus! Itulah sensor ultrasonik yang diurus!
Menghubungkan Dua Tampilan Matriks LED 8x8
Sambungkan kabel hitam antara pin GND masuk pada salah satu tampilan matriks LED ke rel GND pada papan roti. Lakukan hal yang sama dengan kabel merah dan pin VCC (DAYA) masuk pada tampilan dan rel DAYA pada papan roti.
Sambungkan kabel hitam antara pin GND keluar tampilan satu dan pin GND masuk tampilan dua. Lakukan hal yang sama dengan kabel merah dan pin VCC keluar tampilan satu dan pin VCC masuk tampilan 2.
Sedang menghubungkan kabel antara 2 tampilan, mari kita selesaikan bagian ini...
Sambungkan kabel kuning antara pin SCK (Clock) keluar tampilan satu dan pin SCK masuk tampilan dua.
Sambungkan kabel biru antara pin MOSI (Data) keluar tampilan satu dan pin MOSI masuk tampilan dua.
Sambungkan kabel putih antara pin CS (Select) keluar tampilan satu dan pin CS masuk tampilan dua.
Bagus! Sekarang mari kita hubungkan sisa tampilan satu ke papan roti...
Sambungkan kabel kuning antara pin SCK masuk tampilan satu dan pin digital 13 pada Arduino.
Sambungkan kabel biru antara pin MOSI masuk tampilan satu dan pin digital 11 pada Arduino.
Sambungkan kabel putih antara pin CS masuk tampilan satu dan pin digital 10 pada Arduino.
INGAT: Kode yang disediakan menggunakan Hardware SPI, jadi jika Anda menggunakan papan Arduino yang berbeda dari Nano, periksa pin mana yang merupakan pin Hardware SPI untuk MOSI dan SCK dan sambungkan sesuai dengan itu!
Selamat. Sekarang ke langkah kabel terakhir...
Menghubungkan LDR dan Resistor untuk Mendeteksi Cahaya Sekeliling
Sebelum kita menghubungkan kabel ini, mengapa kita bahkan melakukan langkah ini? Nah, saya senang Anda bertanya! LDR yang terhubung ke Arduino akan memungkinkan kita untuk mendeteksi apakah terang atau gelap di sekitar UltrasonicEyes dan kita akan menggunakan informasi tersebut untuk menyelorahkan atau meredupkan tampilan LED sesuai dengan itu.
Kami tidak ingin tampilan sangat terang pada waktu malam karena dalam cahaya redup, kita masih dapat melihat tampilan cukup baik ketika kecerahan sekitar 30%, tapi pada siang hari, atau di ruang yang terang, kita perlu menaikkan kecerahan agar tampilan lebih terlihat.
Ok, mari kita selesaikan langkah terakhir ini sehingga kita dapat melanjutkan untuk memasukkannya ke dalam casing 3D!
Sambungkan LDR di seluruh 2 baris pin pada papan roti, sama seperti dalam diagram kabel di atas. Tinggalkan ruang untuk menempatkan resistor dan kabel yang akan pergi ke Arduino.
Sambungkan resistor 330ohm antara satu baris pin di satu sisi LDR dan rel GND papan roti.
Sambungkan kabel merah antara baris pin di sisi lain LDR ke rel DAYA papan roti.
Terakhir, mari kita sambungkan kabel cokelat antara baris pin yang resistor 330ohm terhubung dan pin Analog 5 (A5) pada Arduino. Ini perlu menjadi pin analog karena kita perlu membaca nilai antara 0 dan 255 dari LDR (kekuatan cahaya) alih-alih hanya 0 dan 1, seperti yang akan kita peroleh dari pin digital.
Menyalakan dan Mengunggah Kode
Ok, itu saja, kita semua telah terhubung. Waktu untuk mencabut kabel USB antara Arduino dan komputer Anda, dan unggah sketsa UltrasonicEyes yang disediakan di bawah ini untuk melihat semuanya bekerja.
Setelah menyala dan kode telah diunggah, berjalan di depan sensor Anda, atau gerakkan tangan Anda di depannya dan lihat apa yang terjadi!
Ingin Membuatnya Lebih Permanen?
Mencoba membuat UltrasonicEyes Anda lebih permanen? Lihat video saya yang mencakup mengambil versi papan roti dan memastikannya ke papan proto di sini...
Dan cetak 2 bagian casing di printer 3D apa pun dan rakit seperti yang saya lakukan dalam video!
Saya juga mempertimbangkan untuk memperluas UltrasonicEyes untuk memiliki tombol sentuh kapasitif (atau tombol biasa) untuk mengubah bentuk mata yang berbeda... Anda dapat melihat eksperimen saya di sini...
Anda dapat melihat proyek & video lainnya saya di... unexpectedmaker.com
Ikuti saya di twitter, Facebook, Instagram & tindie
https://www.patreon.com/unexpectedmaker
Itu saja!
Kode
Ultrasonic Eyes
Ultrasonic EyesC/C++
#include <MD_MAX72xx.h> // Kita menggunakan ini untuk mengontrol Tampilan Matriks LED 8x8 - Anda perlu menginstal perpustakaan ini dari manajer perpustakaan jika belum memilikinya. #include <NewPing.h> // Kita menggunakan NewPing untuk mengontrol Sensor Ultrasonik - Anda perlu menginstal perpustakaan ini dari manajer perpustakaan jika belum memilikinya. // define pins attached to LED matrix display 1 //#define CLK_PIN 13 // Kita menggunakan hardware SPI - pastikan Anda telah menghubungkan pin CLK ke pin CLK hardware pada perangkat Anda //#define DATA_PIN 11 // Kita menggunakan hardware SPI - pastikan Anda telah menghubungkan pin MOSI ke pin MOSI hardware pada perangkat Anda #define CS_PIN 10 // Pin Chip Select #define MAX_DEVICES 2 // jumlah tampilan - kita butuh 2, satu untuk setiap mata #define LIGHT A5 // Kita menggunakan Pin Analog 5 untuk membaca nilai cahaya dari LDR // Kita menggunakan hardware SPI yang secara otomatis MD_MAX72XX mx = MD_MAX72XX(CS_PIN, MAX_DEVICES); // Inisialisasi 2 Tampilan Matriks #define t1 2 // Pin Trigger pada Sensor Ultrasonik 1 #define e1 3 // Pin Echo pada Sensor Ultrasonik 1 #define t2 4 // Pin Trigger pada Sensor Ultrasonik 2 #define e2 5 // Pin Echo pada Sensor Ultrasonik 2 #define maxDist 400 // jarak maksimum untuk pulsa ultrasonik NewPing eyeR(t2, e2, maxDist ); // Inisialisasi Sensor Ultrasonik 2 NewPing eyeL(t1, e1, maxDist ); // Inisialisasi Sensor Ultrasonik 1 // Kita melacak keadaan sistem saat ini dengan variabel integer ini, dengan cara ini setelah berkedip, kita dapat mengembalikan mata ke arah terakhir mereka // Kemungkinan keadaan adalah: // 0: Melihat ke depan // 1: Melihat ke Kanan // 2: Melihat ke Kiri int currentState = -1; // Kita menyimpan waktu dan jarak untuk ping untuk setiap Sensor Ultrasonik dalam variabel ini long duration1, duration2; int distance1, distance2; // Kita ingin berkedip dimasukkan secara acak ke dalam siklus float nextBlink = millis() + 1000; // Kita menyimpan intensitas cahaya saat ini dalam variabel ini float lightAmount = 0; uint8_t eye_forward[COL_SIZE] = { 0b00111100, 0b01000010, 0b01011010, 0b10101101, 0b10111101, 0b10011001, 0b01000010, 0b00111100 }; uint8_t eye_right[COL_SIZE] = { 0b00111100, 0b01000010, 0b01110010, 0b11011001, 0b11111001, 0b10110001, 0b01000010, 0b00111100 }; uint8_t eye_left[COL_SIZE] = { 0b00111100, 0b01000010, 0b01001110, 0b10010111, 0b10011111, 0b10001101, 0b01000010, 0b00111100 }; uint8_t eye_blink[COL_SIZE] = { 0b00000000, 0b00111100, 0b01111110, 0b11111111, 0b10111101, 0b11000011, 0b01111110, 0b00111100 }; void setup() { // Inisialisasi perpustakaan Tampilan Matriks mx.begin(); // Tetapkan mode pin untuk Sensor Ultrasonik 1 pinMode( t1, OUTPUT ); pinMode( e1, INPUT ); // Tetapkan mode pin untuk Sensor Ultrasonik 2 pinMode( t2, OUTPUT ); pinMode( e2, INPUT ); // Tetapkan setiap pin trigger pada Sensor Ultrasonik untuk memulai di LOW digitalWrite( t1, LOW ); digitalWrite( t2, LOW ); // Tetapkan mode pin untuk LDR sebagai INPUT pinMode( LIGHT, INPUT ); // Mulai dengan mata melihat ke depan ShowEye_Forward(); currentState = 0; } void loop() { // baca tingkat cahaya saat ini lightAmount = analogRead( LIGHT ); // pastikan nilai cahaya berada dalam rentang Intensitas Maksimum tampilan lightAmount = ( lightAmount / 255 ) * MAX_INTENSITY; // setel intensitas mx.control(MD_MAX72XX::INTENSITY, lightAmount ); // Ping Mata Kiri dengan rekursi 5 distance1 = eyeL.ping_median( 5 ); // Tunda 500ms sebelum kita ping Mata Kanan, jadi kita tidak mendapatkan hasil yang bertentangan delay(500); // Ping Mata Kanan dengan rekursi 5 distance2 = eyeR.ping_median( 5 ); // Periksa apakah saatnya mencoba menyisipkan berkedip if ( nextBlink < millis() ) { // Tetapkan waktu berkedip berikutnya menjadi waktu acak antara sekarang + 2 detik dan 10 detik nextBlink = millis() + random(2000, 10000); // Sekarang kita perlu memutuskan apakah berkedip ini adalah berkedip tunggal, atau berkedip ganda // Pilih angka acak antara 1 dan 13 dan jika kurang dari atau sama dengan 6, itu akan menjadi berkedip ganda if ( random(1,13) <= 6 ) ShowEye_Blink_Dbl(); else ShowEye_Blink(); // Tunda 250ms untuk memastikan berkedip dapat terjadi sebelum kita kembali melihat sekeliling delay(250); // Keluarkan dari iterasi loop ini lebih awal. return; } // Kita perlu menentukan apakah selisih antara jarak item yang terdeteksi oleh setiap sensor ultrasonik kurang dari 15 // atau jika kedua jaraknya 0, artinya tidak ada yang terdeteksi // Jika kondisi ini terpenuhi, buatlah mata melihat ke depan float difference = ( distance2 - distance1 ); if ( abs( difference ) < 250 || (distance1 == 0 && distance2 == 0 ) ) { ShowEye_Forward(); currentState = 0; } // Sekarang jika distance1 lebih besar dari distance2 dan distance1 juga lebih besar dari 0, maka kita ingin melihat ke kanan else if ( distance2 < distance1 && distance1 > 0) { ShowEye_Right(); currentState = 1; } // Sekarang jika distance2 lebih besar dari distance1 dan distance2 juga lebih besar dari 0, maka kita ingin melihat ke kiri else if ( distance1 < distance2 && distance2 > 0 ) { ShowEye_Left(); currentState = 2; } // tunda loop selama 250ms untuk memastikan mata memiliki waktu untuk ditampilkan dengan benar delay(250); } /***************************************/ /************ MAX7219 Stuff ************/ /***************************************/ void ShowEye_Right() { // Bersihkan tampilan mx.clear(); // Tetapkan kecerahan tampilan saat ini mx.control(MD_MAX72XX::INTENSITY, lightAmount ); // Loop melalui setiap baris tampilan for (uint8_t row=0; row<ROW_SIZE; row++) { // Tetapkan kolom tampilan 1 mx.setColumn(row, eye_right[row]); // Tetapkan kolom tampilan 2 mx.setColumn(row+8, eye_right[row]); } } void ShowEye_Left() { // Bersihkan tampilan mx.clear(); // Tetapkan kecerahan tampilan saat ini mx.control(MD_MAX72XX::INTENSITY, lightAmount ); // Loop melalui setiap baris tampilan for (uint8_t row=0; row<ROW_SIZE; row++) { // Tetapkan kolom tampilan 1 mx.setColumn(row, eye_left[row]); // Tetapkan kolom tampilan 2 mx.setColumn(row+8, eye_left[row]); } } void ShowEye_Forward() { // Bersihkan tampilan mx.clear(); // Tetapkan kecerahan tampilan saat ini mx.control(MD_MAX72XX::INTENSITY, lightAmount ); // Loop melalui setiap baris tampilan for (uint8_t row=0; row<ROW_SIZE; row++) { // Tetapkan kolom tampilan 1 mx.setColumn(row, eye_forward[row]); // Tetapkan kolom tampilan 2 mx.setColumn(row+8, eye_forward[row]); } } void ShowEye_Blink() { // Bersihkan tampilan mx.clear(); // Tetapkan kecerahan tampilan saat ini mx.control(MD_MAX72XX::INTENSITY, lightAmount ); // Loop melalui setiap baris tampilan for (uint8_t row=0; row<ROW_SIZE; row++) { // Tetapkan kolom tampilan 1 mx.setColumn(row, eye_blink[row]); // Tetapkan kolom tampilan 2 mx.setColumn(row+8, eye_blink[row]); } // Pegang berkedip selama 150ms delay(150); // Kembalikan keadaan mata seperti semula if ( currentState == 0 ) ShowEye_Forward(); else if ( currentState == 1 ) ShowEye_Right(); else if ( currentState == 2 ) ShowEye_Left(); } void ShowEye_Blink_Dbl() { // Bersihkan tampilan mx.clear(); // Tetapkan kecerahan tampilan saat ini mx.control(MD_MAX72XX::INTENSITY, lightAmount ); // Loop melalui setiap baris tampilan for (uint8_t row=0; row<ROW_SIZE; row++) { // Tetapkan kolom tampilan 1 mx.setColumn(row, eye_blink[row]); // Tetapkan kolom tampilan 2 mx.setColumn(row+8, eye_blink[row]); } // Tunggu 75ms delay(75); // Kembalikan keadaan mata seperti semula - singkat if ( currentState == 0 ) ShowEye_Forward(); else if ( currentState == 1 ) ShowEye_Right(); else if ( currentState == 2 ) ShowEye_Left(); // Tunggu 75ms delay(75); // Berkedip mata ShowEye_Blink(); }
Bagian Khusus dan Penutup
Cetak dengan printer 3D apa pun, tidak ada pengaturan spesifik yang diperlukan.