Có thể có hơn 14 chân đầu ra trên Arduino, tôi đang làm việc trong một dự án mà tôi cần phải chiếu sáng một số đèn LED riêng lẻ. Tôi chỉ có Arduino Uno và tôi không muốn nhận Mega.
Có thể có hơn 14 chân đầu ra trên Arduino, tôi đang làm việc trong một dự án mà tôi cần phải chiếu sáng một số đèn LED riêng lẻ. Tôi chỉ có Arduino Uno và tôi không muốn nhận Mega.
Câu trả lời:
Một cách phổ biến để mở rộng tập hợp các chân đầu ra có sẵn trên Arduino là sử dụng các thanh ghi thay đổi như IC 74HC595 ( liên kết đến biểu dữ liệu ).
Bạn cần 3 chân để điều khiển các chip này:
Trong một chương trình, bạn truyền dữ liệu từng bit một vào thanh ghi shift bằng lệnh shiftOut () , như vậy:
shiftOut(dataPin, clockPin, data);
Với lệnh đó, bạn đặt từng đầu ra trong số 8 đầu ra trên 595 IC với 8 bit trong data
biến.
Với một 595, bạn có được 5 chân (8 trên IC, nhưng bạn dành 3 để nói chuyện với nó). Để có được nhiều kết quả đầu ra, bạn có thể xâu chuỗi một chuỗi 595 lại với nhau, bằng cách kết nối chân nối tiếp của nó với chân dữ liệu của cái tiếp theo. Bạn cũng phải kết nối đồng hồ và chốt của tất cả 595 IC.
Mạch kết quả (sử dụng một 595) sẽ trông như thế này:
Hình trên được lấy từ trang web codeproject.com này :
Chốt chốt được sử dụng để giữ cho 595 đầu ra ổn định trong khi bạn chuyển dữ liệu vào đó, như vậy:
digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, data);
digitalWrite(latchPin, HIGH);
Có hai cách bạn có thể nhận được nhiều chân hơn từ một arduino.
Cách đầu tiên là sử dụng các chân Analog làm chân đầu ra kỹ thuật số, điều này thực sự dễ thực hiện. Tất cả những gì bạn cần làm là tham khảo A0-A5 dưới dạng các chân 14,15,16,17,18,19. Ví dụ để ghi cao vào pin A0, chỉ cần sử dụng digitalWrite (14, CAO).
Một cách khác để lấy thêm chân ra khỏi Arduino là sử dụng thanh ghi Shift. Để làm điều này, tôi khuyên bạn nên sử dụng EZ-Expander Shield , cho phép bạn sử dụng DigitalWrite ([20-35], CAO) khi bạn nhập Thư viện EZ-Expander. Tuy nhiên, tấm chắn này chỉ cho phép các chân chỉ được sử dụng làm đầu ra và sử dụng các chân 8,12 và 13 để điều khiển các thanh ghi thay đổi.
Điều tuyệt vời là, bạn có thể sử dụng cả hai phương pháp trên với nhau mà không gặp vấn đề gì.
A0
- A5
trực tiếp thay vì sử dụng các số 14-19. Ví dụ , digitalWrite(A0, HIGH)
.
digitalWrite(A0)
thì chính xác hơn so với digitalWrite(14)
trước đây sẽ luôn ánh xạ tới pin vật lý (analog) chính xác. Trên một bảng khác, pin 14
trên thực tế có thể không A0
, ví dụ pin 14
trên MEGA là Nối tiếp 3 TX
và sẽ không ảnh hưởng đến chân analog mà bạn đang theo dõi. tức là, nếu sử dụng digitalWrite
trên một chân tương tự, hãy sử dụng tham chiếu A0
- A5
.
Nếu bạn muốn lái đèn LED, thì bạn cũng có thể sử dụng MAX7219 có thể lái 64 đèn LED, không cần thêm mạch (không cần bóng bán dẫn để khuếch đại tín hiệu).
Lái MAX7219 chỉ cần 3 chân đầu ra trên Arduino. Ngoài ra, bạn có thể tìm thấy một vài thư viện Arduino cho nó.
Bạn cũng có thể xâu chuỗi một vài trong số chúng nếu bạn cần cấp nguồn cho hơn 64 đèn LED.
Tôi đã sử dụng nó thành công cho nhiều màn hình LED 7 đoạn.
Nhược điểm: nó đắt tiền (khoảng $ 10).
Bạn có thể sử dụng Charlieplexing . Với kỹ thuật này, bạn có thể lái trực tiếp n*(n-1)
đèn LED từ n chân. Vì vậy, với 3 chân, bạn có thể lái 6 đèn LED, 4 chân - 12 đèn LED, 5 chân - 20 đèn LED, v.v.
Ví dụ:
Sáu đèn LED trên 3 chân
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
Bạn có thể xem một hướng dẫn tốt hơn ở đây .
Bạn có thể sử dụng giao thức I 2 C (Thư viện dây) để kết nối với các thiết bị khác như bộ mở rộng cổng. Ví dụ: MCP23017.
Tôi đã sử dụng một trong những con chip đó để kết nối với bảng LCD. MCP23017 có 16 cổng, có thể được cấu hình làm đầu vào hoặc đầu ra. Là đầu vào, họ có thể tăng ngắt nếu muốn.
Ví dụ về kết nối 13 trong số 16 với LCD:
Bây giờ chúng tôi kết nối với Arduino chỉ bằng 2 dây (SDA / SCL) cộng với nguồn và nối đất:
Một số nhà sản xuất bên thứ ba đã tạo ra các bảng với 4 x MCP23017 trên đó, điều này mang lại cho bạn 64 đầu vào / đầu ra:
Bạn có thể sử dụng bộ ghép kênh tương tự như 74HC4051 (8 cổng) hoặc 74HC4067 (16 cổng) để kết nối một chân với một trong các cổng 8/16 (nhưng chỉ một cổng tại một thời điểm nhất định), như sau:
Đây là hai hướng, vì vậy có thể được sử dụng như một thiết bị mở rộng đầu vào hoặc đầu ra.
Sử dụng SPI, bạn có thể gửi dữ liệu nối tiếp nhanh đến một thanh ghi thay đổi, chẳng hạn như 74HC595. Đây có thể là hoa cúc xích lại với nhau. Trong ví dụ này, tôi đang điều khiển 32 đèn LED chỉ với 3 chân I / O (MOSI / MISO / SCK) cộng với nguồn và mặt đất.
Tôi tìm thấy bên trong một đèn LED thương mại rằng 72 đèn LED được điều khiển bởi chip 74HC595.
Điều này có 9 chip điều khiển các cột (9 x 8 = 72 đèn LED) và một chip điều khiển các hàng, trong một cấu hình đa kênh.
Nếu bạn chỉ muốn lái đèn LED, bạn thường có thể ghép chúng. MAX7219 đơn giản hóa điều đó bằng cách được thiết kế để điều khiển ma trận LED, ví dụ như màn hình 7 đoạn:
Hoặc ma trận 64-LED:
Trong cả hai trường hợp, chúng có thể được nối với nhau, ví dụ:
Tất cả những ví dụ đó chỉ sử dụng 3 chân của Arduino (MOSI / MISO / SCK) cộng với sức mạnh và mặt đất.
Thiết bị mở rộng cổng 16 cổng được đề cập trước đó (MCP23017) cũng có một biến thể SPI (MCP23S17), thực hiện những điều gần như giống hệt nhau. Nó sử dụng thêm một dây, nhưng sẽ nhanh hơn.
Dải đèn LED (như đèn NeoPixel) có giao thức riêng. Có một bài đăng trên Youtube của Josh Levine , nơi tác giả đã lái hơn 1000 pixel bằng một Duemilanove!
Các thanh ghi thay đổi đã được đề cập trong các câu trả lời khác, và chúng chắc chắn là một lựa chọn tuyệt vời cho nhiều dự án. Chúng rẻ, đơn giản, nhanh vừa phải và thường có thể được kết nối với nhau để thêm đầu ra. Tuy nhiên, chúng có nhược điểm là chúng thường cần sử dụng độc quyền một số chân (từ 2 đến 4, tùy thuộc vào cách bạn thiết lập chúng).
Một cách khác là sử dụng các bộ mở rộng cổng tiên tiến hơn, chẳng hạn như 16 bit MCP23017 và MCP23S17 . Chúng hỗ trợ I2C và SPI tương ứng, có nghĩa là bạn có thể đặt chúng trên xe buýt với một số thiết bị khác (có khả năng thuộc các loại khác nhau). Mỗi thiết bị trên xe buýt có thể được giải quyết riêng, có nghĩa là bạn chỉ cần 2 hoặc 3 chân để nói chuyện với tất cả chúng. Tốc độ cập nhật thường cực kỳ nhanh, do đó bạn không có khả năng gặp phải độ trễ đáng kể (nghĩa là độ trễ truyền) trong một dự án Arduino.
Ở mức độ thấp, sử dụng I2C hoặc SPI phức tạp hơn nhiều so với thanh ghi thay đổi đơn giản. Tuy nhiên, có mã thư viện cho Arduino để chăm sóc điều đó cho bạn. Xem câu hỏi này, ví dụ: Làm cách nào để sử dụng thiết bị I2C với Arduino?
Ngoài câu trả lời của Ricardo , những gì Wikipedia nêu trên các thanh ghi thay đổi :
Một trong những cách sử dụng phổ biến nhất của thanh ghi thay đổi là chuyển đổi giữa các giao diện nối tiếp và song song. [...] Các thanh ghi SIPO thường được gắn vào đầu ra của bộ vi xử lý khi cần nhiều chân Đầu vào / Đầu ra Mục đích chung hơn là có sẵn. Điều này cho phép một số thiết bị nhị phân được điều khiển chỉ bằng hai hoặc ba chân, nhưng chậm hơn so với I / O song song.
Trong bài viết Ricardo liên kết, bạn có thể xem sơ đồ của thanh ghi thay đổi.
Điều xảy ra ở đây là bạn đặt dữ liệu của 8 chân theo một chuỗi và với mỗi đồng hồ, thanh ghi dịch chuyển sẽ dịch chuyển (di chuyển dữ liệu nhị phân từ mỗi chốt sang chốt tiếp theo) cho đến khi "tạo một vòng tròn" tức là bit đầu tiên đến pin cuối cùng Các thanh ghi Shift cũng có một đầu vào nơi bạn có thể bật / tắt dịch chuyển để trạng thái có thể được giữ sau khi dữ liệu được chuyển sang vị trí. Đối với một cuộc biểu tình đơn giản xem hoạt hình sau đây.
Ở đây đèn đỏ là đầu vào nối tiếp và đèn xanh đang hiển thị trạng thái của các chốt trong thanh ghi dịch chuyển SIPO đơn giản này . Sau khi dữ liệu được dịch chuyển sang vị trí dịch chuyển có thể được tắt và bạn có thể đọc các chân. Trong ví dụ này tôi đã chuyển đi 10101011
.
Từ những ví dụ này, bạn có thể nhận ra rằng việc chuyển đổi nối tiếp sẽ chậm hơn so với song song, vì bạn phải đợi thanh ghi dịch chuyển các bit đến vị trí của chúng. Bạn sẽ phải chờ cùng một lượng đồng hồ đánh dấu là bao nhiêu bit bạn muốn tải. Đây là một trong nhiều lý do tại sao bạn không thể xâu chuỗi chúng vô thời hạn, bởi vì việc tải sẽ mất mãi mãi.
Như bạn đã viết rồi, bạn có thể sử dụng tất cả các chân, bao gồm TX và RX làm đầu ra kỹ thuật số. Tôi đã làm điều đó một thời gian trước cho một người biểu tình và ghi lại một video - 20 LEDS trên 20 chân - của dự án khá vô nghĩa này.
Theo mô tả của Peter R. Bloomfield tại đây , bạn phải ngắt kết nối TX và RX để tải lên. Hơn nữa, bạn không thể đọc được các cảm biến để có thể tương tác và phải đảm bảo rằng tổng giới hạn hiện tại không đạt được. Đừng quên rằng bạn bị giới hạn ở đèn led 5V nếu bạn lái chúng trực tiếp với Arduino của bạn.
Do đó, việc sử dụng các thanh ghi thay đổi nói chung và 595, được mô tả bởi Ricardo rất được khuyến khích.
Tôi đã sử dụng chúng cách đây một thời gian khi tôi nhận ra phần hàn và lập trình của Kawaii me (văn bản của liên kết là tiếng Đức) của nghệ sĩ thượng lưu Dominik Jais .
Ở đây, chỉ một bó 595 đã được sử dụng để lái một màn hình của đèn led 8x11. Vì các đèn led đã được cắt từ một dải đèn led SMD 12 V, nên cần có thêm một bộ nguồn và một số mảng DarDN UDN2804A , được nối với các chân đầu ra của các thanh ghi thay đổi.
Các phương pháp chung khác sẽ bao gồm việc sử dụng các bộ mở rộng cổng 8 bit PCF8574 (A), được điều khiển thông qua bus I2C.
Dù sao, tôi sẽ thử 595 đăng ký thay đổi trước.
Tuy nhiên, nếu bạn cần điều khiển một vài đèn led RGB, bạn có thể muốn tìm kiếm các giải pháp chuyên biệt hơn. Một số đèn led RGB đi kèm với WS2812 của riêng họ . Những mảnh tốt này có thể được xếp tầng (bus 1 dây) và được xử lý thông qua vị trí của chúng trong chuỗi.
Nếu đó là tất cả về đèn LED, vậy còn dải đèn LED WS2812B, hay chỉ riêng chip điều khiển? Bạn có thể điều khiển số lượng đèn LED hầu như không giới hạn chỉ bằng một pin!
Mặc dù mọi người đang sử dụng những dải này, nhưng chúng có sẵn dưới dạng đèn LED độc lập (được gọi là pixel pixel trên Adaf nhung). Hoặc nếu bạn chỉ lái một màu duy nhất, mỗi chip WS2811 có thể điều khiển 3 đèn LED bằng cách sử dụng từng đầu ra RGB cho mỗi đèn LED.
Gần đây tôi vừa tạo một dự án sử dụng 5 đèn LED như vậy: Cửa đóng / mở, Cửa đóng / đóng cửa, motor1 hoạt động, motor2 hoạt động và nguồn. Đèn LED "hoạt động" là mục đích kép vì tôi có màu đỏ là đầu vào từ động cơ hoạt động và màu xanh lá cây là cờ hoạt động bên trong Arduino.
Điểm hiện tại, với 1 pin và thư viện được cài đặt, bạn có thể điều khiển bất kỳ số lượng đèn LED nào
Tôi không yêu cầu phương pháp này cho riêng mình, nhưng tôi đã tìm thấy thủ thuật gọn gàng này trên trang web MUX-DEMUX: CD4051 Parlor Tricks
Dù bạn chọn sử dụng phương pháp nào để điều khiển đầu ra hoặc đọc đầu vào (thanh ghi thay đổi, bộ ghép kênh hoặc sử dụng trực tiếp các chân Arduino), bạn có thể NHÂN ĐÔI số lượng đầu ra hoặc đầu vào bằng cách sử dụng khéo léo các cặp mạch song song (để tạo thành một cặp kép ngân hàng đầu vào hoặc đầu ra ), sử dụng điốt theo các giác quan đối lập trên mỗi nhánh song song và chuyển đổi đầu vào / đầu ra thành cao và thấp.
Để minh họa phương thức cho đầu ra (đèn LED trong trường hợp này, lưu ý rằng không cần điốt thêm):
Nếu bạn coi cặp đèn LED trong ví dụ này là "ngân hàng" và bạn muốn bật đèn LED_0, bạn cần đặt mã PIN 17 thành CAO và mã PIN 18 thành THẤP. (Các số pin khó hiểu, nhưng chúng khớp với ví dụ sau rất trần với tôi). Để bật đèn LED_1, bạn chỉ cần đảo ngược mã PIN. Bản chất diode của đèn LED giữ cho dòng điện chạy ngược chiều giữ cho cái kia tắt.
Để minh họa phương thức cho đầu vào (CdS trong trường hợp này, lưu ý rằng các điốt bổ sung là bắt buộc):
Điều này sẽ phức tạp hơn một chút nếu bạn muốn thực hiện đọc tương tự trên cảm biến ánh sáng CdS. Đầu tiên, bạn cần thêm một diode vào mỗi cảm biến để kiểm soát dòng chảy. Thứ hai, vì bạn đang đọc các giá trị, bạn cần kéo đầu vào cao hoặc thấp để giữ cho chúng không bị trôi. Là một người lười biếng, tôi sẽ kéo chúng lên cao bằng cách sử dụng điện trở kéo lên bên trong. Để đọc CdS_0, bạn đặt chế độ PIN 17 thành OUTPUT và đặt nó ở mức THẤP. Điều này làm cho nó mặt đất. Sau đó, bạn đặt chế độ PIN 18 thành INPUT và đặt nó ở mức CAO để kích hoạt điện trở kéo lên. Bây giờ bạn đã thiết lập để đọc mã PIN 18 (còn gọi là chân tương tự 4). Để truy cập cảm biến khác, chỉ cần chuyển đổi chế độ và đầu ra.
Vì vậy, nếu bạn có bộ ghép kênh 8 cổng CD4051, sử dụng 5 chân trên Arduino (thay vì 3 thông thường), bạn có thể nhận được 16 đầu vào hoặc đầu ra hoặc kết hợp cả hai.
Tương tự như vậy, nếu bạn có bộ ghép kênh 4067 16 cổng, bạn có thể nhận được 32 đầu vào hoặc đầu ra hoặc kết hợp cả hai.
Một ví dụ phác thảo sẽ là:
/*
* 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);
}
}
}
Giống như tôi đã nói ở dòng đầu tiên, có thể tìm thấy lời giải thích đầy đủ trên MUX-DEMUX: CD4051 Parlor Tricks
Đối với một dự án lớp tôi đã sử dụng một CD4024 và hai chân Arduino để điều khiển màn hình 7 đoạn.
Có một số hãy cẩn thận với phương pháp này. Ví dụ, để viết một high
giá trị cho đầu ra đầu tiên của bộ đếm gợn chỉ cần một reset
và bật / tắt pin đồng hồ hai lần. Nhưng nếu bạn muốn ghi high
cho tất cả n chân đòi hỏi phải chuyển đổi qua lại pin đồng hồ 2 n lần, và trong thời gian đó tất cả các chân khác đang không ngừng chuyển đổi qua lại và tắt.
Nếu ứng dụng của bạn có thể giải quyết những hạn chế này và bạn thiếu chân, thì đó là một lựa chọn khác.
Phần thưởng trả lời: có rất nhiều ví dụ về đầu vào ghép kênh ở đây , nhiều trong số đó cũng áp dụng cho đầu ra ghép kênh.
Với một chút công việc (cài đặt bộ tải khởi động khác), bảy dòng I / O bổ sung có sẵn trên Uno, trên các tiêu đề ICSP1 và JP2. Bộ tải khởi động thay thế được gọi là HoodLoader2 . Nó cho phép bạn cài đặt các bản phác thảo trên cả Atmega328 và Atmega16U2 trên Uno. Đối phó với nhiều bộ xử lý sẽ là biến chứng chính từ việc sử dụng phương pháp này.
Trên Uno, các tiêu đề ICSP1 và JP2 kết nối với các chân PB1 ... PB7 của Atmega16U2. Ngoài ra, Atmega16U2 có khoảng 9 chân I / O không có kết nối với bảng mạch. Một người làm việc dưới kính hiển vi có thể gắn dây vào tổng số 18 chân I / O trên 16U2, trong khi để lại ba chân I / O khác được gắn vào các kết nối thông thường của họ.
HoodLoader2 cũng hoạt động trên bảng Mega.