Czy możliwe jest posiadanie więcej niż 14 pinów wyjściowych na Arduino, pracuję nad projektem, w którym muszę osobno zapalić kilka diod LED. Mam tylko Arduino Uno i nie chcę mieć Mega.
Czy możliwe jest posiadanie więcej niż 14 pinów wyjściowych na Arduino, pracuję nad projektem, w którym muszę osobno zapalić kilka diod LED. Mam tylko Arduino Uno i nie chcę mieć Mega.
Odpowiedzi:
Typowym sposobem na rozszerzenie zestawu dostępnych pinów wyjściowych w Arduino jest użycie rejestrów przesuwnych, takich jak 74HC595 IC ( link do arkusza danych ).
Potrzebujesz 3 piny do kontrolowania tych układów:
W programie dane są przesyłane pojedynczo po kolei do rejestru przesuwnego za pomocą polecenia shiftOut () , w taki sposób:
shiftOut(dataPin, clockPin, data);
Za pomocą tego polecenia ustawiasz każde z 8 wyjść na 595 IC z 8 bitami w data
zmiennej.
Z jednym 595 zyskujesz 5 pinów (8 na IC, ale wydajesz 3 na rozmowę z nim). Aby uzyskać więcej wyjść, możesz połączyć szeregowo serię 595, łącząc jej pin wyjścia szeregowego z pinem danych następnego. Musisz także połączyć razem styki zegara i zatrzasku wszystkich 595 układów scalonych.
Powstały obwód (używając jednego 595) wyglądałby tak:
Powyższy rysunek pochodzi z tej strony codeproject.com :
Kołek zatrzaskowy służy do utrzymywania stabilnego poziomu wyjściowego 595 podczas przenoszenia danych, np .:
digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, data);
digitalWrite(latchPin, HIGH);
Istnieją dwa sposoby, aby uzyskać więcej szpilek z arduino.
Pierwszym sposobem jest użycie pinów analogowych jako cyfrowych pinów wyjściowych, co jest naprawdę łatwe do zrobienia. Wszystko, co musisz zrobić, to odnieść się do A0-A5 jako pinów 14, 15, 16, 17, 18, 19. Na przykład, aby zapisać high na pin A0, wystarczy użyć digitalWrite (14, HIGH).
Innym sposobem na uzyskanie większej liczby pinów z Arduino jest użycie rejestru Shift. W tym celu zalecam użycie EZ-Expander Shield , która pozwala na korzystanie z digitalWrite ([20-35], HIGH) podczas importowania biblioteki EZ-Expander. Ta tarcza pozwala jednak tylko na używanie pinów jako wyjść i używa pinów 8,12 i 13 do sterowania rejestrami przesuwnymi.
Wspaniałą rzeczą jest to, że możesz używać obu powyższych metod bez żadnych problemów.
A0
- A5
bezpośrednio identyfikatory zamiast korzystania z numerów 14-19. Na przykład digitalWrite(A0, HIGH)
.
digitalWrite(A0)
jest bardziej poprawne niż digitalWrite(14)
ponieważ pierwsza z nich zawsze będzie mapować na właściwy fizyczny (analogowy) pin. Na innej płycie pin 14
może tak naprawdę nie być A0
, np. pin 14
Na MEGA jest Serial3 TX
i nie wpłynie na pin analogowy, którego szukasz. tzn. jeśli używasz digitalWrite
na pinie analogowym, użyj odniesienia A0
- A5
.
Jeśli chcesz sterować diodami LED, możesz także użyć MAX7219, który może sterować 64 diodami LED, bez dodatkowych obwodów (nie ma potrzeby tranzystora w celu wzmocnienia sygnału).
Prowadzenie MAX7219 wymaga tylko 3 pinów wyjściowych na Arduino. Możesz również znaleźć dla niego kilka bibliotek Arduino .
Możesz także połączyć kilka z nich, jeśli chcesz zasilić więcej niż 64 diody LED.
Z powodzeniem wykorzystałem go do wielu 7-segmentowych wyświetlaczy LED.
Wada: jest drogi (około 10 USD).
Możesz użyć Charlieplexing . Dzięki tej technice możesz bezpośrednio sterować n*(n-1)
diodami LED z n pinów. Tak więc za pomocą 3 pinów możesz sterować 6 diodami LED, 4 pinami - 12 diod LED, 5 pinów - 20 diod LED i tak dalej.
Przykład:
Sześć diod LED na 3 piny
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
Można zobaczyć lepszy samouczek tutaj .
Za pomocą protokołu I 2 C (biblioteka Wire) można łączyć się z innymi urządzeniami, takimi jak ekspandery portów. Na przykład MCP23017.
Użyłem jednego z tych układów do podłączenia wyświetlacza LCD. MCP23017 ma 16 portów, które można skonfigurować jako wejścia lub wyjścia. Jako dane wejściowe mogą w razie potrzeby zgłaszać przerwania.
Przykład podłączenia 13 z tych 16 do LCD:
Teraz łączymy się z Arduino za pomocą tylko 2 przewodów (SDA / SCL) oraz zasilania i uziemienia:
Niektórzy producenci zewnętrzni stworzyli płyty z 4 x MCP23017, co daje 64 wejścia / wyjścia:
Możesz użyć multiplekserów analogowych, takich jak 74HC4051 (8 portów) lub 74HC4067 (16 portów), aby podłączyć jeden pin do jednego z portów 8/16 (ale tylko jednego w danym momencie), w następujący sposób:
Są dwukierunkowe, więc mogą być używane jako ekspander wejść lub wyjść.
Za pomocą SPI można wysyłać szybkie dane szeregowe do rejestru przesuwnego, takiego jak 74HC595. Mogą być połączone ze sobą stokrotką. W tym przykładzie kontroluję 32 diody LED za pomocą tylko 3 pinów I / O (MOSI / MISO / SCK) oraz zasilania i uziemienia.
Znalazłem wewnątrz komercyjnego znaku LED, że 72 diody LED były napędzane przez układy 74HC595.
Miało to 9 układów napędzających kolumny (9 x 8 = 72 diody LED) i jeden układ napędzający rzędy, w konfiguracji multipleksowanej.
Jeśli chcesz tylko napędzać diody LED, zwykle możesz je multipleksować. MAX7219 upraszcza to, ponieważ jest przeznaczony do zasilania matryc LED, na przykład wyświetlaczy 7-segmentowych:
Lub matryce 64-LED:
W obu przypadkach można je połączyć łańcuchowo, na przykład:
Wszystkie te przykłady wykorzystują tylko 3 piny Arduino (MOSI / MISO / SCK) plus moc i uziemienie.
Wspomniany wcześniej 16-portowy ekspander portów (MCP23017) występuje również w wariancie SPI (MCP23S17), który robi praktycznie identyczne rzeczy. Używa jeszcze jednego drutu, ale byłoby szybsze.
Taśmy LED (podobnie jak NeoPixel) mają własne protokoły. Na Youtube był post Josha Levine'a, w którym autor przejechał ponad 1000 pikseli Duemilanove!
Rejestry Shift zostały wspomniane w innych odpowiedziach i są zdecydowanie doskonałym wyborem dla wielu projektów. Są tanie, proste, umiarkowanie szybkie i zwykle można je łączyć ze sobą, aby dodać więcej wyników. Mają jednak tę wadę, że zwykle wymagają wyłącznego użycia kilku pinów (od 2 do 4, w zależności od ich konfiguracji).
Alternatywą jest użycie bardziej zaawansowanych ekspanderów portów, takich jak 16-bitowy MCP23017 i MCP23S17 . Obsługują one odpowiednio I2C i SPI, co oznacza, że możesz umieścić je na magistrali z kilkoma innymi urządzeniami (potencjalnie różnych typów). Każde urządzenie w magistrali może być adresowane indywidualnie, co oznacza, że potrzebujesz tylko 2 lub 3 piny do rozmowy ze wszystkimi. Prędkości aktualizacji są zazwyczaj bardzo szybkie, więc nie jest prawdopodobne, aby wystąpiły znaczne opóźnienia (tj. Opóźnienia transmisji) w projekcie Arduino.
Na niskim poziomie używanie I2C lub SPI jest znacznie bardziej skomplikowane niż prosty rejestr przesuwny. Istnieje jednak kod biblioteczny dla Arduino, który zajmie się tym za Ciebie. Zobacz to pytanie, na przykład: Jak korzystać z urządzeń I2C w Arduino?
Oprócz odpowiedzi Ricardo , co Wikipedia podaje w rejestrach zmianowych :
Jednym z najczęstszych zastosowań rejestru przesuwnego jest konwersja między interfejsami szeregowym i równoległym. [...] Rejestry SIPO są zwykle dołączane do wyjścia mikroprocesorów, gdy wymaganych jest więcej pinów wejścia / wyjścia ogólnego zastosowania niż jest dostępnych. Umożliwia to sterowanie kilkoma urządzeniami binarnymi za pomocą tylko dwóch lub trzech pinów, ale wolniej niż równoległe We / Wy.
W połączonym artykule Ricardo możesz zobaczyć schemat rejestru przesuwnego.
To, co się tutaj dzieje, polega na umieszczeniu danych 8 pinów w sekwencji i dla każdego tyknięcia zegara rejestr przesuwny będzie się przesuwał (przenosi dane binarne z każdego zatrzasku na następny), aż „zrobi okrąg”, tj. Pierwszy bit dociera do ostatniej szpilki. Rejestry Shift mają również wejście, w którym można włączyć / wyłączyć przesunięcie, dzięki czemu status można zachować po przesunięciu danych do pozycji. Aby zobaczyć prostą demonstrację, zobacz następującą animację.
Tutaj czerwone światło jest wejściem szeregowym, a zielone pokazują stan zatrzasków w tym uproszczonym rejestrze przesuwnym SIPO . Po przeniesieniu danych na miejsce przesuwanie można wyłączyć i można odczytać piny. W tym przykładzie wyprowadziłem się 10101011
.
Z tych przykładów możesz zrozumieć, że transfer szeregowy będzie wolniejszy niż równoległy, ponieważ musisz poczekać, aż rejestr przesuwny przeniesie bity na swoje miejsce. Będziesz musiał poczekać tyle samo zegara, ile bitów chcesz załadować. Jest to jeden z wielu powodów, dla których nie można ich łączyć w nieskończoność, ponieważ ładowanie trwa wiecznie.
Jak już pisałeś, możesz używać wszystkich pinów, w tym TX i RX jako wyjścia cyfrowego. Zrobiłem to jakiś czas temu dla demonstratora i nagrałem wideo - 20 diod LED na 20 pinach - tego raczej bezsensownego projektu.
Jak opisano tutaj Peter R. Bloomfield , musisz odłączyć TX i RX w celu przesłania. Co więcej, brakuje Ci pinów do odczytu czujników pod kątem możliwej interaktywności i musisz upewnić się, że nie osiągnięto limitu całkowitego prądu. Nie zapominaj, że jesteś ograniczony do diod 5 V, jeśli prowadzisz je bezpośrednio za pomocą Arduino.
Dlatego też zaleca się stosowanie rejestrów przesuwnych ogólnie i 595, opisanych przez Ricardo .
Użyłem ich jakiś czas temu, kiedy zdałem sobie sprawę z lutowania i programowania części Kawaii me (tekst linku jest w języku niemieckim) artysty upcyklingu Dominika Jaisa .
Tutaj tylko kilka 595 użyto do sterowania wyświetlaczem diod LED 8x11. Ponieważ diody LED zostały wycięte z paska 12 diod SMD LED, konieczne było dodatkowe źródło zasilania i niektóre tablice Darlinga UDN2803A , podłączone do styków wyjściowych rejestrów przesuwnych.
Inne ogólne metody obejmują stosowanie ekspanderów portów 8-bitowych PCF8574 (A), które są kontrolowane przez magistralę I2C.
W każdym razie najpierw wypróbuję rejestry zmiany 595.
Jeśli jednak potrzebujesz kontrolować kilka diod RGB, możesz poszukać bardziej specjalistycznych rozwiązań. Niektóre diody RGB są dostarczane z własnym WS2812 . Te drobne elementy można kaskadowo (magistrala 1-Wire) i adresować poprzez ich położenie w łańcuchu.
Jeśli chodzi o diody LED, to co z taśmami LED WS2812B, czy tylko z samymi chipami sterownika? Możesz kontrolować praktycznie nieograniczoną liczbę diod LED za pomocą tylko jednego pinu!
Chociaż ludzie są przyzwyczajeni do nich w paskach, są one dostępne jako samodzielne diody LED (znane jako neo-piksele w Adafruit). Lub jeśli prowadzisz tylko jeden kolor, każdy układ WS2811 może sterować 3 diodami LED, używając każdego z wyjść RGB dla jednej diody LED.
Niedawno właśnie stworzyłem projekt, który wykorzystuje 5 takich diod LED: drzwi 1 otwarte / zamknięte, drzwi 2 otwarte / zamknięte, silnik 1 aktywny, silnik 2 aktywny i moc. „Aktywne” diody LED mają podwójne zastosowanie, ponieważ mam czerwony jako sygnał wejściowy z aktywnego silnika i zielony będący flagą aktywną wewnątrz Arduino.
Chodzi o to, że z 1 pinem i zainstalowaną biblioteką możesz kontrolować dowolną liczbę diod LED
Nie twierdzę, że mam taką metodę, ale tę fajną sztuczkę znalazłem na stronie MUX-DEMUX: CD4051 Parlor Tricks
Niezależnie od wybranej metody sterowania wyjściami lub odczytu wejść (rejestry przesuwne, multipleksery lub proste bezpośrednie użycie samych pinów Arduino) można PODWÓJNIE liczbę wyjść lub wejść dzięki sprytnemu zastosowaniu równoległych par obwodów (aby utworzyć podwójny bank wejściowy lub wyjściowy ), wykorzystując diody w przeciwnych zmysłach na każdej gałęzi równoległej i przełączając wejścia / wyjścia na wysokie i niskie.
Aby zilustrować metodę wyjść (diody LED w tym przypadku, należy pamiętać, że dodatkowe diody nie są wymagane):
Jeśli weźmiesz pod uwagę parę diod LED w tym przykładzie jako „bank” i chcesz zapalić LED_0, musisz ustawić PIN 17 na WYSOKI, a PIN 18 na NISKI. (Numery pinów są mylące, ale pasują do tak późnego przykładu, tak nagiego dla mnie). Aby zapalić LED_1, wystarczy odwrócić PINS. Diodowa natura diod LED zapobiega przepływowi prądu w przeciwnym kierunku, pozostawiając wyłączony drugi.
Aby zilustrować metodę wprowadzania (w tym przypadku CdS, należy pamiętać, że wymagane są dodatkowe diody):
To staje się nieco bardziej skomplikowane, jeśli chcesz dokonać odczytu analogowego na czujniku światła CdS. Najpierw musisz dodać diodę do każdego czujnika, aby kontrolować przepływ. Po drugie, ponieważ odczytujesz wartości, musisz pociągnąć wejścia wysokie lub niskie, aby nie były zmienne. Będąc leniwą osobą, zamierzam wyciągnąć je wysoko za pomocą wewnętrznych rezystorów podciągających. Aby odczytać CdS_0, ustaw tryb PIN 17 na WYJŚCIE i ustaw na NISKI. To sprawia, że jest to ziemia. Następnie ustaw tryb PIN 18 na WEJŚCIE i ustaw go na WYSOKI, aby włączyć rezystor podciągający. Teraz możesz już odczytać kod PIN 18 (inaczej analogowy pin 4). Aby uzyskać dostęp do drugiego czujnika, wystarczy przełączyć tryby i wyjścia.
Tak więc, jeśli masz 8-portowy multiplekser CD4051, używając 5 pinów na Arduino (zamiast zwykłych 3), możesz uzyskać 16 wejść lub wyjść lub mieszankę tych dwóch.
Podobnie, jeśli masz multiplekser 4067 z 16 portami, możesz uzyskać 32 wejścia lub wyjścia lub mieszankę tych dwóch.
Przykładowy szkic to:
/*
* 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);
}
}
}
Jak powiedziałem w pierwszym wierszu, pełne wyjaśnienie można znaleźć w MUX-DEMUX: CD4051 Parlor Tricks
Do projektu klasowego użyłem CD4024 i dwóch pinów Arduino do sterowania 7-segmentowym wyświetlaczem.
Istnieją pewne zastrzeżenia dotyczące tego podejścia. Na przykład, aby zapisać high
wartość na pierwszym wyjściu licznika tętnień, wystarczy a reset
i dwukrotne przełączenie pinu zegara. Ale jeśli chcesz napisać high
do wszystkich n pinów, musisz przełączać pin nn 2 razy i w tym czasie wszystkie pozostałe piny ciągle się włączają i wyłączają.
Jeśli Twoja aplikacja poradzi sobie z tymi ograniczeniami i brakuje Ci szpilek, jest to inna opcja.
Bonus odpowiedź: istnieje wiele przykładów multipleksowania wejść tutaj , z których wiele również zastosowanie do multipleksowanie wyjścia.
Przy odrobinie pracy (instalowanie innego programu ładującego) dostępnych jest siedem dodatkowych linii we / wy w Uno, na nagłówkach ICSP1 i JP2. Zamienny bootloader nazywa się HoodLoader2 . Pozwala zainstalować szkice zarówno na Atmega328, jak i Atmega16U2 na Uno. Radzenie sobie z wieloma procesorami byłoby główną komplikacją przy użyciu tej metody.
W Uno nagłówki ICSP1 i JP2 łączą się ze stykami PB1 ... PB7 Atmega16U2. Ponadto Atmega16U2 ma około 9 styków we / wy bez połączenia z płytką drukowaną. Osoba pracująca pod mikroskopem może być w stanie podłączyć przewody do 18 styków we / wy 16U2, pozostawiając trzy inne styki we / wy przymocowane do swoich zwykłych połączeń.
HoodLoader2 działa również na tablicach Mega.