Apakah mungkin untuk memiliki lebih dari 14 pin keluaran pada Arduino, saya sedang mengerjakan proyek di mana saya perlu menyalakan beberapa LED secara terpisah. Saya hanya memiliki Arduino Uno, dan saya tidak ingin mendapatkan Mega.
Apakah mungkin untuk memiliki lebih dari 14 pin keluaran pada Arduino, saya sedang mengerjakan proyek di mana saya perlu menyalakan beberapa LED secara terpisah. Saya hanya memiliki Arduino Uno, dan saya tidak ingin mendapatkan Mega.
Jawaban:
Cara umum untuk memperluas set pin output yang tersedia di Arduino adalah dengan menggunakan register geser seperti IC 74HC595 ( tautan ke lembar data ).
Anda membutuhkan 3 pin untuk mengontrol chip ini:
Dalam sebuah program, Anda meneruskan data satu per satu ke register geser menggunakan perintah shiftOut () , seperti:
shiftOut(dataPin, clockPin, data);
Dengan perintah itu, Anda mengatur masing-masing 8 output pada 595 IC dengan 8 bit dalam data
variabel.
Dengan satu 595, Anda mendapatkan 5 pin (8 pada IC, tetapi Anda menghabiskan 3 untuk berbicara dengannya). Untuk mendapatkan lebih banyak output, Anda dapat menghubungkan rangkaian 595 secara bersamaan, dengan menyambungkan pin serial-out, ke pin data yang berikutnya. Anda juga harus menghubungkan bersama jam dan kait pin dari semua 595 IC.
Sirkuit yang dihasilkan (menggunakan satu 595) akan terlihat seperti ini:
Gambar di atas diambil dari halaman web codeproject.com ini :
Pin kait digunakan untuk menjaga agar output 595 tetap stabil saat Anda memindahkan data ke dalamnya, seperti:
digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, data);
digitalWrite(latchPin, HIGH);
Ada dua cara Anda bisa mendapatkan pin lebih banyak dari arduino.
Cara pertama adalah dengan menggunakan pin Analog sebagai pin output digital, yang sangat mudah dilakukan. Yang perlu Anda lakukan adalah merujuk ke A0-A5 sebagai pin 14,15,16,17,18,19. Misalnya untuk menulis tinggi ke pin A0 cukup gunakan digitalWrite (14, HIGH).
Cara lain untuk mendapatkan pin lebih banyak dari Arduino adalah dengan menggunakan Daftar Shift. Untuk melakukan ini, saya sarankan menggunakan EZ-Expander Shield , yang memungkinkan Anda untuk menggunakan digitalWrite ([20-35], HIGH) ketika Anda mengimpor Perpustakaan EZ-Expander. Namun pelindung ini hanya memungkinkan pin untuk digunakan sebagai output saja dan menggunakan pin 8,12 dan 13 untuk mengontrol register shift.
Yang hebat adalah, Anda bisa menggunakan kedua metode di atas secara bersamaan, tanpa masalah.
A0
- A5
pengidentifikasi langsung daripada menggunakan angka 14-19. Sebagai contoh digitalWrite(A0, HIGH)
,.
digitalWrite(A0)
lebih benar daripada digitalWrite(14)
karena yang pertama akan selalu memetakan ke pin fisik (analog) yang benar. Pada papan yang berbeda, pin 14
mungkin sebenarnya tidak A0
, misalnya pin 14
pada MEGA adalah Serial3 TX
dan tidak akan mempengaruhi pin analog yang Anda cari. yaitu, jika menggunakan digitalWrite
pin analog, gunakan A0
- A5
referensi.
Jika Anda ingin menggerakkan LED, maka Anda juga dapat menggunakan MAX7219 yang dapat menggerakkan 64 LED, tanpa sirkuit tambahan (tidak perlu transistor untuk memperkuat sinyal).
Mengemudi MAX7219 hanya membutuhkan 3 pin keluaran pada Arduino. Anda juga dapat menemukan beberapa perpustakaan Arduino untuk itu.
Anda juga dapat menghubungkan beberapa di antaranya jika Anda membutuhkan daya lebih dari 64 LED.
Saya telah menggunakannya dengan sukses untuk beberapa tampilan LED 7-segmen.
Kekurangannya: mahal (sekitar $ 10).
Anda dapat menggunakan Charlieplexing . Dengan teknik ini Anda dapat langsung mengarahkan n*(n-1)
LED dari n pin. Jadi dengan 3 pin Anda dapat mengendarai 6 LED, 4 pin - 12 LED, 5 pin - 20 LED dan seterusnya.
Contoh:
Six LED ada di 3 Pin
PINS LEDS
0 1 2 1 2 3 4 5 6
0 0 0 0 0 0 0 0 0
0 1 Z 1 0 0 0 0 0
1 0 Z 0 1 0 0 0 0
Z 0 1 0 0 1 0 0 0
Z 1 0 0 0 0 1 0 0
0 Z 1 0 0 0 0 1 0
1 Z 0 0 0 0 0 0 1
0 0 1 0 0 1 0 1 0
0 1 0 1 0 0 1 0 0
0 1 1 1 0 0 0 1 0
1 0 0 0 1 0 0 0 1
1 0 1 0 1 1 0 0 0
1 1 0 0 0 0 1 0 1
1 1 1 0 0 0 0 0 0
Anda dapat melihat tutorial yang lebih baik di sini .
Anda dapat menggunakan protokol I 2 C (Perpustakaan kawat) untuk menghubungkan ke perangkat lain seperti port-ekspander. Misalnya, MCP23017.
Saya menggunakan salah satu chip itu untuk terhubung ke papan LCD. MCP23017 memiliki 16 port, yang dapat dikonfigurasi sebagai input atau output. Sebagai input, mereka dapat meningkatkan interupsi jika diinginkan.
Contoh menghubungkan 13 dari 16 tersebut ke LCD:
Sekarang kita terhubung ke Arduino hanya menggunakan 2 kabel (SDA / SCL) plus daya dan ground:
Beberapa produsen pihak ketiga telah membuat papan dengan 4 x MCP23017 pada mereka, ini memberi Anda 64 input / output:
Anda dapat menggunakan multiplexer analog seperti 74HC4051 (8 port) atau 74HC4067 (16 port) untuk menghubungkan satu pin ke salah satu port 8/16 (tetapi hanya satu pada waktu tertentu), seperti ini:
Ini adalah dua arah, sehingga dapat digunakan sebagai input atau output expander.
Menggunakan SPI Anda dapat mengirim data serial cepat ke register geser, seperti 74HC595. Ini bisa daisy dirantai bersama. Dalam contoh ini saya mengendalikan 32 LED dengan hanya 3 pin I / O (MOSI / MISO / SCK) plus daya dan arde.
Saya menemukan di dalam tanda LED komersial bahwa 72 LED didorong oleh chip 74HC595.
Ini memiliki 9 chip yang menggerakkan kolom (9 x 8 = 72 LED) dan satu chip yang menggerakkan baris, dalam konfigurasi multipleks.
Jika Anda hanya ingin mengendarai LED, Anda biasanya dapat membuatnya multiplex. MAX7219 menyederhanakan bahwa dengan dirancang untuk menggerakkan matriks LED, misalnya tampilan 7-segmen:
Atau 64-LED matriks:
Dalam kedua kasus ini dapat dirantai daisy bersama, misalnya:
Semua contoh itu hanya menggunakan 3 pin Arduino (MOSI / MISO / SCK) plus power dan ground.
Expander port 16-port yang disebutkan sebelumnya (MCP23017) juga hadir dalam varian SPI (MCP23S17), yang melakukan hal-hal yang hampir identik. Ini menggunakan satu kabel lagi, tetapi akan lebih cepat.
Strip LED (seperti yang NeoPixel) memiliki protokol sendiri. Ada posting di Youtube oleh Josh Levine di mana penulis melaju lebih dari 1000 piksel dengan Duemilanove!
Register shift telah disebutkan dalam jawaban lain, dan mereka jelas merupakan pilihan yang sangat baik untuk banyak proyek. Mereka murah, sederhana, cukup cepat, dan biasanya dapat dirantai bersama untuk menambah lebih banyak output. Namun, mereka memiliki kelemahan yang biasanya mereka butuhkan penggunaan beberapa pin secara eksklusif (antara 2 dan 4, tergantung pada bagaimana Anda mengaturnya).
Alternatifnya adalah dengan menggunakan ekspander port yang lebih canggih, seperti MCP23017 16-bit dan MCP23S17 . Ini mendukung I2C dan SPI masing-masing, yang berarti Anda dapat menempatkannya di bus dengan beberapa perangkat lain (berpotensi dari jenis yang berbeda). Setiap perangkat di bus dapat ditangani secara individual, artinya Anda hanya perlu 2 atau 3 pin untuk berbicara dengan semuanya. Kecepatan pembaruan biasanya sangat cepat, sehingga Anda tidak mungkin mengalami latensi yang signifikan (yaitu keterlambatan transmisi) dalam proyek Arduino.
Pada level rendah, menggunakan I2C atau SPI jauh lebih rumit daripada register geser sederhana. Namun, ada kode perpustakaan untuk Arduino untuk mengurusnya untuk Anda. Lihat pertanyaan ini, misalnya: Bagaimana cara menggunakan perangkat I2C dengan Arduino?
Selain jawaban Ricardo , apa yang dinyatakan Wikipedia tentang register geser :
Salah satu kegunaan paling umum dari register geser adalah untuk mengkonversi antara antarmuka serial dan paralel. [...] Register SIPO biasanya melekat pada output mikroprosesor ketika lebih banyak Input Tujuan Umum / pin Output diperlukan daripada yang tersedia. Ini memungkinkan beberapa perangkat biner dikendalikan hanya menggunakan dua atau tiga pin, tetapi lebih lambat dari I / O paralel.
Dalam artikel yang dihubungkan Ricardo, Anda dapat melihat diagram register geser.
Apa yang terjadi di sini adalah bahwa Anda meletakkan data 8 pin secara berurutan dan untuk setiap jam centang register geser akan bergeser (pindahkan data biner dari setiap kait ke yang berikutnya) sampai "membuat lingkaran" yaitu bit pertama tiba ke pin terakhir. Register geser juga memiliki input tempat Anda dapat menghidupkan / mematikan pergeseran sehingga status dapat disimpan setelah data dialihkan ke posisi. Untuk demonstrasi sederhana lihat animasi berikut.
Di sini lampu merah adalah input serial dan yang hijau menunjukkan status kait dalam register geser SIPO yang disederhanakan ini . Setelah data bergeser ke tempat pemindahan dapat dimatikan dan Anda dapat membaca pin. Dalam contoh ini saya bergeser 10101011
.
Dari contoh-contoh ini Anda dapat menyadari bahwa transfer serial akan lebih lambat daripada paralel, karena Anda harus menunggu register shift untuk menggeser bit ke tempatnya. Anda harus menunggu jumlah clock tick yang sama dengan banyak bit yang ingin Anda muat. Ini adalah salah satu dari banyak alasan mengapa Anda tidak dapat mengikatnya tanpa batas, karena pemuatan akan berlangsung selamanya.
Seperti yang sudah Anda tulis, Anda dapat menggunakan semua pin, termasuk TX dan RX sebagai output digital. Saya melakukan itu beberapa waktu lalu untuk seorang demonstran dan merekam video - 20 LED pada 20 pin - dari proyek yang agak tidak masuk akal ini.
Seperti yang dijelaskan oleh Peter R. Bloomfield di sini , Anda harus memutuskan TX dan RX untuk diunggah. Selain itu, Anda kehabisan pin untuk membaca sensor untuk kemungkinan interaktivitas dan harus memastikan bahwa batas arus total tidak tercapai. Jangan lupa bahwa Anda terbatas pada led 5V jika Anda mengarahkannya langsung dengan Arduino Anda.
Oleh karena itu penggunaan register geser secara umum dan 595, yang dijelaskan oleh Ricardo sangat dianjurkan.
Saya menggunakannya beberapa saat yang lalu ketika saya menyadari bagian solder dan pemrograman Kawaii saya (teks tautannya adalah dalam bahasa Jerman) dari artis daur ulang Dominik Jais .
Di sini, hanya sekelompok 595 yang digunakan untuk menggerakkan tampilan 8x11 led. Karena led dipotong dari strip 12V SMD led, catu daya tambahan dan beberapa UDN2803A array Darlington , dihubungkan ke pin output dari register geser, diperlukan.
Metode umum lainnya akan mencakup penggunaan ekspander port 8bit PCF8574 (A), yang dikendalikan melalui bus I2C.
Bagaimanapun, saya akan mencoba register 595 shift terlebih dahulu.
Namun, jika Anda perlu mengontrol beberapa led RGB, Anda mungkin ingin mencari solusi yang lebih khusus. Beberapa led RGB datang dengan WS2812 mereka sendiri . Potongan-potongan halus ini dapat di-cascade (1-Wire bus) dan dialamatkan melalui posisi mereka di rantai.
Jika itu semua tentang LED, bagaimana dengan strip LED WS2812B, atau hanya chip driver itu sendiri? Anda dapat mengontrol jumlah LED yang hampir tak terbatas hanya dengan menggunakan satu pin!
Meskipun orang terbiasa dengan strip ini, mereka tersedia sebagai LED mandiri (dikenal sebagai piksel neo pada Adafruit). Atau jika Anda hanya mengendarai satu warna, setiap chip WS2811 dapat mengontrol 3 LED dengan menggunakan masing-masing output RGB untuk masing-masing LED.
Saya baru-baru ini menciptakan proyek yang menggunakan 5 LED seperti: Door1 buka / tutup, Door2 buka / tutup, motor1 aktif, motor2 aktif dan daya. LED "aktif" memiliki dua tujuan karena saya merah sebagai input dari motor aktif dan hijau menjadi bendera aktif di dalam Arduino.
Intinya, dengan 1 pin dan perpustakaan terpasang, Anda dapat mengontrol sejumlah LED
Saya tidak mengklaim metode ini untuk saya sendiri, tetapi saya menemukan trik yang rapi ini di halaman web MUX-DEMUX: CD4051 Parlor Trik
Metode apa pun yang Anda pilih untuk menggerakkan output atau membaca input (register geser, multipleksor atau penggunaan langsung pin Arduino sendiri), Anda dapat MENGGANDAKAN jumlah output atau input dengan menggunakan pasangan sirkuit paralel yang cerdas (untuk membentuk dual input atau output bank ), menggunakan dioda dalam indera yang berlawanan pada setiap cabang paralel, dan mengalihkan input / output ke tinggi dan rendah.
Untuk mengilustrasikan metode untuk keluaran (LED dalam kasus ini, perhatikan bahwa dioda tambahan tidak diperlukan):
Jika Anda menganggap pasangan LED dalam contoh ini sebagai "bank", dan Anda ingin menyalakan LED_0, Anda perlu mengatur PIN 17 ke TINGGI, dan PIN 18 ke RENDAH. (Nomor pin membingungkan, tetapi cocok dengan contoh nanti jadi telanjang dengan saya). Untuk menyalakan LED_1, Anda cukup membalik PIN. Sifat dioda LED membuat arus mengalir dari arah yang berlawanan menjaga yang lain mati.
Untuk mengilustrasikan metode input (CdS dalam kasus ini, perhatikan bahwa dioda tambahan diperlukan):
Ini menjadi sedikit lebih rumit jika Anda ingin melakukan pembacaan analog pada sensor cahaya CdS. Pertama, Anda perlu menambahkan dioda ke masing-masing sensor untuk mengontrol aliran. Kedua, karena Anda membaca nilai, Anda harus menarik input tinggi atau rendah agar tidak mengambang. Menjadi orang yang malas, saya akan menarik mereka tinggi menggunakan resistor pull-up internal. Untuk membaca CdS_0, Anda mengatur mode PIN 17 ke OUTPUT dan mengaturnya ke RENDAH. Ini membuatnya menjadi tanah. Kemudian Anda mengatur mode PIN 18 ke INPUT dan mengaturnya ke TINGGI untuk menggunakan resistor pull-up. Sekarang Anda diatur untuk melakukan pembacaan pada PIN 18 (alias pin analog 4). Untuk mengakses sensor lain, cukup alihkan mode dan output.
Jadi, jika Anda memiliki multiplexor port CD4051 8, menggunakan 5 pin pada Arduino (bukan 3 biasa), Anda dapat memperoleh 16 input atau output, atau campuran keduanya.
Demikian juga, jika Anda memiliki multiplexor port 4067 16 Anda dapat memperoleh 32 input atau output, atau campuran keduanya.
Contoh sketsa adalah:
/*
* Example of getting 16 i/o from 5 pins using a CD4051
*
* Based on tutorial and code by david c. and tomek n.* for k3 / malmö högskola
* http://www.arduino.cc/playground/Learning/4051?action=sourceblock&ref=1
*/
int selPin[] = { 14, 15, 16 }; // select pins on 4051 (analog A0, A1, A2)
int commonPin[] = { 17, 18}; // common in/out pins (analog A3, A4)
int led[] = {LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW }; // stores eight LED states
int CdSVal[] = { 0, 0, 0, 0 }; // store last CdS readings
int cnt = 0; // main loop counter
int persistDelay = 100; // LED ontime in microseconds
void setup(){
Serial.begin(9600); // serial comms for troubleshooting (always)
for(int pin = 0; pin < 3; pin++){ // setup select pins
pinMode(selPin[pin], OUTPUT);
}
}
void loop(){
flashLEDs();
if (cnt == 0){
for(int x; x < 8; x++){
led[x] = random(2);
}
}
cnt++;
if (cnt > 100) { cnt = 0; }
}
void flashLEDs() {
for(int pin = 0; pin < 2; pin++) { // set common pins low
pinMode(commonPin[pin], OUTPUT);
digitalWrite(commonPin[pin], LOW);
}
for (int bank = 0; bank < 4; bank++) {
for(int pin = 0; pin < 3; pin++) { // parse out select pin bits
int signal = (bank >> pin) & 1; // shift & bitwise compare
digitalWrite(selPin[pin], signal);
}
if (led[bank * 2]){ // first LED
digitalWrite(commonPin[0], HIGH); // turn common on
delayMicroseconds(persistDelay); // leave led lit
digitalWrite(commonPin[0], LOW); // turn common off
}
if (led[bank * 2 + 1]){ // repeat for second LED
digitalWrite(commonPin[1], HIGH);
delayMicroseconds(persistDelay);
digitalWrite(commonPin[1], LOW);
}
}
}
Seperti yang saya katakan di baris pertama, penjelasan lengkap dapat ditemukan di MUX-DEMUX: CD4051 Parlor Tricks
Untuk proyek kelas saya menggunakan CD4024 dan dua pin Arduino untuk menggerakkan tampilan 7-segmen.
Ada beberapa peringatan untuk pendekatan ini. Misalnya, untuk menulis high
nilai ke output pertama dari penghitung riak hanya membutuhkan a reset
dan toggling pin jam dua kali. Tetapi jika Anda ingin menulis high
untuk semua pin n membutuhkan Toggling jam pin 2 n kali, dan selama waktu itu semua pin lainnya terus-menerus Toggling dan mematikan.
Jika aplikasi Anda dapat mengatasi keterbatasan ini dan Anda kekurangan pin, itu pilihan lain.
Jawaban bonus: ada banyak contoh input multiplexing di sini , banyak di antaranya juga berlaku untuk output multiplexing.
Dengan sedikit kerja (menginstal bootloader yang berbeda), tujuh jalur I / O tambahan tersedia pada Uno, pada header ICSP1 dan JP2. Bootloader pengganti disebut HoodLoader2 . Ini memungkinkan Anda untuk menginstal sketsa pada Atmega328 dan Atmega16U2 pada Uno. Berurusan dengan banyak prosesor akan menjadi komplikasi utama dari menggunakan metode ini.
Pada Uno, header ICSP1 dan JP2 terhubung ke pin PB1 ... PB7 dari Atmega16U2. Selain itu, Atmega16U2 memiliki sekitar 9 pin I / O tanpa koneksi ke papan sirkuit. Seseorang yang bekerja di bawah mikroskop mungkin dapat memasang kabel ke total 18 pin I / O pada 16U2, sambil meninggalkan tiga pin I / O lainnya yang terpasang pada koneksi biasa mereka.
HoodLoader2 juga berfungsi di papan Mega.