SSD1306 OLED problems

Post here first, or if you can't find a relevant section!
gigabyte091
Posts: 7
Joined: Sat Mar 18, 2017 6:19 am

SSD1306 OLED problems

Postby gigabyte091 » Sat Mar 18, 2017 6:48 am

Hi,

Yesterday I installed STM32 for Arduino following this Youtube video:

[youtube]https://www.youtube.com/watch?v=1zVgLyuCejM[/youtube]

I'm running Arduino 1.8.1 IDE and I'm using OLED_I2C library found on this forum.

Problem is, i wrote a simple TEST code, and code compiles and upload to MCU via ST-Link v2 interface (MCU is STM32F103C8T6, standard ebay blue pill with 20k RAM and 128k ROM).

I tried every I2C output from MCU and nothing... blank screen. Tried example code, nothing, blank screen.
Tried on Arduino Uno to test OLED, and is working propertly.

Example of my test code:

Code: Select all

#include <OLED_I2C.h>

OLED myOLED(SDA,SCL);


void setup() {
  }

void loop() {

  myOLED.begin();
  myOLED.setBrightness(255);
  myOLED.print("Hello World",CENTER,0);
  myOLED.update();
  delay(2000);

}


Output of compiler

Code: Select all

C:\Users\Krešo - Radni PC\Desktop\sketch_mar18a\sketch_mar18a.ino: In function 'void loop()':

C:\Users\Krešo - Radni PC\Desktop\sketch_mar18a\sketch_mar18a.ino:13:38: warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]

Sketch uses 78184 bytes (59%) of program storage space. Maximum is 131072 bytes.
Global variables use 7360 bytes of dynamic memory.
STM32 ST-LINK CLI v2.1.0
STM32 ST-LINK Command Line Interface

ST-LINK SN : 49FF6E064970525437262287
ST-LINK Firmware version : V2J27S6
Connected via SWD.
SWD Frequency = 1800K.
Connection mode : Normal.
Device ID:0x410
Device flash Size : 128 Kbytes
Device family :STM32F10xx Medium-density

Loading file...
Flash Programming:
  File : C:\Users\KREO-R~1\AppData\Local\Temp\arduino_build_888561\sketch_mar18a.ino.bin
  Address : 0x08000000
Flash memory programming...
±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±± 0%
 0%ŰŰŰŰ 9%ŰŰŰŰŰ 19%ŰŰŰŰŰ 29%ŰŰŰŰŰ 39%ŰŰŰŰŰ 49%ŰŰŰŰŰ 58%ŰŰŰŰŰ 68%ŰŰŰŰŰ 78%ŰŰŰŰŰ 88%ŰŰŰŰŰ 98%Ű 100%
Flash memory programmed in 9s and 515ms.
Programming Complete.

MCU Reset.

Application started.

User avatar
Pito
Posts: 609
Joined: Sat Mar 26, 2016 3:26 pm
Location: Rapa Nui

Re: SSD1306 OLED problems

Postby Pito » Sat Mar 18, 2017 10:37 am

Double check the SDA SCL pins are set properly. You need pull-ups on those pins too.

User avatar
BennehBoy
Posts: 384
Joined: Thu Jan 05, 2017 8:21 pm
Location: Yorkshire
Contact:

Re: SSD1306 OLED problems

Postby BennehBoy » Sat Mar 18, 2017 11:47 am

What OLED library is that, it looks to me like it's bitbanging the i2C, can't understand why it would need to know the pins otherwise.

If it is bitbanging then it's probably an implementaion issue.

Perhaps try adafruit's ssd1306 library.
-------------------------------------
https://github.com/BennehBoy

gigabyte091
Posts: 7
Joined: Sat Mar 18, 2017 6:19 am

Re: SSD1306 OLED problems

Postby gigabyte091 » Sat Mar 18, 2017 12:09 pm

Nothing happens, i tried all three I2C and nothing...

gigabyte091
Posts: 7
Joined: Sat Mar 18, 2017 6:19 am

Re: SSD1306 OLED problems

Postby gigabyte091 » Sat Mar 18, 2017 12:17 pm

I found Adafruit STM32 I2C example, here is compiler output

Code: Select all

C:\Program Files (x86)\Arduino\hardware\STM32\STM32F1\libraries\Adafruit_SSD1306\Adafruit_SSD1306_STM32.cpp: In member function 'virtual void Adafruit_SSD1306::drawPixel(int16_t, int16_t, uint16_t)':

C:\Program Files (x86)\Arduino\hardware\STM32\STM32F1\libraries\Adafruit_SSD1306\Adafruit_SSD1306_STM32.cpp:115:14: error: 'swap' was not declared in this scope

     swap(x, y);

              ^

