The datasheet (https://www.ti.com/lit/ds/symlink/pcf8574.pdf) first shows the package pinout (in one of 4 different versions)
And then in chapter 8.3 and 8.4, it shows how an I2C write operation is used to set the values of the output pins P7…P0.
In other words, doing an I2C write operation on the devices’s address followed by one byte (8 bits) will set the 8 output pins P7…P0 to that sent one byte. That can also be seen in Arduino library code.
So now that PCF8574 expander’s data bus (P7…P0) is in some way connected the LCD screen.
I’m taking this module as an example of how it’s connected to an LCD now.
As you can see in this reference diagram (that they say is the intended usage of the module), the LED+ of the LCD is conncted to VCC (+5V/+3.3V). The backlight is turned on when current flows from LED+ through LED-, so, LED- has to be put to GND. The LED- can be switched to GND via the BJT NPN transistor, whose base pin is connected to the “BT” pin, which is in turn “P3” of the I2C expander. So with these connections between the expander and the backlight it is clear that we need to send set P3 to “1” / HIGH to activate the transistor to turn on the backlight and “0” respectively to turn it off.
Thus in that configuration we would need the on/off commands to be
uint8_t offCmd[1] = {0x00};
uint8_t onCmd[1] = {(uint8_t)(1 << 3)}; /* for P3. equivalent 0x08 */
(I’ve taken the liberty to correct the types to unsigned 8-bit).
This pin mapping is further confirmed in the PDF by the given Arduino example code. The constructor to the LiquidCrystal_I2C
object gives the pin mapping from the I2C expander to the LCD pins.
And there you can see again that P3 maps to the backlight, and has polarity “POSITIVE”, aka a HIGH on P3 will make it turn on.
You can also begin to see a thing with mbed-os: Libraries are a bit few and sparse and vary in code quality, especially user code from https://os.mbed.com/ – often times pins are just hardcoded, e.g…
In this case however there are libraries available. In fact, a port of LiquidCrystal_I2C, to be exact: PlatformIO Registry (with mbed-os example: LiquidCrystalIO/examples/helloMbed/helloMbed.cpp at master · davetcc/LiquidCrystalIO · GitHub). In this case howeever, the library and its dependencies are so big that it does not compile for disco_f051r8
– by 504 bytes in RAM usage. I’ve uploaded that reference project for the above board and for the larger chip on the Nucleo L476RG here: GitHub - maxgerhardt/pio-mbed-i2c-lcd-example: An PlatformIO compilable example for mbed-os and an LCD display connected to an I2C expander.
Thus another lesson with mbed-os is: most cases, compiling for mbed-os takes more Flash and RAM than Arduino. And that’s bad for small microcontrollers.
Another library might be small enough to fit: LiquidCrystal_I2C - Port of the Arduino library with the same library… | Mbed. That is compilable: GitHub - maxgerhardt/pio-mbed-i2c-lcd-example-f051: PlatformIO compilable example for the disco_f051r8 board and I2C LCD display
But gets the chip to its limits.
Checking size .pio\build\disco_f051r8\firmware.elf
Advanced Memory Usage is available via "PlatformIO Home > Project Inspect"
RAM: [==== ] 43.8% (used 3592 bytes from 8192 bytes)
Flash: [========= ] 92.9% (used 60868 bytes from 65536 bytes)
Size constraints are a major caveat with mbed-os… Looking back I should have looked at your chip more closely and said that with 64KByte flash and 8Kbyte of RAM, mbed-os will run into limitations extremely fast – maybe an addition to the Arduino core will be much better, if done correctly