Есть ли способ иметь более 14 выходных контактов на Arduino?


52

Возможно ли иметь более 14 выходных выводов на Arduino, я работаю над проектом, в котором мне нужно зажечь несколько светодиодов по отдельности. У меня есть только Arduino Uno, и я не хочу получать Mega.


В духе расширяемости, I2C - это даже вариант с Arduino?
Крис О,

@ChrisO Что вы подразумеваете под I2C? Потому что, насколько я понимаю, регистры сдвига будут считаться I2C.
JVarhol

О, заставь меня ответить на мой вопрос ;-) Вот статья в Википедии об этом стандарте автобуса. И я только что нашел поддержку Wire lib для I2C, чтобы вы могли подключить цепочку I2C к вашему Uno.
Крис О,

@JVarhol Не совсем. I2C, он же TWI - это двухпроводной интерфейс, а SPI можно считать трехпроводным.
Клаус-Дитер Варзеча

1
@JVarhol вы уже выбрали решение для своего проекта? Если да, было бы полезно отредактировать ваш вопрос и принять ответ, который соответствует (или является ближайшим) вашим решением.
jfpoilpret

Ответы:


50

Распространенным способом расширения набора доступных выходных выводов на Arduino является использование сдвиговых регистров, таких как микросхема 74HC595 ( ссылка на таблицу данных ).

Вам нужно 3 контакта для управления этими чипами:

  1. Часы
  2. задвижка
  3. Данные

В программе вы передаете данные по одному в регистр сдвига с помощью команды shiftOut () , например так:

shiftOut(dataPin, clockPin, data); 

С помощью этой команды вы устанавливаете каждый из 8 выходов на 595 IC с 8 битами в dataпеременной.

С одним 595 вы получаете 5 булавок (8 на IC, но вы тратите 3, чтобы поговорить с ним). Чтобы получить больше выходов, вы можете последовательно соединить серию 595, соединив ее вывод последовательного выхода с выводом данных следующего. Вы также должны соединить вместе контакты часов и фиксаторов всех 595 ИС.

Результирующая схема (с использованием одного 595) будет выглядеть так:

Схема с использованием 595 сдвигового регистра

Приведенный выше рисунок был взят с этой веб-страницы codeproject.com :

Защелка используется для обеспечения стабильной работы выходов 595 во время перемещения данных в нее, например, так:

digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, data); 
digitalWrite(latchPin, HIGH);

1
Спасибо, забыл включить, как работает регистр сдвига. Я планировал, но я должен был уйти от своего компа, и когда я вернулся, это ускользнуло от меня. :)
JVarhol

Нет проблем, поэтому мы сообщество. Мы дополняем ответы друг друга. Но приятно, что вы также добавили несколько хороших советов в свой ответ, особенно о щите EZ-Expander. Это позволяет тем, кто не может легко сделать свои печатные платы, увеличить количество доступных для них портов.
Рикардо

2
Кроме того, это облегчает программирование, вам не нужно сдвигать данные и пульсировать часы, а затем активировать фиксатор. Я знал о щите довольно давно, и я думаю, что он идеально подходит для начинающих. Лучше всего то, что, поскольку код является открытым исходным кодом, вы можете использовать код, даже если вы не используете фактически щит, но имеете свою собственную доску или используете макет.
JVarhol

1
Не забывайте, что вы можете связывать их в строке (теоретически) бесконечно, поэтому 2 8-битных регистра могут стать одним 16-битным.
Скотт М.

Спасибо! Вот ссылка на архив с удивительным описанием кода проекта на тот случай, если ссылка когда-нибудь выйдет из архива .fo
1uvPE

27

Есть два способа получить больше булавок из Arduino.

Первый способ - использование аналоговых выводов в качестве выводов цифрового выхода, что очень легко сделать. Все, что вам нужно сделать, это обратиться к A0-A5 как кеглям 14,15,16,17,18,19. Например, для записи высокого значения на вывод A0 просто используйте digitalWrite (14, HIGH).

Другой способ получить больше пинов из Arduino - использовать Shift Register. Для этого я рекомендую использовать EZ-Expander Shield , который позволяет использовать digitalWrite ([20-35], HIGH) при импорте библиотеки EZ-Expander. Этот экран, однако, позволяет использовать выводы только в качестве выходов и использует контакты 8, 12 и 13 для управления регистрами сдвига.

Самое замечательное то, что вы можете использовать оба вышеупомянутых метода без проблем.


3
Согласно справочнику Arduino, вы можете напрямую использовать идентификаторы A0- A5вместо цифр 14-19. Например, digitalWrite(A0, HIGH).
Питер Блумфилд

3
@ PeterR.Bloomfield Оба варианта верны, однако я рекомендую A0-A5 для простоты и удобства чтения. Ничего страшного в том, что светодиод мигает, но когда у вас большие проекты, небольшие привычки складываются.
Анонимный Пингвин

2
На самом деле, хотя оба будут выполнять работу на UNO и совместимых платах, digitalWrite(A0)это более правильно, чем то, digitalWrite(14)что первое всегда будет отображаться на правильный физический (аналоговый) вывод. На другой плате pin 14может фактически не быть A0, например, pin 14на MEGA есть Serial3 TXи не будет влиять на аналоговый вывод, который вам нужен . то есть, если вы используете digitalWriteаналоговый вывод, используйте ссылку A0- A5.
Мадивад

18

Если вы хотите управлять светодиодами, то вы также можете использовать MAX7219, который может управлять 64 светодиодами, без дополнительной схемы (нет необходимости в транзисторе для усиления сигнала).

Для вождения MAX7219 требуется всего 3 выходных контакта на Arduino. Также вы можете найти несколько библиотек Arduino для него.

Вы также можете подключить несколько из них, если вам нужно подключить более 64 светодиодов.

Я успешно использовал его для нескольких 7-сегментных светодиодных дисплеев.

Недостаток: это дорого (около 10 долларов).


Я забыл про MAX7219, спасибо за публикацию!
JVarhol

384 светодиода ... аааа! Плюс два вывода для вывода USB. Вам интересно, какую раздражающую безделушку вы можете создать (при достаточном питании).
Анонимный Пингвин

17

Вы можете использовать Чарлиплексирование . С помощью этой техники вы можете напрямую управлять n*(n-1)светодиодами из n контактов. Таким образом, с 3 контактами вы можете управлять 6 светодиодами, 4 контактами - 12 светодиодов, 5 контактами - 20 светодиодов и так далее.

Exemple:

Шесть светодиодов на 3 контакта

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

введите описание изображения здесь

Вы можете увидеть лучший учебник здесь .


Стоит отметить, что эта техника позволяет вам контролировать больше светодиодов, но не обязательно одновременно.
Контур

1
@ kontur да, ты прав. Но с точки зрения постоянства зрения вы можете считать, что они есть. Вопрос не имеет таких деталей.
Даниэль Грилло,

Чарлиплексирование не является ЕДИНСТВЕННЫМ способом мультиплексирования светодиодов без использования сдвиговых регистров.
linhartr22

1
@ linhartr22 Я НИКОГДА не говорил, что это единственный способ. Charlieplexing - это просто общее решение этой проблемы. И мой ответ был седьмым. Таким образом, другие возможности уже показали раньше.
Даниэль Грилло

@DanielGrillo Я должен был быть более конкретным и объяснил, как мультиплексирование столбцов и строк, которое обычно используется на светодиодных кубах, может быть выполнено без сдвигового регистра и без ограничений Charlieplexing. Матрица столбцов строки 4x4 может индивидуально управлять 16 светодиодами с 8 линиями ввода / вывода. Куб 4x4x4 может индивидуально управлять 64 светодиодами с 12 линиями ввода / вывода (возможно даже на Uno с использованием аналоговых A0-A5 в качестве цифровых линий).
linhartr22

13

I 2 C (Провод)

Вы можете использовать протокол I 2 C (библиотека проводов) для подключения к другим устройствам, таким как расширители портов. Например, MCP23017.

Я использовал один из этих чипов для подключения к ЖК-плате. MCP23017 имеет 16 портов, которые можно настроить как входы или выходы. В качестве входных данных они могут вызывать прерывания, если это необходимо.

Пример подключения 13 из этих 16 к ЖК-дисплею:

MCP23017 подключен к ЖК-экрану

Теперь мы подключаемся к Arduino, используя только 2 провода (SDA / SCL) плюс питание и заземление:

MCP23017 подключен к Arduino


Некоторые сторонние производители изготовили платы с 4-мя MCP23017 на них, что дает вам 64 входа / выхода:

Сороконожка


