Bodmer / TFT_eSPI

Arduino and PlatformIO IDE compatible TFT library optimised for the Raspberry Pi Pico (RP2040), STM32, ESP8266 and ESP32 that supports different driver chips
Other
3.73k stars 1.07k forks source link

Scrolling text with st7735 with software. #1155

Closed zekageri closed 3 years ago

zekageri commented 3 years ago

Hi!

I want to scroll any text ( its a notification text line on the screen ) while the screen is tft.setRotation(3);.

I achived this with the following code:

String scrollableText = "";
int lastPos = 160;

// This is where the notification function puts the message to the scrollableText buffer and resets the coordinates.
static const inline void addNoty(String msg){
  if(!Firmware_Is_Updating){
    scrollableText = Replace_Accent(msg);
    tft.fillRect(1,87,157,45,WHITE);
    lastPos = 160;
  }else{
    tft.setCursor(0,95);
    tft.setTextSize(2);
    tft.fillRect(0,93,160,45,WHITE);
    tft.print( Replace_Accent(msg) );
  }
}

// This is where the update happens.
static const inline void updateText(){
  if(scrollableText != ""){
    tft.setTextWrap(false,false); // setting text wrap to false because i want to scroll the text
    int minPos = scrollableText.length() * 17; // get the text length multiplied some tested numbers to scroll trought the whole screen
    if(lastPos < -minPos){ lastPos = 160;} // if we reached the minPos we have to reset the position to the other side of the screen
    tft.setCursor(lastPos,93); // always start at the last pos.
    tft.setTextSize(3); // size for readability
    tft.fillRect(1,92,157,45,WHITE); // have to clear the last text from the screen
    lastPos = lastPos - 3; // set the next position.
    tft.print( scrollableText ); // actually print the text
    tft.setTextWrap(true,true); // set the wrap back because some other function writes to the screen too on another task.
  }
}

long startScrollMs = 0;
static const inline void scrollNoty(){
// update the screen every 30 millis if we got IP.
  if(millis() - startScrollMs >= 30){
    startScrollMs = millis();
    if(ETH_Got_IP){
      updateText();
    }
  }
}

The problem is that the text flickering because of this tft.fillRect(1,92,157,45,WHITE); line.

How can i update the text without filling this rect with white background?

Bodmer commented 3 years ago

Have you set the background colour for the text to white, so thne the new text over-writes the old text?

zekageri commented 3 years ago

Have you set the background colour for the text to white, so thne the new text over-writes the old text?

Oh. I thought the text background is default white and my screen background is filled with white default too. The text color is green.

zekageri commented 3 years ago

Here is a video from the flickering on my drive

zekageri commented 3 years ago

Okay. The text background color to WHITE did solved my problem. Thank you for your help!

The update function looks like this now:

static const inline void updateText(){
  if(scrollableText != "" && !writing){
    if(millis() - lastUpdateMs <= LAST_NOTY_DISP_TIME_MS){
      tft.setTextColor(DKGREEN,WHITE);
      tft.setTextWrap(false,false);
      int minPos = scrollableText.length() * 18;
      if(lastPos < -minPos){ lastPos = 160; tft.fillRect(1,92,158,45,WHITE);}
      tft.setCursor(lastPos,93);
      tft.setTextSize(3);
      lastPos = lastPos - 3;
      tft.print( scrollableText );
      tft.setTextWrap(true,true);
    }else if(!resetOnce){
      resetOnce = true;
      tft.fillRect(1,92,158,45,WHITE);
    }
  }
}