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

Detektor Logam Arduino IB Sensitif DIY dengan Diskriminasi

Komponen dan persediaan

Arduino Nano R3
× 1
Adafruit LCD Standar - 16x2 Putih di Atas Biru
× 1
IC Penguat Operasional TL081
× 1
Speaker:0,25W, 8 ohm
× 1
NPN Transistor Serbaguna
× 1
Cari kumparan
× 2
Resistor, Kapasitor
× 1

Aplikasi dan layanan online

Arduino IDE

Tentang proyek ini

Kali ini saya akan menunjukkan cara membuat detektor logam sensitif juga mampu membedakan antara bahan besi dan nonferrous. Sensitivitasnya memuaskan, mengingat ini adalah perangkat yang relatif sederhana.

Proyek ini disponsori oleh PCBgogo:

https://www.pcbgogo.com/promo/from_MirkoPavleskiMK

Ini adalah kelanjutan dari proyek David Crocker yang dipresentasikan di Forum Arduino CC pada tahun 2013. Saya memutuskan untuk menguji kodenya karena saya tidak menemukan bukti (Gambar atau video) bahwa detektor logam ini dibuat oleh siapa pun dan berfungsi dengan baik.

Pertama saya membuat versi dasar dengan kode yang disajikan di GitHub, untuk memastikan fungsionalitas perangkat dan kemudian saya memutakhirkan kode sehingga memiliki sinyal yang dapat didengar, dan pada LCD 16 on 2 menampilkan informasi visual tentang jenis objek terdeteksi (Bahan besi atau nonferrous) dan grafik batang LCD untuk kedekatan objek yang terdeteksi.

Perangkat ini sangat mudah dibuat dan hanya terdiri dari beberapa komponen:

- Mikrokontroler Arduino Nano

- Penguat operasional (dalam kasus saya LT1677, tetapi Anda dapat menggunakan TL081 atau 741 )

- Beberapa resistor dan kapasitor

- Transistor dan speaker kecil

- Layar LCD

- 3 sakelar

- Potensiometer

- Baterai

- Dan koil pencarian

Ini adalah teknologi detektor Keseimbangan Induksi VLF (frekuensi sangat rendah) dan berisi dua kumparan identik:kumparan pemancar dan penerima. Seperti semua detektor keseimbangan induksi, keseimbangan koil sangat penting. Potensiometer digunakan untuk meniadakan komponen kecil di luar fase 90 derajat dari sinyal. (komponen dalam-fase dibatalkan dengan menyesuaikan penempatan relatif kumparan dalam gaya detektor IB yang khas). Masing-masing gulungan dililitkan pada badan 11cm menggunakan 64 lilitan kawat tembaga berenamel 0,5mm^2 berbentuk D, melilitkan pita di sekelilingnya, disaring menggunakan aluminium foil yang diikat dengan kawat tembaga kaleng (hati-hati untuk meninggalkan celah kecil sehingga layar tidak berperilaku seperti belokan pendek), dan mengikatnya ke piring plastik.

Pertama-tama kita perlu menentukan frekuensi resonansi paralel dari rangkaian kumparan-kapasitor primer menggunakan salah satu dari banyak kalkulator online. Saya mengukurnya dengan osiloskop, tetapi jika Anda mengikuti dimensi yang diberikan di atas, itu akan menjadi 7,64 kHz, sehingga Anda dapat langsung memasukkan nilai yang diberikan dalam kode. Dalam kasus nilai lain dari frekuensi resonansi, kita perlu membuat perubahan yang sesuai pada kode dalam antrian:

#define TIMER1_TOP (249) // menyempurnakan frekuensi

Seperti yang Anda lihat di video, hasilnya sangat bagus. Tanpa kehadiran logam, perangkat ini sangat stabil. Rentangnya relatif besar dan misalnya, penutup logam dengan diameter 15 cm terdeteksi pada jarak lebih dari 30 cm. Benda logam yang lebih besar terdeteksi pada jarak lebih dari 40-50cm. Kita dapat mendeteksi koin kecil pada jarak 15cm di udara. Saya menggunakan dua baterai lithium untuk catu daya yang dihubungkan secara seri (7,4 volt) dan tegangan ini terhubung ke input Vin dari Arduino. Konsumsi tidak melebihi 20mA sehingga baterai bertahan sangat lama. Video tersebut menjelaskan secara detail konstruksi seluruh perangkat.

Ini hanya hasil awal. Ada kemungkinan untuk meningkatkan sensitivitas secara signifikan dengan memasukkan transistor MOSFET daya untuk menggerakkan kumparan Tx, tetapi saya akan menguji dan menyajikannya di salah satu video berikut.

Kode

  • Kode Arduino
  • LcdBarGraph lib.
Kode ArduinoArduino
// Detektor logam keseimbangan induksi// Kami menjalankan CPU pada 16MHz dan jam ADC pada 1MHz. Resolusi ADC dikurangi menjadi 8 bit pada kecepatan ini.// Timer 1 digunakan untuk membagi jam sistem sekitar 256 untuk menghasilkan gelombang persegi 62.5kHz. // Ini digunakan untuk menggerakkan timer 0 dan juga untuk memicu konversi ADC.// Timer 0 digunakan untuk membagi output timer 1 dengan 8, memberikan sinyal 7.8125kHz untuk menggerakkan koil transmisi.// Ini memberi kita 16 ADC siklus clock untuk setiap konversi ADC (sebenarnya membutuhkan 13,5 siklus), dan kami mengambil 8 sampel per siklus tegangan penggerak koil.// ADC mengimplementasikan empat detektor peka fase pada interval 45 derajat. Menggunakan 4 bukan hanya 2 memungkinkan kita untuk membatalkan harmonik ketiga dari // frekuensi koil.// Timer 2 akan digunakan untuk menghasilkan nada untuk lubang suara atau headset.// Rasio pembagian lain untuk timer 1 dimungkinkan, dari sekitar 235 ke atas.// Pengkabelan:// Hubungkan pin digital 4 (alias T0) ke pin digital 9// Hubungkan pin digital 5 melalui resistor ke kumparan primer dan kapasitor tuning// Hubungkan output dari penguat penerima ke pin analog 0. Output penerima amplifier harus bias sekitar setengah dari referensi analog.// Saat menggunakan daya USB, ubah referensi analog ke pin 3.3V, karena terlalu banyak noise pada rel +5V untuk mendapatkan sensitivitas yang baik.#include  #include #define max_ampRata-rata 200LiquidCrystal lcd(6, 7, 10, 11, 12, 13);LcdBarGraph lbg(&lcd, 16, 0, 1); #define TIMER1_TOP (259) // dapat menyesuaikan ini untuk menyempurnakan frekuensi agar koil disetel (lihat di atas)#define USE_3V3_AREF (1) // setel ke 1 berjalan pada Arduino dengan daya USB, 0 untuk tertanam atmega28p tanpa suplai 3.3V tersedia // Definisi pin digital // Pin digital 0 tidak digunakan, namun jika kita menggunakan port serial untuk debugging maka input serialconst int debugTxPin =1; // mengirimkan pin yang disediakan untuk debuggingconst int encoderButtonPin =2; // tombol encoder, juga IN0 untuk bangun dari mode tidurconst int earpiecePin =3; // lubang suara, alias OCR2B untuk pembangkitan nadaconst int T0InputPin =4;const int coilDrivePin =5;const int LcdRsPin =6;const int LcdEnPin =7;const int LcdPowerPin =8; // Pengaktifan daya dan lampu latar LCDconst int T0OutputPin =9;const int lcdD4Pin =10;const int lcdD5Pin =11; // pin 11-13 juga digunakan untuk ICSPconst int LcdD6Pin =12;const int LcdD7Pin =13;// Definisi pin analogconst int receiverInputPin =0;const int encoderAPin =A1;const int encoderBpin =A2;// Pin analog 3-5 tidak digunakan// Variabel yang hanya digunakan oleh bin ISRint16_t[4]; // bin digunakan untuk mengakumulasi pembacaan ADC, satu untuk masing-masing dari 4 fasesuint16_t numSamples =0;const uint16_t numSamplesToAverage =1024;// Variabel yang digunakan oleh ISR dan di luar rata-rata int16_t yang mudah menguap[4]; // ketika kita telah mengumpulkan cukup bacaan di tempat sampah, ISR menyalinnya ke sini dan memulai lagi volatile uint32_t ticks =0; // penghitung centang sistem untuk ketepatan waktu volatil bool sampleReady =false; // menunjukkan bahwa array rata-rata telah diperbarui// Variabel yang digunakan hanya di luar kalib ISRint16_t[4]; // nilai (ditetapkan selama kalibrasi) yang kita kurangi dari rata-rata volatil uint8_t lastctr; volatil uint16_t misses =0; // ini menghitung berapa kali ISR ​​terlambat dieksekusi. Harus tetap nol jika semuanya bekerja dengan benar.const double halfRoot2 =sqrt(0.5);const double quarterPi =3.1415927/4.0;const double radiansToDegrees =180.0/3.1415927;// Sampel dan penahanan ADC terjadi 2 jam ADC (=32 sistem clocks) setelah flag overflow timer 1 disetel.// Ini memperkenalkan sedikit kesalahan fase, yang kami sesuaikan dalam perhitungan.const float phaseAdjust =(45.0 * 32.0)/(float)(TIMER1_TOP + 1);float threshold =5.0; // lebih rendah =sensitivitas lebih besar. 10 hampir dapat digunakan dengan koil yang seimbang. // Pengguna akan dapat menyesuaikan ini melalui pot atau rotary encoder.void setup(){ lcd.begin(16, 2);// LCD 16X2 pinMode(encoderButtonPin, INPUT_PULLUP); digitalWrite(T0OutputPin, RENDAH); pinMode(T0OutputPin, OUTPUT); // pin pulsa dari timer 1 digunakan untuk mengumpankan timer 0 digitalWrite(coilDrivePin, LOW); pinMode(coilDrivePin, OUTPUT); // keluaran timer 0, gelombang persegi untuk menggerakkan transmisi koil cli(); // Menghentikan timer 0 yang diatur oleh inti Arduino TCCR0B =0; // hentikan timer TIMSK0 =0; // nonaktifkan interupsi TIFR0 =0x07; // hapus semua interupsi yang tertunda // Atur ADC untuk memicu dan membaca saluran 0 pada timer 1 overflow#if USE_3V3_AREF ADMUX =(1 <> 8); OCR1AL =(TIMER1_TOP/2 &0xFF); ICR1H =(TIMER1_TOP>> 8); ICR1L =(TIMER1_TOP &0xFF); TCNT1H =0; TCNT1L =0; TIFR1 =0x07; // hapus semua interupsi yang tertunda TIMSK1 =(1 <
 15000) *p =15000; } else { *p -=nilai; jika (*p <-15000) *p =-15000; } if (ctr ==7) { ++numSamples; if (numSamples ==numSamplesToAverage) { numSamples =0; if (!sampleReady) // jika sampel sebelumnya telah digunakan { memcpy((void*)averages, bins, sizeof(averages)); sampelSiap =benar; } memset(tempat sampah, 0, sizeof(tempat sampah)); } }}void loop(){ while (!sampleReady) {} uint32_t oldTicks =ticks; if (digitalRead(encoderButtonPin) ==LOW) { // Tombol kalibrasi ditekan. Kami menyimpan keluaran detektor fase saat ini dan menguranginya dari hasil di masa mendatang. // Ini memungkinkan kita menggunakan detektor jika koil sedikit tidak seimbang. // Akan lebih baik untuk meratakan beberapa sampel daripada hanya mengambil satu. for (int i =0; i <4; ++i) { calib[i] =rata-rata[i]; } sampelSiap =salah; Serial.print("Terkalibrasi:"); lcd.setCursor(0,0); lcd.print("Kalibrasi... "); for (int i =0; i <4; ++i) { Serial.write(' '); Serial.print(kalib[i]); lcd.setCursor(0,1); lcd.print(' '); lcd.print(kalib[4]); lcd.print(""); } Serial.println(); } else { untuk (int i =0; i <4; ++i) { rata-rata[i] -=kalib[i]; } const ganda f =200.0; // Pijat hasilnya untuk menghilangkan kepekaan terhadap harmonik ke-3, dan bagi dengan 200 double bin0 =(rata-rata[0] + halfRoot2 * (rata-rata[1] - rata-rata[3]))/f; double bin1 =(rata-rata[1] + halfRoot2 * (rata-rata[0] + rata-rata[2]))/f; double bin2 =(rata-rata[2] + halfRoot2 * (rata-rata[1] + rata-rata[3]))/f; double bin3 =(rata-rata[3] + halfRoot2 * (rata-rata[2] - rata-rata[0]))/f; sampelSiap =salah; // kita sudah selesai membaca rata-ratanya, jadi ISR ​​bebas untuk menimpanya lagi double amp1 =sqrt((bin0 * bin0) + (bin2 * bin2)); amp2 ganda =kuadrat((bin1 * bin1) + (bin3 * bin3)); double ampRata-rata =(amp1 + amp2)/2.0; // Sample/hold ADC berlangsung 2 jam setelah timer overflow double phase1 =atan2(bin0, bin2) * radiansToDegrees + 45.0; double phase2 =atan2(bin1, bin3) * radiansToDegrees; if (fase1> fase2) { suhu ganda =fase1; fase1 =fase2; fase2 =suhu; } double phaseRata-rata =((phase1 + phase2)/2.0) - phaseAdjust; if (fase2 - fase1> 180,0) { if (rata-rata fase <0,0) { rata-rata fase +=180,0; } else { rata-rata fase -=180.0; } } // Untuk tujuan diagnostik, cetak jumlah nampan individu dan 2 keuntungan dan fase yang dihitung secara independen Serial.print(misses); Serial.write(' '); if (bin0>=0.0) Serial.write(' '); Serial.print(bin0, 2); Serial.write(' '); if (bin1>=0.0) Serial.write(' '); Serial.print(bin1, 2); Serial.write(' '); if (bin2>=0.0) Serial.write(' '); Serial.print(bin2, 2); Serial.write(' '); if (bin3>=0.0) Serial.write(' '); Serial.print(bin3, 2); Serial.print(""); Serial.print(amp1, 2); Serial.write(' '); Serial.print(amp2, 2); Serial.write(' '); if (fase1>=0.0) Serial.write(' '); Serial.print(fase1, 2); Serial.write(' '); if (fase2>=0.0) Serial.write(' '); Serial.print(fase2, 2); Serial.print(""); // Cetak amplitudo dan fase akhir, yang kami gunakan untuk memutuskan apa (jika ada) yang kami temukan) if (ampAverage>=0.0) Serial.write(' '); Serial.print(ampRata-rata, 1); Serial.write(' '); lcd.setCursor(0,0); lcd.print(""); lcd.print(ampRata-rata); lcd.setCursor(0,1); lbg.drawValue(ampAverage, max_ampAverage); if (phaseAverage>=0.0) Serial.write(' '); Serial.print((int)faseRata-rata); // Putuskan apa yang telah kami temukan dan beri tahu pengguna jika (ampAverage>=threshold) { // Ketika dipegang sejajar dengan pusat kumparan:// - logam non-ferrous memberikan pergeseran fasa negatif, mis. -90deg untuk tembaga atau aluminium tebal, zaitun tembaga, -30deg untuk aluminium tipis. // Logam besi memberikan pergeseran fasa nol atau pergeseran fasa positif kecil. // Jadi kita akan mengatakan bahwa apa pun dengan pergeseran fase di bawah -20deg adalah non-ferrous. if (phaseAverage <-20.0) { Serial.print(" Non-ferrous"); lcd.setCursor(0,0); lcd.print("Tidak Berbahaya "); } else { Serial.print("Besi"); lcd.setCursor(0,0); lcd.print("Besi"); } float temp =ampRata-rata; int thisPitch =peta (temp, 10, 200, 100, 1500); nada(3, Nada Ini,120); while (temp>
 ambang batas) { Serial.write('!'); suhu -=(ambang/2); } } Serial.println(); } while (ticks - oldTicks <8000) {} }
LcdBarGraph lib.C/C++
Tidak ada pratinjau (hanya unduhan).

Skema


Proses manufaktur

  1. Detektor tangisan bayi DIY yang mudah dengan Raspberry Pi
  2. Jam IV9 Numitron DIY paling sederhana dengan Arduino
  3. Game Arduino Gyroscope dengan MPU-6050
  4. Detektor Gempa ADXL335 Sensitif DIY
  5. Voltmeter DIY dengan Arduino dan Tampilan Nokia 5110
  6. MobBob:Robot Arduino DIY Dikendalikan oleh Smartphone Android
  7. Roda Pengukur Sederhana DIY dengan Rotary Encoder
  8. Pengukur IoT dengan Arduino, Yaler &IFTTT
  9. Pemantau Kualitas Udara DIY dengan Sensor Sharp GP2Y1010AU0F
  10. Penghitung Geiger Genggam dengan Arduino Nano