Never enough GPIO pins on a Micro Processor

Placed on

Somehow, no matter which microprocessor I choose, I run out of GPIO pins for the project needs or for what I want to do.

So for a recent project I switched from the ESP8266 to the ESP32 which has a lot more GPIO pins than its predecessor.. but still not enough for the project I'm working on.

To end this run for GPIO pins once and for all, I decided I needed a cheap expansion board that could be configured for switches (input) and LEDs or other things (output). And while I was at it, I thought some extra logic would be nice.

So what I came up with is an I2C board with eight GPIO pins that are freely configurable for input or output (I call the GPIO pins "Slots").

The expansion board is ideal for use on a solderless breadboard. The schematic can later be incorporated into the overall hardware design.

ADW0720 Type 2 ADW0720 Type 2

A Slot configured for input will probably be used for switches and then it would be great if we could distinguish between pressing the button and releasing it (quick release, middle release and long release). In the code on the main processor you can just say:

Slots configured for output become a "shoot and forget" type of slot. That is, you can tell the Slot to be HIGH or LOW as with the digitalWrite() function in the Arduino IDE. But you can also say: goes HIGH for 2500 ms and then goes LOW again. In your main program you don't have to write the code to wait 2500 ms and then make the GPIO pin LOW.

You can also tell the Lock to flash with an on time and an off time and, if you want, a duration. For example:

The Lock flashes at 500ms on, 1000ms off for a period of 10 seconds (10000ms) and then stops flashing.

Similar to the example above, but now the Lock will blink forever (or until you tell it to do something else);

The hardware is designed around an ATtiny841 microcontroller. Communication is via the I2C bus (two wires, SCL and SDA).
You can run the boards at 5Volt or 3.3Volt depending on your needs (mainly the voltage the main processor uses) but you can't wire 5Volt and 3.3Volt systems together without some extra logic (level shifters for the SDA and SCL lines).

ADW0720 ATtiny841 ADW0720 ATtiny841

To control the ADW0720 boards I developed a library with simple functions.
Every I2C device has an address in the range of 1 to 127 (decimal). The default address for the ADW0720 boards is 0x18 (24 decimal) but you can change this to whatever you want with the following code:

The second line stores this newAddress into EEPROM and from then on it is newAddress the address for this module.

By giving each ADW0720 board a unique address, you can control multiple ADW0720 boards using just the two I2C lines!

I have designed two types of ADW0720 boards that are ready to use. The Type-1 board has 4 tactile switches and 4 LEDs, the Type-2 board has 8 LEDs but no switches.

ADW0720 Type 1 (4 LEDs, 4 Switches) ADW0720 Type 1 (4 LEDs, 4 Switches)
ADW0720 Type-2 (8 LEDs, no Switches) ADW0720 Type-2 (8 LEDs, no Switches)

Instead of the LEDs, it is also possible to drive an N-channel MOSFET (such as the 2N7000 or 2N7002) as a switch to drive larger loads such as buzzers, relays or motors.

You can find the library and code for the ATtiny841-I2C slave at github. There you will also find the documentation for the library.

The library comes with two example sketches. The first is to show what the ADW0720 boards can do (show-of) and the second example (I2C_ADW0720_Configurator) shows the more advanced usage.

For example, with the second example you can set the function (input or output) of the Slots and you can set the I2C address of the ADW0720 so that you don't have to do that in your main program.

Schematic of the ADW0720 Type-1 board Schematic of the ADW0720 Type-1 board
ADW0720 Type-2 board ADW0720 Type-2 board
Helper functions from the library Helper functions from the library
Posted by Website Willem Aandewiel (1955) has a background in electronics and digital techniques. However, most of his working life he has worked in automation where he has worked in just about all disciplines from programmer to project leader and project manager. Willem was one of the first Dutchmen with a micro-computer (KIM-1, 1976) at a time when the PC had yet to be invented. Nowadays he is mainly concerned with the design and production of small electronic circuits with microprocessors. His 'mission in life' is to make people enthusiastic about making their own electronic circuits, microcomputers and programming.


The Netherlands Edwin vd Oetelaar
Hello Mr Willem, Wouldn't applying an MCP23017 16 bit IO expander with interrupt generation ... be more convenient in the projects than making a separate IO processor yourself? I am asking this because I am also birding myself. I want to equip an ESP32-S module with a series of thermocouple interfaces - a pair of 0-10V ADCs - and a row of logic inputs / outputs to do a project regarding the control of heat pumps (and also understand the behavior) It is to help this club I'm hoping on 2 thoughts, an ESP32 with everything via I2C bus or a separate AVR (eg an atmega2560) that handles all IO (and possibly realtime behavior) and with which I let the ESP32 talk via a serial protocol. Please your insights. Regards, Edwin van den Oetelaar
Placed on 
Hi Edwin, Such an I/O expander is also suitable, but it does not provide the extra options such as handling short, medium and long button presses or flashing LEDs without the intervention of your own code or after a specified time turn an LED off again. See:
Placed on 
Hello Mr. Willem, thank you for your feedback on this topic. I came to the same conclusion, both options are feasible. However, there is one thing that concerns me when using a firmware controlled IO processor. That is the fact that the firmware may have problems (bugs or otherwise). By updating the main firmware in the ESP32, I would also like to update and remove bugs in the entire system. Have you ever flashed from another master CPU the firmware of an AVR MCU that was already in circuit and deployed? An alternative approach I am considering is to use an FPGA for IO processing. The FPGA firmware (image) is provided by the main processor at system boot. This way, the firmware of the entire system can be updated while the system is in the field, without human intervention. Your thoughts and rich experience are highly welcomed. Kind regards, Edwin
Placed on 
Webwinkelkeur Kiyoh Trustpilot Opencircuit