Как стать автором
Обновить

Как увеличить количество пинов на esp32?

Уровень сложностиСредний
Время на прочтение9 мин
Количество просмотров17K
Всего голосов 42: ↑39 и ↓3+53
Комментарии60

Комментарии 60

Природная лень заставила меня поискать готовые решения, однако здесь пришлось натолкнуться на практически полное их отсутствие (связь двух и более esp32 между собой)

А почему не взять какой-нибудь готовый extender, типа MCP23017?

Согласен, вариантов расширителей портов целая куча. На том же I2C. Как автор искал готовые решения, не понятно )

Справедливости ради, сейчас посмотрел цены - распаянный MCP23017, оказывается, нынче идёт по $3, что сравнимо с ценой распаянного esp32. В 2020 MCP23017 стоил $1.

Ну этож надо покупать, где то заказывать и т.д. Лень :-) А под рукой - просто куча esp32.

А почему не взять какой-нибудь готовый extender, типа MCP23017?

самый дешевый вариант будет этот:

на него можно повесить еще 16 таких же, получим 256 пинов.

74HC595 - классика же. Причем протокол управления здорово напоминает SPI.

Он подходит для размножения выходных пинов. Для входных 74HC165.

80 битный ЛУТ
Даже в простом stm32 удобно в SPI по DMA пулять...
Даже в простом stm32 удобно в SPI по DMA пулять...

64 битный от плазмы (аж 80 мощных Вольт) и пара 595

нашёлся повод вставить свою картинку :)

Намучался я как-то с MCP23S17 (SPI-версия).

Если с записью в расширитель у меня проблем не было, то с последовательным чтением данных у меня так ничего и не вышло. Мне нужно было условно записать 1 в конкретный бит порта. Затем этот же пин настроить на вход и посмотреть, 1 там или 0. В общем мучился долго и плюнул на это дело. Вот все эти танцы с бубном нужны были под конкретную периферию. На её инициализацию.

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

Да и ценник на эти MCP сопоставимы с ценой МК. Но на другом МК банально удобнее.

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

Впрочем, судя по статье, требования к надежности у автора минимальные.

Автор торжественно забил гвоздь микроскоп другим микроскопом ;)

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

Ну хоть кто-то не умеет в запланированное устаревание ;)

В связке с тем же esp32 использую одновременно 4 расширителя "PCAL9535APW ,118" , что увеличило количество портов аж на 64 штуки. Количество портов можно увеличивать в разумных пределах.

В связке с тем же esp32 использую одновременно 4 расширителя "PCAL9535APW ,118" , что увеличило количество портов аж на 64 штуки. Количество портов можно увеличивать в разумных пределах.

Ну да, можно и так наверное...А если использовать соединение esp32-esp32 (39-пиновые) то, учитывая, что на каждую можно повесить 16 штук (реально больше - но я имею в виду пины без всяких нюансов). То тогда, чтобы выбрать весь диапазон адресов (127), потребуется 127/16 = 7,9 штук :-)

И, в теории, можно ещё сделать систему распределённой.

И, в теории, можно ещё сделать систему распределённой.

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

В любительских поделках можно и вынести за пределы устройства. У меня i2c стабильно работал через четырёхметровый неэкранированный телефонный кабель. Правда, пришлось пропустить кабель через ферритовый фильтр. Никаких преимуществ специально предназначенный интерфейс не дал бы. Только недостатки в виде нагромождения преобразователей в какой-нибудь RS-485 и обратно.

Помимо устойчивости связи есть еще защита от перенапряжений. И именно поэтому "нагромождения преобразователей" для RS-485 является не недостатком, а достоинством - найти микросхемы приемопередатчиков, устойчивые к статике не проблема. Для защиты же линий I2C готовых решений еще надо поискать - они, в принципе, существуют, но вся выпускаемая номенклатура ограничивается всего парой штук, и это именно потому, что I2C не предназначен для вывода наружу устройства.

Мне сложно представить, что в домашних условиях может быть источником такой наводки на четырёхметровый кабель, что её энергии хватит на выжигание пина микроконтроллера. Если только удар молнии прямо в дом.

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

При подключении кабеля отнюдь не факт, что земляной проводник соединится раньше сигнального, если это не обеспечено специальной конструкцией разъема (типа как это сделано в USB). Выравнивание потенциалов корпусов устройств через сигнальный проводник вполне может приводить к выгоранию входов, если не при первом, то при тысячепервом подключении, собенно при подключениии "на горячую". Разность потенциалов может быть как от статики, так и от сетевой наводки.

Даже специальные интерфейсные микросхемы каких-то 30 лет назад были не столь неубиваемые, как сегодня. Кто застал реализацию RS-232 на паре микросхем 75188/75189 поймет о чем я - "бизнес" по их замене просто процветал в то время.

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

Для того и нужен RS485, чтобы можно было не на 4 места передавать, а на сотню. Если, конечно, задача того требует.

Достаточно эти четыре метра положить параллельно сетевому проводу 220В и порты микроконтроллера вылетят к чертовой матери. Не сразу, так в самый неприятный момент.

Я имел в виду, что (теоретически) можно увеличить количество I2C -пинов у esp32 (не только 2 пары, как обычно). А скажем, написать свою библиотеку и "зеркалировать" данные. Скажем, каждую esp32 обвешать другими esp32 - и одну из них использовать как скажем так "магистральную" - через которую все кидают данные. Но это потребует уже самостоятельно это все реализовывать, насколько я понимаю. Но- почему бы и нет? :-)

Но это не нужно - проще конечно просто к линиям присоединиться и все (а то "масло масляное" как бы).

Да, по идее можно использовать 2 аппаратных шины I2C на esp32. повесить по 127 девайсов на каждую, плюс использовать софтовый i2c драйвер и поднять еще примерно (16/2) 8 софтварных I2C по 127 девайсов на каждом. Итого 1270 slave-ов на 1 esp повесить ) на каждый из которых так же можно повесить по 1270 штук и так до бескончености )

Вы не сможете повесить на шину даже 10 устройств - шина будет работать катастрофически нестабильно. Про 127 устройств можете смело забыть. Это всего лишь адресное пространство, а не максимальное количество устройств.

Человек явно не ходил на схемотехнику. Тут же явно нужен мультиплексор, например такой CD74HC4067. Но вы решили решить вопрос по-другому - создавать протокол, передавать данные по I2C и прочее.

Спасибо за коммент! :-) Любым хорошим идеям я всегда рад. С мультиплексорами сталкивался- но весьма шапочно и в своих проектах не применял.

Я не специалист, но как я понимаю, мультиплексор гораздо слабее по своим возможностям чем предложенное решение.
Если задача – опрос датчиков, то мультиплексор может переключаться между множеством источников. Таким образом можно последовательно опросить все датчики.
Но если задача – управление какими-то реле или двигателями, то каждый выходной пин должен находиться в требуемом состоянии, пока это состояние не будет изменено управляющей программой. У мультиплексора (и демультиплексора) нет памяти, поэтому он не может так работать.

Обычно IIC работает либо на скорости 10кбит/с — в медленном режиме, либо на 100кбит/с в быстром.

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

M24M01-R M24M01-DF
1-Mbit serial I²C bus EEPROM

• Compatible with all I2C bus modes:
– 1 MHz
– 400 kHz
– 100 kHz

НЛО прилетело и опубликовало эту надпись здесь

Каждый ESP32 потребляет от 100 до 400 мА, а каждый расширитель портов PCF8575 на порядок меньше и стоит в 3-5 раз меньше.

Обычный сдвиговый регистр с защелкой - просто, дешево и надёжно.

Желаю успешного запуска I2C рядом с моторами… даже если без "встроенные 45 кОм" и с соединением GND… ммм, это может быть жыр.
Кстати, I2C через библиотеку wire — не програмный ли?

Насчет движков - всё ок, даже видео приложил в конце статьи ;-) А вчера тестил I2C с коллекторным движком - тоже ок. Насчет реализации I2C в wire - не копал.

