Tentang proyek ini
Pendahuluan
Interupsi berguna. Mereka, selain terkadang membuat kode lebih sederhana, dapat digunakan untuk pengaturan waktu yang tepat atau untuk membangunkan Arduino dari mode tidur.
Katakanlah Anda memiliki antarmuka pengguna, pengontrol jarak jauh, misalnya, yang menggunakan baterai. Anda mungkin ingin menempatkan Arduino (atau ATmega yang berdiri sendiri) ke mode mati untuk menghemat daya. Ketika Arduino memasuki mode power-down, itu hanya bisa dibangunkan oleh interupsi eksternal. Chip ATmega328P yang digunakan dalam Arduino Uno hanya memiliki dua interupsi pin eksternal. (INT0
dan INT1
pada pin 2 dan 3) Karena antarmuka pengguna cenderung memiliki lebih dari dua tombol, itu menjadi masalah.
Cara standar untuk menyelesaikan
ini akan menghubungkan semua tombol secara normal, tetapi juga menghubungkannya ke pin interupsi dengan dioda. Hal ini, bagaimanapun, memperumit sirkuit secara signifikan.
Selain interupsi eksternal standar, ATmega328P juga memiliki interupsi perubahan pin. Ada perpustakaan untuk menanganinya dan mereka adalah solusi yang baik untuk masalah ini.
Namun, selama kompetisi pemrograman, saya menemukan cara melakukannya menggunakan interupsi eksternal standar tanpa komponen listrik tambahan.
Sirkuit
Kami memiliki beberapa tombol. Saya menggunakan sepuluh, yang pas di papan tempat memotong roti saya. (Saya juga tidak punya lebih banyak.) Anda dapat memiliki satu tombol per pin, yang berarti hingga 20 pada Uno dan hingga 70 pada Mega! (Jika Anda benar-benar membutuhkan 70 tombol, saya sarankan menggunakan multiplexing, Anda tidak memerlukan seluruh Mega untuk itu.)
Setiap tombol memiliki satu sisi yang terhubung ke pin arbitrer. (4-13 dalam kasus saya) Sisi lain dari semua tombol terhubung bersama ke satu pin berkemampuan interupsi. (2 dalam kasus saya)
Kode
Kode terlampir di bawah ini. Agar contoh ini berfungsi, unggah ke papan Anda. Buka monitor serial Anda. Ketika Anda menekan tombol, nomornya akan muncul. Seperti yang Anda lihat, fungsi loop tidak digunakan sama sekali.
Bagaimana cara kerjanya?
Jelas ada interupsi. Dalam kasus saya, itu dilampirkan ke pin 2. Ini dikonfigurasi sebagai FALLING
.
Untuk menghindari penggunaan dioda, Arduino memasang kembali sirkuit dengan cepat. Ada dua kemungkinan konfigurasi:Mode umum dan Mode berbeda .
Mode umum
Sebagian besar waktu, sirkuit akan berada dalam mode umum. Pin interupsi akan dikonfigurasi sebagai INPUT_PULLUP
dan sisanya akan menjadi OUTPUT
dan RENDAH
.
void configureCommon() { pinMode(commonPin, INPUT_PULLUP); for (int i =0; i
Dalam mode umum, menekan tombol apa saja akan menarik pin interupsi kita ke bawah dan menembakkan interupsi kita. Setelah itu terjadi, rutin layanan interupsi kami akan mengonfigurasi ulang pin untuk mode berbeda.
Mode berbeda
Setelah interupsi kami dipicu, kami dengan cepat beralih ke mode berbeda.
Distinct mode adalah kebalikan dari common mode. Pin interupsi akan menjadi OUTPUT
dan RENDAH
dan sisanya adalah INPUT_PULLUP
.
void configureDistinct() { pinMode(commonPin, OUTPUT); digitalWrite(Pin umum, RENDAH); for (int i =0; i
Dalam mode berbeda, hanya pin yang sesuai dengan tombol yang benar-benar ditekan yang akan ditarik ke bawah. Kita dapat dengan mudah memeriksa semua pin untuk mengetahui pin mana yang memicu interupsi.
Setelah itu selesai, Arduino dapat beralih kembali ke mode umum dan menunggu interupsi lain. Atau, tergantung pada aplikasi Anda, ia dapat tetap berada dalam mode berbeda dan memproses input pengguna seperti biasanya, beralih kembali ke mode umum sebelum Arduino tidur.
Contoh yang lebih kompleks
Mari kita coba sesuatu yang sedikit lebih kompleks. Kami akan memasang servo dan memetakan setiap tombol ke sudut yang berbeda. (1=0°, 2=20°... 10=120°) Kami juga akan memberi daya pada Arduino kami dengan beberapa baterai.
Dalam contoh ini, kami menempatkan Arduino ke mode mati setelah lima detik tidak aktif untuk menghemat daya. Anda dapat menemukan beberapa tutorial tentang mode tidur online. Selain itu, kami memberi daya servo melalui transistor untuk mematikannya saat tidak digunakan.
Kode untuk contoh ini juga dilampirkan di bawah.
Kode
- Pencatat serial
- Servo dengan mode tidur
Pencatat serialArduino
const int commonPin =2;const int buttonPins[] ={4,5,6,7,8,9,10,11,12,13};unsigned long lastFire =0;void setup() { configureCommon( ); // Atur pin untuk interupsi attachInterrupt(digitalPinToInterrupt(commonPin), tekanInterrupt, FALLING); Serial.begin(9600);}void loop() { // Empty!}void pressInterrupt() { // ISR if (millis() - lastFire <200) { // Debounce return; } api terakhir =milis(); konfigurasikanDistinct(); // Atur pin untuk menguji tombol individual untuk (int i =0; i Servo dengan mode tidurArduino
#include #include #include const int commonPin =2;const int buttonPins[] ={4,5,6,7,8 ,9,10,11,12,13};const int servoEnablePin =A1;const int servoPin =A0;Servo servo;unsigned long lastFire =0;int status =0;void setup() { pinMode(commonPin, INPUT_PULLUP); konfigurasiUmum(); attachInterrupt(digitalPinToInterrupt(commonPin), tekanInterrupt, FALLING); servo.attach(servoPin); pinMode(servoEnablePin, OUTPUT);}void loop() { if (millis()-lastFire> 5000) { digitalWrite(servoEnablePin, LOW); set_sleep_mode(SLEEP_MODE_PWR_DOWN); sleep_enable(); mode tidur(); } delay(10);}void pressInterrupt() { sleep_disable(); power_all_enable(); if (milis()-lastFire <200) { kembali; } api terakhir =milis(); konfigurasikanDistinct(); for (int i=0;i Skema
multiinterrupt_hoF76Oc4T5.fzz servo_with_sleep_u9ZqxF0jhY.fzz