lexus2k / ssd1306

Driver for SSD1306, SSD1331, SSD1351, IL9163, ILI9341, ST7735, PCD8544, Nokia 5110 displays running on Arduino/ESP32/Linux (Rasperry) platforms
MIT License
674 stars 127 forks source link

Print text at any Y-value? #157

Open SvarunSoda opened 1 year ago

SvarunSoda commented 1 year ago

I'm attempting to print several rows of text, at certain Y-values, on an SSD1306 128x64 LCD display. I'm doing this using the Arduino IDE, with ssd1306 by Alexy Dunda, which is supposedly this library (it links here from the Arduino IDE Library Manager).

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. Hence, I opted for using this library.

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: IMG_5552

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 it's printing location on the screen), which doesn't have that warning in it's 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 SSD1306 LCD with this library?

Thanks for reading my post, any guidance is appreciated.

lexus2k commented 1 year ago

@SvarunSoda Hi Direct ssd1306 API functions are trade-off of code complexity, speed and flash ram usage. This is described in the documentation:

 * Prints text to screen using fixed font.
 * @param xpos - horizontal position in pixels
 * @param y - vertical position in pixels
 * @param ch - NULL-terminated string to print
 * @param style - font style (EFontStyle), normal by default.
 * @returns number of chars in string
 * @see ssd1306_setFixedFont
 * @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.
 * @warning Be careful with you flash space! Do not mix too many different functions in single sketch.
 *          ssd1306_printFixedN() uses much flash: ~396 bytes, ssd1306_printFixed() needs 388 bytes.
 *          Placing both of these functions to your sketch will consume almost 1KiB.

To get expected results, please use NanoCanvas. The way to use NanoCanvas is demostrated in ssd1306_demo example.