Как увеличить количество цифровых выводов Arduino с помощью расширителя портов. Arduino Shields – платы расширения для ардуино Arduino увеличение портов ввода вывода

Одним из ключевых преимуществ платформы Arduino является популярность. Популярную платформу активно поддерживают производители электронных устройств, выпускающие специальные версии различных плат, расширяющих базовую функциональность контроллера. Такие платы, совершенно логично называемые платами расширения (другое название: arduino shield, шилд), служат для выполнения самых разнообразных задач и могут существенно упростить жизнь ардуинщика. В этой статье мы узнаем, что такое плата расширения Arduino и как ее можно использовать для работы с разнообразными устройствами Arduino: двигателями (шилды драйверов двигателей), LCD-экранами (шилды LCD), SD-картами (data logger), датчиками (sensor shield) и множеством других.

Давайте сперва разберемся в терминах. Плата расширения Ардуино – это законченное устройство, предназначенное для выполнения определенных функций и подключаемое к основному контроллеру с помощью стандартных разъемов. Другое популярное название платы расширения – англоязычное Arduino shield или просто шилд. На плате расширения установлены все необходимые электронные компоненты, а взаимодействие с микроконтроллером и другими элементами основной платы происходят через стандартные пины ардуино. Чаще всего питание на шилд тоже подается с основной платы arduino, хотя во многих случаях есть возможность запитки с других источников. В любом шилде остаются несколько свободных пинов, которые вы можете использовать по своему усмотрению, подключив к ним любые другие компоненты.

Англоязычное слово Shield переводится как щит, экран, ширма. В нашем контексте его следует понимать как нечто, покрывающее плату контроллера, создающего дополнительный слой устройства, ширму, за которой скрываются различные элементы.

Зачем нужны шилды arduino?

Все очень просто: 1) для того, чтобы мы экономили время, и 2) кто-то смог заработать на этом. Зачем тратить время, проектируя, размещая, припаивая и отлаживая то, что можно взять уже в собранном варианте, сразу начав использовать? Хорошо продуманные и собранные на качественном оборудовании платы расширения, как правило, более надежны и занимают меньше места в конечном устройстве. Это не значит, что нужно полностью отказываться от самостоятельной сборки и не нужно разбираться в принципе действия тех или иных элементов. Ведь настоящий инженер всегда старается понять, как работает то, что он использует. Но мы сможем делать более сложные устройства, если не будем каждый раз изобретать велосипед, а сосредоточим свое внимание на том, что до нас еще мало кто решал.

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

Наиболее популярным примерами шилдов являются платы расширения для работы с датчиками, двигателями, LCD-экранами, SD-картами, сетевые и GPS-шилды, шилды со встроенными реле для подключения к нагрузке.

Подключение Arduino Shields

Для подключения шилда нужно просто аккуратно «надеть» его на основную плату. Обычно контакты шилда типа гребенки (папа) легко вставляются в разъемы платы ардуино. В некоторых случаях требуется аккуратно подправить штырки, если сама плата спаяна неаккуратно. Тут главное действовать аккуратно и не прилагаться излишней силы.

Как правило, шилд предназначен для вполне конкретной версии контроллера, хотя, например, многие шилды для Arduino Uno вполне нормально работают с платами Arduino Mega. Распиновка контактов на меге выполнена так, что первые 14 цифровых контактов и контакты с противоположной стороны платы совпадают с расположением контактов на UNO, поэтому в нее легко становится шилд от ардуино.

Программирование Arduino Shield

Программирование схемы с платой расширения не отличается от обычного программирования ардуино, ведь с точки зрения контроллера мы просто подключили наши устрйоства к его обычным пинам. В скетче нужно указывать те пины, которые соединены в шилде с соответствующими контактами на плате. Как правило, производитель указывает соответствие пинов на самом шилде или в отдельной инструкции по подключению. Если вы скачаете скетчи, рекомендованные самим производителем платы, то даже это делать не понадобится.

