Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Font not initialized when accessing an instance via a pointer? #20

Closed
PaulZC opened this issue Mar 19, 2024 · 8 comments
Closed

Font not initialized when accessing an instance via a pointer? #20

PaulZC opened this issue Mar 19, 2024 · 8 comments

Comments

@PaulZC
Copy link
Contributor

PaulZC commented Mar 19, 2024

This is a fun one...!

#include <SparkFun_Qwiic_OLED.h> //http://librarymanager/All#SparkFun_Qwiic_OLED

QwiicMicroOLED *myOLED;

void setup()
{
    delay(1000);
    
    Serial.begin(115200);
    Serial.println("Running OLED example");

    Wire.begin();

    myOLED = new QwiicMicroOLED;

    if (myOLED->begin() == false)
    {
        Serial.println("Device begin failed. Freezing...");
        while (true)
            ;
    }
    Serial.println("Begin success");
}

void loop()
{
}

causes ESP32 to explode at this line.

My TemplateFu is not strong enough to understand why... But I think it has something to do with the QwFont or QwGrBufferDevice m_currentFont not being initialized properly? I think ->height is possibly returning nullptr?

@PaulZC
Copy link
Contributor Author

PaulZC commented Mar 19, 2024

My code example was missing Wire.begin(); . Added. Code is still failing in the same place. And I'm seeing failures on other platforms too, so I don't think this is ESP32-specific.

@PaulZC
Copy link
Contributor Author

PaulZC commented Mar 19, 2024

Humm. The more I play with this, the more I think something just isn't getting constructed or initiated correctly when using a pointer and new... Beyond my pay grade! ;-)

@gigapod
Copy link
Member

gigapod commented Mar 19, 2024

On class QwGrBufferDevice, the constructor that had the (x, y, w, h) parameters wasn't calling the default constructor - which initialized m_currentFont to nullptr.

This worked when using a global/stack variable - since memory is probably zeroed in this case, but when alloc'd from the heap, memory is what it is - so m_currentFont was garbage - thus the font class variable looked valid, but it was not.

This is fixed - my mistake from the beginning...

-K

@gigapod gigapod closed this as completed Mar 19, 2024
@PaulZC
Copy link
Contributor Author

PaulZC commented Mar 19, 2024

Thanks for the fast fix @gigapod ! Much appreciated. But sadly we're not out of the woods yet...

If I add myOLED->display(); it blows up again. I'm having trouble finding out exactly where.

I'll dig into this in the morning...

#include <SparkFun_Qwiic_OLED.h> //http://librarymanager/All#SparkFun_Qwiic_OLED

QwiicMicroOLED *myOLED;

void setup()
{
    delay(1000);
    
    Serial.begin(115200);
    Serial.println("Running OLED example");

    Wire.begin();

    myOLED = new QwiicMicroOLED;

    if (myOLED->begin() == false)
    {
        Serial.println("Device begin failed. Freezing...");
        while (true)
            ;
    }
    Serial.println("Begin success");

    myOLED->display();
}

void loop()
{
}

@gigapod
Copy link
Member

gigapod commented Mar 19, 2024

ahh heck ... standby ...

@gigapod
Copy link
Member

gigapod commented Mar 19, 2024

Similar issue with the grssd1306 driver - bad logic with instance variable initialization. I really had my head wrong on constructor chaining when implementing this. Fixed!! and version of library bumped

@PaulZC
Copy link
Contributor Author

PaulZC commented Mar 20, 2024

Oh, that is SO much better! It makes the following possible. Thanks!!

// This demo shows how to use the QwiicCustomOLED class,
// allowing the display width, height etc. to be set manually.
// It also shows how to use pointers to the OLED object and the I2C port.

#include <SparkFun_Qwiic_OLED.h> //http://librarymanager/All#SparkFun_Qwiic_OLED

QwiicCustomOLED *myOLED = nullptr;

TwoWire *I2C_0 = nullptr; // Note: do not use the name I2C0. It causes much badness on ESP32!
TwoWire *I2C_Display = nullptr; // If we have two I2C busses, we can point I2C_Display at either one. Handy!

void setup()
{
    delay(1000);
    
    Serial.begin(115200);
    Serial.println("Running OLED example");

    I2C_0 = new TwoWire(0); // Use I2C port 0 on ESP32

    I2C_Display = I2C_0; // Point I2C_Display at I2C_0

    I2C_0->begin(21, 22); // Begin I2C_0: SDA = 21, SCL = 22

    myOLED = new QwiicCustomOLED;

    // If desired, we can customize the OLED before we begin it.
    // Otherwise it will default to 128x64 (1.3" OLED).
    // These are the settings for the Micro OLED: 64x48
    myOLED->setXOffset(2);
    myOLED->setYOffset(0);
    myOLED->setDisplayWidth(64);
    myOLED->setDisplayHeight(48);
    myOLED->setPinConfig(0x12);
    myOLED->setPreCharge(0xF1);
    myOLED->setVcomDeselect(0x40);
    myOLED->setContrast(0x8F);

    // Initalize the OLED device and related graphics system
    if (myOLED->begin(*I2C_Display, 0x3D) == false)
    {
        Serial.println("Device begin failed. Freezing...");
        while (true)
            ;
    }
    Serial.println("Begin success");

    // Do a simple test - fill a rectangle on the screen and then print hello!

    // Fill a rectangle on the screen that has a 4 pixel board
    myOLED->rectangleFill(4, 4, myOLED->getWidth() - 8, myOLED->getHeight() - 8);

    String hello = "hello"; // our message

    // Center our message on the screen. Get the screen size of the "hello" string,
    // calling the getStringWidth() and getStringHeight() methods on the oled

    // starting x position - screen width minus string width  / 2
    int x0 = (myOLED->getWidth() - myOLED->getStringWidth(hello)) / 2;

    // starting y position - screen height minus string height / 2 
    int y0 = (myOLED->getHeight() - myOLED->getStringHeight(hello)) / 2;

    // Draw the text - color of black (0)
    myOLED->text(x0, y0, hello, 0);

    // There's nothing on the screen yet - Now send the graphics to the device
    myOLED->display();

    // That's it - HELLO!
}

void loop()
{
    delay(1000); // Do nothing
}

@PaulZC
Copy link
Contributor Author

PaulZC commented Mar 20, 2024

Just FYI: I bumped the library.properties version and re-released. Please Pull so you're all up to date!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants