Você está na página 1de 10

09/06/2018 Expandindo as portas do ESP8266 com o MCP23017 - Pedro Minatel - Sistemas Embarcados

Expandindo as portas do ESP8266 com o MCP23017


Pedro Minatel - Sistemas Embarcados > Ferramentas > nodeLHC > Expandindo as portas do ESP8266 com o MCP23017

l Pedro Minatel } 24 de outubro de 2015 v 29 Comments


m ESP8266, nodeLHC  Access Point, Arduino, Eletrônica, ESP8266,
MCP23017, nodeLHC, sistemas embarcados e IoT,
Software

Em alguns projetos, precisamos de um número significativo de portas digitais (IO’s), o que nos leva a escolher
plataformas que atendam a esta demanda. Em alguns casos, não é tão simples alterar a plataforma ou mudar de
tecnologia, o que muitas vezes aumenta consideravelmente o custo do projeto.

Para contornar este problema, existem alguns chips que expandem as portas digitais, como o caso da família
MCP230XX da Microchip.

MCP23017

Vamos utilizá-lo com o ESP8266, através da IDE do Arduino.

Existem duas versões, o MCP23008 com 8 portas e o MCP23017 com 16, e que utilizam do barramento I2C para
comunicação. Todas as portas podem ser configuradas tanto como saída ou entrada digital.

O chip pode ser endereçável para até 8 endereços distintos, o que permite uma expansão de até 128 portas (8
chips de 16 portas).

http://pedrominatel.com.br/pt/esp8266/expandindo-as-portas-do-esp8266-com-o-mcp23017/ 1/10
09/06/2018 Expandindo as portas do ESP8266 com o MCP23017 - Pedro Minatel - Sistemas Embarcados

Download do datasheet:
MCP23008 – http://ww1.microchip.com/downloads/en/DeviceDoc/21919e.pdf

MCP23017 – http://ww1.microchip.com/downloads/en/DeviceDoc/21952b.pdf

A utilização é bastante simples, apenas 2 registradores de 8bits são necessários, um registrador para a direção,
entrada ou saída digital, e outro registrador com o status da porta.

Abaixo um vídeo de demonstração com o nodeLHC:

Utilizando o MCP23017 no ESP8266 com I2C

O código com a implementação das funções de configuração, escrita e leitura, segue


abaixo:

1 /*
2 * MCP23017 for ESP8266
3 *
4 *  Created on: 07/10/2015

http://pedrominatel.com.br/pt/esp8266/expandindo-as-portas-do-esp8266-com-o-mcp23017/ 2/10
09/06/2018 Expandindo as portas do ESP8266 com o MCP23017 - Pedro Minatel - Sistemas Embarcados

5 *      Author: pedrominatel
6 */
7  
8 #include "Wire.h"
9  
10 //GPIOs definition
11 #define GPIO1 0
12 #define GPIO2 1
13 #define GPIO3 2
14 #define GPIO4 3
15 #define GPIO5 4
16 #define GPIO6 5
17 #define GPIO7 6
18 #define GPIO8 7
19 #define GPIO9 8
20 #define GPIO10 9
21 #define GPIO11 10
22 #define GPIO12 11
23 #define GPIO13 12
24 #define GPIO14 13
25 #define GPIO15 14
26 #define GPIO16 15
27 //GPIO mode
28 #define GPIO_OUTPUT 0
29 #define GPIO_INPUT 1
30 //GPIO state
31 #define GPIO_HIGH 0
32 #define GPIO_LOW 1
33 //GPIO BANK
34 #define IODIRA 0x00 //Config register PORTA
35 #define IODIRB 0x01 //Config register PORTB
36 #define PORTA 0x12 //PORT A register
37 #define PORTB 0x13 //PORT B register
38 //Chip Model
39 //#define CHIP8BITS
40 #define CHIP16BITS
41  
42 unsigned short u16_GPIO_register = 0x00;
43 unsigned short u16_GPIO_controlState = 0x00;
44 byte u8_MCP23017_address = 0x20; //Default address is 0x20
45  
46 /*
47 *
48 * */
49 void MCP23017_I2C_send(byte portRegister, byte portValue){
50 Wire.beginTransmission(u8_MCP23017_address);
51 Wire.write(portRegister); // PORT A register
52 Wire.write(portValue);
53 Wire.endTransmission();
54 }
55  
56 /*
57 *
58 * */
59 void MCP23017_init(byte chipAddress, byte sda, byte scl) {
60 u8_MCP23017_address = chipAddress;
61 u16_GPIO_register = 0x00;
62 u16_GPIO_controlState = 0x00;
63 Wire.begin(sda, scl);
64 }
65  
66 /*
67 *
68 * */
69 void MCP23017_config(void) {
70 MCP23017_I2C_send(IODIRA,0x00);
71 #ifdef CHIP16BITS
72 MCP23017_I2C_send(IODIRB,0x00);
73 #endif

http://pedrominatel.com.br/pt/esp8266/expandindo-as-portas-do-esp8266-com-o-mcp23017/ 3/10
09/06/2018 Expandindo as portas do ESP8266 com o MCP23017 - Pedro Minatel - Sistemas Embarcados

74 }
75  
76 /*
77 *
78 * */
79 void MCP23017_GPIO_config(byte gpio, byte gpioMode) {
80 if (gpioMode == GPIO_OUTPUT)
81 u16_GPIO_register |= 1 << gpio;
82 if (gpioMode == GPIO_INPUT)
83 u16_GPIO_register &= ~(1 << gpio); byte iodira = u16_GPIO_register; MCP23017_
84 MCP23017_I2C_send(IODIRB,iodirb);
85 #endif
86 }
87  
88 /*
89 *
90 * */
91 void MCP23017_GPIO_write(byte gpio, byte gpioState) {
92 if (gpioState == GPIO_OUTPUT)
93 u16_GPIO_controlState |= 1 << gpio;
94 if (gpioState == GPIO_INPUT)
95 u16_GPIO_controlState &= ~(1 << gpio); byte porta = u16_GPIO_controlState; M
96 MCP23017_I2C_send(PORTB,portb);
97 #endif
98 }
99  
100 /*
101 *
102 * */
103 void MCP23017_GPIO_writeBits(unsigned short gpioState) {
104  
105 u16_GPIO_controlState = gpioState;
106  
107 byte porta = u16_GPIO_controlState;
108  
109 MCP23017_I2C_send(PORTA,porta);
110 #ifdef CHIP16BITS
111 byte portb = u16_GPIO_controlState >> 8;
112 MCP23017_I2C_send(PORTB,portb);
113 #endif
114 }
115  
116 /*
117 *
118 * */
119 byte MCP23017_GPIO_read(byte gpio) {
120  
121 byte port = PORTA;
122 byte inputs = 0;
123  
124 if(gpio > GPIO8)
125 port = PORTB;
126  
127 Wire.beginTransmission(u8_MCP23017_address);
128 Wire.write(port); // set MCP23017 memory pointer to GPIOB address
129 Wire.endTransmission();
130 Wire.requestFrom(u8_MCP23017_address, gpio); // request one byte of data from MCP20317
131 inputs = Wire.read(); // store the incoming byte into "inputs"
132  
133 if(inputs > 0)
134 return inputs;
135  
136 return 0;
137 }
138  
139 void setup() {
140   MCP23017_init(u8_MCP23017_address, 4,14);
141   MCP23017_config();
142 }

http://pedrominatel.com.br/pt/esp8266/expandindo-as-portas-do-esp8266-com-o-mcp23017/ 4/10
09/06/2018 Expandindo as portas do ESP8266 com o MCP23017 - Pedro Minatel - Sistemas Embarcados

143  
144 void loop() {
145   
146   MCP23017_GPIO_write(GPIO9, GPIO_HIGH);
147   MCP23017_GPIO_write(GPIO1, GPIO_LOW);
148   delay(1000);
149   MCP23017_GPIO_write(GPIO9, GPIO_LOW);
150   MCP23017_GPIO_write(GPIO1, GPIO_HIGH);
151   delay(1000);
152   
153 //   for (int a=0; a<65536; a++)
154 // {
155 //   MCP23017_GPIO_writeBits(a);
156 //   delay(50);
157 // }
158 }

Esta é uma ótima solução para expansão de portas digitais e de relativo baixo custo.

Happy Hacking!

← Previous post Next post →

29 Comments

Yuri Lima 13 de novembro de 2015 at 1:00 PM

Pedro. O esp 8266-01 tem SDA e Clock?

Pedro Minatel (Post author) 13 de novembro de 2015 at 1:26 PM

Yuri, quando se trata de I2C por software, dá para configurar os pinos. Eu usei em um projeto os
pinos 4 e 14. No caso do ESP-01, você poderia usar a GPIO0 como SCL e a GPIO2 como SDA.

Diogo 16 de dezembro de 2015 at 2:16 PM

Sabe se posso substituir o MCP23008 pelo 74HC595N ? Sei que nesse caso não vou poder usar a I2C.

pedrominatel 17 de dezembro de 2015 at 4:09 PM

Diogo, o 74HC595 é um shift register, dá para usa-lo como o MCP23008, mas você só conseguirá saídas
com esse chip. Para entradas você terá que usar um 74HC165.
http://pedrominatel.com.br/pt/esp8266/expandindo-as-portas-do-esp8266-com-o-mcp23017/ 5/10
09/06/2018 Expandindo as portas do ESP8266 com o MCP23017 - Pedro Minatel - Sistemas Embarcados

Rafael da Silva Monteiro Leite 12 de Janeiro de 2016 at 7:23 AM

Muito bom Pedro, Gostei muito de sua explicação, sou bem leigo nisso, tipo muito mesmo hehehehe gostaria de
saber, se por acaso, não poderia me explicar melhor ou até mesmo fazer um tutorial explicando como funciona o
MCP23017, como que liga ele e para que serve cada perna, como fazer o código ativar determinada perna dele e
etc. Desculpe pedir isso mas gostaria de entender mais.

Obrigado

Pedro Minatel (Post author) 12 de Janeiro de 2016 at 9:47 PM

Rafael, boa noite!

O código já está preparado para o controle de todos os terminais (pernas). Tem uma
documentação, datasheet, que tem todas as informações, só que em Ingles.

Se tiver alguma dúvida é só perguntar!!

Pedro Minatel (Post author) 26 de Janeiro de 2016 at 8:56 PM

Rafael, em breve vou tentar disponibilizar uma explicação mais detalhada!

Rafael leite 27 de Janeiro de 2016 at 12:02 AM

Iria me ajudar muito, sou meio leigo nisso, agradeço desde já..

Jean 18 de Janeiro de 2016 at 9:55 AM

Teria como mostrar o esquema de montagem com uma figura e os pinos?


Tenho Esp8266 01 e gostaria de expandir as portas.

Pedro Minatel (Post author) 26 de Janeiro de 2016 at 8:55 PM

Jean, eu segui o datasheet do componente. Quanto à ligação no ESP, vou ver se tenho alguma
foto ou diagrama.

Obrigado!

Felix 3 de Abril de 2016 at 1:47 PM

http://pedrominatel.com.br/pt/esp8266/expandindo-as-portas-do-esp8266-com-o-mcp23017/ 6/10
09/06/2018 Expandindo as portas do ESP8266 com o MCP23017 - Pedro Minatel - Sistemas Embarcados

Pedro, estou começando com o ESP8266. Em meu primeiro projeto estou tentando conectar um LCD Display via
i2c (GPIO4,GPIO5) e um keyboard 8 teclas (8 vias e 1 comum). Porém, estou com muita dificuldade em
compreender quais portas posso utilizar na versão 12E para conectar as 8 vias do teclado. Encontro muita
documentação, porém fico confuso porque preciso da GPIO1 e GPIO3 para FTDI, as GPIO9 e 10 vejo
recomendação de não usar, quanto a GPIO0 e 16 fico em dúvida porque tem funções especiais, não imagino como
usar para ler as teclas ao mesmo tempo que já estão em uso. Além das 6-11 que vi em alguns sites estares
indisponíveis. Se tiver alguma dica de como fazer esta ligação eu agradeço. Parabéns pelo post, estou sempre
acompanhando :)

Vinicius Oliveira 19 de outubro de 2016 at 12:54 PM

Pedro, boa tarde.

Estou utilizando o seu código exemplo, mas creio que meu hardware esteja com algum erro de projeto.
Estou utilizando um WeMos D1 R2 ligando o MCP23017 na protoboard. Estou utilizando jumpers de protoboard
iguais os que você usa.
Estou alimentando o MCP23017 com 5 V, pull-up de 1 kOhms no SDA e SCL, pull-down de 10 kOhms no
endereçamento (A0, A1 e A2), e leds com resistor de 220 Ohms.

O que acontece é o seguinte, na maioria das vezes ele não dá sinal algum, parece que ignora os comandos I2C.

As vezes, após alguns resets, começa a mostrar a contagem binária nos LEDs e do nada apagam-se todos os
LEDs no meio da contagem, como se tivesse dado um reset no MCP23017 e como não foi enviado novamente o
comando para configuração dos PORTs como saída, eles não acendem mais, acho que é isso que está
acontecendo.

Também tentei algumas variações de hardware, coloquei um capacitor eletrolítico de 3.3 uF na protoboard proximo
ao MCP23017 e um de 1000 uF no barramento da protoboard, coloquei um pull-up no reset do MCP23017 mesmo
sendo somente saída, pois vi no seu vídeo você colocou um jumper direto no VCC.

Enfim, pode me ajudar a solucionar este problema?


Desde já agradeço.
Abraço.
Att, Vinicius

Diogo 27 de outubro de 2016 at 7:54 PM

Pedro,
Sabe se poderia ligar um conversor logico entre os pinos SCL/SDA (3.3v para 5v) alimentar o mcp com 5v e
trabalhar com as portas do mcp em 5v ?

Pedro Minatel (Post author) 28 de outubro de 2016 at 11:18 AM

Da para usar conversor de sinal sim. O ideal é usar aqueles com MOSFET ou um chip dedicado.

http://pedrominatel.com.br/pt/esp8266/expandindo-as-portas-do-esp8266-com-o-mcp23017/ 7/10
09/06/2018 Expandindo as portas do ESP8266 com o MCP23017 - Pedro Minatel - Sistemas Embarcados

hussainb 26 de novembro de 2016 at 12:24 PM

I am having difficulty in understanding the language since its not in english, so would like to ask few questions.

Could you post the circuit diagram for the connections you made.
The nodeMCU works on 3.3V and the MCP works on 5V, so does it need any logic level converter or its possible to
connect the pins directly?

Thanks.

Pedro Minatel (Post author) 29 de novembro de 2016 at 6:49 PM

Hello! The MCP23017 works on both voltages. In this circuit I’ve used the 3.3v as well some 220R
resistors for the LEDs. You can find on the datasheet how to connect them.

hussainb 3 de dezembro de 2016 at 1:45 AM

Yep, I read that in its datasheet that it has voltage ranging from 1.8 to 5.

Thankyou for the code because thats the difficult thing to do.

I was able to make the port extender work with your code without any issues.

josiel 4 de dezembro de 2016 at 1:34 PM

Boa tarde, esse CI pode ao mesmo tempo ter uma porta como entrada e outra como saída ?

Pedro Minatel (Post author) 4 de dezembro de 2016 at 1:51 PM

