Когда на ESP8266/ESP32/Arduino не хватает GPIO можно использовать чип MCP23017 для увеличения количества портов на 16. Управление чипом происходит по двум проводам I2C, коммуникация удобная. Цена за чип около 0,8 $. На Aliexpress достаточно большой выбор вариантов чипа и два основных варианта плат.
Wemos D1 mini (ESP8266) широко представлен на Aliexpress по цене менее 3 USD.
Поскольку плата поддерживает I2C адресацию позволяющую подключить 8 плат, суммарно к микроконтроллеру можно добавить 128 GPIO.
Схема соединения
Распиновка MCP23017 следующая:
Адресация I2C платы задается замыканием ножек A0-2 на +3,3 В или GND. Таблица адресации такая:
Схема соединения Wemos D1 с MCP23017:
Wemos D1 Pin Name | MCP23017 Physical Pin | MCP23017 Pin Name | Description |
---|---|---|---|
D1 (SCL) | 12 | SCL | I/O Serial Clock input |
D2 (SDA) | 13 | SDA | I/O Serial Data |
3V3 | 18 | Reset | |
3V3 | 9 | VDD | Power |
GND | 10 | VSS | Ground |
GND | 15 | A0 | Hardware address pin |
GND | 16 | A1 | Hardware address pin |
GND | 17 | A2 | Hardware address pin |
В качестве сенсора я использовал датчик пересечения линии. На схеме в качестве примера использована плата датчика дождя. Схемотехника сенсоров одинаковые, а для fritzing мне не удалось найти библиотеки для датчика пересечения линии.
При срабатывании сенсора сигнал поступает на вход GPA0 и ESP8266 зажигает светодиод скоммутированный к выходу GPB0.
Программа
Если MCP23017 подключен к ESP8266 корректно, при запуске скетча https://playground.arduino.cc/Main/I2cScanner будет найдено устройство.
11:04:46.058 -> Scanning... 11:04:46.058 -> I2C device found at address 0x20 ! 11:04:46.140 -> done
При работе с MCP23017 через библиотеку Adafruit MCP23017. потребуется таблица перевода входов Adafruit в названия входов и номера ножек на микросхеме.
Adafruit PIN | Pin Name | Physical Pin |
0 | GPA0 | 21 |
1 | GPA1 | 22 |
2 | GPA2 | 23 |
3 | GPA3 | 24 |
4 | GPA4 | 25 |
5 | GPA5 | 26 |
6 | GPA6 | 27 |
7 | GPA7 | 28 |
8 | GPB0 | 1 |
9 | GPB1 | 2 |
10 | GPB2 | 3 |
11 | GPB3 | 4 |
12 | GPB4 | 5 |
13 | GPB5 | 6 |
14 | GPB6 | 7 |
15 | GPB7 | 8 |
В программе потребуется также адресация Adafruit, она отличается от адресации I2C.
Address I2C | Adafruit address | A0 / PIN 15 | A1 / PIN 16 | A2 / PIN 17 |
---|---|---|---|---|
0x20 | 0 | LOW | LOW | LOW |
0x21 | 1 | HIGH | LOW | LOW |
0x22 | 2 | LOW | HIGH | LOW |
0x23 | 3 | HIGH | HIGH | LOW |
0x24 | 4 | LOW | LOW | HIGH |
0x25 | 5 | HIGH | LOW | HIGH |
0x26 | 6 | LOW | HIGH | HIGH |
0x27 | 7 | HIGH | HIGH | HIGH |
Программа принимает сигнал с входа GPA0 и зажигает светодиод на выходе GPB0 MCP23017 и на плате Wemos D1.
#include <Wire.h> #include "Adafruit_MCP23017.h" #define MCP23017_GPA0 0 // Digital input on MCP23017 correspond to A0 //#define MCP23017_ADDR 0x20 #define LedPin 2 //A0 #define MCP23017_LED 8 //GPB0 Adafruit_MCP23017 mcp; void setup() { Serial.begin(9600); mcp.begin(); // use default address 0x20 mcp.pinMode(MCP23017_GPA0, INPUT); //Define GPA0 as input pin mcp.pinMode(MCP23017_LED, OUTPUT); //Define GPB0 as output pin //mcp.pullUp(MCP23017_GPA0, HIGH); // turn on a 100K pullup internally pinMode(LedPin, OUTPUT); // use the LedPin LED as debugging } void loop() { int value_A0 = analogRead(A0); // reads the analog input from the IR distance sensor bool value_D0 = mcp.digitalRead(MCP23017_GPA0);// reads the digital input from the IR distance sensor mcp.digitalWrite(MCP23017_LED, !value_D0); digitalWrite(LedPin, value_D0); //Serial.println(value_D0 + " Value: " + String(value_A0)); //delay(1000); }
Подключение реле к MCP23017
Загорающийся светодиод — штука информативная, но в жизни при срабатывании датчика нужно выполнять какие-то действия, нередко физические: что-то открыть и закрыть, переместить и т.п. Поэтому подключим к светодиоду реле.
Что касается реле и подбора для микроконтроллеров — это тема для отдельной статьи, вариантов много и есть нюансы. Чтобы долго не мудрить, подключил к MCP23017 «родное» реле заточенное под Wemos D1 Mini. Такое реле недорогое, широко представлено у продавцов на Aliexpress, поддерживает уровень TTL 3V, т.е. не нужно ставить преобразователь уровней 3V <-> 5V.
Собственно, подключать его несложно. Управление идет по high level, т.е. по 1-це на управляющем входе D1. Если бы это был low level trigger, то в софте надо было ставить инверсию по логике, чтобы включение было по 0-ю, а отключение по 1-це на входе управления. Причем, не для всех реле программная инверсия срабатывает.
В общем, чтобы не иметь проблем при подключении реле к микроконтроллеру, работающему на напряжении 3,3 V, с соотвествующим уровнем TTL логики, нужно:
- Выбирать high level trigger/relay.
- С поддержкой напряжения срабатывания TTL логики 3,3 V.
- JD Vcc входом, чтобы отдельно запитать 5V обмотку реле.
- Гальванической (оптической) развязкой оптроном, чтобы не «спалить» микроконтроллер.
Итак, параллельно или вместо светодиода подключаем MCP23017 к реле.
MCP23017 pin | Wemos D1 Mini relay shield | Примечания |
GND | GND | |
GPB0 | D1 | |
5V | На БП +5V для управления обмотками реле. | |
GND | На БП GND для управления обмотками реле. |
После подключения, реле нормально коммутируется при срабатывании датчика. Программный код менять не нужно.
CJMCU-2317 (MCP23017) Fritzing part
Не нашел Fritzing part для платы CJMCU-2317 (MCP23017), поэтому пришлось создать свой вариант. Пользуйтесь и не забывайте лайкать, приятно. 🙂
Полезные ссылки
- https://github.com/adafruit/Adafruit-MCP23017-Arduino-Library
- https://medium.com/@wilko.vehreke/more-gpios-for-the-esp8266-with-the-mcp23017-b89f5e15cde3
- https://tronixstuff.com/2011/08/26/tutorial-maximising-your-arduinos-io-ports/
- https://arduinodiy.wordpress.com/2017/03/14/adding-an-mcp23017-16-port-io-expander-to-arduino-or-esp8266/
- http://ww1.microchip.com/downloads/en/DeviceDoc/21952a.pdf — документация от производителя
- http://omnigatherum.ca/wp/?p=338 — Fritzing part для датчика дождя.