3

I'm attempting to print several rows of text, at certain Y-values, on an SSD1306 128x64 LCD display.

I'm using the ssd1306 library by Alexey Dynda. I initially wanted to use the more common LCD libraries out there, such as the Adafruit SSD1306 LCD library, however it unfortunately does not appear I can set custom I2C pins for most such libraries out there, which is required as I'm using a custom board with an ESP32-WROOM-DA chip. The ssd1306 by Dynda appears to be able to do so.

I have the following example code, which prints 6 lines of text:

#include "ssd1306.h"
#include "nano_gfx.h"

const int PIN_I2C_SCL = 16;
const int PIN_I2C_SDA = 13;

void LCDTextDraw(int x, int y, const char* text)
{
  EFontStyle fontStyle;
  
  ssd1306_printFixed(x, y, text, fontStyle);
}

void LCDRectDraw(int x, int y, int w, int h)
{
  ssd1306_fillRect(x, y, x + w, y + h);
}

void LCDScreenClear(bool fill)
{
  ssd1306_clearScreen();

  if (fill)
    LCDRectDraw(0, 0, 128, 64);
}

void LCDInit()
{
  ssd1306_setFixedFont(ssd1306xled_font6x8);
  ssd1306_128x64_i2c_initEx(PIN_I2C_SCL, PIN_I2C_SDA, 0);
}

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

  pinMode(PIN_I2C_SCL, OUTPUT);
  pinMode(PIN_I2C_SDA, OUTPUT);

  LCDInit();
  LCDScreenClear(true);

  LCDTextDraw(30, 0, "TEST 1");
  LCDTextDraw(30, 10, "TEST 2");
  LCDTextDraw(30, 20, "TEST 3");
  LCDTextDraw(30, 30, "TEST 4");
  LCDTextDraw(30, 40, "TEST 5");
  LCDTextDraw(30, 50, "TEST 6");
}

void loop() 
{}

With which I wish to print out 6 lines of text, each line evenly vertically spaced out by 10 pixels.

Which produces the following output on my LCD:

enter image description here

As you can see, the text rows are not evenly vertically spaced out as I wish them to be, with a large space between the TEST 4 and TEST 5 strings.

After looking at the definition of the ssd1306_printFixed function I'm using to print out my text in the example above, it turns out that it can only print rows of text at certain fixed Y-positions:

@warning ssd1306_printFixed() can output chars at fixed y positions: 0, 8, 16, 24, 32, etc.
If you specify [10,18], ssd1306_printFixed() will output text starting at [10,16] position.

Hence, I also tried using the ssd1306_print function (which uses a cursor to delineate its printing location on the screen), which doesn't have that warning in its header declaration. I replaced my LCDTextDraw function with:

void LCDTextDraw(int x, int y, const char* text)
{
  ssd1306_setCursor8(x, y);
  ssd1306_print(text);
}

However, that still produced the exact same output on my LCD, with the same spacing issues.

What is the proper way to print text rows at any Y-value on an LCD?

Thanks for reading my post, any guidance is appreciated.

3
  • 1
    wokwi.com/projects/341940000159433299
    – jsotola
    Oct 29, 2023 at 19:43
  • @jsotola, a quick look at your linked to Adafruit code and I think I see the same vertical numbers restrictions that Rohit was commenting on.
    – st2000
    Oct 30, 2023 at 12:27
  • @Runsva, this is just a guess, but after writing code to interface w/a small Sharp display, there may be some difficulties addressing anomalies which can be avoided by placing images (characters) in constrained locations. Also, these characters may be part of the display programming and their placement is constrained by the display. I think you can do what you want. But you may have to write all the code from scratch.
    – st2000
    Oct 30, 2023 at 12:35

1 Answer 1

1

Turns out using the Adafruit SSD1306 library is much easier than I first thought. One just must specify the I2C pins used with Wire, and pass it as reference to the Adafruit_SSD1306 constructor. Additionally, the Adafruit library doesn't appear to have the uneven vertical spacing issue.

The equivalent code below using the Adafruit library:

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

const int PIN_I2C_SCL = 16;
const int PIN_I2C_SDA = 13;

Adafruit_SSD1306 LCD(128, 64, &Wire);

void LCDTextDraw(int x, int y, const char* text, byte size)
{
  LCD.setCursor(x, y);
  LCD.setTextSize(size);
  LCD.print(text);
  LCD.display();
}

void LCDRectFill(int x, int y, int w, int h, int color)
{
  LCD.fillRect(x, y, w, h, color);
}

void LCDScreenClear(bool fill)
{
  LCD.clearDisplay();
  LCD.display();
  LCD.setTextColor(WHITE, BLACK);

  if (fill)
    LCDRectFill(0, 0, 128, 64, 1);
}

void LCDInit()
{
  LCD.begin(SSD1306_SWITCHCAPVCC, 0x3C);
}

void setup() 
{
  Serial.begin(9600);
  
  pinMode(PIN_I2C_SCL, OUTPUT);
  pinMode(PIN_I2C_SDA, OUTPUT);

  Wire.setPins(PIN_I2C_SDA, PIN_I2C_SCL);
  Wire.begin();

  LCDInit();
  LCDScreenClear(true);

  LCDTextDraw(30, 0, "TEST 1", 1);
  LCDTextDraw(30, 10, "TEST 2", 1);
  LCDTextDraw(30, 20, "TEST 3", 1);
  LCDTextDraw(30, 30, "TEST 4", 1);
  LCDTextDraw(30, 40, "TEST 5", 1);
  LCDTextDraw(30, 50, "TEST 6", 1);
}

void loop() 
{}

Now produces the desired result:

enter image description here

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.