Sim! Pode ter entrada e saída digital!

Diego Faria 12 de Janeiro de 2017 at 12:19 PM

Boa tarde Pedro sempre estou me referenciando com seus posts gostaria de peguntar como posso aumentar as
saidas do esp8266 01 74hc ou hc156 poderia se for o caso me mandar um exemplo desde já agradeço um
abraço..

Antonio Borges 7 de Abril de 2017 at 10:48 AM

Pedro, o exemplo funcionou perfeitamente, porém somente com o cabo serial ligado. Quando desconecto a serial
do micro, parece que o CI nao inicializa. Estou utilizando o ESP8266 fazendo conexao com os pinos de dados

http://pedrominatel.com.br/pt/esp8266/expandindo-as-portas-do-esp8266-com-o-mcp23017/ 8/10
09/06/2018 Expandindo as portas do ESP8266 com o MCP23017 - Pedro Minatel - Sistemas Embarcados

14,12 e conexão com o micro (tx.rx) com um adaptador USB TTL

Pedro Minatel (Post author) 11 de Abril de 2017 at 9:25 AM

Antônio, bom dia! Tem a imagem da ligação na placa?

Antonio Borges 11 de Abril de 2017 at 10:48 AM

Bom dia, obrigado pela atenção, mas já consegui resolver,


Adicionei um resistor de 10K fazendo pull-up nos pinos 14 e 12 SCL e SDA. Está
funcionando perfeitamente;

Aproveito então para emendar outra pergunta rsrs

Existe alguma vantagem em usar os pinos que são aqueles definidos por padrão na ESP
para SCL e SSA ou não tem nenhuma diferença em definir os pinos no momento que estou
instanciando a conexao.
Mesma duvida para SoftwareSerial, tenho alguma perda em usar a função e não os pinos
UART que são definidos por padrao na ESP?

Felipe Barreto 9 de Maio de 2017 at 12:10 PM

Onde adquirir o mcb23017 no Brasil? Sem ser smd

Antonio Borges 9 de Maio de 2017 at 12:39 PM

Boa tarde Felipe, este item, mcp23017 está muito difícil de encontrar em lojas no Brasil. Já procurei
bastante. Inclusive no mercadoLivre alguns que tinham em Salvador, já acabaram.
Como fizemos nosso projeto usando este CI, fizemos uma compra de maior quantidade na China e estamos
aguardando o fim da greve dos Correios pois já estão liberados em Curitiba.

Chegando nossa encomenda, posso disponibilizar um link aqui. Mas deve demorar ainda uns 20 dias.

Felipe 11 de Maio de 2017 at 2:20 PM

Daria pra fazer PWM usando esse expansor?

Antonio Borges 3 de junho de 2017 at 11:45 PM

Caro Felipe Barreto, já estão disponíveis alguns MCP23017 no mercadolivre. O meu é este aqui:
http://produto.mercadolivre.com.br/MLB-874252392-mcp23017-esp-dip-28-mcp23017-16-bit-io-expander-_JM

http://pedrominatel.com.br/pt/esp8266/expandindo-as-portas-do-esp8266-com-o-mcp23017/ 9/10
09/06/2018 Expandindo as portas do ESP8266 com o MCP23017 - Pedro Minatel - Sistemas Embarcados

Mas estou em Joao Pessoa/PB, talvez encontre outro mais próximo de você.

Ney Silva 5 de Fevereiro de 2018 at 12:37 PM

Pedro, boa tarde!!! Primeiro meus parabéns pelo post. Estou tendo um problema na hora de compilar o sketch na
ide do arduino. Dá mensagem #endif without #if. Pode me ajudar?

Jean 18 de Fevereiro de 2018 at 5:18 PM

Boa tarde!
O MCP23017 tb tem como configurar a sua porta com a função de PWM?

http://pedrominatel.com.br/pt/esp8266/expandindo-as-portas-do-esp8266-com-o-mcp23017/ 10/10

Você também pode gostar