Чи є спосіб мати більше 14 вихідних штифтів на arduino?


52

Чи можливо мати більше 14 вихідних штифтів на Arduino, я працюю над проектом, в якому мені потрібно запалити кілька світлодіодів окремо. У мене є тільки Arduino Uno, і я не хочу отримати Мегу.


Чи є в дусі розширюваності можливість I2C навіть варіантом з Arduino?
Кріс О

@ChrisO Що ви маєте на увазі під I2C? Бо з того, що я розумію, регістри Shift вважатимуться I2C.
JVarhol

О, змусити мене відповісти на моє запитання тоді ;-) Ось стаття з wikipedia про цей стандарт шини. І я щойно знайшов підтримку від Wire lib для I2C, щоб ви могли підключити ланцюг I2C до свого Uno.
Кріс О

@JVarhol Не зовсім. I2C, він же TWI - це двожильний інтерфейс, тоді як SPI може вважатися 3-провідним інтерфейсом.
Klaus-Dieter Warzecha

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

Відповіді:


50

Поширеним способом розширення набору доступних вихідних штифтів на Arduino є використання регістрів зсуву, таких як 74HC595 IC ( посилання на лист даних ).

Для управління цими фішками вам потрібні 3 штирі:

  1. Годинник
  2. Засувка
  3. Дані

У програмі ви передаєте дані по одному біту в регістр зсуву за допомогою команди shiftOut () , наприклад:

shiftOut(dataPin, clockPin, data); 

За допомогою цієї команди ви встановлюєте кожен з 8 виходів на ІС 595 з 8 бітами dataзмінної.

За один 595 ви отримуєте 5 штифтів (8 на ІМС, але витрачаєте 3, щоб поговорити з ним). Щоб отримати більше результатів, ви можете вирізати ланцюжок серії 595 разом, підключивши її послідовний штифт, до шпильки наступного. Ви також повинні з'єднати штифти годинника та засувки всіх 595 ІМС.

Отриманий контур (використовуючи один 595) виглядатиме так:

Схему за допомогою регістра зсуву 595

Наведена вище цифра взята з цієї веб-сторінки codeproject.com :

Шпилька засувки використовується для постійного збереження 595 виходів під час переміщення в неї даних:

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

1
Thx, забув включити, як працює реєстр змін. Я планував, але мені довелося піти від свого комп, і коли я повернувся, це мені спалахнуло. :)
JVarhol

Немає проблем, тому ми - громада. Ми доповнюємо відповіді один одного. Але приємно, що ви додали кілька хороших порад у свою відповідь, особливо про щит EZ-Expander. Це дозволяє тим, хто не може легко зробити свої друковані плати, розширити кількість доступних їм портів.
Рікардо

2
Крім того, це робить програмування легким, вам не потрібно зміщувати дані і натискати на годинник, а потім активувати засувку. Я знаю про щит досить давно і думаю, що він ідеально підходить для новачків. Найкраще те, що через те, що код є відкритим джерелом, ви можете використовувати код, навіть якщо ви не використовуєте власне щит, але маєте власну дошку або використовуєте дошку.
JVarhol

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

Дякую! Ось архів посилання на дивовижний опис кодового проекту на випадок, якщо посилання коли-небудь знизиться archive.fo/1uvPE
akhmed

27

Є два способи отримати більше шпильок з ардуїно.

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

Інший спосіб отримати більше шпильок з Arduino - це за допомогою регістра Shift. Для цього я рекомендую використовувати щит EZ-Expander , який дозволяє використовувати 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 на Arduino потрібні лише 3 вихідних штифта. Також ви можете знайти кілька бібліотек Arduino для нього.

Ви також можете зав'язати декілька з них, якщо потрібно живити більше 64 світлодіодів.

Я його успішно використовую для декількох 7-сегментних світлодіодних дисплеїв.

Знизу: це дорого (близько 10 доларів).


Я забув про MAX7219, дякую за публікацію!
JVarhol

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

17

Можна використовувати Charlieplexing . За допомогою цієї методики ви можете безпосередньо керувати n*(n-1)світлодіодами з n штифтів. Тож за допомогою 3-х штифтів ви можете керувати 6 світлодіодами, 4 контактами - 12 світлодіодами, 5 контактами - 20 світлодіодами тощо.

Приклад:

Шість світлодіодів на 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

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

Кращий підручник ви можете побачити тут .


Варто зазначити, що ця методика дозволяє контролювати більше світлодіодів, але не обов'язково одночасно.
kontur

1
@kontur так, ти маєш рацію. Але з точки зору стійкості бачення можна вважати, що вони є. Питання не має таких деталей.
Даніель Грілло

Charlieplexing - це не ТІЛЬКИ спосіб мультиплексування світлодіодів без використання регістрів зсуву.
linhartr22

1
@ linhartr22 Я ніколи не казав, що це єдиний спосіб. Чарліплекс - це просто поширене рішення цієї проблеми. І моя відповідь була 7-ю. Тож інші можливості вже були показані раніше.
Даніель Грілло

@DanielGrillo Я повинен був бути більш конкретним і пояснив, як мультиплексування стовпців і рядків, яке, як правило, використовується на світлодіодних кубиках, можна робити без реєстрації зрушень і без обмежень Charlieplexing. Матриця стовпців 4х4 рядків може індивідуально керувати 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 x MCP23017 на них, це дає 64 входи / виходи:

Сороконічна дошка


Мультиплексори

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

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

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


SPI з 74HC595

Використовуючи SPI, ви можете надсилати швидкі послідовні дані до регістру зрушень, наприклад 74HC595. Це можуть бути ромашки, прикуті разом. У цьому прикладі я керую 32 світлодіодами лише з 3 вводами / виводами (MOSI / MISO / SCK) плюс потужністю та землею.

74HC595, що управляє 32 світлодіодами


Я виявив всередині комерційного світлодіодного знаку, що 72 світлодіоди керуються мікросхемами 74HC595.

Прокрутка світлодіодний знак

У ньому було 9 мікросхем, що ведуть колони (9 х 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?


Нічого собі, я ніколи не знав про них, THX, погано дивлюся на них!
JVarhol

Чи можете ви використовувати I2C для управління світлодіодами?
Pro Q

1
@ProQ Не можна керувати стандартними світлодіодами безпосередньо за допомогою I2C. Однак можна придбати деякі світлодіодні продукти, які мають вбудований драйвер I2C. Зазвичай це для виробів з великою кількістю світлодіодів, таких як смужки або матриці.
Пітер Блумфілд

8

На додаток до відповіді Рікардо , що у Вікіпедії зазначено про регістри змін :

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

У пов'язаній статті Рікардо ви можете побачити схему регістра зсуву.

Зміна регістрової діаграми

Тут відбувається те, що ви ставите дані 8 штифтів послідовно, і для кожного годинника галочка зсувний реєстр зміщуватиметься (переміщувати двійкові дані з кожної засувки на наступну), поки вона не зробить коло, тобто перший біт доходить до останньої шпильки. У регістри зсуву також є вхід, де ви можете вмикати / вимикати зсув, щоб стан можна зберігати після переміщення даних у положення. Для простої демонстрації див наступну анімацію.

Зміна реєстрації анімації

Тут червоне світло - це послідовний вхід, а зелене - показує стан засувок у цьому спрощеному регістрі зміни SIPO . Після переміщення даних на місце переміщення можна вимкнути, і ви можете прочитати штифти. У цьому прикладі я змістився 10101011.

З цих прикладів ви можете зрозуміти, що послідовна передача буде протікати повільніше, ніж паралельна, тому що вам доведеться чекати, коли реєстр змін змістить біти на їх місце. Вам доведеться почекати стільки ж галочок, скільки годин ви хочете завантажити. Це одна з багатьох причин, чому ви не можете їх ланцюговувати нескінченно довго, оскільки завантаження займе назавжди.


1
+1 для додаткової інформації ТА для симпатичного анімаційного GIF та його динамічного ефекту! Де ти знайшов GIF? Або ти встиг?
Рікардо

1
@Ricardo Я створив схему з Digital Works, потім надрукував екран, редагував, gif animator.
totymedli

6

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

Як описав Пітер Р. Блумфілд тут , вам доведеться відключити TX і RX для завантаження. Більше того, у вас немає шпильок для зчитування датчиків щодо можливої ​​інтерактивності, і ви повинні переконатися, що загальна межа струму не досягнута. Не забувайте, що ви обмежені 5 В світлодіодами, якщо керуєте ними безпосередньо зі своїм Arduino.

Тому вкрай не рекомендується використовувати регістри зсуву та 595, описані Рікардо .

  • Вони дешеві!
  • Каскадувати їх досить просто.
  • Велику швидкість можна отримати, якщо використовувати апаратно-SPI.

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

Тут просто 595 використали для дисплея 8x11 світлодіодів. Оскільки світлодіоди були відрізані від смуги 12В SMD, необхідні додаткові джерела живлення та деякі масиви Дарлінгтона UDN2803A , підключені до вихідних штифтів регістрів зсуву, були необхідні.

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

У будь-якому разі я спершу спробую зареєструвати регістри змін 595.

Якщо вам потрібно керувати парою RGB світлодіодів, можливо, ви захочете шукати більш спеціалізовані рішення. Деякі світлодіодні RGB поставляються із власним WS2812 . Ці дрібні шматочки можуть бути каскадними (1-дротова шина) і адресовані через їх положення в ланцюзі.


3

Якщо все стосується світлодіодів, а що з світлодіодними смужками WS2812B або просто чіпами драйвера? Ви можете керувати практично необмеженою кількістю світлодіодів, використовуючи лише один контактний контакт!

Хоча люди звикли їх до смужок, вони доступні як окремі світлодіоди (відомі як неопікселі на Adafruit). Або якщо ви керуєте лише одним кольором, кожен чіп WS2811 міг керувати 3 світлодіодами, використовуючи кожен з RGB-виходів для одного світлодіода.

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

З огляду на те, що з одним штифтом та встановленою бібліотекою ви можете керувати будь-якою кількістю світлодіодів


2

Я не претендую на цей метод як власний, але я знайшов цю акуратну хитрість на веб - сторінці MUX-DEMUX: CD4051 Parlor Tricks

Який би метод ви не вибрали для керування виходами або зчитування входів (регістри зсуву, мультиплексори або пряме безпосереднє використання самих шпильок Arduino), ви можете ДВОЙСТАТИ кількість виходів або входів шляхом розумного використання паралельних пар схем (для формування подвійних банк вводу чи виводу ), використовуючи діоди в протилежних відчуттях на кожній паралельній гілці та перемикаючи входи / виходи на високі та низькі.

Для ілюстрації способу виходів (світлодіоди в цьому випадку зауважте, що додаткові діоди не потрібні):

Світлодіодний банк

Якщо ви вважаєте, що пара світлодіодів у цьому прикладі є "банком", і ви хочете засвітити світлодіод_0, вам потрібно встановити PIN-код 17 ВИСОКИЙ, а PIN-код 18 - НИСЬКИЙ. (Номери штифтів плутають, але вони відповідають наступному прикладу, настільки голому зі мною) Щоб засвітити LED_1, ви просто поверніть PINS. Діодний характер світлодіодів утримує струм від течії в протилежному напрямку, утримуючи інший.

Щоб проілюструвати спосіб введення даних (у цьому випадку CdS, зауважте, що потрібні додаткові діоди):

CdS банк

Це стає трохи складніше, якщо ви хочете зробити аналогове зчитування на датчику світла CdS. Спочатку потрібно додати діод до кожного датчика, щоб контролювати витрату. По-друге, оскільки ви читаєте значення, вам потрібно витягувати входи високо або низько, щоб не плавати. Будучи ледачою людиною, я збираюся підтягнути їх високо, використовуючи внутрішні підтягуючі резистори. Щоб прочитати CdS_0, ви встановите для режиму PIN 17 режим "OUTPUT" та встановите його на "LOW". Це робить його грунтом. Потім ви встановите для режиму PIN 18 ВХОД і встановите його ВИСОК для включення підтягуючого резистора. Тепер ви налаштовані на читання PIN-коду 18 (він же аналоговий контакт 4). Щоб отримати доступ до іншого датчика, просто перемкніть режими та виходи.

Отже, якщо у вас є мультиплексор для порту CD4051 8, використовуючи 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 Parlor Tricks


1

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

Існує кілька застережень до цього підходу. Наприклад, для запису highзначення на перший вихід лічильника пульсацій потрібно лише a resetі перемикання годинникового штифта двічі. Але якщо ви хочете записати highна всі n штифтів, потрібно перемикати годинний штифт 2 n рази, і за цей час усі інші штифти постійно включаються та вимикаються.

Якщо ваша програма може вирішити ці обмеження, і вам не вистачає шпильок, це інший варіант.

Бонус Відповідь: Є багато прикладів мультиплексування входів тут , багато з яких застосовуються також до мультиплексування виходів.


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

1

Додавши трохи роботи (встановлення іншого завантажувача), на Uno, на заголовках ICSP1 та JP2 доступні додаткові сім ліній вводу / виводу. Замінний завантажувач називається HoodLoader2 . Це дозволяє встановлювати ескізи як на Atmega328, так і на Atmega16U2 на Uno. Робота з декількома процесорами була б головним ускладненням від використання цього методу.

На Uno заголовки ICSP1 та JP2 підключаються до контактів PB1 ... PB7 Atmega16U2. Крім того, Atmega16U2 має близько 9 контактів вводу / виводу без підключення до друкованої плати. Людина, яка працює під мікроскопом, може мати змогу приєднати дроти до загального 18 штифтів вводу / виводу на 16U2, залишивши три інші шпильки вводу / виводу, приєднані до своїх звичайних з'єднань.

HoodLoader2 також працює на Mega дошках.


0

Тут є безліч хороших відповідей, але якби ви витратили свій час, вам буде дешевше придбати Мегу.

Моя 3/2-д варті.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.