Чтение или запись сигналов шилдов производится тоже обычным методом: с помощью функций , и других, привычных любому ардуинщику команд. В некоторых случаях возможны коллизии, когда вы привыкли к оной схеме соединения, а производитель выбрал другую (например, вы подтягивали кнопку к земле, а на шилде – к питанию). Тут нужно быть просто внимательным.

Как правило, эта плата расширения идет в наборах ардуино и поэтому именно с ней ардуинщики встречаются чаще всего. Шилд достаточно прост – его основная задача предоставить более удобные варианты подключения к плате Arduino. Это осуществляется за счет дополнительных разъемов питания и земли, выведенных на плату к каждому из аналоговых и цифровых пинов. Также на плате можно найти разъемы для подключения внешнего источника питания (для переключения нужно установить перемычки), светодиод и кнопка перезапуска. Варианты шилда и примеры использования можно найти на иллюстрациях.




Существует несколько версий сенсорной платы расширения. Все они отличаются количеством и видом разъемов. Наиболее популярными сегодня являются версии Sensor Shield v4 и v5.

Данный шилд ардуино очень важен в робототехнических проектах, т.к. позволяет подключать к плате Arduino сразу обычный и серво двигатели. Основная задача шилда – обеспечить управление устройствами потребляющими достаточно высокий для обычной платы ардуино ток. Дополнительным возможностями платы является функция управления мощностью мотора (с помощью ШИМ) и изменения направления вращения. Существует множество разновидностей плат motor shield. Общим для всех них является наличие в схеме мощного транзистора, через который подключается внешняя нагрузка, теплоотводящих элементов (как правило, радиатора), схемы для подключения внешнего питания, разъемов для подключения двигателей и пины для подключения к ардуино.



Организация работы с сетью – одна из самых важных задач в современных проектах. Для подключения к локальной сети через Ethernet существует соответствующая плата расширения.




Платы расширения для прототипирования

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





Arduino LCD shield и tft shield

Данный тип шилдов используется для работы с LCD-экранами в ардуино. Как известно, подключение даже самого простого 2-строчного текстового экрана далеко не тривиальная задача: требуется правильно подключить сразу 6 контактов экрана, не считая питания. Гораздо проще вставить готовый модуль в плату ардуино и просто загрузить соответствующий скетч. В популярном LCD Keypad Shield на плату сразу заведены от 4 до 8 кнопок, что позволяет срзау организовать и внешний интерфейс для пользователя устройства. TFT Shield также помогает



Arduino Data Logger Shield

Еще одна задача, которую достаточно трудно реализовывать самостоятельно в своих изделиях – это сохранение данных, полученных с датчиков, с привязкой по времени. Готовый шилд позволяет не только сохранить данные и получать время со встроенных часов, но и подключить датчики в удобном виде путем пайки или на монтажной плате.




Краткое резюме

В этой статье мы с вами рассмотрели только небольшую часть огромного ассортимента всевозможных устройств, расширяющих функциональность ардуино. Платы расширения позволяют сосредоточиться на самом главном – логике вашей программы. Создатели шилдов предусмотрели правильный и надежный монтаж, необходимый режим питания. Все, что вам остается, это найти нужную плату, используя заветное английское слово shield, подключить ее к ардуино и загрузить скетч. Обычно любое программирование шилда заключается в выполнении простых действий по переименованию внутренних переменных уже готовой программы. В итоге мы получаем удобство в использовании и подключении, а также быстроту сборки готовых устройств или прототипов.

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

Всем хороши недорогие платы Arduino, но так часто для проекта не хватает буквально одного-двух свободных портов! А иногда портов хватает, но не хочется тянуть к другой части конструкции пучок проводов. Допустим, на передней панели устройства надо разместить несколько кнопок и светодиодов. Надежнее и проще соединить их с основной платой всего двумя проводами шины данных, а не шлейфом или жгутом, не так ли?

Для таких ситуаций предназначены различные расширители (экспандеры) портов Arduino.

Обычно выводы микроконтроллера реализуют несколько различных функций, поэтому расширители бывают разные:

  1. Расширитель стандартных портов ввода-вывода GPIO
  2. Расширитель выходов ШИМ
  3. Расширители аналоговых входов – мультиплексоры и внешние АЦП

Отдельно стоит упомянуть цифро-аналоговые преобразователи (ЦАП) и расширители адресного пространства шины I2C. Эти устройства не дублируют функции портов напрямую, но расширяют возможности микроконтроллеров.

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

Выбираем модуль расширителя для Arduino

Самый популярный и недорогой модуль изготовлен на микросхеме PCF8574 (рис. 1)

Рис. 1. Популярный модуль расширителя портов PCF8574

Достоинства:
  • Низкая цена.
  • Модули можно соединять цепочкой, просто вставляя штекеры одного модуля в гнезда предыдущего. Не забудьте установить перемычками разные адреса модулей!
Недостатки:
  • Нельзя вставить прямо в макетную плату (рекомендую перепаять разъем портов на обратную сторону).
  • Всего восемь портов в одном модуле.

Если вы настроены на более серьезные проекты, закажите на Aliexpress 16-разрядный модуль на PCF8575 . Настоятельно рекомендую именно модуль, изображенный на рис. 2.

Рис. 2. Модуль расширителя портов PCF8575

Достоинства:
  • Вдвое больше портов.
  • Встроенный источник питания на 3.3 вольта, можно питать другие модули.
  • Встроенное согласование логических уровней для шины I2C при разном напряжении питания.
  • Удобный формат для макетной платы.
Недостатки:
  • Выше цена.

Принцип работы расширителя портов GPIO PCF8574/PCF8575

Обмен данными происходит по шине I2C. Для подключения к плате Arduino требуется лишь четыре провода, включая питание. Адрес расширителя задается тремя перемычками на входах A0…A2, поэтому к шине можно одновременно подключить восемь одинаковых микросхем и получить максимум 8*8=64 дополнительных порта с PCF8574 или 8*16=128 с микросхемой PCF8575.

Чтобы вывести данные в порт, записывают байт данных по адресу модуля на шине I2C. Чтобы прочитать данные с порта, читают байт по этому же адресу. Байт всегда пишется и читается целиком, работа с отдельными разрядами происходит программно.

Выходы микросхемы одновременно являются входами, и никакого служебного регистра, определяющего назначение вывода, нет. Есть только регистр-защелка, в который записывают выходной байт. Как такое возможно?

Порты работают по схеме, аналогичной открытому коллектору и оснащены внутренними подтягивающими резисторами. Если в выход записан логический ноль, то открывается выходной транзистор, который принудительно тянет вывод «на землю». Чтение из такого порта всегда будет возвращать ноль.

Будьте осторожны – при подаче прямого напряжения питания на вывод с низким уровнем или при превышении допустимого тока 50 мА вы испортите микросхему!

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

Чтобы одновременно использовать часть портов как входы, а часть как выходы, перед каждой записью байта данных в экспандер необходимо при помощи операции «логическое ИЛИ» накладывать маску из единиц на те разряды, которые соответствуют входам. Вот и все)))

Генерация прерывания

Расширители портов PCF857* генерируют импульс прерывания низкого уровня на выходе INT при любом изменении входного сигнала на любом входе микросхемы. Это удобно, если расширитель обслуживает кнопочную панель. Но вы должны сами определить в обработчике прерывания, какая кнопка была нажата или отпущена. Генератор прерывания оснащен фильтром подавления дребезга контактов.

Пример 1. Использование модуля PCF8574

Соберем простую схему из четырех светодиодов, модуля PCF8574 и платы Arduino (рис. 3 и 4). При такой схеме включения нам даже не требуются гасящие резисторы для светодиодов. Ток протекает через светодиод и встроенный резистор, подключенный к шине питания.

Рис. 3. Схема подключения модуля PCF8574

Рис. 4. Макет схемы с модулем PCF8574

Скопируйте и запишите в плату Arduino скетч 1:

