Arduino as I2C GPIO expander

แชร์
ฝัง
  • เผยแพร่เมื่อ 5 ก.พ. 2025
  • Использование Arduino UNO, Nano или Pro Mini в качестве I2C расширителя GPIO (не забудьте подтянуть к VCC через резисторы 4.7 кОм SDA и SCL на слейве и про конвертер уровней при использовании с ESP8266!).
    Поддерживаются функциональные аналоги стандартным методам работы с портами (pinMode, digitalWrite, digitalRead, analogWrite, analogRead). Через 5 сек. бездействия плата уйдет в сон, но проснется сразу же при очередном обращении.
    Скетч клиента I2C (для заливки в AVR): drive.google.c...
    Скетч с примером использования (пригоден для AVR и ESP8266): drive.google.c...
    Чуть усложнив протокол обмена с мастером, можно создать I2C "обертку" для специфических датчиков, требующих сложного подключения.
    PS: код клиента, пригодный для Mega (исправьте в .h файле константу последнего пина на используемую вашей платой) или дальнейшего расширения протокола: drive.google.c...

ความคิดเห็น • 52

  • @plantingAsia
    @plantingAsia 8 ปีที่แล้ว

    спасибо, очень мило! Буду юзать ваши наработки для димера 220В лампы накала)

  • @anatoliysemochkin2723
    @anatoliysemochkin2723 8 ปีที่แล้ว

    Спасибо за столь интересное и полезное решение! Не подскажете, как на Slave управлять сервой? При передаче с мастера значения через WireIO.analogWrite(servo_pin, 118); в логах я вижу в дебаге переданное значение, но если на слэйве прочитать значение через analogRead(servo), то получаю странные цифры, например 981.

    • @arduinoetc
      @arduinoetc  8 ปีที่แล้ว

      Я думаю правильно только расширением протокола обмена командами сервы и использованием соответствующей библиотеки на слейве.
      И зачем читать пин сервы? И это очевидно не "аналоговый" пин, чтобы его analogRead читать.

    • @anatoliysemochkin2723
      @anatoliysemochkin2723 8 ปีที่แล้ว

      На слейве подключена библиотека сервы, разумеется. Из добавленого на слейв:
      #include
      #define incomingValue 13
      Servo myservo;
      myservo.attach(servo_pin);
      в лупе:
      int encoderValue = analogRead(incomingValue);
      Serial.println(encoderValue);
      myservo.write(encoderValue);
      Только вот почему-то в дебаге все здорово, а если делать int encoderValue = analogRead(incomingValue); то в переменную encoderValue попадает какое-то левое значение.

    • @arduinoetc
      @arduinoetc  8 ปีที่แล้ว

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

    • @anatoliysemochkin2723
      @anatoliysemochkin2723 8 ปีที่แล้ว

      Серва на слейве управляется удаленно с мастера через энкодер. Мастер передает значение энкодера на 4 пин слэйва. Значение приходит на слейв, я его вижу в дебаге . Далее на слейве читаю полученное значение в переменную encoderValue и пишу его в myservo.write. Но суть в том, что не присваивается корректное значение командой analogRead(). Ничего не понимаю, потратил уйму времени на такую простую операцию. Скетч залил сюда. yadi.sk/d/leSAWTUJ3DEb9Y

    • @arduinoetc
      @arduinoetc  8 ปีที่แล้ว

      Я не знаю что и сказать... :)
      Еще раз спрашиваю, что за плата в качестве слейва? UNO или подобная или Леонардо или Мега?
      Как вы передаете на пин 4 слейва информацию с энкодера? Чем?
      Вы понимаете, что обмен информацией в подобном случае должен идти по I2C протоколу, а иначе в этом вообще никакого смысла нет?!

  • @AlexanderAbramovNN
    @AlexanderAbramovNN 7 ปีที่แล้ว

    интересное решение, жаль в коде мало комментариев. подскажите, каким образом организовано хранение в буфере i2c мастера (esp8266), если слейв прочитает например 2 байта, а в буфере мастера будет 5, то при следующем приёме на слеиве они не вылезут? в общем как очищается буфер отправки в wire.h?

    • @arduinoetc
      @arduinoetc  7 ปีที่แล้ว

      Мастер выдает команду в пределах транзакции. Если команда на чтение - то он сразу ждет результат. Откуда в буфере могут остаться данные? Обмен синхронный.

    • @AlexanderAbramovNN
      @AlexanderAbramovNN 7 ปีที่แล้ว

      Видимо не откуда, но не совсем понятно.
      т.е. если связь отвалится в процессе передачи например Wire.write("message"); то программа не зависнет ожидая бита подтверждения, а по команде Wire.endTransmission(); данные будут "отправлены" сеанс полностью завершается? как долго может ждать мастер ответа от слейва? другими словами нужно ли как-то убедится перед новым сеансом связи, что все предыдущие завершены?

    • @arduinoetc
      @arduinoetc  7 ปีที่แล้ว

      Вводите в протокол обмена обязательное подтверждение приема и исполнения команды - будет у вас 100% обратная связь.

    • @AlexanderAbramovNN
      @AlexanderAbramovNN 7 ปีที่แล้ว

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

  • @ingrislt
    @ingrislt 8 ปีที่แล้ว

    Привет, я снова со своими вопросами, а можно таким способом привязать вашу умною реле, и ище место uno использовать megu, вес фрамеварк можно аставить esp8266, и получить много gpio?

    • @arduinoetc
      @arduinoetc  8 ปีที่แล้ว

      Можно, но скетч все равно придется немного переделать.
      Другое дело, что если WiFi не нужен, то правильнее, конечно, на Mega с Ethernet shield все сделать.

    • @ingrislt
      @ingrislt 8 ปีที่แล้ว

      Ну конечно лучше с w5100 но тогда почти всё надо переделать, а с есп8266 только добавить...

    • @arduinoetc
      @arduinoetc  8 ปีที่แล้ว

      Надежность сложной системы в разы ниже простой.

  • @ulibkaify
    @ulibkaify 6 ปีที่แล้ว

    Спасибо большое за видео!
    Дайте пожалуйста ссылку на конвертер уровней.

    • @arduinoetc
      @arduinoetc  6 ปีที่แล้ว +1

      Любой или на транзисторах, или на TXS010xE (для данного примера достаточно двухканального), выбирайте:
      www.aliexpress.com/af/level-converter.html?SearchText=level+converter

    • @ulibkaify
      @ulibkaify 6 ปีที่แล้ว

      Спасибо! Я почему спросил - для данного примера нужен высокоскоростной двунаправленный конвертер, который желательно чтобы работал на 800kHZ - это получается конвертер на TXS010xE ?

    • @arduinoetc
      @arduinoetc  6 ปีที่แล้ว +1

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

  • @сергейгончар-п3д
    @сергейгончар-п3д 8 ปีที่แล้ว

    Добрый вечер Спасибо Вам за видео можно Вас попросит не могу запустить на
    Raspberry Pi 3 онлайн радио majordomo нет как я понимаю проигрывателя для этого например vlc
    Заранее спасибо за ответ

    • @arduinoetc
      @arduinoetc  8 ปีที่แล้ว +1

      Здравствуйте.
      Простите, но я не специалист по Raspberry и по Majordomo. Для меня они не более чем умный клиент для отладки глупых вещей. :)

  • @SergKua
    @SergKua 8 ปีที่แล้ว

    Спасибо большое. Искал подобное решение - не нашел. Вы случайно не планировали объединить Ваше умное реле и ардуино экспандер? Я сейчас экспериментирую с веб-сервером на Arduino Mega, а ESP-12 в качестве шилда управляется АТ командами. Использовал схему: istarik.ru/blog/esp8266/29.html Но не нравиться стабильность работы такой схемы, поэтому хочу сделать по-человечески, веб-сервер на ESP-12(master), а датчики, кнопки, реле на Меге(slave).

    • @arduinoetc
      @arduinoetc  8 ปีที่แล้ว +2

      А чего их объединять? :)
      Там поправить не так уж и много кода придется. Все вхождения pinMode, digitalRead и digitalWrite и другой список доступных для подключения реле и кнопок GPIO.
      Вот только с ИК придется повозиться, если его переносить на слейв. С DHT все просто, расширяем протокол обмена данными двумя командами чтения температуры и чтения влажности. А вот постоянно опрашивать ИК мастером - не самая удачная идея (ИМХО). Правильнее один пин на слейве и мастере зарезервировать для "внешнего прерывания" по приходу данных от ИК на слейве. Впрочем, кнопки тоже могут не опрашиваться постоянно, а генерировать прерывание при изменении состояния.
      У Mega ног слишком много, 5 бит на номер пина в текущем протоколе не хватит, обмен станет минимум двухбайтным, немного пострадает компактность протокола, но это неизбежно и при расширении количества команд.

    • @SergKua
      @SergKua 8 ปีที่แล้ว

      Спасибо. Наверное проще не переносить ИК и DHT, им всего по одной ноге нужно, а вот кнопки и 16-канальный блок реле так и просятся на Мегу.

    • @arduinoetc
      @arduinoetc  8 ปีที่แล้ว +2

      Mega дороговата для экспандера, вот Pro Mini в самый раз. 20 пинов, из них 6 аналоговых, правда 2 работают только как аналоговые входы (A6, A7). :)
      Ну и 74HC595 в каскаде никто не отменял для размножения цифровых выходов. :)

    • @SergKua
      @SergKua 8 ปีที่แล้ว

      Действительно очень просто внедрил скетч в умное реле, работает шикарно, спасибо. А вот задействовать более 32 ног Меги так и не смог. Прокопался пол ночи :) не хватает мозгов, может направите что нужно менять. Мега нужна чтобы можно было подключить 16 кнопок 16 реле и еще осталось место... :)

    • @arduinoetc
      @arduinoetc  8 ปีที่แล้ว

      Я же говорил, что 5 бит на номер пина недостаточно! Надо первым байтом слать только команду, а вторым - пины. Тогда до 256 пинов можно будет использовать. Но придется и прием и передачу переделать соответственно.

  • @anatoliysemochkin2723
    @anatoliysemochkin2723 7 ปีที่แล้ว

    Не понимаю ничего. Команды Slave успешно получает от мастера, но мастер не получает ничего в ответ. Например, командой WireIO.digitalRead(13) на мастере пытаюсь прочитать состояние 13 пина слэйва, которое меняется периодически, но команда приходит, а ответ на мастер не возвращается. Симплекс какой-то. Железо: ESP8266 NodeMCU (Мастер) + ArduinoProMini (слэйв). В библиотеке менял номера SDA/SCL на свои. Чтобы не согласовывать уровни, ProMini запитал от 3.3 В. Может в этом проблема? Еще на слейв я заливаю пример номер два.

    • @arduinoetc
      @arduinoetc  7 ปีที่แล้ว

      А на мастер Вы копируете файлы из примера №2?
      Ну и подтяжка SDA и SCL к VCC через R 4K7 на слейве и минимизация длины проводов.
      Скорость I2C понизить. На ESP setClockStretchLimit раскомментировать и поиграться его значением.

    • @anatoliysemochkin2723
      @anatoliysemochkin2723 7 ปีที่แล้ว

      Простите, я не понял что значит копируете на мастер файлы из примера №2? Я распаковал архив WireSlave2, отредактировал номера SDA/SCL под себя, скопировал файлы в библиотеку ардуино. Далее я прошиваю одной и той же библиотекой оба контроллера. В примере№2 содержится только файл для Slave (WireSlave2.ino), остальные три - библиотека. На мастере я инициализирую ногу второго контроллера WireIO.pinMode(13, INPUT_PULLUP); и раз в секунду его читаю WireIO.digitalRead(13). Но в ответ я получаю всегда 0, хотя на слэйве состояние ноги 13 меняется. setClockStretchLimit раскоментировал и пробовал разные значения. Подтяжку к VCC делал. Грешу на то, что у меня на I2С еще висит OLED экран.

    • @arduinoetc
      @arduinoetc  7 ปีที่แล้ว

      Вы из архива №2 все файлы кроме .ino в мастер скопировали?
      Отключите OLED экран и проверьте без него. Скорость I2C пробовали уменьшать?

    • @anatoliysemochkin2723
      @anatoliysemochkin2723 7 ปีที่แล้ว

      Я кажется понял ошибку. Вечером попробую отписаться. Я правильно понял, что на мастер нужно перенести содержимое файлов .cpp и .h из второго архива?

    • @arduinoetc
      @arduinoetc  7 ปีที่แล้ว

      Да, они другие относительно первого архива и нужны именно мастеру. Слейв использует из них только .h-файл с общими параметрами.

  • @ingrislt
    @ingrislt 7 ปีที่แล้ว

    привет , както у мениа неработает slave2, a на slave1 mega raботает толко до 31 пина, где может быть проблема?

    • @arduinoetc
      @arduinoetc  7 ปีที่แล้ว

      Из второго кода надо все .cpp и .h фалы скопировать в код мастера взамен совместимых с первым кодом.
      И константы SDA и SCL изменить на значения в Меге и максимальный номер пина.

  • @ingrislt
    @ingrislt 8 ปีที่แล้ว

    Или невозможно это реализовать?

    • @arduinoetc
      @arduinoetc  8 ปีที่แล้ว

      Мне это неинтересно, но никаких трудностей в этом нет.
      Если вам нужно много реле - то проще к ESP подключить 74HC595 хоть каскадом хоть одну. Вот с опросом кнопок сложнее. Но даже если перейти на внешний GPIO-расширитель, с кнопками все равно придется повозиться.

  • @ingrislt
    @ingrislt 7 ปีที่แล้ว

    спасибо заработало... а к есп привезать w5100 небило вам интересно? провод есть провод. тогда можно есп исползовать как ум а мегу как силу... на такои плате мега+есп :robotdyn.com/catalog/boards/mega_wifi_r3_atmega2560_esp8266_flash_32mb_usb_ttl_ch340g_micro_usb/

    • @arduinoetc
      @arduinoetc  7 ปีที่แล้ว

      После привязки к UNO я могу W5100 к чему угодно прикрутить, только зачем?
      Кроме вас никому 500 реле не нужно к одному модулю подключать. :)
      А если не нужен WiFi, то ESP8266 становится весьма сомнительным выбором при наличии STM32 на нормальном ARM ядре за сущие копейки.

    • @ingrislt
      @ingrislt 7 ปีที่แล้ว

      лу4е било би на меге вес код переделать все реле, но там много работы а на есп вы узе всио сделали...

    • @arduinoetc
      @arduinoetc  7 ปีที่แล้ว

      У меня нет Меги, не на чем отлаживаться, а то за неделю я бы перенес основной код на Мегу, тем более что нужную часть веб-сервера я уже портировал с ESP.
      В любом случае, библиотека веб-сервера для ESP работает только с WiFi, поэтому добавление W5100 на ESP все равно потребует переписать библиотеку, а значит ESP не нужна вообще в этом случае.