Skip to main content

Raspberry PI and additional GPIO pins on several mcp23017 chips and a transistor switch


Some time ago I came to the conclusion that the home automation control system I made before was too complicated. I've been using a Raspberry PI + arduino + ethernet shield + additional connector board. 
Arduino together with ethernet shield sometimes causes problems, especially after power outages. It has problems with restarting and requires manual restart. So this was the element I wanted to get rid of. It seems that the raspberry PI itself should definitely be enough. The only limitation is the number of GPIO pins and current efficiency. To avoid that problem I have already started designing the PCB which, when connected to raspberry, will provide us with additional pins and the ability use more power consumng devices.
The easiest way to gain additional pins is to use the mcp23017 chip. It uses I2C bus to connect to the raspberry PI. Each chip will provide us with 16 additional pins. The chips can be connected together in chain, so you can have even more pins. I calculated that for my needs two such chips would be sufficient. There are many examples of connecting mcp23017 to RPI on the network, but there are not too many examples of connecting few of them at the same time.
An additional assumption is that I want to be able to control devices requiring more than 5V voltage supplied by raspberry PI. This can be done using the the N-MOSFET transistor.
Below I present a diagram of connecting two mcp23017 chips to Raspberry PI and connecting two transistor keys to them. One (connected to the first MCP) controls the LED, the other controls the relay module (to which we can connect any 220V device). In my example, an additional external power supply is still 5V (both relay module and LED require that voltage), but there is no problem to connect 12V or 24V power supply (or higher - the limit is the transistor parameter) and control devices requiring a higher voltage by connecting them to the system in the same way.





For the system to work properly we need to activate the I2C bus in the raspberry PI.
A description of how to do this can be found, for example, here:


https://learn.adafruit.com/adafruits-raspberry-pi-lesson-4-gpio-setup/configuring-i2c


Each mcp23017 system that we connect must have a separate address on the I2C bus.





The addressing corresponds to the pins marked in the drawing. The address always starts from 0x2. The last digit in the address depends on the way in which we connect the address pins. Each of them must be connected either to ground or to VCC. In the given example, the first chip has all the pins connected to GND, reading them in binary, we have zero, so the last digit of the address is 0.
The first chip therefore has the address 0x20.
The second's chip middle pin is connected to VCC, so 010 binary, gives us 2 hexadecimal, so the address of the second chip is 0x22. Connecting all pins to the VCC would give us 111 binary, that is 7 in hexadecimal, then the address would be 0x27.

After connecting the system, we can check its operation.
We log in to Raspberry Pi (I use Raspbian, where all I2C software is installed - in other distributions it may be necessary to install additional packages).

we execute the command

sudo bash

to give yourself root privileges (thanks to that before each command you will not have to add "sudo")

Then we issue the command:

i2cdetect -y 1

in the case of raspberry pi 1 it will be:

i2cdetect -y 0

After executing the command, we should receive:




You can see that on the bus we have two devices with addresses 20 and 22

Bus control is performed using the i2cset command.

First, set the GPA0-7 pins of both circuits to work as outputs.

To do this, we execute the commands:

i2cset -y 1 0x20 0x00 0x00

i2cset -y 1 0x22 0x00 0x00


1 - i2c bus number

0x20, 0x22 - addresses of MCP circuits

0x00 - MCP register's register number, the register 0x00 is IODIRA (according to the MCP specification), which is responsible for the way GPA0-7 pins work. MCP chip's pins are controlled independently by 8 - GPA0-7 and GPB0-7. To set the operating modes for pins GPB0-7 we would have to enter values ​​into the IODIRB register, the address of which is 0x01

0x00 - value entered in the appropriate register - set to the 8-pin output mode. 0 binary corresponds to the output, 1 binary corresponds to the input. we set all pins as outputs, i.e. binary 00000000, hexadecimal 0x00.

After setting the modes of the pins, we can set high state on the outputs, which will turn on our transistor key and activate the diode relay. The diode is connected to the GPA1 pin of the system with the address 0x20.

So binary, we want to have state 00000010 on the outputs GPA0-7, it gives us 0x02 hexadecimal

So, we execute the command:

i2cset -y 1 0x20 0x14 0x02
0x14 - OLATA register address, which is responsible for setting values ​​on GPA0-7 pins

To turn off the diode will be this command:

i2cset -y 1 0x20 0x14 0x00

For the relay they will be respectively commands:

i2cset -y 1 0x22 0x14 0x02

i2cset -y 1 0x22 0x14 0x00


In this way, we can manage 32 additional Raspberry PI outputs that can be connected to externally powered devices. If necessary, we can add more MCP chips by changing only the addressing. It gives us a really wide range of possibilities.

MCP23017 systems can also be powered by 3.3V.

Then on the outputs the high state is also 3.3V

I used IRF540N transistors, so the minimum switching voltage was about 4V. That's why I had to connect them to 5V.

Feel free to comment.

Comments

Popular posts from this blog

Control OpenHab using Telegram Messenger

Recently, I've been trying to discover a way to control my OpenHab instance using Google Assistant. It is rather easy to do this using  IFTTT , but only when You use OpenHab in a cloud. I prefer using private instalation of OpenHab in my LAN, so that was not an option for me. I was searching for another solution, but only app supported by IFTTT which might be usefull form me was Telegram messenger. The only problem is, that OpenHab does not support Telegram controling by default. I google'd a little and it turned out that Telegram has a great public API with good Java support, so I decided to write a simple Spring Boot application as a bridge between Telegram Bot and OpenHab instance. You can find source code of my application on my GitHub account: https://github.com/aogorek/openhabtelegrambot In order to run it there are few steps required: 1. Create Bot in Telegram Messenger First You have to create Your own bot to communicate with. You need to contact @BotFather

Angular 5, SpringBoot 2, Oauth2 and IMPLICIT flow - silent token refresh

Recently I've been working on simple web application for managing students and users. Application will be published on the internet, so it needs proper access control. I wanted to learn some new stuff, so I decided to use Angular5 with Oauth2 authentication. I didn't want to use any options as "Login with Facebook", or "Login with Google". I wanted my Spring Boot app to work as the authentication server and the resource server. I read a little abouth Oauth2 and different flows possible, and it turns out, that preffered flow to use with web application is IMPLICIT flow. Implicit flow uses only one token. It doesn't have a refresh token, as it could be overtaken by an attacker. Access token has defined validity period. In other flows, where refresh token exists it is used to get another access token when the first one expires. In theory in implicit flow user should just log again, but forcing a user to log in during active session is not an option.