мультиплексоры

Вы можете использовать аналоговые мультиплексоры, такие как 74HC4051 (8 портов) или 74HC4067 (16 портов), чтобы подключить один контакт к одному из портов 8/16 (но только один в данный момент времени), например так:

74HC4051 мультиплексор

Они являются двунаправленными, поэтому их можно использовать как расширитель входа или выхода.


SPI с 74HC595

Используя SPI, вы можете отправлять быстрые последовательные данные в сдвиговый регистр, такой как 74HC595. Они могут быть соединены вместе. В этом примере я управляю 32 светодиодами только с 3 контактами ввода / вывода (MOSI / MISO / SCK) плюс питание и заземление.

74HC595 управляет 32 светодиодами


Внутри коммерческого светодиода я обнаружил, что эти 72 светодиода работают на чипах 74HC595.

Прокрутка светодиодной вывески

Он имел 9 чипов, управляющих столбцами (9 x 8 = 72 светодиода), и один чип, управляющий рядами, в мультиплексированной конфигурации.


SPI с MAX7219

Если вы просто хотите управлять светодиодами, вы обычно можете их мультиплексировать. MAX7219 упрощает это, будучи разработанным для управления светодиодными матрицами, например, 7-сегментными дисплеями:

MAX7219 с 7-сегментным дисплеем

Или 64-светодиодные матрицы:

MAX7219 с 64-светодиодной матрицей

В обоих случаях они могут быть соединены последовательно, например:

MAX7219 гирляндная цепь

Во всех этих примерах используются только 3 контакта Arduino (MOSI / MISO / SCK) плюс питание и заземление.


SPI с MCP23S17

Упомянутый ранее 16-портовый расширитель портов (MCP23017) также поставляется в варианте SPI (MCP23S17), который делает практически идентичные вещи. Он использует еще один провод, но будет быстрее.


Другие протоколы

У светодиодных лент (как у NeoPixel) есть свои протоколы. На Youtube был пост от Джоша Левина, где автор проехал более 1000 пикселей с помощью Duemilanove!


Рекомендации


12

Сдвиговые регистры упоминались в других ответах, и они, безусловно, являются отличным выбором для многих проектов. Они дешевы, просты, в меру быстрые и, как правило, могут быть объединены в цепочку, чтобы добавить больше выходов. Однако у них есть недостаток, заключающийся в том, что они обычно нуждаются в эксклюзивном использовании нескольких контактов (от 2 до 4, в зависимости от того, как вы их настроили).

Альтернативой является использование более продвинутых расширителей портов, таких как 16-битные MCP23017 и MCP23S17 . Они поддерживают I2C и SPI соответственно, что означает, что вы можете разместить их на шине с несколькими другими устройствами (потенциально разных типов). Каждое устройство в шине может быть адресовано индивидуально, то есть вам нужно всего 2 или 3 контакта, чтобы общаться со всеми из них. Скорость обновления, как правило, чрезвычайно высока, поэтому вы вряд ли будете испытывать значительные задержки (т.е. задержки передачи) в проекте Arduino.

На низком уровне использование I2C или SPI существенно сложнее, чем простой сдвиговый регистр. Однако для Arduino есть код библиотеки, который позаботится об этом за вас. Посмотрите этот вопрос, например: Как я могу использовать устройства I2C с Arduino?


Ух ты, я никогда не знал о тех, спасибо, плохо смотрю на них!
JVarhol

Можете ли вы использовать I2C для управления светодиодами?
Про Q

1
@ProQ Вы не можете управлять стандартными светодиодами напрямую, используя I2C. Тем не менее, можно получить некоторые светодиодные продукты, которые имеют встроенный драйвер I2C. Это обычно для продуктов с большим количеством светодиодов, таких как полоски или матрицы.
Питер Блумфилд

8

В дополнение к ответу Рикардо , что Википедия указывает на сменные регистры :

Одним из наиболее распространенных применений сдвигового регистра является преобразование между последовательным и параллельным интерфейсами. [...] Регистры SIPO обычно присоединяются к выходу микропроцессоров, когда требуется больше выводов общего / общего назначения, чем доступно. Это позволяет управлять несколькими двоичными устройствами, используя только два или три контакта, но медленнее, чем параллельный ввод / вывод.

В статье Ricardo Linked вы можете увидеть схему регистра сдвига.