C:\Program Files (x86)\Arduino\hardware\STM32\STM32F1\libraries\Adafruit_SSD1306\Adafruit_SSD1306_STM32.cpp: In member function 'virtual void Adafruit_SSD1306::drawFastHLine(int16_t, int16_t, int16_t, uint16_t)':

C:\Program Files (x86)\Arduino\hardware\STM32\STM32F1\libraries\Adafruit_SSD1306\Adafruit_SSD1306_STM32.cpp:571:16: error: 'swap' was not declared in this scope

       swap(x, y);

                ^

C:\Program Files (x86)\Arduino\hardware\STM32\STM32F1\libraries\Adafruit_SSD1306\Adafruit_SSD1306_STM32.cpp: In member function 'virtual void Adafruit_SSD1306::drawFastVLine(int16_t, int16_t, int16_t, uint16_t)':

C:\Program Files (x86)\Arduino\hardware\STM32\STM32F1\libraries\Adafruit_SSD1306\Adafruit_SSD1306_STM32.cpp:639:16: error: 'swap' was not declared in this scope

       swap(x, y);

                ^

exit status 1
Error compiling for board Generic STM32F103C series.

User avatar
BennehBoy
Posts: 384
Joined: Thu Jan 05, 2017 8:21 pm
Location: Yorkshire
Contact:

Re: SSD1306 OLED problems

Postby BennehBoy » Sat Mar 18, 2017 12:40 pm

Use the stock adafruit library, not the STM32 variant in the core.
-------------------------------------
https://github.com/BennehBoy

gigabyte091
Posts: 7
Joined: Sat Mar 18, 2017 6:19 am

Re: SSD1306 OLED problems

Postby gigabyte091 » Sat Mar 18, 2017 5:24 pm

Now its working but update speed is very slow... like every 500 ms, without any delay in code...

User avatar
BennehBoy
Posts: 384
Joined: Thu Jan 05, 2017 8:21 pm
Location: Yorkshire
Contact:

Re: SSD1306 OLED problems

Postby BennehBoy » Sat Mar 18, 2017 5:54 pm

Can you share your code.
-------------------------------------
https://github.com/BennehBoy

gigabyte091
Posts: 7
Joined: Sat Mar 18, 2017 6:19 am

Re: SSD1306 OLED problems

Postby gigabyte091 » Sat Mar 18, 2017 6:38 pm

It is example code from Adafruit library, the only thing i changed is display address, from 0×3D to 0×3C

Code: Select all

/*********************************************************************
This is an example for our Monochrome OLEDs based on SSD1306 drivers

  Pick one up today in the adafruit shop!
  ------> http://www.adafruit.com/category/63_98

This example is for a 128x64 size display using I2C to communicate
3 pins are required to interface (2 I2C and one reset)

Adafruit invests time and resources providing this open source code,
please support Adafruit and open-source hardware by purchasing
products from Adafruit!

Written by Limor Fried/Ladyada  for Adafruit Industries. 
BSD license, check license.txt for more information
All text above, and the splash screen must be included in any redistribution
*********************************************************************/

#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);

#define NUMFLAKES 10
#define XPOS 0
#define YPOS 1
#define DELTAY 2


#define LOGO16_GLCD_HEIGHT 16
#define LOGO16_GLCD_WIDTH  16
static const unsigned char PROGMEM logo16_glcd_bmp[] =
{ B00000000, B11000000,
  B00000001, B11000000,
  B00000001, B11000000,
  B00000011, B11100000,
  B11110011, B11100000,
  B11111110, B11111000,
  B01111110, B11111111,
  B00110011, B10011111,
  B00011111, B11111100,
  B00001101, B01110000,
  B00011011, B10100000,
  B00111111, B11100000,
  B00111111, B11110000,
  B01111100, B11110000,
  B01110000, B01110000,
  B00000000, B00110000 };

#if (SSD1306_LCDHEIGHT != 64)
#error("Height incorrect, please fix Adafruit_SSD1306.h!");
#endif

