logo elektroda
logo elektroda
X
logo elektroda

PCF8574 port expander module - PlatformIO tutorial - Arduino/ESP/itd pin expansion

p.kaczmarek2 2754 11

TL;DR

  • PCF8574 I/O expander module drives up to eight configurable GPIOs over I2C, with optional interrupt output, shown on a NodeMCU/ESP8266 in PlatformIO.
  • The setup uses an I2C scanner, the Renzo Mischianti PCF8574 library, and simple pinMode/digitalWrite/digitalRead calls on the PCF8574 object instead of global Arduino functions.
  • A single chip uses only two I2C signals, and eight expanders on one bus provide 64 pins, or 128 with the alternate-address version.
  • Blink, binary countdown, button input, and INT-driven interrupt examples all work, including a button tied to ground without an external pull-up resistor.
  • One limitation appears when digitalWriteAllBytes is private; the article notes PCF8574_LOW_MEMORY may expose a byte-based write path.
Generated by the language model.
ADVERTISEMENT
Treść została przetłumaczona polish » english Zobacz oryginalną wersję tematu
📢 Listen (AI):
  • Several PCF8574 modules with exposed goldpins .
    Here I will present a simple to use module to get additional I/O ports. One PCF8574 is controlled by only two signals, and gives us as many as 8 configurable I/Os together with an additional optional interrupt signal. What's more, two pins can drive as many as eight PCF8574s simultaneously, giving us a total of 64 pins, and combined with the alternate address version up to 128 pins! It is also worth knowing that nothing prevents other devices, such as sensors or there RTC clock, from being connected together with the PCF8574 on the I2C bus ... but one step at a time.

    The PCF8574 is a so-called IO expander, i.e. a circuit which, when suitably controlled, allows us to obtain additional input/output pins in our project. Specifically, the PCF8574 is controlled via the I2C bus, which is a bus based on two signals (clock and data) and allows us to handle multiple devices simultaneously - multiple chips can be connected to a single I2C line, as long as their addresses do not collide.
    The PCF operates at 2.5 V to 6 V, so there should be no problems running it with either the classic Arduino or the ESP8266.
    Consider the leads of the PCF8574:
    PCF8574 schematic with I2C bus. .
    SDA and SCL are the mandatory I2C lines, this is what we control this chip with. P0-P7 are the legs of the circuit we control, they can be in the role of digital inputs and outputs. Pins A0, A1, A2 allow us to change the address of a given PCF piece, so we can connect more of them on one bus:
    I2C address table for PCF8574 with inputs A2, A1, A0 settings. .
    The PCF offers four GPIO modes of operation:
    Description of four port operation modes in PCF8574. .
    For more advanced users, it is also useful to provide a more detailed schematic, which also takes into account the line pull-up resistors from I2C:
    Diagram of PCF8574 application with connected resistors and devices. .
    Out of curiosity, I should add that the catalogue note also proposes a PCB layout for the expander:
    PCF8574 connection schematic .
    Here, however, I will use a ready-made module, which will simplify everything considerably.


    Module PCF8574 .
    The commercially available PCF8574 module outputs all its legs on goldpins, which relieves us of the need to solder. All IO, interrupt output, address pins and the I2C bus are routed out - and on both sides. The aforementioned pull-up resistors are also on board.
    Several PCF8574 modules with exposed goldpins .
    PCF8574 modules with yellow connectors on a white background .
    PCF8574 modules on prototype boards. .
    You can get the module for a few zlotys. By importing from abroad you can even get 5 pieces for 10-20 PLN, depending on the promotion.
    Image of five PCF8574 modules on a white background. .
    Set of PCF8574 modules packed in transparent plastic bags. .


    Demonstration platform .
    As a rule, I've done this type of demonstration on an Arduino, but this time I was tempted to use a NodeMCU with an ESP8266. It will come out almost the same anyway, but in my opinion PlatformIO is a bit more convenient than the Arduino IDE, and knowledge of Visual Code is also useful for other languages. Recall the topic where I already presented PlatformIO:
    Clock on ESP12 and MAX7219 display - tutorial - part 1, ArduinoOTA, basics .
    How to program a Wemos D1 (ESP8266) board in the shape of an Arduino? ArduinoOTA in PlatformIO
    Plate used:
    ESP8266 module connected to a breadboard. .


    I2C scan .
    Using the expander is very straightforward, but users often get lost through the I2C addresses. For this reason I always suggest running an I2C scanner to start with. This simple program will verify our connections and display the I2C addresses of the devices connected to the bus. This will tell us if at least hardware-wise the situation is ok, as it is easy to swap SCL with SDA or connect something wrong....
    Here is my connection:
    PCF8574 module with connected wires. .
    Well, and the aforementioned scanner:
    Code: C / C++
    Log in, to see the code
    .
    It works, the layout address is seen:
    Screenshot of a terminal showing I2C scan results. .
    Now the same thing, but for five expanders with different addresses. The connection is trivial:
    Image of eight PCF8574 modules connected in series. .
    Result:
    
    Scanning...
    I2C device found at address 0x20
    I2C device found at address 0x21
    I2C device found at address 0x22
    I2C device found at address 0x24
    I2C device found at address 0x26
    
    .
    All expanders are seen.





    Add the PCF8574 library .
    I've discussed adding a library in PlatformIO before, but basically it's done via Libraries, just click through. Type PCF8574 in the search engine and add preferably the same result as in my screenshot (by Renzo Mischianti):
    Screenshot from PlatformIO showing the PCF8574 library by Renzo Mischianti. .
    The search engine can also show beforehand a library from a 2x16 LCD controlled by the PCF8574, but we care about the PCF8574 control itself. We will run the LCD another time.
    You can see examples of the library when adding it, but I've also put together some simplified demonstrations myself below.





    Blink .
    The library I propose (by Renzo Mischianti) is characterised by a syntax that is deceptively reminiscent of Arduino pins, i.e. we still have here our famous pinMode, digitalWrite and digitalRead, only that not as global functions, but on an object of the PCF8574 class. To instantiate the PCF8574 we use the constructor, which in my example takes the I2C address of the device and the SDA and SCL pins as arguments:
    Code: C / C++
    Log in, to see the code
    .
    Running the PCF, it will tell us if we have connected it correctly and if the address matches:
    Code: C / C++
    Log in, to see the code
    .
    Setting the mode of operation of the pin looks like I mentioned earlier:
    Code: C / C++
    Log in, to see the code
    .
    Similarly setting the value on the output:
    Code: C / C++
    Log in, to see the code
    .
    Full code:
    Code: C / C++
    Log in, to see the code
    .
    Rather nothing to comment on here, the diode simply blinks:


    .
    Obviously the diode connected with a resistor - I gave about 300 ohms to avoid burning the diode.



    Binary countdown .
    Now let's flick all the LEDs. It's probably not necessary, but I was tempted to fire off some simple animation this way. Let's do a binary countdown.
    This is where the first hiccup occurred, because I thought I would expose a byte to the IO pins as I would normally do on a microcontroller, but the function of the PCF8574 class is private....
    
    src\main.cpp: In function 'void loop()':
    src\main.cpp:29:33: error: 'bool PCF8574::digitalWriteAllBytes(byte)' is private within this context
       29 |   pcf8574.digitalWriteAllBytes(x);
    
    .
    Finally, I used the digitalWrite call in the loop... but I leave that to your own interpretation.
    Code: C / C++
    Log in, to see the code
    .
    Works:



    PS: Now I see that defining PCF8574_LOW_MEMORY would maybe help and expose a function that accepts a byte, I leave that for you to try out.

    Button .
    Since there was digitalWrite, we also have digitalRead. What's more, we don't have to connect the pull-up resistor ourselves, because the circuit itself "pulls" the inputs to the logic 1 potential. We can only short them to ground (e.g. with a button) and then we get a low state on it. In this way, we do not need to connect a resistor ourselves.
    Datasheet excerpt describing the reset and initialization of I/Os with an internal current source. .
    So I have connected:
    - a button between GPIO and ground
    - additionally, just for visualisation, an LED on the second GPIO together with a resistor of a few hundred ohms
    Running the pins:
    Code: C / C++
    Log in, to see the code

    Looping, reading the GPIO, writing out to the console (on the UART), and setting the second pin:
    Code: C / C++
    Log in, to see the code
    .
    It works, except that a button released here means state 1, so the LED is on, and a button pressed is state 0 - LED off.


    .


    Button and interrupt .
    What remains to be discussed is the INT pin from the PCF8574. This pin will show a falling edge when something on the input of the PCF8574 changes. This can be used in conjunction with a GPIO interrupt on our NodeMCU to get information that something has happened at the PCF8574, for example someone has pressed a button.
    So we connect INT to, say, GPIO5. Now the interrupt needs to be triggered:
    Code: C / C++
    Log in, to see the code
    .
    The interruptHandler function will call when there is a falling edge (FALLING) on D5:
    Code: C / C++
    Log in, to see the code
    .
    Here, for demonstration purposes, I'm just setting a variable, which I then use to check in the main loop whether the PCF pins need to be read again.
    Code: C / C++
    Log in, to see the code
    .
    The operation is quite similar to the previous example, except that the loop only checks the state of the pins when an interrupt is received.

    More pins can be handled this way - here is an example from the documentation of the library used:
    Code: C / C++
    Log in, to see the code
    .
    This relieves us from having to do a digitalReadAll scan every refresh.

    Can even more outputs/inputs be connected? .
    A version of the chip with different addressing is also available on the market, giving us a total of 128 controlled pins:
    Information about I/O expanders PCF8574 and PCF8574A. .


    Summary .
    A useful and easy to use module. Everything you need is brought out on the goldpins, and also the address selection is quite wide. With 8 pieces you can drive the whole 64 receivers, will anyone need more?
    It's also worth mentioning that the module shown here can do a lot more - there's even an encoder demo in the library used, but I didn't have any on hand to try it out today:
    Spoiler:
    Code: C / C++
    Log in, to see the code
    .
    But even without this, I can conclude that it is a very useful arrangement. What do you think? Have you used the PCF8574 in your projects and if so for what? .

    Cool? Ranking DIY
    Helpful post? Buy me a coffee.
    About Author
    p.kaczmarek2
    Moderator Smart Home
    Offline 
    p.kaczmarek2 wrote 14393 posts with rating 12314, helped 650 times. Been with us since 2014 year.
  • ADVERTISEMENT
  • #2 21398046
    _ACeK_
    Level 14  
    Posts: 149
    Help: 5
    Rate: 140
    Board Language: polish
    :) Many years ago tasha developed a very cool ⇨ LXT chip ⇦ I even have a slightly modified board for it ;) .

    Diagram of an LXT electronic circuit with colored paths.
  • ADVERTISEMENT
  • #3 21398168
    p.kaczmarek2
    Moderator Smart Home
    Posts: 14393
    Help: 650
    Rate: 12314
    Nice project, a pure classic. I opened the attachment and see files dated 2004:
    List of source files in ZIP file management software. .
    Still that MAX232... I remember running the MAX232 back in my school days and being surprised by this electrolytic capacitor connection, which is deliberately reversed in polarity. At the time I thought that I might still use RS232 in this form, but since then I have only been riding on USB<->UART converters.

    I myself once did a project based on MCP23017, there are 16 pins there, but the rest is quite similar to PCF:
    Circuit board with relays and wiring. .
    This is the expansion board for:
    Home Assistant/Tasmota HTTP compatible relay controller + housing .
    Helpful post? Buy me a coffee.
  • #4 21398236
    _ACeK_
    Level 14  
    Posts: 149
    Help: 5
    Rate: 140
    Board Language: polish
    :) I didn't want to give the exact date because women generally don't like the subject of age being brought up ;)

    As it happens, that I'm going to do this layout in a few days :) My version will be SMD . with a choice between MAX3232 and USB ;) .

    Here the almost finished board ⇓

    Image showing a printed circuit board design with colorful traces.
    .
    PCB with electronic components on a colorful background.
    .

    Collected parts and board ⇑ ;) .
  • ADVERTISEMENT
  • #5 21398387
    p.kaczmarek2
    Moderator Smart Home
    Posts: 14393
    Help: 650
    Rate: 12314
    What method are you using to make the PCB and how do you ultimately want to organise the LEDs? As far as I can see the original design is a bit lacking in some final effect already, where the LEDs are actually somehow arranged in the title "christmas tree", I don't know, on some mini-tree :D .

    Although nowadays it's probably simpler to go for WS2812 and the cheapest MCU anyway, maybe I'll do some project where I'll try to drive it with PIC12F. The PCF8574 I would already see more with relays:
    Set of relay modules of various sizes on a white background. .
    Helpful post? Buy me a coffee.
  • #6 21398560
    _ACeK_
    Level 14  
    Posts: 149
    Help: 5
    Rate: 140
    Board Language: polish
    :) I draw in Illustrator. Then I heat-transfer as shown in the photo ⇓

    The process of producing electronic boards using the iron-on transfer method.
    .
    Breadboard prototype with a 7-segment display and marked I2C pins.
    .

    The layout will be the layout itself for the time being :) The display as in the picture marked with ellipsis ⇑ I have pins I2C , so I can easily view what is happening on the bus ;) .
  • #7 21398585
    kulmar
    Level 33  
    Posts: 1897
    Help: 184
    Rate: 368
    Board Language: polish
    In my opinion, these expanders are form over substance - I usually use sliding registers to expand I/O.
  • ADVERTISEMENT
  • #8 21398636
    Anonymous
    Level 1  
  • #9 21398678
    kulmar
    Level 33  
    Posts: 1897
    Help: 184
    Rate: 368
    Board Language: polish
    And I don't switch - I use both types simultaneously (if I need it). And for typical applications like display control the 75HC595 is not needed. A 74HC164 is enough.
  • #10 21399517
    Karol966
    Level 31  
    Posts: 2035
    Help: 83
    Rate: 645
    Board Language: polish
    khoam wrote:
    Typical shift registers (like 74HC595) only support outputs,
    .
    Well, but you can with an extra pin and together with the use of the cheapest diodes also realise a keyboard with outputs. On the x164 I did such a thing. To operate the keyboard, similar to a matrix keyboard, you sent one state (0/1 depending on the concept) and searched on which position the keyboard output has this, searched state.
    Registers such as the 595 have the advantage that they can also be connected to hardware SPI. For simple applications, such as displaying the status of LEDs or generally controlling unimportant outputs, such sliding registers as the 595/164 are OK, the price is small, so it's worth it. For more restrictive applications, I personally use integrated expanders. The PCF857x is such a dinosaur so I definitely prefer the MCP23017. Unfortunately, more and more often I wonder whether "it made sense", because adding little to the price of the processor I buy one with more IO and the expander becomes unnecessary.

    Only then the board is so poor, not much happens on it :D .
  • #11 21429567
    Mocny Amper
    Level 11  
    Posts: 86
    Rate: 18
    Board Language: polish
    The PCF8574 is also quite slow, supposedly it can get a max clock of 100kHz, but I'm using it in a project where I2C goes to 200kHz, and it works flawlessly, but a slight concern I have.
    Well, and the current capacity of the GPIO expander in the high state is lousy, you have to control "zero".
    And it would also be useful to have PWM, which is not available.
  • #12 21432429
    KarolGT
    Level 10  
    Posts: 38
    Rate: 3
    Board Language: polish
    Which expander is better, more stable?
    PCF8574 or mcp23017 ?

    or perhaps another, preferably on 16 pins?

    Added after 1 [minute]: .

    Karol966 wrote:
    For more restrictive ones I personally use already integrated expanders. Akurat PCF857x is such a dinosaur so I definitely prefer MCP23017. Unfortunately, more and more often I wonder whether "it made sense", because adding little to the price of the processor I buy one with more IO and the expander becomes unnecessary.
    .
    Can you elaborate? which integrated expanders?
    and which processor are you talking about with more IO instead of an expander?
📢 Listen (AI):

Topic summary

✨ The discussion revolves around the PCF8574 I/O expander module, which allows for the expansion of input/output ports via the I2C bus. Users share experiences and projects involving the PCF8574, comparing it with other expanders like the MCP23017 and sliding registers such as the 74HC595 and 74HC165. Concerns are raised about the limitations of the PCF8574, including its interrupt handling, speed (max 100kHz), and current capacity. Alternatives for specific applications, such as using integrated microcontrollers with more I/O pins, are also considered. The conversation highlights various project implementations and PCB design methods, emphasizing the versatility and challenges of using I/O expanders in electronic projects.
Generated by the language model.

FAQ

TL;DR: One PCF8574 uses 2 I2C wires to add 8 GPIO, and “a useful and easy to use module” fits Arduino, ESP8266, and PlatformIO users who need cheap pin expansion for LEDs, buttons, and interrupt-driven inputs without redesigning a board. [#21397809]

Why it matters: It expands small boards fast, keeps wiring simple, and scales from one module to multi-device I2C setups.

Option Pins discussed in thread Direction Interrupt notes Noted trade-off
PCF8574 8 per chip Configurable I/O One INT, no per-pin masking mentioned Weak HIGH drive, no PWM
MCP23017 16 per chip Configurable I/O Preferred in thread for richer interrupt use Higher feature level, more than basic needs
74HC595 / 74HC164 Output expansion Output only in cited discussion None discussed Good for simple LEDs/displays
74HC165 Input expansion Input only None discussed Needs pairing for mixed I/O

Key insight: Choose PCF8574 when you want the fewest wires and simple digital I/O. Choose MCP23017 or a larger MCU when you need finer interrupt control, 16 pins, or more headroom.

Quick Facts

  • PCF8574 works from 2.5 V to 6 V, so the thread author uses it with both classic Arduino boards and ESP8266 modules. [#21397809]
  • One chip gives 8 configurable I/O, uses 2 I2C signals plus optional INT, and up to 8 chips can share the bus for 64 pins total. [#21397809]
  • Using the alternate-address version discussed in the thread raises the practical total to 128 controlled pins on the same concept. [#21397809]
  • Ready-made modules were described as costing roughly 10–20 PLN for 5 pieces, with pull-up resistors and both-side goldpin breakouts already onboard. [#21397809]
  • Real-project limits called out by users were 100 kHz rated I2C, operation observed at 200 kHz, weak sourcing in HIGH state, and no PWM. [#21429567]

What is a PCF8574 I2C port expander, and how does it add extra GPIO pins to an Arduino or ESP8266 project?

A PCF8574 is an I/O expander that adds 8 configurable digital pins over the 2-wire I2C bus. “IO expander” is a control IC that adds extra input/output lines, using a serial bus instead of many direct MCU pins. Its key trait here is 8 GPIO from one addressed chip over SDA and SCL. In the thread, one chip uses SDA and SCL for control, exposes P0-P7 as digital inputs or outputs, and can run from 2.5 V to 6 V, which suits Arduino and ESP8266 boards. [#21397809]

How do I connect a PCF8574 module to a NodeMCU ESP8266 and run an I2C scanner in PlatformIO to find its address?

Connect SDA to D2/GPIO4, SCL to D3/GPIO0, plus power and ground, then scan addresses 1 to 126. In the shown PlatformIO example, Wire.begin(4, 0) sets those ESP8266 pins, and the scanner prints any responding address as 0x20, 0x21, and so on.
  1. Wire SDA, SCL, VCC, and GND.
  2. Start I2C with Wire.begin(4, 0) and open Serial at 115200.
  3. Loop through addresses and print every device that returns error == 0.
The author’s first module appeared at 0x20. [#21397809]

Why is my PCF8574 not showing up in the I2C scan, and what wiring mistakes with SDA, SCL, power, or address pins should I check first?

Most failures come from wrong SDA/SCL wiring, bad power, or an unexpected address setting. The thread explicitly warns that users often swap SCL with SDA or wire something incorrectly, so the I2C scanner is the first hardware check. Verify VCC and GND, confirm SDA and SCL go to the intended ESP8266 pins, and make sure A0, A1, and A2 match the address you expect. In the working example, five modules appeared at 0x20, 0x21, 0x22, 0x24, and 0x26, which proves address wiring directly changes scan results. [#21397809]

How do I set the A0, A1, and A2 address pins on the PCF8574 so I can use multiple expanders on one I2C bus?

Set A0, A1, and A2 to different logic states so each chip gets a unique I2C address. The thread explains that these three pins change the address, allowing up to 8 PCF8574 chips on one bus without collisions. In the demonstrated multi-device scan, five expanders were detected at 0x20, 0x21, 0x22, 0x24, and 0x26, showing that not every address must be consecutive. If two modules share the same A0-A2 pattern, the bus will not distinguish them cleanly. [#21397809]

What is the INT pin on the PCF8574, and how does interrupt handling work on an ESP8266 when an input changes?

The INT pin signals that an input state changed, and the ESP8266 can catch that with a GPIO interrupt. “INT pin” is an interrupt output that alerts the microcontroller to an input event, reducing constant polling and letting firmware read the expander only after a state change occurs. In the example, INT goes to ESP8266 D5/GPIO5, the code sets pinMode(D5, INPUT_PULLUP), and attachInterrupt(..., FALLING) flips a volatile bool flag. The main loop then reads P0 only after that flag becomes true. [#21397809]

Why does a button connected to a PCF8574 with INPUT_PULLUP read LOW when pressed and HIGH when released?

It reads LOW when pressed because the input is internally pulled up and the button shorts it to ground. The thread states you can use INPUT_PULLUP, skip an external pull-up resistor, and wire the button between the GPIO and ground. In that arrangement, released means logic 1, so the LED in the example stays on, while pressed means logic 0, so the LED turns off. The demo reads the button on P0, mirrors the state to P1, and delays 100 ms between checks. [#21397809]

How can I blink an LED from a PCF8574 output using the Renzo Mischianti PCF8574 library in PlatformIO?

Create a PCF8574 object, set one pin as OUTPUT, call begin(), and toggle it with digitalWrite(). The thread uses Renzo Mischianti’s library, creates PCF8574 pcf8574(0x20, 4, 0);, sets P0 to OUTPUT, and then writes HIGH and LOW every 1000 ms. The author also notes using an LED with about 300 ohms series resistance to avoid damage. If begin() prints OK, the address and wiring are correct enough for the blink test. [#21397809]

What does the I2C pull-up resistor do, and when can I rely on the pull-ups already built into a PCF8574 module?

The I2C pull-up resistor holds SDA and SCL high so open-drain bus signals can switch cleanly. The thread includes a schematic that explicitly shows the I2C pull-ups and then notes that the ready-made PCF8574 module already has those resistors on board. That means you can often rely on the module’s built-in pull-ups in a simple single-bus setup, especially when using the exact board shown. Still, the author recommends scanning first, because a working scan confirms the bus is electrically correct. [#21397809]

Why does digitalWriteAllBytes() appear private in the PCF8574 library, and what is the practical way to write all 8 outputs at once?

It appears private because the used library does not expose that method in the default way shown by the compiler error. The thread shows the exact error for digitalWriteAllBytes(byte) and then solves the task by looping from i = 0 to 7 and calling digitalWrite(i, ...) for each bit. That practical workaround successfully runs an 8-LED binary count from 0 to 255. The author also notes that defining PCF8574_LOW_MEMORY may expose a byte-based function, but leaves it as a try-it-yourself option. [#21397809]

PCF8574 vs MCP23017 — which expander is better for stability, interrupts, speed, and 16-pin applications?

MCP23017 is the better fit when you need 16 pins, finer interrupt behavior, or a less limited feature set. In the discussion, users call PCF857x “such a dinosaur,” prefer MCP23017 for more restrictive applications, and point out that PCF8574 interrupts trigger on any state change with no per-pin mask. Another user also flags PCF8574 as rated around 100 kHz, with weak HIGH-state current and no PWM. PCF8574 still wins for simple, low-wire, 8-pin jobs where cost and simplicity matter more than advanced control. [#21398636]

When does it make more sense to use shift registers like 74HC595, 74HC165, or 74HC164 instead of a PCF8574 GPIO expander?

Use shift registers when the job is fixed-direction and simple, such as LEDs, displays, or basic scanned inputs. The thread says 74HC595 and 74HC164 are fine for simple outputs, while 74HC165 handles inputs; one user also praises hardware SPI compatibility for 595-style parts. Their weakness is mode flexibility: cited users note typical shift registers do not switch easily between input and output roles. If you need mixed-direction GPIO, button interrupts, or one chip that handles both input and output pins, PCF8574 or MCP23017 fits better. [#21399517]

How many total pins can I expand with PCF8574 devices on one I2C bus, and how does the alternate address version increase that limit?

You can expand to 64 pins with 8 standard PCF8574 chips, and to 128 pins when you add the alternate-address version discussed in the thread. Each chip contributes 8 configurable I/O, and all share the same 2-wire I2C bus as long as their addresses do not collide. The author states that two controller pins can handle up to 8 PCF8574s simultaneously, then doubles that total by combining them with the alternate address variant. That scaling is the main reason the part stays useful for relay banks and larger button or LED groups. [#21397809]

What are integrated GPIO expanders, and which ones are good alternatives if I need more features than the PCF8574 offers?

Integrated GPIO expanders are dedicated chips that add extra digital I/O without replacing the main microcontroller. In this thread, MCP23017 is the clearest alternative: it offers 16 pins, was used in a Home Assistant/Tasmota relay expansion board, and is repeatedly preferred over PCF8574 for stricter applications. The practical reason is feature depth, not just pin count. Commenters specifically criticize PCF8574 for coarse interrupt behavior, limited speed expectations, weak sourcing, and no PWM, which makes MCP23017 the stronger next step when those limits matter. [#21398168]

Which microcontrollers are worth choosing with more built-in GPIO instead of adding an external expander like PCF8574 or MCP23017?

Choose a larger MCU when adding the expander costs nearly as much as moving up to a pin-richer controller. The thread does not name a specific replacement family, but one commenter states that “adding little to the price of the processor” can buy a microcontroller with more I/O, making the expander unnecessary. That advice fits best when the board is still early in design and you control the MCU choice. If your PCB is fixed or you already use I2C heavily, an expander remains the faster retrofit. [#21399517]

What limitations of the PCF8574 should I watch for in real projects, such as weak sourcing current in HIGH state, 100 kHz I2C rating, and lack of PWM?

Watch three limits first: weak HIGH-state drive, conservative I2C speed expectations, and no hardware PWM. A user reports the chip is “supposedly” rated for a maximum 100 kHz clock, though their project runs it at 200 kHz without issues. The same post warns that output current in the HIGH state is poor, so designs should prefer sinking current, or “control zero,” rather than sourcing strongly. Another practical limit is no PWM support, which makes direct dimming or proportional control a bad fit. [#21429567]
Generated by the language model.
ADVERTISEMENT