greiman / SSD1306Ascii

Text only Arduino Library for SSD1306 OLED displays
MIT License
504 stars 121 forks source link

software horizontal smooth scrolling helper #63

Closed d-a-v closed 5 years ago

d-a-v commented 5 years ago

This is a proof of concept. I'm using this helper to allow smooth scrolling for a specific horizontal line by calling oled.xshift(n) prior calling oled.print("my long string") every 50ms, with n varying.

(formula to calculate maximum n value depending on string and font is not yet exact)

greiman commented 5 years ago

Scrolling a long line would be useful. It needs to be easy to use.

When I have time, I would like to do something like https://github.com/androdlang/InfoTicker.

Click on https://youtu.be/L9V65wh85Yk.

See this example for the code.

d-a-v commented 5 years ago

It needs to be easy to use.

I have got the same smooth visual with only the following pseudo code (and your library with this PR) to scroll one horizontal line:

        // if last call was more than 50ms ago:
        if (m_shift >= _shiftmax)
            m_shiftdir = -1;
        if (m_shift == 0)
            m_shiftdir = 1;
        m_shift += _shiftdir;

        oled.setCursor(0, y);
        oled.xShift(xshift);
        oled.print('long line ... ...');

Please tell me if you are interested with me pursuing with this PR:

Or I can leave this as-is and wait for this idea to find its way your way on your repository (like I did with vertical smooth scrolling (and thanks for it :))

greiman commented 5 years ago

I want to think more about the API.

I think there are implementations for systems like MicroPython, mbed and maybe Raspberry Pi.

Some of these may be the hardware scroll which only scrolls the display memory. I don't see a way to use the hardware horizontal scroll.

greiman commented 5 years ago

I have been trying some code for the ticker. It is similar to the JLInfoTicker library.

When it is debugged, I will post it.

I implemented a variation of your xshift as a helper. I had problems with larger fonts, 2X magnification and various letter space so I moved the pixel discard to writeRam().

Currently I am playing with this "simple" implementation. Simple since it is a bit trickier than I expected.

I use a struct and two member functions. I may include the font and mag factor in state so you can write other parts of the display without restoring font and mag factor.

struct TickerState {
  const char* text;  // Pointer to start of displayed text.
  uint8_t bgnCol;    // Begin column of ticker.
  uint8_t endCol;    // End column of ticker.
  uint8_t col;       // Column for start of displayed text.
  uint8_t row;       // Row for ticker
  uint8_t skip;      // Number of pixels to skip in first character.
};

// Initialize state and clear ticker field. Default endCol is last column of display
void tickerInit(TickerState* state, const char* text,
       uint8_t row, uint8_t bgnCol = 0, uint8_t endCol = 255);

// Move display one pixel.  Return false when entire string has disappeared.
bool tickerTick(TickerState* state);

Here is a test program.

#include <Wire.h>
#include "SSD1306Ascii.h"
#include "SSD1306AsciiWire.h"

// 0X3C+SA0 - 0x3C or 0x3D
#define I2C_ADDRESS 0x3C

// Define proper RST_PIN if required.
#define RST_PIN -1

SSD1306AsciiWire oled;
TickerState state;
const char* text = "My ticker test string 1234567890 ABCDEFGHIJK";

void setup() {
  Wire.begin();
  Wire.setClock(400000L);

#if RST_PIN >= 0
  oled.begin(&Adafruit128x64, I2C_ADDRESS, RST_PIN);
#else // RST_PIN >= 0
  oled.begin(&Adafruit128x64, I2C_ADDRESS);
#endif // RST_PIN >= 0

  oled.setFont(Adafruit5x7);
 // oled.set2X();
  // Use field at row 2, columns 16 through 100.
  oled.tickerInit(&state, text, 2, 16, 100);
}

uint32_t tickTime = 0;

void loop() {
  if (tickTime <= millis()) {
    tickTime = millis() + 30;
    if (!oled.tickerTick(&state)) {
      // Use row 0 and entire width of display.
      oled.tickerInit(&state, text, 0);
    }
  }
d-a-v commented 5 years ago

The proposed API allows to independently scroll several lines at different speed (and size?) and not necessarily within the entire screen line. Thanks for working on this!

A vert + horz scrolling demo will beat any youtube video :)

greiman commented 5 years ago

I have the first cut working but now want to extended it to allow providing a next string as soon as all of the first string is displayed so you can have a continuous ticker.

The JLInfoTicker only allows one string to be displayed. You can't join a second string.

Also I will save font and mag-factor in state.

greiman commented 5 years ago

Try the latest release. It has the scrolling text ticker.

Look at TickerTextDemo first then TickerAdcDemo.

TickerTextDemo has extra lines that I will delete in the next version.

d-a-v commented 5 years ago

I tried both examples on a MicroOLED64x48 on esp8266 and they work just great !

Happily closing,

I am now waiting for a "youtube" smooth vertical + horizontal scrolling demo :laughing: