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

Baca PWM, Dekode Input Penerima RC, dan Terapkan Fail-Safe

Komponen dan persediaan

Arduino UNO
× 1
Motor servo mikro SG90
× 2

Tentang proyek ini

Proyek ini berisi kode generik namun efisien yang dapat digunakan untuk membaca penerima RC (atau sinyal PWM lainnya) pada pin input Arduino apa pun, dan juga menerapkan fail-safe jika sinyal pemancar hilang.

Di bawah ini adalah video yang menunjukkan Arduino uno yang bertindak sebagai mixer servo menggunakan kode PWMread_RCfailsafe.ino yang tersedia di bagian bawah halaman ini.

Membantu fungsi-fungsi di PWMread_RCfailsafe.ino menjaga register interupsi untuk Anda, dan dapat dipindahkan dengan mudah di antara berbagai proyek yang menggunakan pin berbeda.

Dalam contoh video di bawah ini:

  • Fail-safe aktif ketika penerima tidak memiliki sinyal dari pemancar. saluran elevator disetel ke penuh, dan saluran aileron disetel ke netral
  • Arah servo biru diatur oleh posisi throttle
  • Rentang pergerakan (laju) servo biru diatur oleh penggeser di sisi pemancar
  • Pencampuran dimatikan menggunakan sakelar gigi pada pemancar

Isi

  • Bagaimana servo dikendalikan oleh PWM
  • Contoh penggunaan Arduino dalam model/robot RC
  • Ikhtisar Kode:Decode PWM dari penerima RC dengan fail-safe
  • Cara menggunakan PWMread_RCfailsafe.ino
  • Menampilkan frekuensi dan frekuensi gambar penerima
  • Contoh pencampuran servo
  • Alasan dari pendekatan yang diambil
  • Batasan

Bagaimana servo dan pengontrol kecepatan dikendalikan oleh PWM?

Diasumsikan dalam sisa proyek ini bahwa Anda memiliki pemahaman tentang sinyal PWM yang digunakan untuk mengontrol servos dan pengontrol kecepatan. Berikut adalah video bagus yang menjelaskan cara kerja sinyal modulasi lebar pulsa (PWM).

Anda juga harus memiliki pengetahuan tentang:

  • Arduino IDE
  • Variabel float, boolean, dan int
  • Jika loop
  • Untuk loop
  • Array
  • Perpustakaan servo

Contoh penggunaan Arduino dalam model / robot RC

Anda hanya akan dibatasi oleh imajinasi Anda:

  • Terapkan pencampuran servo, nyalakan/matikan lampu, kontrol pompa/katup, atur urutan pesanan...
  • Buat pengontrol (yaitu stabilisasi penerbangan/pilot otomatis, penahan heading, penahan ketinggian/kedalaman, perataan otomatis, indera dan hindari, kembali ke rumah...)
  • Suruh model RC Anda merespons hilangnya sinyal atau tegangan baterai rendah...
  • Gunakan pemancar yang sama untuk beberapa model/proyek tanpa harus mengubah setelan apa pun atau menggunakan fitur memori model.

Ikhtisar kode:Decode PWM dari penerima RC dengan fail-safe

Kode ini mengukur sinyal PWM (Pulse Width Modulation) menggunakan interupsi perubahan pin. Fungsi yang digunakan mengotomatiskan pengaturan interupsi dan ekstraksi data dari pin digital atau analog apa pun (tidak termasuk A6 dan A7), pada Arduino Uno, Nano atau Pro Mini. Ini membuat kode mudah digunakan bahkan untuk pemula.

Tujuan utama dari proyek ini adalah untuk membuat penerima RC generik dengan "modul" fail-safe yang dapat dengan cepat dipindahkan antar proyek. Dengan demikian, contoh kode yang ditampilkan di bagian "cara menggunakan" hanya dapat digunakan sebagai alat untuk mencapai tujuan.

Catatan: kode ini tidak akan bekerja dengan serial perangkat lunak atau perpustakaan lain yang menggunakan interupsi perubahan pin.

Bagi mereka yang tertarik dengan cara kerja kode:

  • Pin input diidentifikasi dalam array. Panjang larik ini bisa berapa saja.
  • Fungsi setup memungkinkan interupsi perubahan pin dengan menyetel register yang sesuai untuk setiap pin yang tercantum dalam larik pin.
  • Perubahan voltase pada salah satu pin yang dipilih akan memicu salah satu dari tiga Interrupt Service Routes (ISR) tergantung pada port mana register pin milik ISR(PCINT0_vect) -> Port B, ISR(PCINT1_vect) -> Port C atau ISR(PCINT2_vect) -> Port D.
  • Dalam setiap ISR, sebuah loop FOR dan pernyataan IF digunakan untuk menentukan pin mana yang telah berubah, dan saluran RC mana yang dimilikinya. Waktu interupsi dicatat melalui penggunaan micros() sebelum kembali ke loop utama().
  • Interval waktu antara perubahan pin digunakan untuk menghitung lebar pulsa, dan periode pengulangan.
  • Bendera disetel di setiap ISR untuk menunjukkan kapan pulsa baru telah diterima
  • Bendera tersebut kemudian digunakan oleh fungsi lainnya untuk mengekstrak dan memproses data yang dikumpulkan oleh ISR

Video YouTube berikut dibuat oleh Joop Brokking berbicara tentang proyek berbeda yang menggunakan metode yang sama untuk menghubungkan penerima RC ke arduino. Selama 8 menit pertama Joop dengan jelas menjelaskan caranya gunakan interupsi perubahan pin untuk mengukur sinyal PWM dari penerima RC.

Semua detail ini dijaga oleh PWMread_RCfailsafe.ino yang dapat diunduh di bagian bawah halaman ini.

Beberapa informasi berguna tentang manipulasi port juga dapat ditemukan di sini: https://tronixstuff.com/2011/10/22/tutorial-arduino-port-manipulation/

Selain penanganan interupsi perubahan pin, fungsi khusus RC_decode() telah ditulis untuk mengubah lebar pulsa (1000-2000uS) menjadi sinyal kontrol +-100% dari pemancar. Pemeriksaan fail-safe untuk sinyal pemancar yang valid menggunakan toleransi sinyal 10-330Hz, dan 500-2500uS. Jika sinyal hilang maka RC_decode() mengembalikan nilai fail-safe yang telah ditentukan sebelumnya.

Nilai kalibrasi untuk pemancar tertentu, dan posisi fail-safe dapat diatur untuk setiap saluran di PWMread_RCfailsafe.ino

Cara menggunakan PWMread_RCfailsafe.ino

Langkah 1: Contoh perangkat keras penyiapan dengan Arduino Tidak

Jika mengikuti contoh pengaturan dengan Arduino Uno, hubungkan receiver Anda sebagai berikut:(jika tidak, jika Anda menggunakan proyek Anda sendiri, langsung ke langkah 2)

  • Beri daya penerima menggunakan pin 5v dan GND
  • Hubungkan pin sinyal dari receiver ke pin 2 hingga 7 pada Arduino menggunakan kabel jumper female ke male. (Jika Anda memiliki penerima 2 saluran, sambungkan hanya ke pin 2 dan 3)
  • Untuk contoh servo mixer, pasang satu kabel sinyal servo ke pin 9 dan yang lainnya ke pin 10.

Langkah 2:Salin PWMread_RCfailsafe.ino ke dalam folder sketsa

Contoh sketsa RC_Read_Example telah disertakan untuk diunduh di bagian bawah halaman. Anda dapat menggunakan ini sebagai sketsa utama Anda saat mengikuti langkah-langkah di bawah ini.

Salin dan lewati file PWMread_RCfailsafe.ino ke dalam folder yang berisi sketsa utama Anda. Saat berikutnya Anda membuka sketsa di IDE, tab kedua akan muncul berisi kode di dalam PWMread_RCfailsafe.ino.

Langkah 3:Tentukan yang masukan pin

Buka atau buka kembali sketsa utama di Arduino IDE.

Klik pada tab PWMread_RCfailsafe, gulir ke bawah ke judul "USER DEFINED VARIABLES" dan masukkan pin input dalam array pwmPIN[].

Catatan: Sejumlah pin dapat digunakan, dan dalam urutan apa pun. Perlu diketahui bahwa semakin banyak input yang Anda miliki, semakin banyak waktu yang akan dihabiskan kode untuk menangani rutin interupsi. Catatan A6 dan A7 adalah pin analog saja dan tidak dapat digunakan.

Arduino MEGA saat ini tidak didukung, namun ini dapat dengan mudah diatasi jika ada keinginan untuk itu.

Catatan: elemen pertama di pwmPIN[] adalah saluran 1, elemen kedua saluran 2, dll... jika Anda menggunakan semua saluran dari receiver, sebaiknya pastikan saluran receiver 1 sesuai dengan saluran 1 di pwmPIN[]...

Langkah 4: Ulasan yang tersedia fungsi di PWMread_RCfailsafe.ino

Langkah 5: Cetak yang denyut nadi lebar data ke serial

Unggah kode RC_Read_Example, nyalakan pemancar Anda dan cetak data lebar pulsa mentah ke serial.

Fungsi RC_avail() harus digunakan untuk memeriksa kapan data baru telah diterima di semua saluran, dan kemudian gunakan print_RCpwm() untuk mengirim data lebar pulsa ke serial.

Langkah 6: Kalibrasi pemancar

Menggunakan data lebar pulsa yang dicetak ke serial melalui print_RCpwm() untuk secara manual mengubah nilai dalam array RC_min[], RC_mid[], dan RC_max[] untuk mengkalibrasi setiap saluran ke dalam kisaran +-100%.

Langkah 7:Cetak saluran yang dikalibrasi ke serial

Komentari fungsi print_RCpwm()

Gunakan fungsi RC_decode(channel) untuk mengkalibrasi setiap saluran ke dalam rentang +-1.

Kemudian cetak setiap saluran yang dikalibrasi ke serial menggunakan fungsi decimal2percentage() diikuti oleh Serial.println("")

Langkah 8: Setel yang aman dari kegagalan

Sesuaikan posisi fail-safe dalam larik RC_failsafe[] untuk setiap saluran (dalam kisaran +-1).

Nyalakan dan matikan pemancar untuk memeriksa apakah fail-safe beroperasi sesuai keinginan.

Input RC sekarang dapat digunakan dalam sketsa Anda.

Catatan: Anda mungkin harus menonaktifkan fitur fail-safe di receiver, jika tidak arduino tidak akan dapat merespon hilangnya sinyal pemancar.

Menampilkan frekuensi dan frekuensi gambar penerima

Periode pengulangan pulsa penerima, dan frekuensi dapat dicetak ke serial. Periksa apakah data baru tersedia pada saluran yang dipilih dengan menggunakan fungsi PWM_read(nomor saluran), sebelum menggunakan PWM_period() dan PWM_freq() untuk mengekstrak data untuk dicetak. Contoh kode tersedia di RC_FrameRate.ino.

Yang terbaik adalah menggunakan saluran pertama karena ini akan menjadi pulsa pertama yang dikirim di setiap bingkai penerima. PWM_read() menggunakan flag yang sama dengan RC_decode(CH) jadi pastikan PWM_read() dipanggil terlebih dahulu.

Lihat tangkapan layar di bawah ini:

Periode penerima dapat berguna untuk diketahui karena memberi tahu Anda berapa banyak waktu yang dimiliki kode sebelum kumpulan data berikutnya tiba. Jika RC_avail() tidak mendeteksi data RC baru setelah waktu yang telah ditentukan yaitu 21ms, maka jalankan RC_decode() untuk memicu fail-safe dan atau untuk melanjutkan menjalankan program (yang dapat berupa pengontrol PID) pada frekuensi tetap.

Ini dicapai di RC_Read_Example.ino dengan pernyataan if berikut.

sekarang =milis();if(RC_avail() || sekarang - rc_update> 21) rc_update =sekarang; // perbarui data input RC menggunakan RC_decode() // jalankan pengontrol PID // terapkan servo mixing // posisikan servos} 

Contoh pencampuran servo

Saya telah menyertakan RC_ServoMixer_Example.ino untuk menunjukkan bagaimana Anda dapat mencampur dua saluran penerima (dalam hal ini saluran 2 dan 3, elevator dan aileron). Sketsa juga menunjukkan metode untuk mengatur arah, kecepatan, dan sub trim servo. Pustaka servo digunakan untuk mengontrol servo melalui pin 9 dan 10.

Di bawah ini adalah cuplikan layar bagian pencampuran servo dari kode:

Campuran dicapai hanya dengan menambahkan dan mengurangi dua saluran bersama-sama, dan membatasi output ke kisaran -1 hingga +1. Saat menerapkan pencampuran elevator dan aileron, Anda membuat dua output satu untuk setiap servo.

mix1 =saluran 2 - saluran3 (elv - ail)

mix2 =saluran 2 + saluran3 (elv - ail)

Sebelum memposisikan servo, Anda perlu mengubah sinyal +-100% (+-1) menjadi lebar pulsa yang setara dalam mikrodetik untuk servo. Di RC_ServoMixer_Example.ino saya menggunakan fungsi calc_uS() untuk melakukan ini. Fungsi ini ditempatkan di bagian bawah sketsa dan ditunjukkan pada tangkapan layar di bawah ini.

Arah, kecepatan, dan sub trim yang ditentukan untuk setiap servo digunakan untuk menghitung lebar pulsa yang sesuai untuk servo.

Pulsa netral standar adalah 1500uS, dan kisaran normal di kedua sisi netral adalah +-500uS. Ini memberikan lebar pulsa min 1000uS (-100%) dan maks 2000uS (+100%). Oleh karena itu, pulsa dengan laju, arah, dan sub trim yang diterapkan dapat dihitung sebagai berikut.

pulsa, uS =1500 + (servo_position_% * tarif * arah + sub trim) * 500

Arah servo, kecepatan dan sub trim dapat statis atau dimodifikasi secara dinamis dengan sketsa sebagai respons terhadap input dari saluran penerima lain, atau dengan cara lain.

Alasan pendekatan yang diambil

Dimungkinkan untuk membaca penerima RC menggunakan fungsi pulseIn(PIN, HIGH), namun pulseIn() memblokir kode dalam loop() sementara menunggu pulsa untuk memulai dan kemudian selesai, membuang-buang waktu pemrosesan yang berharga. Jika ada lebih dari satu input data juga bisa hilang.

Untuk kecepatan, yang terbaik adalah menggunakan fitur interupsi perubahan pin Arduino bersama dengan manipulasi port langsung untuk memungkinkan kode dalam loop() berjalan dengan penundaan minimum. Namun ini lebih terlibat dan memakan waktu daripada sekadar memanggil pulseIn(PIN, HIGH).

Oleh karena itu saya ingin mendapatkan keuntungan dari kedua dunia dengan menulis beberapa kode generik yang dapat saya pindahkan antar proyek. Yang diperlukan hanyalah menyalin dan menempelkan file an.ino (berisi fungsi dan rutin interupsi) ke folder sketsa utama, tentukan pin input, lalu gunakan fungsi dalam sketsa.

Batasan

Yang fungsi mikro()

Pengaturan waktu mikrodetik pada arduino dilakukan menggunakan fungsi micros(). Fungsi ini dihitung dalam langkah 4uS. Ini berarti kita memiliki tingkat presisi 4 mikrodetik ketika kita mengukur pulsa 1000-2000uS. Dari sudut pandang praktis, ini lebih dari cukup.

Jika diinginkan Resolusi ini dapat ditingkatkan menjadi 0,5uS dengan menggunakan interupsi pengatur waktu. lihat tautan di bawah ini:

https://www.instructables.com/id/How-to-get-an-Arduino-micros-function-with-05us-pr/

Efisiensi PWMread_RCfailsafe.ino

Jika Anda menggunakan PWMread_RCfailsafe.ino untuk membaca penerima saluran 6 atau 9, 1,4-2,0% dari waktu pemrosesan dihabiskan untuk menjalankan rutinitas interupsi perubahan pin, yang menurut saya lebih dari dapat diterima.

Namun, selalu baik untuk memahami batasan kode, dan bagaimana hal itu dapat dipercepat jika diperlukan.

Di bawah ini adalah daftar waktu yang diperlukan untuk menjalankan setiap ISR tergantung pada jumlah saluran input yang dipilih.

1 saluran <8uS

2 saluran <12uS

3 saluran <16uS

4 saluran <20uS

5 saluran <20uS

6 saluran <24uS

Catatan: semakin banyak saluran yang digunakan, semakin lama waktu yang dibutuhkan setiap ISR untuk berjalan. Ini karena untuk loopruns melalui setiap saluran setiap kali ISR ​​dipanggil.

Waktu ekstra ini (inefisiensi) dapat diabaikan saat mengukur sinyal RC frekuensi rendah (mis.50hz).

Di atas hal di atas dibutuhkan ~4uS untuk masuk dan keluar dari ISR. Untuk satu pulsa, ISR berjalan dua kali, sekali di awal pulsa (RENDAH ke TINGGI) dan sekali lagi di akhir (TINGGI ke RENDAH).

Waktu yang dibutuhkan untuk mengukur 1 pulsa saat menggunakan 6 input RC adalah

2 * (4us untuk memasukkan ISR + 24uS untuk menjalankan ISR) =2 * 28 =48uS.

Catatan: ini adalah lebar pulsa minimum yang dapat diukur.

Waktu yang dibutuhkan untuk membaca semua 6 saluran adalah 288uS (6 * 48uS)

Dengan asumsi bahwa periode pengulangan penerima adalah 20 milidetik, maka interupsi akan berjalan selama 1,44% (0,000288/0,02) dari waktu tersebut. Ini secara signifikan lebih baik daripada menggunakan fungsi pulseIn(). pulseIn() akan memblokir kode hingga 20 milidetik untuk setiap pin.

Untuk diketahui: jika arduino hanya memiliki 2 input RC maka ISR akan berjalan hanya 0,16% dari waktu (0,000032/0,02)

Frekuensi praktis maksimum (Hz)

Jika menggunakan kode ini untuk tujuan lain saya akan menyarankan bahwa frekuensi praktis maksimum adalah 2.5kHz. Ini memberikan 100 langkah resolusi dari fungsi micros() (+- 0,025kHz).

Jika menggunakan satu pin input pada frekuensi ini 3% dari waktu dihabiskan untuk interupsi, yang berarti bahwa tugas minimum yang dapat diukur adalah 0,03. Ini setara dengan pulsa minimum dengan 12uS.

Untuk frekuensi yang lebih tinggi, tulis ulang ISR agar sesuai dengan aplikasi Anda.

Kode

  • PWMread_RCfailsafe
  • RC_Read_Contoh
  • RC_FrameRate
  • RC_ServoMixer_Example
