Closed bmidgley closed 4 years ago
I too have the same problem. How to scroll long text sideways?
If you are just looking at scrolling a single line of text horizontally, below is the solution I came up with. Note this still does not solve the problem of longer text strings (note the "quick brown fox" at line 55 which will show the problem if you uncomment it), but it does demonstrate an easy method of horizontal scrolling. It would be great if someone could wrap this up into a function for the ssd1306 library and make it work off of an interrupt.
This technique works by first trying to guess at the pixel length of the whole string you want to scroll. Since characters are of differing widths I have to make a rough estimate of an average character size in scroll_char_width. You will need to adjust this based on your particular text. Once we have a width, the string is drawn to the display twice -- first the main string that should always be showing some part of itself, and the a second string to fill in the gaps, either before or after the primary string base on the current scroll position. (See lines 69-73.) Every 20ms we shift the scroll position one more pixel to the left, draw a filled white rectangle to clear the current text, and redraw the two strings at their new offset. The string also includes a display of millis() so you can see constantly-changing text as it scrolls.
From my testing, it looks like the string-wrap issue happens if you try to print a string longer than 60 characters. If there were a way to find the exact pixel length that a string will require on the screen for the given font size, then I could rewrite the function to line up the two scrolling strings exactly, and I could scroll just a portion of the string so that length would no longer be a factor. Without that, I think we're stuck working with shorter strings.
The following demonstration was run on a Lolin32 which has an ESP32 and a 128x64 display onboard. Adjust the parameters to suit your own hardware. (Sorry, doesn't look like code pasting is supported here, so I also attached a file with the proper indentations.)
// OLED SCREEN PARAMETERS
SSD1306Wire display(SCREEN_I2C_ADDRESS, SCREEN_SDA_PIN, SCREEN_SCL_PIN);
// Parameters for the scrolling text
int scroll_pos = SCREEN_WIDTH; unsigned int next_scroll = 0; String scroll_string; const char* scroll_div = " | ";
void setup() { Serial.begin(115200);
Wire.begin(SCREEN_SDA_PIN, SCREEN_SCL_PIN); Wire.beginTransmission(SCREEN_I2C_ADDRESS); if(Wire.endTransmission() == 0) { display.init(); display.setContrast(255); if(SCREEN_VERTICAL_FLIP) display.flipScreenVertically(); display.clear(); display.setFont(ArialMT_Plain_16); display.setTextAlignment(TEXT_ALIGN_CENTER); display.drawString(63, 26, "Waiting for data..."); display.display(); } else { Serial.print("OLED screen not found at 0x"); Serial.println(SCREEN_I2C_ADDRESS, HEX); while (1); } }
void loop() { unsigned long NOW = millis();
if (NOW >= next_scroll) { scroll_pos--; next_scroll = NOW + scroll_delay;
scroll_string = "1024 hPa" + String(scroll_div);
scroll_string += "30.24 Hg" + String(scroll_div);
scroll_string += "192.168.0.100" + String(scroll_div);
scroll_string += String(millis()) + String(scroll_div);
//scroll_string += "The quick brown fox jumped over the lazy dog" + String(scroll_div);
scrollText(scroll_string);
} }
void scrollText(String str) { int len = str.length() * scroll_char_width; if (scroll_pos + len <= SCREEN_WIDTH) scroll_pos += len;
display.setFont(ArialMT_Plain_10); display.setTextAlignment(TEXT_ALIGN_LEFT); display.setColor(WHITE); // blank out the scrollable area display.fillRect(0, scroll_y+1, SCREEN_WIDTH, scroll_height); display.setColor(BLACK); // draw text in opposite color display.drawString(scroll_pos, scroll_y, str); if (scroll_pos > 0) display.drawString(scroll_pos - len, scroll_y, str); else display.drawString(scroll_pos + len, scroll_y, str); display.display(); display.setColor(WHITE); // set drawing color back to default }
Looks like you can calculate the width: *for (uint16_t i = 0; i < length; i++) { strWidth += pgm_read_byte(fontData + JUMPTABLE_START + (text[i] - firstChar) JUMPTABLE_BYTES + JUMPTABLE_WIDTH); }**
From: https://github.com/squix78/esp8266-oled-ssd1306/blob/master/OLEDDisplay.cpp
Thanks for finding this! Let me see what I can work out with it and I'll post back...
I don't know if this is any help (or if I just totally missed that this lib already has it), but I just added a basic display scroll left and right to my fork. Using the commands used in the Adafruit SSD1306 library.
See: https://github.com/kosso/esp8266-oled-ssd1306/blob/add-scrolling/OLEDDisplay.cpp#L558
This will scroll the whole screen (which might not be what you want) from left to right:
display.init();
display.clear();
display.setColor(WHITE);
display.setFont(ArialMT_Plain_10);
display.setTextAlignment(TEXT_ALIGN_CENTER);
display.drawString(DISPLAY_WIDTH / 2, 2, "WOO! SCROLLING");
display.setFont(ArialMT_Plain_10);
display.drawString(DISPLAY_WIDTH / 2, 18, "until we stop it...");
display.display();
display.startscrollright(0x00, 0x0F);
delay(4000);
display.stopscroll();
Also, (and this might be exactly what you want) the library already has the methods:
display.getStringWidth(String text)
// Returns the width of the text with the current font settings
and
display.drawStringMaxWidth(int16_t x, int16_t y, uint16_t maxLineWidth, String text)
// Draws a String with a maximum width at the given location.
// If the given String is wider than the specified width
// The text will be wrapped to the next line at a space or dash
A bit late, but I just finished a library for the SSD1306 covering "scrolling text" with unlimited text length, variable font and speed. If you arre interested, have a look into the source https://github.com/androdlang/InfoTicker
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
Are there any examples out there for using the side scrolling? I tried drawstring with my string printed twice and then moved to a negative offset, but this only works with short strings. (Long strings wrap around and print over the start of the string)