i2c display garbage

Edje11
Posts: 18
Joined: Thu May 17, 2018 10:33 am
Contact:

i2c display garbage

Postby Edje11 » Tue Jan 01, 2019 4:16 pm

After updating the Arduino-esp32 Core from ?.? to 1.0.0 my i2c SH1106 Oled display doesn't work correct anymore when updating it from a separate task, the output to the display is garbage.
It must have something to do with the task were my screen update is running because if I update the screen in the main loop it works fine again.
With this I create a new task for the display

Code: Select all

xTaskCreate(screenupdate,  "Screenupdate",  10000,  NULL,   5, &ScreenUpdateHandle);
and in the task sub I'm doing something like this.

Code: Select all

void screenupdate( void * pvParameters ) {
    while (1) {
     display.clear();
     display.drawString(display.getWidth() / 2, 1 , "Hello world");
     display.display();
     vTaskDelay( 2000 / portTICK_PERIOD_MS);
  }
  vTaskDelete( NULL );
}
What's going wrong? Is this a freertos problem or maybe is the display driver not up to date?
Somebody a hint/tip to get me going.

idahowalker
Posts: 166
Joined: Wed Aug 01, 2018 12:06 pm

Re: i2c display garbage

Postby idahowalker » Thu Jan 03, 2019 5:10 pm

What library are you using?

Why not try the #include <U8g2lib.h> test program for graphics and the differing driver offerings they have. With the <U8g2lib.h> I put my task stack at #define TaskStack10K5 10500 for the least amount of issues.

You can run, at the end of your code,

Code: Select all

Serial.print(uxTaskGetStackHighWaterMark( NULL )); // stack size used
      Serial.println();
      Serial.flush();
to get an idea of how much ram the task is using. Let this code run for several hours to see if there is a burp in memory use.

I use, for the U8g2lib, both i2c and spi OLED drivers with HW and F ( hardware and full buffer). Consider the code used to display the info and the buffer size when selecting the task stack size.

A 128X64 SSD1306 or SH1106 will have a buffer size of 128X64 but a OLED like the 128x128 Pixels, 16-bit,SSD1327 will have a buffer size of 128X128X16 and your stack size must represent the buffer size, using the U8g2lib and have enough stack size for the task you are running for the display.

idahowalker
Posts: 166
Joined: Wed Aug 01, 2018 12:06 pm

Re: i2c display garbage

Postby idahowalker » Thu Jan 03, 2019 5:17 pm

Oh yea, I like to keep the stacks sized to 200 over the max reported used. Seems to keep my programs out of trouble that way.

Edje11
Posts: 18
Joined: Thu May 17, 2018 10:33 am
Contact:

Re: i2c display garbage

Postby Edje11 » Fri Jan 04, 2019 12:13 pm

Hi Thanks for your reply,

First I used a library from Thingpulse https://github.com/ThingPulse/esp8266-oled-ssd1306
After that I changed to U8x8lib that's from the same maker as U8g2lib.h.
Also tested the Graphicstest.ino from the U8g2lib, same problem.

All the above lib's working fine until you put some display stuff in a separate task.

Tested the stack use with your suggestion, however the simple test program as below the stack isn't a problem, stack use will never change and is something like 70bytes.

Running the simple test below will always show .A.A.A.A etc.
So for some reason there's always a dot inserted. I'm in proces now to find out with a jtag debugger why this happens, but easier said then done.


Code: Select all

#include <U8x8lib.h>

U8X8_SH1106_128X64_NONAME_HW_I2C u8x8(/* reset=*/ U8X8_PIN_NONE);

TaskHandle_t ScreenUpdateHandle;

void setup(void)
{
  Serial.begin(115200);
  u8x8.begin();
  u8x8.setPowerSave(0);
  u8x8.setFont(u8x8_font_chroma48medium8_r);
  xTaskCreate(screenupdate,  "Screenupdate",  10500,  NULL,   5, &ScreenUpdateHandle);
}

void loop(void)
{
  vTaskDelay( 2000 / portTICK_PERIOD_MS);
}

void screenupdate( void * pvParameters ) {
  int loopcounter = 0;
  while (1) {
    u8x8.drawString(1, 1, "A");
    vTaskDelay( 2000 / portTICK_PERIOD_MS);
  }
  vTaskDelete( NULL );
}

Edje11
Posts: 18
Joined: Thu May 17, 2018 10:33 am
Contact:

Re: i2c display garbage

Postby Edje11 » Sun Jan 06, 2019 2:46 pm

The screenupdate sub needs to run on core 1.
The code below solved my problem. :D

Code: Select all

#include <U8x8lib.h>

#if CONFIG_FREERTOS_UNICORE
#define ARDUINO_RUNNING_CORE 0
#else
#define ARDUINO_RUNNING_CORE 1
#endif

U8X8_SH1106_128X64_NONAME_HW_I2C u8x8(/* reset=*/ U8X8_PIN_NONE);

TaskHandle_t ScreenUpdateHandle;


void setup(void)
{
  Serial.begin(115200);
  u8x8.begin();
  u8x8.setFont(u8x8_font_chroma48medium8_r);
  xTaskCreatePinnedToCore(screenupdate,  "Screenupdate", 4000, NULL,  5, &ScreenUpdateHandle, ARDUINO_RUNNING_CORE); 
}

void loop(void)
{
  vTaskDelay( 20000 / portTICK_PERIOD_MS);
}

void screenupdate( void * pvParameters ) {
  while (1) {
    u8x8.drawString(0, 0, "Hello world!");
    vTaskDelay( 2000 / portTICK_PERIOD_MS);
  }
  vTaskDelete( NULL );
}

sultbab
Posts: 1
Joined: Mon Apr 06, 2020 11:37 am

Re: i2c display garbage

Postby sultbab » Mon Apr 06, 2020 11:45 am

hello,

I had exactly the same issue running multiple tasks with display access on ESP32 using SSD1306, no matter if adafruit or u8g2 driver was used.

Pinning the task to one core solved only the problem partly. There was always an issue with first access to display from any of the tasks, no matter if they were pinned to cpu0 or 1, then access later on were all fine.

Complete solution seems to be for me is setting i2c clock speed to 100000:

Code: Select all

Adafruit_SSD1306 display(DISPLAY_WIDTH, DISPLAY_HEIGHT, &Wire, DISPLAY_PIN_RST , 100000UL, 100000UL);
Although this causes slowing down screen refresh speed, but now everything is stable and no garbage is displayed.

Who is online

Users browsing this forum: No registered users and 61 guests