PCF8574 стоят на Али 450 - 800 руб./10 шт., имеют 8 IO, 8 выставляемых перемычками адресов, бывает 2 вида с разными группами адресов, такая уже стоит на экране 1602. В прочем и PCF8575 стоит примерно столько же.

Мягко скажем - так себе решение.

Мягко скажем - так себе решение.

В моём случае это оправданно, т.к. на slave повешены двигатели - а ими надо "рулить": генерить пульсации и т.д. по команде, пришедшей с I2C. Так как на мастере все пины заняты и подключить двигатели некуда. То есть, другими словами, в моём случае - slave обязательно должен быть "умным" а не просто уметь "висеть на том конце провода" :-)

I2C шина хороша только тем, что требует меньше проводов, на этом её достоинства заканчиваются и начинаются одни сплошные недостатки, а именно:

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

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

  • сложность поиска "глючного" устройства на шине;

  • необходимость опытным путем подбирать номиналы резисторов подтяжки если на шине много (более трех) устройств, при этом, очень часто получается эффект "то работает, то не работает, то вот опять работает";

  • конфликт адресов на шине - нельзя размести на шине массив из одинаковых датчиков если в самих датчиках не предусмотрена возможность задавать адрес;

  • сложность программирования протокола "в ручную" (если в МК нет или неоступен аппаратный интерфейс) - правильно запрограммировать и выдержать тайминги вам врядли удастся;

  • низкая устойчивость к ЭМ помехам - эл.моторы и эл.магниты в непосредственной близости с устройством часто приводят к зависанию шины;

  • не рекомендована для использования в межплатных коммуникациях;

  • общая ненадежность и нестабильность.

Куда веселей обстоят дела с шиной SPI: на порядок (а местами и на два порядка) выше скорости, синхронный полнодуплексный характер обмена, большой спектр доступных устройств: многоканальные ЦАП и АЦП, расширители GPIO, Ж/К дисплеи и т.д.

Но встает вопрос - а как подключить множество SPI устройств когда на хваленой и всеми любимой ESP32 доступно к использованию всего два SPI интерфейса, да и те одновременно использовать нельзя ? Решение есть - использовать ПЛИС в качестве коммутатора шины SPI. Выгладит это так: ESP32 (или аналогичный МК) подключен к ПЛИС по одной шине SPI и еще несколькими линиями GPIO по которым передает в ПЛИС адрес периферийного устройства с которым требуется осуществить обмен, а ПЛИС в свою очередь коммутирует входную шину от МК в сторону адресованного в данный момент устройства. Данное решение достаточно распространено в профессиональной среде, на подобном принципе часто строятся внутренние шины между ПЛК и модулями расширения.

Для тех, кто боится или не желает использовать ПЛИС по каким-то причинам, существует серия микросхем ADGS1408/ADGS1409 от Аналоговых Девиц, которые представляют собой аналоговые многопортовые коммутаторы SPI интерфейса.

И еще. С помощью современных ПЛИС шину SPI можно сделать в разы более устойчивой если использовать дифференциальные линии (LVDS) для передачи отдельных сигналов. Это позволяет вытаскивать шину на десятки метров без потери в скоростях.

Удачи!

У каждого устройства на шине SPI есть сигнал chip select. В чем проблема подключить хоть 10 устройств к одной шине SPI? Я два подключал, работает. Если их больше, будут проблемы?

насколько я помню спи-шные регистры и некоторые другие микросхемы можно подключать цепочкой последовательно

Почему последовательно? Я подключал к Arduino Pro Micro к одному и тому же аппаратному SPI два устройства параллельно. Только сигналы CS у каждого из устройств были подключены к разным пинам Arduino. При инициализации библиотеки для каждого из устройств указывается нужный пин CS, и далее код библиотеки перед каждым обращением к устройству на этот пин правильный уровень подают. Работают устройства, конечно, последовательно (либо одно, либо другое в один момент времени), но подключены к одним и тем же сигналам шины SPI параллельно.

Это хорошо конечно, если все устройства умеют по высокому уровню CS переводить хотя бы MISO в третье состояние. Например есть SD модули с резисторами на интерфейсе - с ними вообще ничего не живет. Они же с буфером тоже специфические- буфер не управляется CS-ом, работать начинает только после доработки- заведения CS на управление соответствующим каналом буфера - MISO.

У меня нет большого опыта в этой области. Тот SD shield, который я использовал, без проблем работает параллельно с чипом статической памяти SRAM, подключенному параллельно к тому же SPI на Arduino.

последовательно выгодней - нужен только 1 сигнал СS а значения грузяца или читаюца последовательно хоть с 4х регистров, хоть со 127.

Это каскадное подключение сдвиговых регистров. В моей статье по ссылке такое тоже есть. Но я говорю про подключение к одной шине SPI двух разнородных устройств. В моей статье это адаптер SD-карты и статическая память SRAM.

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

Про каскадное подключение сдвиговых регистров понятно - они в принципе разработаны с учетом такой возможности. А что, можно, например, адаптер SD-карты и сдвиговый регистр подключить к одной шине SPI последовательно? Честно, не понимаю, как такое возможно.

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

У шины есть нагрузочная способность, два-три или даже четыре устройства в параллель Вы подключите, больше - уже будут проблемы. И еще, Вам придется выделить по отдельному GPIO для каждого CSn (что если Вам необходимо подключить 16 периферийных сутройств ?) и управлять ими программно, что создает проблемы при использовании аппаратного контроллера внутри МК. По этому, вариант с мостом на ПЛИС (или с аналоговым коммутатором) более предпочтителен, так как сигналом CSn управляет контроллер напрямую, а программа перед началом обмена выставляет адрес устройства на три или четыре линии GPIO.

Общение между устройствами в рамках этой шины всегда инициирует master, вызывая соответствующее ведомое устройство

Так это... насколько я понял тут принципиально «односторонняя» связь. Чтобы слейв что-то передал мастеру нужно чтобы мастер сначала инициировал соединение.

То есть если слейв захотел что-то передать, то он не может это сделать пока мастер не инициирует соединение. Или как?

Если это так, то это не очень интересно — хотелось бы иметь возможность передачи данных в оба конца в любой момент.

То есть если слейв захотел что-то передать, то он не может это сделать пока мастер не инициирует соединение. Или как?

Если это так, то это не очень интересно — хотелось бы иметь возможность передачи данных в оба конца в любой момент.

Насколько мне известно - именно так. Благодаря этому обеспечивается "порядок" в шине скажем так :-)

Скажем, надо слейву прередать состояние датчиков мастеру - мастер должен их опрашивать сам.

Порядок на шине это хорошо, но я предпочту другой интерфейс связи (не I2C), лишь бы главный MCU и ведомый MCU могли свободно общаться, не ожидая «милости» мастера.

Копируете получившееся число из окошка наверху и вставляете с припиской «0х...» в свой код 

А можно без приписки писать сразу десятичные. Прямо в коде, представляете? И с конвертацией возиться не надо.

Видел на финальном этапе - но забыл в статье поправить.

Позвольте, но если уж взять 2 есп, то можно и по wifi связь построить, ну или блютуз

Интересная статья (пост). С удовольствием почитал. Но внесу поправку. 7-бит (127) в связке с 16-ой системой запутают не знающего читателя. Железке - 7 бит 2-ой, для ПО - 1 байт в 16-ой.

Есть и применяется еще вариант расширения количества выводов через интерфейс I2S в связке с теми же регистрами 74НС595. Скорость обмена высокая. В частности применяется в GRBL. А конкретнее в управлении шаговыми двигателями. Можно до 8 двигателей, но например FluidNC управляет 6 моторами. Подозреваю, что этот протокол можно использовать не только на передачу, но применив параллельно-последовательные 74HC165, на прием. Нужно только поработать над программой.

Уровень статей на Хабре продолжает поражать воображение..

Зарегистрируйтесь на Хабре, чтобы оставить комментарий