void setup()   {               
  Serial.begin(9600);

  // by default, we'll generate the high voltage from the 3.3v line internally! (neat!)
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);  // initialize with the I2C addr 0x3D (for the 128x64)
  // init done
 
  // Show image buffer on the display hardware.
  // Since the buffer is intialized with an Adafruit splashscreen
  // internally, this will display the splashscreen.
  display.display();
  delay(2000);

  // Clear the buffer.
  display.clearDisplay();

  // draw a single pixel
  display.drawPixel(10, 10, WHITE);
  // Show the display buffer on the hardware.
  // NOTE: You _must_ call display after making any drawing commands
  // to make them visible on the display hardware!
  display.display();
  delay(2000);
  display.clearDisplay();

  // draw many lines
  testdrawline();
  display.display();
  delay(2000);
  display.clearDisplay();

  // draw rectangles
  testdrawrect();
  display.display();
  delay(2000);
  display.clearDisplay();

  // draw multiple rectangles
  testfillrect();
  display.display();
  delay(2000);
  display.clearDisplay();

  // draw mulitple circles
  testdrawcircle();
  display.display();
  delay(2000);
  display.clearDisplay();

  // draw a white circle, 10 pixel radius
  display.fillCircle(display.width()/2, display.height()/2, 10, WHITE);
  display.display();
  delay(2000);
  display.clearDisplay();

  testdrawroundrect();
  delay(2000);
  display.clearDisplay();

  testfillroundrect();
  delay(2000);
  display.clearDisplay();

  testdrawtriangle();
  delay(2000);
  display.clearDisplay();
   
  testfilltriangle();
  delay(2000);
  display.clearDisplay();

  // draw the first ~12 characters in the font
  testdrawchar();
  display.display();
  delay(2000);
  display.clearDisplay();

  // draw scrolling text
  testscrolltext();
  delay(2000);
  display.clearDisplay();

  // text display tests
  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.setCursor(0,0);
  display.println("Hello, world!");
  display.setTextColor(BLACK, WHITE); // 'inverted' text
  display.println(3.141592);
  display.setTextSize(2);
  display.setTextColor(WHITE);
  display.print("0x"); display.println(0xDEADBEEF, HEX);
  display.display();
  delay(2000);
  display.clearDisplay();

  // miniature bitmap display
  display.drawBitmap(30, 16,  logo16_glcd_bmp, 16, 16, 1);
  display.display();
  delay(1);

  // invert the display
  display.invertDisplay(true);
  delay(1000);
  display.invertDisplay(false);
  delay(1000);
  display.clearDisplay();

  // draw a bitmap icon and 'animate' movement
  testdrawbitmap(logo16_glcd_bmp, LOGO16_GLCD_HEIGHT, LOGO16_GLCD_WIDTH);
}


void loop() {
 
}


void testdrawbitmap(const uint8_t *bitmap, uint8_t w, uint8_t h) {
  uint8_t icons[NUMFLAKES][3];
 
  // initialize
  for (uint8_t f=0; f< NUMFLAKES; f++) {
    icons[f][XPOS] = random(display.width());
    icons[f][YPOS] = 0;
    icons[f][DELTAY] = random(5) + 1;
   
    Serial.print("x: ");
    Serial.print(icons[f][XPOS], DEC);
    Serial.print(" y: ");
    Serial.print(icons[f][YPOS], DEC);
    Serial.print(" dy: ");
    Serial.println(icons[f][DELTAY], DEC);
  }

  while (1) {
    // draw each icon
    for (uint8_t f=0; f< NUMFLAKES; f++) {
      display.drawBitmap(icons[f][XPOS], icons[f][YPOS], bitmap, w, h, WHITE);
    }
    display.display();
    delay(200);
   
    // then erase it + move it
    for (uint8_t f=0; f< NUMFLAKES; f++) {
      display.drawBitmap(icons[f][XPOS], icons[f][YPOS], bitmap, w, h, BLACK);
      // move it
      icons[f][YPOS] += icons[f][DELTAY];
      // if its gone, reinit
      if (icons[f][YPOS] > display.height()) {
        icons[f][XPOS] = random(display.width());
        icons[f][YPOS] = 0;
        icons[f][DELTAY] = random(5) + 1;
      }
    }
   }
}


void testdrawchar(void) {
  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.setCursor(0,0);

  for (uint8_t i=0; i < 168; i++) {
    if (i == '\n') continue;
    display.write(i);
    if ((i > 0) && (i % 21 == 0))
      display.println();
  }   
  display.display();
  delay(1);
}

void testdrawcircle(void) {
  for (int16_t i=0; i<display.height(); i+=2) {
    display.drawCircle(display.width()/2, display.height()/2, i, WHITE);
    display.display();
    delay(1);
  }
}

void testfillrect(void) {
  uint8_t color = 1;
  for (int16_t i=0; i<display.height()/2; i+=3) {
    // alternate colors
    display.fillRect(i, i, display.width()-i*2, display.height()-i*2, color%2);
    display.display();
    delay(1);
    color++;
  }
}

void testdrawtriangle(void) {
  for (int16_t i=0; i<min(display.width(),display.height())/2; i+=5) {
    display.drawTriangle(display.width()/2, display.height()/2-i,
                     display.width()/2-i, display.height()/2+i,
                     display.width()/2+i, display.height()/2+i, WHITE);
    display.display();
    delay(1);
  }
}

void testfilltriangle(void) {
  uint8_t color = WHITE;
  for (int16_t i=min(display.width(),display.height())/2; i>0; i-=5) {
    display.fillTriangle(display.width()/2, display.height()/2-i,
                     display.width()/2-i, display.height()/2+i,
                     display.width()/2+i, display.height()/2+i, WHITE);
    if (color == WHITE) color = BLACK;
    else color = WHITE;
    display.display();
    delay(1);
  }
}

void testdrawroundrect(void) {
  for (int16_t i=0; i<display.height()/2-2; i+=2) {
    display.drawRoundRect(i, i, display.width()-2*i, display.height()-2*i, display.height()/4, WHITE);
    display.display();
    delay(1);
  }
}

void testfillroundrect(void) {
  uint8_t color = WHITE;
  for (int16_t i=0; i<display.height()/2-2; i+=2) {
    display.fillRoundRect(i, i, display.width()-2*i, display.height()-2*i, display.height()/4, color);
    if (color == WHITE) color = BLACK;
    else color = WHITE;
    display.display();
    delay(1);
  }
}
   
void testdrawrect(void) {
  for (int16_t i=0; i<display.height()/2; i+=2) {
    display.drawRect(i, i, display.width()-2*i, display.height()-2*i, WHITE);
    display.display();
    delay(1);
  }
}

void testdrawline() { 
  for (int16_t i=0; i<display.width(); i+=4) {
    display.drawLine(0, 0, i, display.height()-1, WHITE);
    display.display();
    delay(1);
  }
  for (int16_t i=0; i<display.height(); i+=4) {
    display.drawLine(0, 0, display.width()-1, i, WHITE);
    display.display();
    delay(1);
  }
  delay(250);
 
  display.clearDisplay();
  for (int16_t i=0; i<display.width(); i+=4) {
    display.drawLine(0, display.height()-1, i, 0, WHITE);
    display.display();
    delay(1);
  }
  for (int16_t i=display.height()-1; i>=0; i-=4) {
    display.drawLine(0, display.height()-1, display.width()-1, i, WHITE);
    display.display();
    delay(1);
  }
  delay(250);
 
  display.clearDisplay();
  for (int16_t i=display.width()-1; i>=0; i-=4) {
    display.drawLine(display.width()-1, display.height()-1, i, 0, WHITE);
    display.display();
    delay(1);
  }
  for (int16_t i=display.height()-1; i>=0; i-=4) {
    display.drawLine(display.width()-1, display.height()-1, 0, i, WHITE);
    display.display();
    delay(1);
  }
  delay(250);

  display.clearDisplay();
  for (int16_t i=0; i<display.height(); i+=4) {
    display.drawLine(display.width()-1, 0, 0, i, WHITE);
    display.display();
    delay(1);
  }
  for (int16_t i=0; i<display.width(); i+=4) {
    display.drawLine(display.width()-1, 0, i, display.height()-1, WHITE);
    display.display();
    delay(1);
  }
  delay(250);
}

void testscrolltext(void) {
  display.setTextSize(2);
  display.setTextColor(WHITE);
  display.setCursor(10,0);
  display.clearDisplay();
  display.println("scroll");
  display.display();
  delay(1);
 
  display.startscrollright(0x00, 0x0F);
  delay(2000);
  display.stopscroll();
  delay(1000);
  display.startscrollleft(0x00, 0x0F);
  delay(2000);
  display.stopscroll();
  delay(1000);   
  display.startscrolldiagright(0x00, 0x07);
  delay(2000);
  display.startscrolldiagleft(0x00, 0x07);
  delay(2000);
  display.stopscroll();
}

User avatar
BennehBoy
Posts: 384
Joined: Thu Jan 05, 2017 8:21 pm
Location: Yorkshire
Contact:

Re: SSD1306 OLED problems

Postby BennehBoy » Sat Mar 18, 2017 6:58 pm

Not to point out the obvious, but you realise there are a LOT of 2000 ms delays in this code?

The other thing to keep in mind is that the library is running i2c at 400khz. Every time the lib calls .display it writes a 1KB framebuffer out over that 400khz i2c bus...

SPI will happily operate at 18MHZ... so is just a bit faster.

You'd have to hook up a logic analyser to the i2C and see how saturated the bus is to work out what's going on.
-------------------------------------
https://github.com/BennehBoy


Return to “General discussion”

Who is online

Users browsing this forum: efftek and 2 guests