olikraus / u8g2

U8glib library for monochrome displays, version 2
Other
4.91k stars 1.02k forks source link

u8g2 bus control and possible conflict #2419

Closed voipin closed 2 months ago

voipin commented 2 months ago

I have a project that uses a display screen and an external GPIO chip for input. I am using the u8g2 library and the pu2clr_pcf8574. I am using a pcf8574N in my board and a esp8266 MCU.

The sample code for input works perfectly I can detect input on my pins on the pcf. However if I try to run the screen at the same time with u8g2.begin() the inputs stop working. It doesn't matter if a screen is connected or not, once I invoke that begin method , the inputs no longer work. I think there is some sort of incompatibility with these libraries.

I don't want to have to rewrite my code base for a new display library if I don't have to, I may just be missing something. I read that the u8g2 lib handles external gpio so perhaps its overriding this communication somehow.

Just for sanity sake I leveraged the Adafruit_SSD1306 library and pu2clr_pcf8574 and it works fine. There is something I am not seeing I just don't quite know what it is.

Here is the code I have been using for testing, its not my project code but it is experiencing the same issues:

/**

include

//#include

include

include

PCF pcf; U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, U8X8_PIN_NONE); void u8g2_prepare() { u8g2.setFont(u8g2_font_helvB18_tf); u8g2.setFontRefHeightExtendedText(); u8g2.setDrawColor(1); u8g2.setFontPosTop(); u8g2.setFontDirection(0); } void setup() { Serial.begin(115200); // The baudrate of Serial monitor is set in 9600 while (!Serial); // Waiting for Serial Monitor

u8g2.begin();

Wire.begin();           // Initiate the Wire library and join the I2C bus as a master

pcf.setup(0x20);        // The PCF8574 is configured to 0x20 I2C address. Check A0, A1 and A2 pins of the device.
pcf.write(0B11111111);  // Turns all pins/ports HIGH

Serial.print("\nPress a button or make one of the ports 4, 5, 6 or 7 LOW (GND) v1\n"); 

}

void loop() { // pulling the PCF8574 ports for (uint8_t i = 4; i < 8; i++ ) { if ( pcf.digitalRead(i) == LOW) { Serial.print("\nThe port "); Serial.print(i); Serial.print(" is LOW (button pressed)"); delay(300); // Taking a little time to allow you to release the button } } }

EDIT: further troubleshooting indicates that pin 7 on he 8574 is active with u8g2 enabled, but that is the only one.

olikraus commented 2 months ago

U8g2 will change I2C for max speed, however if there is another I2C device on the same bus (like your port expander) , then the other device may not work any more. For this reason, u8g2 supports to reduce the I2C bus clock to the lowest speed supported by all of the i2c devices: https://github.com/olikraus/u8g2/wiki/u8g2reference#setbusclock

voipin commented 2 months ago

You are exactly correct, outstanding. I had discovered this using a logic analyzer. I saw when it was working it was operating at 100khz, where as when u8g2.begin() was called the period was 450khz. I manually set the clock and all works as expected. I really appreciate it!