Arduino'da 14'ten fazla çıkış pininin olması mümkün mü, birkaç LED'i ayrı ayrı aydınlatmam gereken bir proje üzerinde çalışıyorum. Sadece bir Arduino Uno'm var ve bir Mega almak istemiyorum.
Arduino'da 14'ten fazla çıkış pininin olması mümkün mü, birkaç LED'i ayrı ayrı aydınlatmam gereken bir proje üzerinde çalışıyorum. Sadece bir Arduino Uno'm var ve bir Mega almak istemiyorum.
Yanıtlar:
Arduino'daki mevcut çıkış pinleri setini genişletmenin yaygın bir yolu, 74HC595 IC ( veri sayfasına bağlantı ) gibi vardiya kayıtlarını kullanmaktır .
Bu çipleri kontrol etmek için 3 pin gerekir:
Bir programda, kullanmakta kayma kaydına bir defada verilere bir bit geçmesi shiftOut () komutu aynen böyle:
shiftOut(dataPin, clockPin, data);
Bu komutla, 595 IC'deki 8 çıkışın her birini data
değişkendeki 8 bit ile ayarlarsınız .
Bir 595 ile 5 pim kazanırsın (IC'de 8, ancak konuşmak için 3 harcıyorsun). Daha fazla çıkış elde etmek için seri çıkış pimini bir sonrakinin veri pimine bağlayarak 595 serisini birlikte zincirleme bağlayabilirsiniz. Ayrıca, 595 IC'nin hepsinin saatini ve mandal pimlerini birbirine bağlamanız gerekir.
Elde edilen devre (bir 595 kullanılarak) şöyle görünür:
Yukarıdaki şekil bu codeproject.com web sayfasından alınmıştır :
Mandal pimi, verileri bu şekilde değiştirirken 595 çıkışlarını sabit tutmak için kullanılır:
digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, data);
digitalWrite(latchPin, HIGH);
Bir arduinodan daha fazla iğne alabilmenin iki yolu var.
İlki, Analog pinleri, gerçekten kolay olan dijital çıkış pinleri olarak kullanmaktır. Tek yapmanız gereken A0-A5'e 14,15,16,17,18,19 pimleri olarak atıfta bulunmaktır. Örneğin, A0 pin yüksek yazmak için sadece digitalWrite (14, HIGH) kullanın.
Arduino'dan daha fazla pin almanın diğer yolu Shift Register kullanmaktır. Bunu yapmak için , EZ-Expander Library'yi içe aktarırken digitalWrite ([20-35], HIGH) kullanmanıza izin veren EZ-Expander Shield'i kullanmanızı öneririm. Bununla birlikte, bu blendaj yalnızca pinlerin yalnızca çıkış olarak kullanılmasına izin verir ve kaydırma kayıtlarını kontrol etmek için pin 8, 12 ve 13'ü kullanır.
Harika olan şey, yukarıdaki iki yöntemin ikisini de birlikte sorunsuz bir şekilde kullanabilmenizdir.
A0
- A5
tanımlayıcılarını doğrudan kullanabilirsiniz . Örneğin, digitalWrite(A0, HIGH)
.
digitalWrite(A0)
daha doğru digitalWrite(14)
. Farklı bir panoda, pin 14
aslında olmayabilir A0
, örneğin pin 14
MEGA'da Seri3'tür TX
ve peşinde olduğunuz analog pimi etkilemeyecektir. yani, eğer digitalWrite
bir analog pin kullanıyorsanız, A0
- A5
referansını kullanın .
LED'leri sürmek istiyorsanız, fazladan devre olmadan (transistörün sinyal büyütmesi gerekmeden) 64 LED'i sürebilen bir MAX7219 kullanabilirsiniz.
MAX7219 kullanmak, Arduino'da sadece 3 çıkış pimi gerektirir. Ayrıca, bunun için birkaç Arduino kütüphanesi bulabilirsiniz .
64 LED'den daha fazla enerjiye ihtiyacınız varsa, birçoğunu zincirleyebilirsiniz.
Birden fazla 7-segment LED ekranlar için başarıyla kullandım.
Dezavantajı: pahalıdır (yaklaşık 10 $).
Charlieplexing'i kullanabilirsiniz . Bu teknikle n*(n-1)
LED'leri doğrudan n pinlerinden çekebilirsiniz . Böylece 3 pin ile 6 LED, 4 pin - 12 LED, 5 pin - 20 LED vb.
exemple:
Altı LED'in 3 iğnesi
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
Burada daha iyi bir öğretici görebilirsiniz .
Bağlantı noktası genişleticileri gibi diğer cihazlara bağlanmak için I 2 C protokolünü (Tel kitaplığı) kullanabilirsiniz. Örneğin, MCP23017.
Bu yongalardan birini LCD panosuna bağlamak için kullandım. MCP23017, giriş veya çıkış olarak yapılandırılabilen 16 bağlantı noktasına sahiptir. Girdiler istenirse kesintileri artırabilir.
Bu 16’dan 13’ünü LCD’ye bağlama örneği:
Şimdi Arduino'ya sadece 2 kablo (SDA / SCL) artı güç ve toprak kullanarak bağlanıyoruz:
Bazı üçüncü taraf üreticiler üzerlerinde 4 adet MCP23017 bulunan kartlar yapmış, bu size 64 giriş / çıkış sağlıyor:
74HC4051 (8 port) veya 74HC4067 (16 port) gibi analog çoğullayıcıları bir pimi 8/16 portlardan birine (ancak belirli bir zamanda yalnızca bir tane) bağlamak için kullanabilirsiniz:
Bunlar çift yönlüdür, bu nedenle giriş veya çıkış genişletici olarak kullanılabilir.
SPI'yi kullanarak hızlı seri verilerini 74HC595 gibi bir vardiya kaydına gönderebilirsiniz. Bunlar birlikte zincirlenmiş papatya olabilir. Bu örnekte, yalnızca 3 G / Ç pimi (MOSI / MISO / SCK) artı güç ve toprakla 32 LED'i kontrol ediyorum.
Ticari bir LED işaretinde 72 LED'in 74HC595 yongaları tarafından kullanıldığını belirttim.
Bu sütunların (9 x 8 = 72 LED) sürdüğü 9 çip ve çok yollu bir konfigürasyonda satırları süren bir çipti.
Sadece LED'leri sürmek istiyorsanız, genellikle onları çoğaltabilirsiniz. MAX7219, LED matrislerini, örneğin 7 segmentli göstergeleri sürmek için tasarlanarak basitleştirir:
Veya 64-LED matrisleri:
Her iki durumda da, bunlar birlikte zincir şeklinde bağlanabilir, örneğin:
Bütün bu örnekler sadece 3 pin Arduino (MOSI / MISO / SCK) artı güç ve toprak kullanır.
Daha önce bahsedilen 16 portlu bağlantı noktası genişleticisi (MCP23017) aynı zamanda hemen hemen aynı şeyler yapan bir SPI varyantında (MCP23S17) gelir. Bir tel daha kullanır, ancak daha hızlı olur.
LED şeritleri (NeoPixel olanlar gibi) kendi protokollerine sahiptir. Bir yoktu Josh Levine tarafından YouTube'da sonrası yazar Duemilanove üzerinde 1000 piksel sürdü!
Vardiya kayıtlarından başka cevaplarda bahsedilmiştir ve kesinlikle birçok proje için mükemmel bir seçimdir. Bunlar ucuz, basit, orta derecede hızlı ve daha fazla çıktı eklemek için genellikle birlikte zincirlenebilirler. Bununla birlikte, genellikle birkaç iğnenin özel kullanımına ihtiyaç duymaları gibi bir dezavantajı vardır (onları nasıl ayarladığınıza bağlı olarak 2 ile 4 arasında).
Bir alternatif, 16 bit MCP23017 ve MCP23S17 gibi daha gelişmiş port genişleticileri kullanmaktır . Bunlar sırasıyla I2C ve SPI'yi desteklemektedir, bu da onları başka bir çok cihazla (potansiyel olarak farklı tiplerde) bir otobüse yerleştirebileceğiniz anlamına gelir. Veriyolundaki her bir cihaz ayrı ayrı adreslenebilir; bu, hepsiyle konuşmak için yalnızca 2 veya 3 pin gerekir. Güncelleme hızları genellikle oldukça hızlıdır, bu nedenle bir Arduino projesinde önemli gecikme yaşamayacaksınız (yani iletim gecikmeleri).
Düşük seviyede, I2C veya SPI kullanmak, basit bir kaydırma yazmacından çok daha karmaşıktır. Ancak, Arduino'nun sizin için halletmesi için kütüphane kodu var. Bu soruya bakınız, örneğin: I2C cihazlarını Arduino ile nasıl kullanırım?
Ricardo'nun cevabına ek olarak , Vikipedi'nin vardiya kayıtlarında belirttiği şey :
Bir vardiya kaydının en yaygın kullanımlarından biri seri ve paralel arayüzler arasında dönüştürmektir. [...] SIPO kayıtları genellikle, Genel Amaçlı Giriş / Çıkış pinleri mevcut olandan daha fazla gerekli olduğunda, mikroişlemci çıkışına eklenir. Bu, birkaç ikili cihazın sadece iki veya üç pim kullanılarak kontrol edilmesine, ancak paralel G / Ç'den daha yavaş olmasına izin verir.
Gelen yazıda Ricardo Eğer kaydırma yazmacının şemasını görebilirsiniz bağladı.
Burada gerçekleşen şey, 8 pimin verilerini bir sıraya koymanızdır ve her saat kene için kaydırma yazmacı kayar (ikili veriyi her bir mandaldan diğerine geçirir) yani bir daire çizene kadar, yani ilk bit Son pime varır. Shift register'larında ayrıca kaymayı açıp kapatabileceğiniz bir giriş vardır, böylece veriler pozisyona getirildikten sonra durum korunur. Basit bir gösteri için aşağıdaki canlandırmaya bakınız.
Burada kırmızı ışık seri giriş ve yeşil olanlar bu basitleştirilmiş SIPO kaydırma yazmacındaki mandalların durumunu gösteriyor . Verileri yerleştirmek için kaydırdıktan sonra, kaydırma kapatılabilir ve pinleri okuyabilirsiniz. Bu örnekte yer değiştirdim 10101011
.
Bu örneklerden seri transferin paralelden daha yavaş olacağını fark edebilirsiniz, çünkü vardiya kaydının bitleri yerine kaydırmasını beklemek zorundasınız. Yüklemek istediğiniz bit kadar aynı saat tikini beklemeniz gerekecektir. Bu, onları süresiz olarak zincirleyememenizin birçok nedeninden biridir, çünkü yükleme sonsuza dek sürecektir.
Zaten yazdığınız gibi, dijital çıkış olarak TX ve RX dahil tüm pinleri kullanabilirsiniz. Bunu bir süre önce bir göstericiye yaptım ve oldukça saçma bir projenin 20 pini 20 LED'le bir video kaydettim .
Tarafından açıklandığı gibi Peter R. Bloomfield burada , bir yükleme için TX ve RX kesmek zorundayız. Dahası, olası etkileşim için sensörleri okumak için iğneniz bitti ve toplam akım limitine ulaşılmadığından emin olmak zorundasınız. Arduino'nuzla doğrudan kullanıyorsanız, 5V ledlerle sınırlı olduğunuzu unutmamak gerekir.
Bu nedenle , genel olarak vardiya kayıtlarının ve Ricardo tarafından tarif edilen 595'in kullanılması şiddetle önerilir.
Ben lehim ve programlama bölümünü fark Bir süre önce kullanmıştır Kawaii beni geri dönüştürerek sanatçının (Bağlantının metni Almanca olan) Dominik Jais .
Burada, 8x11 ledli bir ekranı sürmek için sadece 595 demet kullanılmış. Ledler , 12V SMD ledlerden bir şeritten kesildiği için, ilave bir güç kaynağı ve vardiya kayıtlarının çıkış pinlerine bağlı olan bazı UDN2803A Darlington dizileri gerekliydi.
Diğer genel yöntemler, I2C veriyolu üzerinden kontrol edilen PCF8574 (A) 8bit port genişleticilerin kullanımını içerir.
Neyse, önce 595 vardiya kayıtlarını deneyeceğim.
Ancak birkaç RGB ledini kontrol etmeniz gerekirse, daha özel çözümler aramak isteyebilirsiniz. Bazı RGB ledleri kendi WS2812'leriyle birlikte gelir . Bu ince parçalar basamaklandırılabilir (1-Telli veri yolu) ve zincir içerisindeki konumlarıyla ele alınır.
Hepsi LED'lerle ilgiliyse, WS2812B LED şeritleri veya sadece sürücü kendi kendine çipler çıkarmaya ne dersiniz? Sadece bir pin kullanarak neredeyse sınırsız sayıda LED'i kontrol edebilirsiniz!
İnsanlar bunları şeritlerde kullanmasına rağmen, bağımsız LED'ler (Adafruit'te neo pikseller olarak bilinir) olarak kullanılabilirler. Veya yalnızca tek bir renk kullanıyorsanız, her WS2811 yongası, her biri tek bir LED için RGB çıkışlarının her birini kullanarak 3 LED'i kontrol edebilir.
Kısa süre önce, 5 adet LED kullanan bir proje yarattım: Kapı1 açık / kapalı, Kapı2 açık / kapalı, motor1 aktif, motor2 aktif ve güç. "Aktif" LED'ler çift amaçlıdır, çünkü kırmızı aktif motordan gelen girdi ve yeşil Arduino içindeki aktif bayrak.
1 pim ve kitaplık takılıyken istediğiniz sayıda LED'i kontrol edebilirsiniz.
Bu yöntemi kendim için talep etmiyorum, ama bu güzel numarayı MUX-DEMUX web sitesinde buldum: CD4051 Parlour Tricks
Çıkışları sürmek veya girişleri okumak için hangi yöntemi seçerseniz seçin (vardiya yazmaçları, çoğullayıcılar veya Arduino pinlerinin doğrudan kullanımı doğrudan), paralel devre çiftlerini akıllıca kullanarak çıkış veya giriş sayısını iki katına çıkarabilirsiniz. giriş veya çıkış bankası ), her paralel dalda karşıt duyularda diyotlar kullanmak ve girişleri / çıkışları yüksek ve alçak duruma getirmek.
Çıkış yöntemini göstermek için (bu durumda LED'ler, ekstra diyotların gerekli olmadığına dikkat edin):
Bu örnekteki LED çiftlerinin bir "sıra" olduğunu düşünüyorsanız ve LED_0'ı aydınlatmak istiyorsanız, PIN 17'yi YÜKSEK ve PIN 18'i DÜŞÜK olarak ayarlamanız gerekir. (İğne numaraları kafa karıştırıcıdır, ancak benimle çok çıplak olan sonraki örneğe uyarlar). LED_1 ışığını yakmak için PINS'i tersine çevirirsiniz. LED'lerin diyot yapısı, diğerini uzak tutarak akımın ters yönde akmasını önler.
Giriş yöntemini göstermek için (bu durumda CdS'ler, ekstra diyotların gerekli olduğunu unutmayın):
Bir CdS ışık sensöründe analog okuma yapmak istiyorsanız, bu biraz daha karmaşık bir hal alır. Öncelikle, akışı kontrol etmek için her sensöre bir diyot eklemeniz gerekir. İkincisi, değerleri okuduğunuzdan, girişleri yüzmemeleri için aşağı veya yukarı çekmeniz gerekir. Tembel bir insan olarak, dahili çekme dirençlerini kullanarak onları yükseğe çekeceğim. CdS_0'ı okumak için PIN 17 modunu ÇIKIŞ'a ve DÜŞÜK olarak ayarlayın. Bu zemin yapar. Sonra PIN 18 modunu INPUT (GİRİŞ) olarak ayarlayın ve yukarı çekme direncini devreye sokmak için HIGH (Yüksek) olarak ayarlayın. Şimdi PIN 18 (örneğin analog pin 4) üzerinde bir okuma yapacaksınız. Diğer sensöre erişmek için sadece modları ve çıkışları değiştirin.
Bu nedenle, Arduino'da 5 pin kullanarak bir CD4051 8 portlu çoklayıcıya sahipseniz (normal 3 yerine), 16 giriş veya çıkış ya da ikisinin bir karışımını elde edebilirsiniz.
Aynı şekilde, 4067 16 portlu bir çoklayıcınız varsa, 32 giriş veya çıkış ya da ikisinin bir karışımını elde edebilirsiniz.
Örnek bir çizim şöyle olacaktır:
/*
* 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);
}
}
}
İlk satırda dediğim gibi, tam bir açıklama MUX-DEMUX'da bulunabilir: CD4051 Parlour Tricks
Bir sınıf projesi için 7 segmentli bir ekranı sürmek için bir CD4024 ve iki Arduino pini kullandım.
Bu yaklaşımın bazı uyarıları var. Örneğin, high
bir dalgalanma sayacının ilk çıkışına bir değer yazmak için sadece a reset
ve saat piminin iki kez değiştirilmesi gerekir . Ancak high
, tüm n pinlerine yazmak istiyorsanız , saat pininin 2 n kez değiştirilmesi gerekir ve bu süre zarfında diğer tüm pinler sürekli olarak açılır ve kapanır.
Uygulamanız bu sınırlamalarla başa çıkabilirse ve pinlerde kısaysanız, bu başka bir seçenektir.
Bonus cevap: çoğullama girdilerinin bir çok örnek vardır burada da çıkışlarını multiplexing'i uygulamak birçoğu.
Biraz çalışma ile (farklı bir önyükleyici takma), bir Uno'da, ICSP1 ve JP2 başlıklarında ilave yedi I / O hattı bulunur. Yedek önyükleyiciye HoodLoader2 adı verilir . Bir Uno'daki Atmega328 ve Atmega16U2'ye eskiz yüklemenizi sağlar. Birden fazla işlemciyle ilgilenmek, bu yöntemi kullanmanın ana komplikasyonudur.
Bir Uno'da, ICSP1 ve JP2 başlıkları Atmega16U2'nin PB1 ... PB7 pinlerine bağlanır. Ek olarak, Atmega16U2'de devre kartına bağlantısı olmayan yaklaşık 9 G / Ç pimi vardır. Mikroskop altında çalışan bir kişi, 16U2'deki toplam 18 I / O pinine tel takarken, sıradan bağlantılarına takılı diğer üç I / O pinini bırakabilir.
HoodLoader2 ayrıca Mega panolarda da çalışır.