Programming External Expander cards

I have a project I am developing that includes a UnoR3 and eight (8) pcf8574 boards. I have them all connected and the Uno is recognizing them all with addresses 0x20 thru 0x27.
So far so good.

I am building a midi interface with an organ and each pin on each expander will operate a different organ pipe via a relay and a solenoid.

My question is how do I refer to these pins? How do I set pinmode on a specific pin on 0x24? Once I know how to refer to each of the 64 pins (8 pins x 8 expanders) I can map the midi notes to a particular pin.

I hope this makes sense.
Thank you, Michael

The outputs of the pcf8574 quasi-bidirectional; the pins are always input AND output.

I suggest that you install a PCF8754 library and check the examples. The easiest way to have some form of pin numbers is to create an array of PCF8574 objects and a function that takes a pin number, selects the correct expander in the array based on that pin number and write or reads the specific pin on that expander.

Be aware that the PCF8574 absolutely can not drive a solenoid.

1 Like

PinMode is not valid for the PCF8574 and similar devices. Some libraries can implement this functionality, but I handle it by setting all pins to 1 essentially writing 0xFF to the data port. When a switch closes (pulled up and switched to ground), the corresponding bit goes to zero. You can invert the read operation to interpret a closed switch as a 1.

Regarding the libraries, I don’t use them myself.

You can label the pins however you like; it’s entirely up to how you define them in your code.

three are 16 bits per chip.

  • 0-15 on chip 1
  • 16-31 on chip 2
  • ...
bool
i2cReadBit (
    byte    adr )
{
    if (0 == nChip)
        return digitalRead (adr);

    byte bit  = 1 << (adr & 7);
    byte chip = adr >> 4;

    byte port = adr & 0x8 ? GPIOB : GPIOA;

#if 0
    printf ("  %s: adr %2d, chip %d, bit 0x%02x, port 0x%02x, val 0x%02x\n",
            __func__, adr, chip, bit, port, bit&port);
#endif

    return bit & i2cRead (chip, port);
}

Yes. Keep in mind that this permanent dual I/O purpose, in the case of the PCT8574, means the output can only sink significant current, so LEDs for example need to be wired between the pin and Vcc, with appropriate series current limiting resistor. LOW (writing zero to the pin) would illuminate the LED.

And very definitely do not wire a switch in a pulled down fashion and expect the output to be able to go high when the switch closes. More likely something bad would happen.

An output that can only sink current is not so bad, usually one can work with that, you just need to know that's what you dealing with.

a7

You can consider using GitHub Rob Tillaart's PCF8574 library to simplify interactions with the PCF8574 expansion boards. This library provides easy control over the 8 pins of the PCF8574 and PCF8574A chips, allowing for convenient read and write operations.
The documentation mentions that the address range for the PCF8574 is from 0x20 to 0x27, which matches the addresses you are using for your devices, ensuring that you can communicate correctly with each expansion board. Additionally, the documentation includes example code that demonstrates how to perform basic operations such as setting and reading pin states. These examples can help you understand how to implement MIDI note mapping in your project.
don't know why I can't include the link, you can just look it up yourself.