adafruit / Adafruit_SSD1306

Arduino library for SSD1306 monochrome 128x64 and 128x32 OLEDs
http://www.adafruit.com/category/63_98
Other
1.74k stars 963 forks source link

OLED looks corrupted on STM32 when using bitmap or text functions (Previously: Single library uses up almost all my code space) #245

Open Pecacheu opened 1 year ago

Pecacheu commented 1 year ago

Hi. I'm using a STM32G0 chip with a custom board, and using the STM32 Arduino core here.

My problem is that for some reason this library takes up an absurd amount of space and 98% of my chip's memory is taken just by including the header. You'd think that the Adafruit graphics library would take up the bulk of the space but it only seems to use ~4K of space tops. Meanwhile this one uses up ~12K!! I understand why it would take up some SRAM but why does it take up so much FLASH program space? Isn't it just a simple library for driving the LCD over I2C? Is there anything I can disable inside the library to reduce the size usage?

UPDATE: I managed to get it to fit by changing the compiler optimization flags. For some reason "smallest" isn't actually the smallest. Go figure. Now I have a new problem though. While the library works when using basic functions like drawRect, both the drawBitmap and print functions do this: 20220725_040837

Update 2: In the case of the print function, it only goes garbled if I use setFont to set a custom font. But the weird part is that it's still garbled if I set a font and then clear the screen and go back to default font and try to draw. Also this is only happening on my STM32 board, not on an Uno. Also happens if I call getTextBounds. Also, I've determined that drawBitmap is innocent of the situation, so it's just these text functions that are getting weird.

BillyDonahue commented 1 year ago

You might also consider uncommenting this line to save space. https://github.com/adafruit/Adafruit_SSD1306/blob/33327d02a40f253d0dfb4aa3e15cf6a0b681d469/Adafruit_SSD1306.h#L36

BillyDonahue commented 1 year ago

It kind of sounds like your procedure for setting a custom font is buggy.

Pecacheu commented 1 year ago

You might also consider uncommenting this line to save space.

Thanks, that did help. Besides that, I ended up commenting out every line of code for the SPI mode, since I am using I2C mode (most of these OLED display modules I have seen are I2C only anyhow, no SPI pins). It might be helpful to add a macro to disable the SPI parts of the library in the future, as that actually saved a decent chunk of space.

I also found out from the STM32 wiki you can disable specific modules in the firmware, including RTC, Analog in, DAC, and of course SPI. All said and done it brought my program down from like 200% usage to only 75% usage. In the future though, I probably won't spring for a chip with only 32K of program space, lol. The font issue however remains. (And yes I had the issue before I started disabling stuff btw)

It kind of sounds like your procedure for setting a custom font is buggy.

I'm only using the built in fonts. I commented out a lot of code so I could test what was actually causing the corruption, so here is one thing I tried, with of course all the commented-out stuff taken out:

#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Fonts/FreeSans9pt7b.h>

#define SCR_W 128
#define SCR_H 64
#define SCR_ADDR 0x3C

Adafruit_SSD1306 oled(SCR_W, SCR_H, &Wire, -1);

void textCenter(int16_t x, int16_t y, const __FlashStringHelper *t) {
    uint16_t tw;
    oled.getTextBounds(t,0,0,0,0,&tw,0); //Get Text Width
    oled.setCursor(x - tw/2, y); oled.print(t); //Print
}

void setup() {
    /* Other setup stuff */
    oled.begin(SSD1306_SWITCHCAPVCC, SCR_ADDR);
    oled.fillScreen(0); oled.setTextColor(1); //Set Default Colors
    oled.setFont(&FreeSans9pt7b); //Set Font
    textCenter(50, SCR_H/2, F("Center This"));
    oled.display(); //Draw To Screen
}
BillyDonahue commented 1 year ago

Ok here might be your problem. It's at least one thing that's wrong.

    oled.getTextBounds(t,0,0,0,0,&tw,0); //Get Text Width

You're passing a 0 for three of the output pointer arguments. The getTextBounds function does not accept null-valued pointers, and will be writing to address 0 3 times to deliver its results. This could mess up your microcontroller depending on what it uses address zero for. I think you should make 3 dummy variables and pass their addresses instead of passing 0 literals.