// Адрес модуля на шине (A0, A1, A2 = 0) int address = 0x38; // Данные, прочитанные из модуля uint8_t dataReceive; // Данные для записи в модуль uint8_t dataSend; void setup() { Wire.begin(); Serial.begin(9600); // Высокий уровень во все порты PCF8574 dataSend = B11111111; pcf8574_write(dataSend); } void loop() { // Читаем байт из модуля dataReceive = pcf8574_read(); // Выводим в монитор в двоичном формате Serial.println(dataReceive, BIN); // Сдвигаем биты влево на полубайт dataSend = dataReceive << 4; // Накладываем битовую маску dataSend |= B00001111; // Записываем байт в модуль pcf8574_write(dataSend); delay(500); } // Процедура записи байта в модуль void pcf8574_write(uint8_t dt) { Wire.beginTransmission(address); Wire.write(dt); Wire.endTransmission(); } // Процедура чтения байта из модуля int8_t pcf8574_read() { Wire.beginTransmission(address); Wire.endTransmission(); Wire.requestFrom(address, 1); return (Wire.read()); }

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

Уровни на выводах порта считываются каждые 500 мс и результат считывания выводится в монитор. Если вы соединяете один из входов P0…P3 с общим проводом, в его разряде появляется ноль. Затем считанное значение сдвигается влево на четыре бита, результат выводится в порт и гаснет один из светодиодов. Например, если прочитан ноль на выводе P0, то погаснет светодиод, подключенный к выводу P4.

Обратите внимание, что мы должны перед каждой записью в расширитель наложить битовую маску из единиц на все разряды, которые должны быть входами: dataSend |= B00001111;

Подпрограммы работы с шиной I2C предельно упрощены, никакие ошибки не обрабатываются.

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

Пример 2. Использование модуля PCF8575

Особенность модуля PCF8575 состоит в том, что у него 16 портов, поэтому в него всегда записывают по два байта и читают по два байта . Это правило надо соблюдать, даже если второй байт не нужен.

Немного изменим схему. Светодиоды подключим к портам P10…P13, а соединять перемычкой с общим проводом будем порты P00…P03 (рис. 5 и 6).

Рис. 5. Схема подключения модуля PCF8575

Рис. 6. Макет схемы с модулем PCF8575

В скетче 2 сначала записываются единицы во все порты, затем каждые 500 мс читается их состояние. Процедура чтения возвращает 16-разрядное слово, которое разделяется на байты. Содержимое младшего байта (выводы P00…P07) копируется в старший байт и выгружается обратно в модуль. Если соединить с общим проводом один из выводов P00…P03, то погаснет один из светодиодов, подключенных к P10…P13.

// Библиотека для работы с I2C #include // Адрес модуля на шине по умолчанию int address = 0x20; // Данные, прочитанные из модуля uint8_t hi, lo; uint16_t dataReceive; uint8_t dataHighByte; // Старший байт (P10...P17) uint8_t dataLowByte; // Младший байт (P00...P07) void setup() { Wire.begin(); Serial.begin(9600); // Высокий уровень во все порты PCF8575 dataHighByte = B11111111; dataLowByte = B11111111; pcf8575_write(dataLowByte, dataHighByte); } void loop() { // Читаем байт из модуля dataReceive = pcf8575_read(); // Выводим в монитор в двоичном формате Serial.println(dataReceive, BIN); // Выделяем младший байт из длинного слова dataLowByte = lowByte(dataReceive); // Копируем младший байт в старший байт dataHighByte = dataLowByte; // Накладываем маску на младший байт dataLowByte |= B11111111; // Записываем новые данные в модуль, два байта pcf8575_write(dataLowByte, dataHighByte); delay(500); } // Процедура записи байта в модуль void pcf8575_write(uint8_t dtl, int8_t dth) { Wire.beginTransmission(address); Wire.write(dtl); // Записываем младший байт (P00...P07) Wire.write(dth); // Записываем старший байт (P10...P17) Wire.endTransmission(); } // Процедура чтения байта из модуля int16_t pcf8575_read() { Wire.beginTransmission(address); Wire.endTransmission(); Wire.requestFrom(address, 2); lo = Wire.read(); // Читаем младший байт (P00...P07) hi = Wire.read(); // Читаем старший байт (P10...P17) return (word(hi, lo)); // Возвращаем длинное слово }

Библиотека Arduino для PCF8574/PCF8575

Библиотеку можно скачать на GitHub . Но, как вы могли видеть, работа с расширителями портов очень проста и можно легко обойтись без специальной библиотеки.

Новые статьи

● 5.4. Расширение цифровых портов для NodeMCU ESP8266 с помощью микросхемы MCP23017

Введем светодиодную индикацию и звуковую сигнализацию и при использовании в качестве контроллера умного дома модуля Nodemcu. Количество выводов у модуля Nodemcu гораздо меньше, чем у Arduino Mega, поэтому нам понадобится микросхема расширителя входов MCP23017. Микросхема MCP23017 добавляет 16 портов,которые можно настроить как на вход,так и на выход (рис. 5.7). Микросхема использует популярную двухпроводную шину I2C.

Рис. 5.7. Выводы микросхемы MCP23017

Адрес микросхемы MCP23017 для протокола I2C можно установить комбинацией сигналов на цифровых входах A0 - A2 (рис. 5.8), что позволяет к микроконтроллеру подключиь одновременно 8 микросхем MCP23017, соответственно 16*8=128 контактов.

Рис. 5.8. Установка адреса микросхемы MCP23017

Микросхема имеет 2 банка портов A (GPA0- GPA7) и B (GPB0- GPAB), каждый из которых можно настроить на ввод или вывод.
В листинге 5.3. показан пример настройки банков выводов A и B.

Листинг 5.3

// подключение библиотеки Wire.h #include byte input=0 ; void setup () { Serial.begin(9600 ); Wire.begin(0 ,2 ); // запуск I2C Wire.beginTransmission(0x20 ); // i2c - адрес (A0-0,A1-0,A2-0) Wire.write(0x00 ); // IODIRA register Wire.write(0x00 ); // настроить PORT A как output Wire.endTransmission(); } void loop () { // чтение данных из PORT B Wire.beginTransmission(0x20 ); Wire.write(0x13 ); Wire.endTransmission(); Wire.requestFrom(0x20 , 1 ); input=Wire.read(); // записать полученные данные в PORT A Wire.beginTransmission(0x20 ); Wire.write(0x12 ); // address PORT A Wire.write(input); // PORT A Wire.endTransmission(); delay(100 ); // пауза }

Использование микросхемы MCP23017 позволит расширить количество цифровых контактов модуля Nodemcu на 16 и позволит организовать светодиодную индикацию и звуковую сигнализацию о критических параметрах датчиков.

Как я уже , я заказал три более или менее не пересекающихся набора датчиков для Ардуино. В обоих комплектах ко мне приехала микросхема 74HC595, которая так и осталась лежать в боксе до поры до времени. До поры до времени я даже не знал, что это за микросхема, и как вообще этот черный тараканчик промаркирован.

Но настали черные дни, когда мне перестало хватать выходных сигналов Arduino Nano, когда я занимался созданием устройства для тестирования шаговых двигателей. (TODO: вставить ссылку на статью о тестере ШД, когда будет готова). Моё устройство для тестирования ШД в результате вышло довольно комплексным - двухстрочный дисплей 1602 с системой меню, управляемое полнофункциональной клавиатурой 4x4, 3 цифровых разряда для установки величины микрошага ШД, сигналы Step и Dir для шагового двигателя, и тп. Казалось бы, самое время мигрировать на другую версию Arduino. Но моя природная лень воспротивилась этой миграции. И ленивая голова стала искать решение.

Было принято решение искать решение на базе уже того, что есть. Перебирая платки и детальки из наборов, я заметил 16ти-пинового черного "жука". Сначала в одном наборе, потом в другом. Решил поинтересоваться, что же это за деталь, и зачем её добавляют в наборы. Зачем её кладут в кит-наборы, я не понял, но саму микросхему нашел на сайте NXP .

Оказалось, что это довольно интересная микросхема - сдвиговый регистр с последовательным входом и параллельным выходом.