PWMread_RCfailsafeArduino
File .ino ini berisi fungsi dan rutinitas interupsi perubahan pin (ISR) yang digunakan untuk memecahkan kode Penerima RC dan menerapkan brankas yang gagal jika sinyal pemancar hilang. Salin dan tempel file ini ke folder yang sama dengan sketsa utama (saat Anda membuka sketsa, kode ini akan muncul sebagai tab kedua di IDE arduino). Kemudian ikuti petunjuk dalam file.
/* Kelvin Nelson 24/07/2019 * * Pulse Width Modulation (PWM) decoding Penerima RC dengan failsafe * * Kode ini berisi fungsi yang mudah digunakan untuk mengukur sinyal gelombang persegi pada arduiuno pro mini, nano atau pin uno, tidak termasuk A6 dan A7. * Kode ini dimaksudkan untuk digunakan dengan penerima RC, tetapi juga dapat digunakan di sebagian besar aplikasi pengukuran PWM lainnya sebagai pengganti langsung untuk pulseIn(PIN, HIGH). * (sampai saat ini belum diuji pada frekuensi yang lebih besar dari 1khz atau pada arduino mega) * * Pulsa sinyal RC dapat diubah dari durasi lebar pulsa (1000-2000uS) pada setiap pin input menjadi -+100 % (-+1,0) output untuk digunakan dalam sketsa. * Kalibrasi untuk konversi ini ditambah pengaturan failsafe dapat diatur untuk setiap saluran. (toleransi gagal aman 10-330Hz dan 500-2500uS). * * Data mentah untuk setiap pin juga dapat diekstraksi, yaitu waktu pulsa, lebar pulsa, panjang bingkai, tugas dan frekuensi. * * Pengaturan cepat, organisasi file ini adalah sebagai berikut:* * - Ikhtisar kode * - Daftar fungsi * - Cara menggunakan, termasuk sketsa contoh * - Variabel yang ditentukan pengguna -> tentukan pin input, pemancar kalibrasi, dan failsafe. * - Variabel dan fungsi global * * GAMBARAN UMUM KODE:* * Kode ini memungkinkan interupsi perubahan pin pada pin yang dipilih dengan mengatur register yang sesuai. * * Perubahan tegangan pada salah satu pin yang dipilih akan memicu salah satu dari tiga Rutinitas Layanan Interupsi tergantung pada register mana pin tersebut berada. * - ISR(PCINT0_vect), ISR(PCINT1_vect) atau ISR(PCINT2_vect) * * Dalam setiap ISR, kode menentukan pin mana yang berubah, dan mencatat waktu sebelum kembali ke loop utama(). * * Interval waktu antara perubahan pin digunakan untuk menghitung lebar pulsa dan panjang bingkai. * * Bendera ditetapkan oleh ISR untuk menunjukkan kapan pulsa baru diterima. * * Bendera kemudian digunakan untuk mengekstrak dan memproses data yang dikumpulkan oleh setiap ISR. * * Meskipun tidak persis sama, kode ini mengikuti prinsip yang sama dengan yang dijelaskan dalam video ini:https://youtu.be/bENjl1KQbvo * */// DAFTAR FUNGSI:// JENIS OUTPUT NAMA FUNGSI CATATAN// void setup_pwmRead() menginisialisasi pengukuran PWM menggunakan interupsi perubahan pin// RC RECEIVER DECODING// boolean RC_avail() mengembalikan TINGGI ketika data RC baru tersedia// float RC_decode(nomor saluran) mendekode saluran RC yang dipilih ke dalam kisaran +-100 %, dan menerapkan failsafe.// void print_RCpwm() Mencetak data mentah saluran RC ke port serial (digunakan untuk kalibrasi).// GENERIC PWM MEASUREMENTS// boolean PWM_read(nomor saluran) mengembalikan TINGGI ketika pulsa baru telah terdeteksi pada saluran tertentu. // Fungsi menyimpan data pulsa ke variabel di luar rutinitas interupsi// dan harus dipanggil sebelum menggunakan sisa fungsi PWM.// unsigned long PWM_time() mengembalikan waktu di awal pulsa // float PWM() mengembalikan lebar pulsa// float PWM_period() mengembalikan waktu antara pulsa// float PWM_freq() menghitung frekuensi// float PWM_duty() menghitung tugas// CATATAN:PWM_read(CH) dan RC_decode(CH) menggunakan flag yang sama untuk mendeteksi ketika data baru tersedia, artinya data dapat hilang jika keduanya digunakan pada saluran yang sama pada waktu yang sama.// SARAN:jika Anda ingin menggunakan PWM_read(CH) untuk menemukan kecepatan bingkai saluran RC, panggil saja sebelum RC_decode(CH). Output dari RC_decode(CH) kemudian akan default ke failsafe.// CARA MENGGUNAKAN, termasuk sketsa contoh// di bawah judul "USER DEFINED VARIABLES" pada kode di bawah ini://// Langkah 1:masukkan pin input ke larik pwmPIN[] ={}. //// - Sejumlah pin dapat dimasukkan ke pwmPIN[] (pin tersedia 0 - 13 dan A0 - A5)// - Pin tidak harus dalam urutan numerik, misalnya pwmPIN[] ={A0, 5,6,10,8} untuk 5 saluran, atau pwmPIN[] ={A0,5} untuk 2 saluran// - Elemen pertama dalam larik adalah nomor pin untuk "saluran 1", dan yang kedua adalah pin nomor untuk "saluran 2"... etc.// - Semua pin yang terhubung ke penerima RC harus berada di awal array. yaitu 2 saluran pertama dapat berupa input RC dan saluran ketiga dapat dihubungkan ke perangkat lain seperti pin gema dari sensor ultrasonik.//// Langkah 2:jika penerima RC terhubung ke semua input, atur RC_inputs ke 0, jika tidak tentukan jumlah saluran yang terhubung ke penerima yaitu RC_inputs =2;//// Langkah 3:kalibrasi pemancar Anda dengan mengunggah sketsa sederhana dengan file .ino ini yang disertakan dalam folder sketsa, dan cetak nilai PWM mentah ke serial (sebagai alternatif salin dan tempel fungsi yang diperlukan ke dalam sketsa).// Menggunakan info dari monitor serial secara manual memperbarui nilai dalam array RC_min[], RC_mid[], RC_max[] agar sesuai dengan pemancar Anda (gunakan tarif penuh untuk mendapatkan resolusi terbaik). // contoh sketsa untuk mencetak data PWM saluran RC ke serial. /* void setup() { setup_pwmRead(); Serial.begin(9600); } void loop() { if(RC_avail()) print_RCpwm(); } */// Langkah 4:Pilih posisi failsafe untuk setiap saluran, dalam kisaran -1.0 hingga +1.0, dan masukkan ke dalam larik RC_failsafe[] ={}// Catatan:jika Anda ingin arduino merespons hilangnya sinyal pemancar Anda mungkin perlu menonaktifkan fitur failsafe pada receiver Anda (jika ada).// sketsa contoh untuk memeriksa pengoperasian failsafe, dan untuk mencetak saluran yang dikalibrasi ke serial:/* unsigned long now; // variabel waktu untuk memperbarui data pada interval reguler unsigned long rc_update; saluran int const =6; // tentukan jumlah saluran penerima float RC_in[saluran]; // larik untuk menyimpan input yang dikalibrasi dari receiver void setup() { setup_pwmRead(); Serial.begin(9600); } void loop() { sekarang =milis(); if(RC_avail() || now - rc_update> 25){ // jika data RC tersedia atau 25 ms telah berlalu sejak pembaruan terakhir (sesuaikan dengan kecepatan bingkai penerima) rc_update =sekarang; //print_RCpwm(); // batalkan komentar untuk mencetak data mentah dari receiver ke serial untuk (int i =0; i=0 &&pwmPIN[i] <=7) pwmPIN_port[i] =2; // pin milik PCINT2_vect (PORT D) else if (pwmPIN[i]>=8 &&pwmPIN[i] <=13) pwmPIN_port[i] =0; // pin milik PCINT0_vect (PORT B) // menyembunyikan nomor pin (yaitu pin 11 atau pin A0) ke posisi pin di register port. Kemungkinan besar ada cara yang lebih baik untuk melakukan ini menggunakan makro... // (Membaca status pin langsung dari register port mempercepat kode di ISR) if(pwmPIN[i] ==0 || pwmPIN[i ] ==A0 || pwmPIN[i] ==8) pwmPIN_reg[i] =0b00000001; else if(pwmPIN[i] ==1 || pwmPIN[i] ==A1 || pwmPIN[i] ==9) pwmPIN_reg[i] =0b00000010; else if(pwmPIN[i] ==2 || pwmPIN[i] ==A2 || pwmPIN[i] ==10) pwmPIN_reg[i] =0b00000100; else if(pwmPIN[i] ==3 || pwmPIN[i] ==A3 || pwmPIN[i] ==11) pwmPIN_reg[i] =0b00001000; else if(pwmPIN[i] ==4 || pwmPIN[i] ==A4 || pwmPIN[i] ==12) pwmPIN_reg[i] =0b00010000; else if(pwmPIN[i] ==5 || pwmPIN[i] ==A5 || pwmPIN[i] ==13) pwmPIN_reg[i] =0b00100000; else if(pwmPIN[i] ==6) pwmPIN_reg[i] =0b01000000; else if(pwmPIN[i] ==7) pwmPIN_reg[i] =0b10000000; }}// SETUP OF PIN CHANGE INTERRUPTSvoid setup_pwmRead(){ for(int i =0; i  num_ch) RC_inputs =num_ch; // menentukan jumlah pin yang terhubung ke penerima RC. } // INTERRUPT SERVICE ROUTINES (ISR) DIGUNAKAN UNTUK MEMBACA INPUT PWM// PCINT0_vect (register port B) bereaksi terhadap setiap perubahan pada pin D8-13.// PCINT1_vect (register port C) "" "" A0-A5. // register port PCINT2_vect (D port register) "" "" D0-7.// digunakan untuk mempercepat pernyataan if dalam kode ISR:// https://www.arduino.cc/en/Reference/PortManipulation http ://tronixstuff.com/2011/10/22/tutorial-arduino-port-manipulation/// http://harperjiangnew.blogspot.co.uk/2013/05/arduino-port-manipulation-on-mega-2560 .html// READ INTERRUPTS PADA PIN D8-D13:Rutin ISR mendeteksi pin mana yang berubah, dan mengembalikan lebar pulsa PWM, dan periode pengulangan pulsa.ISR(PCINT0_vect){ // fungsi ini akan berjalan jika perubahan pin terdeteksi pada portB pciTime =mikro(); // Record the time of the PIN change in microseconds for (int i =0; i  RC_inputs) return 0; // if channel number is out of bounds return zero. int i =CH - 1; // determine the pulse width calibration for the RC channel. The default is 1000, 1500 and 2000us. int Min; if(CH <=size_RC_min) Min =RC_min[CH-1]; else Min =1000; int Mid; if(CH <=size_RC_mid) Mid =RC_mid[CH-1]; else Mid =1500; int Max; if(CH <=size_RC_max) Max =RC_max[CH-1]; else Max =2000; float CH_output; if(FAILSAFE(CH) ==HIGH){ // If the RC channel is outside of failsafe tolerances (10-330hz and 500-2500uS) if(CH> size_RC_failsafe) CH_output =0; // and if no failsafe position has been defined, set output to neutral else CH_output =RC_failsafe[i]; // or if defined set the failsafe position } else{ // If the RC signal is valid CH_output =calibrate(PW[i],Min,Mid,Max); // calibrate the pulse width to the range -1 to 1. } return CH_output; // The signal is mapped from a pulsewidth into the range of -1 to +1, using the user defined calibrate() function in this code. // 0 represents neutral or center stick on the transmitter // 1 is full displacement of a control input is one direction (i.e full left rudder) // -1 is full displacement of the control input in the other direction (i.e. full right rudder)}/* * Receiver Calibration */ // NEED TO SPEED UPfloat calibrate(float Rx, int Min, int Mid, int Max){ float calibrated; if (Rx>=Mid) { calibrated =map(Rx, Mid, Max, 0, 1000); // map from 0% to 100% in one direction } else if (Rx ==0) { calibrated =0; // neutral } else { calibrated =map(Rx, Min, Mid, -1000, 0); // map from 0% to -100% in the other direction } return calibrated * 0.001;}// Basic Receiver FAIL SAFE// check for 500-2500us and 10-330Hz (same limits as pololu)boolean FAILSAFE(int CH){ int i =CH-1; boolean failsafe_flag =LOW; if(pwmFlag[i] ==1) // if a new pulse has been measured. { pwmFlag[i] =0; // set flag to zero if(pwmPeriod[i]> 100000) // if time between pulses indicates a pulse rate of less than 10Hz { failsafe_flag =HIGH; } else if(pwmPeriod[i] <3000) // or if time between pulses indicates a pulse rate greater than 330Hz { failsafe_flag =HIGH; } if(PW[i] <500 || PW[i]> 2500) // if pulswidth is outside of the range 500-2500ms { failsafe_flag =HIGH; } } else if (micros() - pwmTimer[i]> 100000) // if there is no new pulswidth measurement within 100ms (10hz) { failsafe_flag =HIGH; } return failsafe_flag; }/* * Quick print function of Rx channel input */void print_RCpwm(){ // display the raw RC Channel PWM Inputs for (int i =0; i =0) Serial.print(" "); if (abs(pc) <100) Serial.print(" "); if (abs(pc) <10) Serial.print(" "); Serial.print(" ");Serial.print(pc);Serial.print("% ");}/* * GENERIC PWM FUNCTIONS */unsigned long pin_time;float pin_pwm;float pin_period;boolean PWM_read(int CH){ if(CH <1 &&CH> num_ch) return false; int i =CH-1; boolean avail =pwmFlag[i]; if (avail ==HIGH){ pwmFlag[i] =LOW; noInterrupts(); pin_time =pwmTimer[i]; pin_pwm =PW[i]; pin_period =pwmPeriod[i]; interupsi(); } return avail;}unsigned long PWM_time(){return pin_time;}float PWM_period(){return pin_period;}float PWM(){return pin_pwm;}float PWM_freq(){ float freq; return freq =1000000 / pin_period; // frequency Hz}float PWM_duty(){ float duty; duty =pin_pwm/pin_period; return duty;}
RC_Read_ExampleArduino
An example sketch used to display raw data in order to calibrate your RC receiver and set your the fail safe. The PWMread_RCfailsafe.ino file should be copied into the same folder in order for the functions to be available.
unsigned long now; // timing variables to update data at a regular interval unsigned long rc_update;const int channels =6; // specify the number of receiver channelsfloat RC_in[channels]; // an array to store the calibrated input from receiver void setup() { setup_pwmRead(); Serial.begin(9600);}void loop() { now =millis(); if(RC_avail() || now - rc_update> 25){ // if RC data is available or 25ms has passed since last update (adjust to be equal or greater than the frame rate of receiver) rc_update =now; print_RCpwm(); // uncommment to print raw data from receiver to serial for (int i =0; i 
RC_FrameRateArduino
Example sketch that prints the frame rate and frequency of an RC Receiver. The PWMread_RCfailsafe.ino file should be copied into the same folder in order for the functions to be available.
void setup() { setup_pwmRead(); Serial.begin(9600);}void loop() { // Print RC receiver frame length and frame rate if (PWM_read(1)){ // if a new pulse is detected on channel 1 Serial.print(PWM_period(),0);Serial.print("uS "); Serial.print(PWM_freq());Serial.println("Hz"); }}
RC_ServoMixer_ExampleArduino
An servo mixing example. Two channels from a 6 channel are receiver are mixed and sent to two servos controlled using the servo library. The PWMread_RCfailsafe.ino file should be copied into the same folder in order for the functions to be available.
// servo variables#include  // include the servo library to control the servosServo servo1; // name each servo output for use with the servo library Servo servo2; // Each servo must be attached to a pin that has a PWM output// on the arduino uno, nano and pro mini these pins are 3, 5, 6, 9, 10 and 11const int servo1_pin =9; // identify the pins that each servo signal wire is connected toconst int servo2_pin =10;// Select Servo Direction, Rates and Sub-trim (the size of each array must match the number of servos)boolean servo_dir[] ={0,1}; // Direction:0 is normal, 1 is reversefloat servo_rates[] ={1,0.5}; // Rates:range 0 to 2 (1 =+-500us (NORMAL), 2 =+-1000us (MAX)):The amount of servo deflection in both directionsfloat servo_subtrim[] ={0.0,0.0}; // Subtrimrange -1 to +1 (-1 =1000us, 0 =1500us, 1 =2000us):The neutral position of the servoboolean servo_mix_on =true;unsigned long now; // timing variables to update data at a regular interval unsigned long rc_update;// Receiver variablesconst int channels =6; // specify the number of receiver channelsfloat RC_in[channels]; // an array to store the calibrated input from receiver void setup() { servo1.attach(servo1_pin, 500, 2500); // attach the servo library to each servo pin, and define min and max uS values servo2.attach(servo2_pin, 500, 2500); setup_pwmRead(); Serial.begin(9600);}void loop() { now =millis(); if(RC_avail() || now - rc_update> 25){ // if RC data is available or 25ms has passed since last update (adjust to> frame rate of receiver) rc_update =now; print_RCpwm(); // uncommment to print raw data from receiver to serial for (int i =0; i 1) mix1 =1; // limit mixer output to +-1 else if(mix1 <-1) mix1 =-1; if(mix2> 1) mix2 =1; // limit mixer output to +-1 else if(mix2 <-1) mix2 =-1; // Calculate the pulse widths for the servos servo1_uS =calc_uS(mix1, 1); // apply the servo rates, direction and sub_trim for servo 1, and convert to a RC pulsewidth (microseconds, uS) servo2_uS =calc_uS(mix2, 2); // apply the servo rates, direction and sub_trim for servo 2, and convert to a RC pulsewidth (microseconds, uS) } else{ // MIXING OFF servo1_uS =calc_uS(RC_in[1],1); // apply the servo rates, direction and sub_trim for servo 1, and convert to a RC pulsewidth (microseconds, uS) servo2_uS =calc_uS(RC_in[2],2); // apply the servo rates, direction and sub_trim for servo 1, and convert to a RC pulsewidth (microseconds, uS) } servo1.writeMicroseconds(servo1_uS); // write the pulsewidth to the servo. servo2.writeMicroseconds(servo2_uS); // write the pulsewidth to the servo. }}int calc_uS(float cmd, int servo){ // cmd =commanded position +-100% // servo =servo num (to apply correct direction, rates and trim) int i =servo-1; float dir; if(servo_dir[i] ==0) dir =-1; else dir =1; // set the direction of servo travel cmd =1500 + (cmd*servo_rates[i]*dir + servo_subtrim[i])*500; // apply servo rates and sub trim, then convert to a uS value if(cmd> 2500) cmd =2500; // limit pulsewidth to the range 500 to 2500us else if(cmd <500) cmd =500; return cmd;}

Skema

This RC Receiver is powered by 5v and ground from the ICSP pins with the 6 signal outputs connected to pins 2-7
Micro servo 1 is powered by 5v pin and ground, with signal wire connected to pin 9
Micro servo 2 powered by 3.3v pin and ground, with signal wired connected to pin 10

Proses manufaktur

  1. C - Masukan dan Keluaran
  2. Animasi dan Permainan LCD
  3. Voltmeter DIY Menggunakan Arduino dan Smartphone
  4. Pencatat Data Suhu dan Kelembaban
  5. Cara membaca suhu dan kelembaban di Blynk dengan DHT11
  6. Python3 dan Komunikasi Arduino
  7. Otomata Seluler berbasis Arduino dan OLED
  8. Radio FM Menggunakan Arduino dan RDA8057M
  9. Penerima Radio FM Arduino TEA5767
  10. Input Analog Terisolasi untuk Arduino