Сдвиговая регистровая диаграмма

Здесь происходит то, что вы помещаете данные из 8 выводов в последовательность, и для каждого такта такта сдвиговый регистр будет сдвигаться (перемещать двоичные данные из каждой защелки в следующую), пока он не "сделает круг", т.е. первый бит прибывает к последнему выводу. Сдвиговые регистры также имеют вход, с помощью которого вы можете включить / выключить смещение, чтобы сохранить статус после смещения данных в положение. Для простой демонстрации смотрите следующую анимацию.

Анимация регистра сдвига

Здесь красный свет является последовательным входом, а зеленый показывает состояние защелок в этом упрощенном сдвиговом регистре SIPO . После того, как данные сдвинуты на место, сдвиг можно отключить, и вы сможете прочитать выводы. В этом примере я переместился 10101011.

Из этих примеров вы можете понять, что последовательная передача будет медленнее, чем параллельная, потому что вам нужно ждать, пока сдвиговый регистр не сдвинет биты на их место. Вам придется ждать столько же тактов, сколько битов вы хотите загрузить. Это одна из многих причин, почему вы не можете связывать их бесконечно, потому что загрузка будет длиться вечно.


1
+1 за дополнительную информацию И за симпатичный анимированный GIF и его диадический эффект! Где вы нашли GIF? Или ты это сделал?
Рикардо

1
@Ricardo Я создал схему с помощью Digital Works, затем распечатал экран, отредактировал gif-аниматор.
Тотимедли

6

Как вы уже писали, вы можете использовать все выводы, включая TX и RX, в качестве цифрового выхода. Я сделал это некоторое время назад для демонстратора и записал видео - 20 светодиодов на 20 контактов - этого довольно бессмысленного проекта.

Как описано Peter R. Bloomfield здесь , Вы должны отключить TX и RX для загрузки. Более того, у вас нет контактов, чтобы прочитать датчики на предмет возможной интерактивности и вы должны убедиться, что общий предел тока не достигнут. Не забывайте, что вы ограничены 5-вольтовыми светодиодами, если управляете ими напрямую с помощью Arduino.

Поэтому настоятельно рекомендуется использовать сдвиговые регистры в целом и 595, описанные Рикардо .

  • Они дешевые!
  • Каскадировать их довольно легко.
  • Большая скорость может быть достигнута при использовании аппаратного SPI.

Я использовал их некоторое время назад, когда понял паяльную и программирующую часть Kawaii me (текст ссылки на немецком языке) художника по восходящему циклу Доминика Джайса .

Здесь всего 595 использовались для управления дисплеями 8x11. Поскольку светодиоды были вырезаны из полосы светодиодов SMD 12 В, был необходим дополнительный источник питания и несколько массивов UDN2803A Darlington, подключенных к выходным контактам сдвиговых регистров.

Другие общие методы включают использование 8-битных расширителей портов PCF8574 (A), которые управляются через шину I2C.

В любом случае, я бы сначала попробовал 595 сменных регистров.

Однако если вам необходимо управлять парой RGB-светодиодов, возможно, вы захотите найти более специализированные решения. Некоторые RGB-светодиоды поставляются с собственным WS2812 . Эти мелкие части могут быть каскадными (1-проводная шина) и адресованы через их положение в цепи.


3

Если речь идет о светодиодах, что о светодиодных полосках WS2812B или самих микросхемах драйверов? Вы можете управлять практически неограниченным количеством светодиодов, используя только один контакт!

Хотя люди используют их в полосах, они доступны в виде автономных светодиодов (известных как нео пикселей на Adafruit). Или, если вы используете только один цвет, каждый чип WS2811 может управлять 3 светодиодами, используя каждый из выходов RGB для одного светодиода каждый.

Недавно я только что создал созданный проект, который использует 5 таких светодиодов: дверь1 открыта / закрыта, дверь2 открыта / закрыта, мотор1 активен, мотор2 активен и мощность. «Активные» светодиоды имеют двойное назначение, потому что у меня красный - вход от активного двигателя, а зеленый - активный флаг внутри Arduino.

Точка, с 1 контактом и установленной библиотекой, вы можете управлять любым количеством светодиодов


2

Я не претендую на этот метод для себя, но я нашел этот хитрый трюк на веб - странице MUX-DEMUX: CD4051 Уловки салона

Какой бы метод вы ни выбрали для управления выходами или считывания входов (сдвиговые регистры, мультиплексоры или прямое прямое использование самих выводов Arduino), вы можете удвоить количество выходов или входов путем умного использования пар параллельных цепей (для формирования двойной банк ввода или вывода ), используя диоды в противоположных направлениях на каждой параллельной ветви, и переключая входы / выходы на высокий и низкий.

Чтобы проиллюстрировать метод для выходов (в этом случае светодиоды, обратите внимание, что дополнительные диоды не требуются):

Светодиодная банка

Если вы рассматриваете пару светодиодов в этом примере как «банк», и вы хотите зажечь LED_0, вам нужно установить PIN 17 на ВЫСОКИЙ и PIN 18 на НИЗКИЙ. (Пин-коды сбивают с толку, но они соответствуют более позднему примеру, так что со мной). Чтобы зажечь LED_1, нужно просто поменять PINS. Диодная природа светодиодов не дает току течь в противоположном направлении, а другой отключается.

Чтобы проиллюстрировать метод для входов (CdS в этом случае, обратите внимание, что требуются дополнительные диоды):

Банк CdS

Это становится немного сложнее, если вы хотите выполнить аналоговое считывание на датчике освещенности CdS. Во-первых, вам нужно добавить диод для каждого датчика, чтобы контролировать поток. Во-вторых, поскольку вы читаете значения, вам нужно увеличить или уменьшить входные значения, чтобы они не всплывали. Будучи ленивым человеком, я собираюсь поднять их высоко, используя внутренние подтягивающие резисторы. Чтобы прочитать CdS_0, вы устанавливаете режим PIN 17 на OUTPUT и устанавливаете его на LOW. Это делает его основой. Затем вы устанавливаете режим PIN 18 на INPUT и устанавливаете его на HIGH, чтобы задействовать подтягивающий резистор. Теперь вы настроены на считывание PIN 18 (аналог аналогового контакта 4). Чтобы получить доступ к другому датчику, просто переключите режимы и выходы.

Итак, если у вас есть 8-портовый мультиплексор CD4051, использующий 5 выводов на Arduino (вместо обычных 3), вы можете получить 16 входов или выходов или их сочетание.

16 выходов / входов с использованием CD4051

Аналогично, если у вас есть 4067 16-портовый мультиплексор, вы можете получить 32 входа или выхода или их сочетание.

Примером эскиза будет:

/*
 * 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); 
    }
  } 
}

Как я уже говорил в первой строке, полное объяснение можно найти на MUX-DEMUX: CD4051 Трюки с салоном


1

Для проекта класса я использовал CD4024 и два вывода Arduino для управления 7-сегментным дисплеем.

Есть некоторые оговорки к этому подходу. Например, чтобы записать highзначение в первый выход счетчика пульсаций, требуется только a resetи дважды переключать тактовый вывод. Но если вы хотите , чтобы писать highна всех п штифтов требует переключая тактовый контакт 2 п раз, и за это время все остальные контакты постоянно переключая и выключаться.

Если ваше приложение может справиться с этими ограничениями, и у вас мало контактов, это еще один вариант.

Бонус Ответ: Есть много примеров мультиплексирования входов здесь , многие из которых применяются также к мультиплексированию выходов.


Использование 7-ступенчатого счетчика для управления 7-сегментным дисплеем кажется неоптимальным подходом по причинам, которые вы сами указали.
jfpoilpret

1

Немного поработав (установка другого загрузчика), дополнительные семь линий ввода / вывода доступны на Uno, на заголовках ICSP1 и JP2. Запасной загрузчик называется HoodLoader2 . Это позволяет вам устанавливать эскизы как на Atmega328, так и на Atmega16U2 на Uno. Работа с несколькими процессорами будет основным осложнением при использовании этого метода.

На Uno заголовки ICSP1 и JP2 подключаются к контактам PB1 ... PB7 Atmega16U2. Кроме того, Atmega16U2 имеет около 9 выводов ввода / вывода без подключения к плате. Человек, работающий под микроскопом, может подключить провода к 18 контактам ввода-вывода на 16U2, оставив три других контакта ввода-вывода на своих обычных соединениях.

HoodLoader2 также работает на мега платах.


0

Здесь есть множество хороших ответов, но если вы будете тратить свое время, вы найдете дешевле купить Mega.

Моя 3/2-я ценность.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.