(из даташита)

Описание выводов

Контакт Наименование Описание и подключение
10 ~MR Master Reset - сброс, активный уровень низкий. В идеальном случае неплохо бы сделать схему сброса, которая сначала подает низкий уровень на этот вход, а затем переводит его в единичное состояние. Но можно не возиться, и подключить его на +5В. В этом случае на выходе до первой записи будут случайные значения
13 ~OE Output Enable - разрешение выхода, активный уровень низкий. При подаче 0 на выходы подается содержимое регистра, при подаче 1 - выходы отключаются, переводятся в Z-состояние, что позволяет использовать одну шину попеременно разным устройствам. Подключаем на землю, если не нужно управлять состоянием выходов
14 DS Serial Data In - последовательный вход. На этот вход следует подавать значение входного сигнала до подачи тактового сигнала сдвига SHCP
11 SHCP Shift Register Input clock - тактовый вход сдвигового регистра. Для вдвигания бита в регистр следует подать переход с 0 на 1. Когда возвращать в 0 - на усмотрение. Можно - сразу же, можно - непосредственно перед вдвиганием. В первом случае можно считать, что переключение происходит по фронту прямого сигнала, во втором - по спаду инверсного. См. также ниже замечания по быстродействию. Также по приходу этого сигнала изменяется значение последовательного выхода Q7/S
12 STCP Storage Register Clock Input - тактовый вход регистра защелки. По фронту данного импульса происходит перенос значения со сдвигового регистра на параллельные выходы Q0-Q7
9 Q7S Serial Data Output - последовательный выход. На него выводится значение старшего разряда сдвигового регистра. Данный выход может использоваться для масштабирования сдвигового регистра до 16ти-разрядной, 24х-разрядной и т.д. схемы
15, 1-7 Q0, Q1-7 Выходы регистра-защелки . Сигнал на них переносится с внутреннего сдвигового регистра по приходу сигнала STCP
8 GND Питание - общий провод
16 VCC Питание - +

Питание

HC версия микросхемы требует от 2В до 6В питания, версия HCT (TTL-совместимая) - от 4.5В до 5.5В. HCT - TTL - а оно вообще еще используется? Ардуино же вроде само по себе CMOS, так что HCT не нужно, но если нужно согласовывать уровни с внешними TTL потребителями, то можно запитать HC от 3.3В, тогда уровни сигналов будут совместимы с TTL. А вообще, с 5ти-вольтовым Ардуино должны работать и HC, и HCT. В интернетах так пишут.

Что более важно, так это блокировочные конденсаторы. Без них схема может работать не так, как задумано, и более того, непредсказуемо. Теоретически, в цепи питания каждого корпуса нужно ставить 0.1мкФ конденсатор. Это значение ёмкости я вычислил как среднее по интернету. Моя схема вполне заработала и без него. Чтобы уточнить, залез было в библию схемотехника, чтобы уточнить - Хилл и Хоровиц, "Искусство схемотехники" - это почти как "Искусство Программирования" Дональда Кнутта, но только для железячников (к слову, Хилл и Хоровиц гораздо ближе к народу, Кнутт через-чур умничает) - но там блокировочными конденсаторами похоже называют развязывающие по входам конденсаторы. Жаль, хорошая книга, но очень отстала уже от жизни. У меня второе или третье русское издание конца 90ых или начала 0ых годов, оригинал скорее всего ещё лет на 10 старше. На третьем, розовом томе, обнаружил наклейку - "14руб" - как же дешево тогда всё было, по современным меркам. А прошло-то всего 15 лет или чуть больше. Аж ностальгия замучала.

Быстродействие

В титле даташита 74HC595 пишут, что она работает на 100МГц. Беглый взгляд на графики и таблицы даташита говорит, что самые большие тайминги в диапазоне температур от -40C до +85C при питании 4.5В - 10-20нс (100-50МГц). С теми частотами, на которых работают Ардуино, ничего больше знать не требуется. Возможно, только то, что стандартные библиотечные digitalRead/digitalWrite - огромнейшие тормоза из-за различных проверок, и их можно (и нужно) переписать в виде более быстрой версии. В планах есть поковырять это и написать поподробнее, но пока у меня нет особой нужды.

Быстродействие Arduino Nano и библиотеки Arduino в плане скорости переключения выходов и обработки входов по моим наблюдениям где-то посередине от единиц килогерц до десятков килогерц. Так что, на мой взгляд, при написании кода для управления сдвиговым регистром 74HC595 нет нужды озадачиваться какими-либо задержками при установке управляющих сигналов.

Другое дело, что для 8ми разрядного последовательного расширителя следует делить максимальную доступную на Ардуино частоту переключения выходов - установили DS, установили SHCP в 1, сбросили SHCP (в 0) - 8 раз, и установка/сброс STCP. Итого, на вскидку, 3*8 + 2 = 26 операций digitalWrite. Итого выходит примерно в 25 раз медленнее, чем может сама Ардуинка.

При масштабировании до 16ти, 24х или 32х выходов замедление будет соответственно примерно 3*16 + 2 = 50, 3*24 + 2 = 74 и 3*32 + 2 = 98 раз.

Для управления чем-то действительно быстрым, очевидно, такой расширитель на сдвиговом регистре 74HC595 не подходит, но, в некоторых применениях, для задания редко меняющихся статичных сигналов вполне подходит. Так, например, я использовал такой расширитель для задания 3х-разрядного режима микрошага для установки режима микрошага для драйвера ШД DRV8825 в тестере для шаговых двигателей. К слову, мне это пока не особо пригодилось - шаговики из матричных принтеров ужасно работают в микрошаговом режиме, по крайней мере, под управлением драйвера DRV8825 - так, например, в режиме микрошага 1/2 половина шага какая-то вялая и не уверенная, только вторая половина бодрая и мощная. Поэтому при использовании микрошага при малейшем усилии на ось ШД он первые пол-шаги начинал пропускать. Остальные режимы микрошага я как-то после этого и не исследовал на имеющихся принтерных ШД.

Масштабирование

Расширитель выходов Ардуино на базе 74HC595 достаточно элементарно из 8ми-разрядной версии может быть переделан в схему любой разрядности. Для этого последовательный выход младшего регистра Q7S нужно соединить со входом DS более старшего, а линии SHCP и STCP соединить параллельно. Ну, и, в зависимости от принятого схемотехнического и программного решения, нужно выбрать, как подключать линии ~MR и ~OE.

Расширение ввода

Расширение линий ввода для Ардуино в принципе похоже на расширение вывода, с учетом того, что нужно не задавать значение DS на выходе, а считывать его на входе, и использовать микросхему типа 74HC597. Впрочем, это я пока на практике не проверял.

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

Увеличить количество выходных линий, которыми управляет Ардуина, можно двумя способами: 1) увеличить разрядность одного последовательного выхода, что при увеличении разрядности в два, три или четыре раза соответственно уменьшает в два, три или четыре раза быстродействие расширителя; 2) параллельным подключением нескольких расширителей, при этом задействуя один дополнительный выход на каждый расширитель, что может сохранить быстродействие на приемлемом уровне, но требует использования как минимум одного выхода Ардуино для каждого расширителя.

Если не управлять прямо сигналами регистра 74HC595 - ~MR, ~OE с Ардуино, то достаточно только трех выходов Ардуино для управления сигналами DS, SHCP и STCP сдвигового регистра, чтобы при помощи микросхемы 74HC595 превратить их в 8 или 16 или больше выходных сигналов.

Для мультиплексирования нескольких расширителей на базе 74HC595 можно пойти двумя путями: 1) для каждого расширителя сигнала выделить отдельный latch сигнал - т.е. все регистры на шине параллельно сдвигают поступающие данные, и, соответственно, сдвигают значения на выходах внутреннего сдвигового регистра, но только один передает значение из внутреннего сдвигового регистра на выходы микросхемы; 2) сигналы сдвига передаются только на один из расширителей, а перенос значений сигналов на выход происходит одновременно для всех модулей расширения.

Я больше склонен использовать вариант, когда во внутренних сдвиговых регистрах может находится всё, что угодно (вариант 1), а на выходе зафиксировано какое-то из предыдущих значений, и вот почему: при переносе значений из внутреннего сдвигового регистра на выход могут происходить неконтролируемые переходы из 0 в 1 и обратно, какой-то дребезг сигнала, даже если исходное значение во внутреннем регистре и на выходе одно и то же. И, на мой взгляд, операцию переноса состояния внутреннего регистра сдвига на выходы 74HC595 следует использовать как можно реже.

Программная поддержка

Программная поддержка этого и подобных расширений заключается в том, чтобы не обращаться к устройствам напрямую через конкретные пины при помощи digitalRead/digitalWrite используемого контроллера Ардуино, а через пины абстрактного устройства ввода-вывода, которое, в свою очередь, может быть инициализировано как привязанное к конкретному типу Ардуино, так и к другому аналогичному абстрактному устройству.

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



В связи с этим встает вопрос о целесообразности расширения количества линий ввода/вывода. В данном материале будет показан пример такого расширения с помощью микросхемы MCP23017.


Возможно, вы знаете, что 6 аналоговых контактов также могут использоваться как цифровые линии ввода/вывода таким образом:


Аналоговый вход 0 = линия 14
Аналоговый вход 1 = линия 15
Аналоговый вход 2 = линия 16
Аналоговый вход 3 = линия 17
Аналоговый вход 4 = линия 18
Аналоговый вход 5 = линия 19

То есть на самом деле мы можем ссылаться на аналоговый вход 5 как на цифровую линию следующим образом: digitalWrite(19,HIGH). Такая команда запишет логическую единицу в порт 19, то есть аналоговую линию 5.


Технически мы можем использовать линии последовательного порта TX/RX. Но в некоторых случаях это сделать крайне затруднительно, особенно когда в коде используются функции типа Serial.begin(), нужные для работы последовательного порта. Таким образом, общее количество контактов, доступных для пользователя, все же будет 17. Но разве можно с семнадцатью выводами управлять большим количеством светодиодов или сервомоторов? В этом случае лучше воспользоваться специальными внешними микросхемами. Зачастую в этих целях используют сдвиговый регистр вроде 74HC595. Но он требует три дополнительных линии для управления и не позволяет одновременно «расширить» все линии. Дисплейные драйверы, такие как MAX7219 тоже фактически «расширяют» количество контактов. Но MAX7219 является дорогостоящей микросхемой. Поэтому дешевле и рациональнее взять микросхему расширителя портов MCP23017. Эта микросхема рассчитана на 16 линий, имеет широкий диапазон рабочего напряжения от 1.8 до 5.5 В и управляется по интерфейсу I2C.


MCP23017 будет использовать 2 контакта Arduino и даст 16 линий ввода/вывода. Так что технически вы можете использовать 8 штук MCP23017 для расширения одного 16-контактного Arduino до 16 x 8 = 128 контактов. Arduino имеет библиотеку для шины I2C под названием Wire.h, поэтому взаимодействие с MCP23017 будет очень простым. Ниже приведена схема подключения Arduino и MCP23017.




#include "Wire.h" void setup() { Wire.begin(); // активируем шину I2C // устанавливаем линии на выход Wire.beginTransmission(0x20); Wire.write(0x00); // регистр IODIRA Wire.write(0x00); // устанавливаем все линии порта A на выход Wire.endTransmission(); } void loop() { Wire.beginTransmission(0x20); Wire.write(0x12); // адресный банк A Wire.write((byte)0xAA); // отправляемое значение - все линии в лог. 1 Wire.endTransmission(); delay(500); Wire.beginTransmission(0x20); Wire.write(0x12); // адресный банк A Wire.write((byte)0x55); // отправляемое значение - все линии в лог. 1 Wire.endTransmission(); delay(500); }

Есть вопросы?

Сообщить об опечатке

Текст, который будет отправлен нашим редакторам: