Start a new topic

Creating a scrolling text box

I would like to use the screen as a "dumb terminal" (a simple 15 line x 40 character display) that simply takes text and adds it to the bottom of the screen - then scrolls the remaining text up. My Arduino project prints status updates to the serial port and I'd like to use the Nextion to simply display these status updates. I have created something that works, but it is VERY inefficient. Would appreciate if someone could point me to a more efficient way of achieving this. The attached code snippet basically fills the screen with AAA .. OOO and then scrolls the LoremIpsum text. On an Arduino Uno this uses up over half the memory, not leaving much space for the project itself.


 

#include <SoftwareSerial.h>
SoftwareSerial mySerial(10, 11); // RX, TX
char Nextion1[] = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
char Nextion2[] = "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB";
char Nextion3[] = "CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC";
char Nextion4[] = "DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD";
char Nextion5[] = "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE";
char Nextion6[] = "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF";
char Nextion7[] = "GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG";
char Nextion8[] = "HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH";
char Nextion9[] = "IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII";
char Nextion10[] = "JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ";
char Nextion11[] = "KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK";
char Nextion12[] = "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL";
char Nextion13[] = "MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM";
char Nextion14[] = "NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN";
char Nextion15[] = "OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO";

char LoremIpsum1[] = "1Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur mollis est ac nunc vehicula rhoncus nec at arcu."; // A long line
char LoremIpsum2[] = "2Etiam mollis tellus lacus";                                                                                           // A short line
char LoremIpsum3[] = "3Vestibulum commodo hendrerit finibus. P";                                                                             // A line that's just right
char LoremIpsum4[] = "4Destroy";// A null line

char newline[41];
int k = 1;

void setup() {
  Serial.begin(9600);
  while (!Serial) {
    ; 
  }
  Serial.println(F("Hardware Serial Initialised..."));
  mySerial.begin(9600);
  Serial.println(F("Software Serial Initialised..."));
}


void loop() {
  updatescreen();
  generatenewdata();
  addnewline();
}

void updatescreen() {
  mySerial.print(F("xstr 0,0,320,240,0,BLACK,WHITE,0,0,1,\"")); //Allows for 15 rows of text with 40 characters per row 
  mySerial.print(Nextion1);
  mySerial.print(Nextion2);
  mySerial.print(Nextion3);
  mySerial.print(Nextion4);
  mySerial.print(Nextion5);
  mySerial.print(Nextion6);
  mySerial.print(Nextion7);
  mySerial.print(Nextion8);
  mySerial.print(Nextion9);
  mySerial.print(Nextion10);
  mySerial.print(Nextion11);
  mySerial.print(Nextion12);
  mySerial.print(Nextion13);
  mySerial.print(Nextion14);
  mySerial.print(Nextion15);
  mySerial.print(F("\""));
  mySerial.write(0xFF);
  mySerial.write(0xFF);
  mySerial.write(0xFF);
}

void addnewline() {

  newline[40]=0;               // Never allow a new line that isn't properly null terminated at 40
  while (strlen(newline)<40){  // Pad out short lines
      strcat(newline, " ");
    }
  strcpy(Nextion1, Nextion2);
  strcpy(Nextion2, Nextion3);
  strcpy(Nextion3, Nextion4);
  strcpy(Nextion4, Nextion5);
  strcpy(Nextion5, Nextion6);
  strcpy(Nextion6, Nextion7);
  strcpy(Nextion7, Nextion8);
  strcpy(Nextion8, Nextion9);
  strcpy(Nextion9, Nextion10);
  strcpy(Nextion10, Nextion11);
  strcpy(Nextion11, Nextion12);
  strcpy(Nextion12, Nextion13);
  strcpy(Nextion13, Nextion14);
  strcpy(Nextion14, Nextion15);
  strcpy(Nextion15, newline);
}

void generatenewdata() {
    newline[0] = 0;
    if (k==1){
      strncat(newline, LoremIpsum1, 40);
      }
    if (k==2){
      strncat(newline, LoremIpsum2, 40);
      }
    if (k==3){
      strncat(newline, LoremIpsum3, 40);
      }
    if (k==4){
      LoremIpsum4[0] = 0; //Simulating a null
      strncat(newline, LoremIpsum4, 40);
      }
    k++;
    if (k==5){
      k=1;
      }
}

 


Hi Patrick and Chris,

I now changed my scrolling screen to the "click m0,1" method with good results. The spare timer now brings me a time display at the lower end of the screen :-)

Thanks for your help!

 

Hey Michael,


In my code, the MCU first reads the tim value of the timer (t0) which performs the scrolling function.  The MCU then delays that amount of time after each scroll text update.  Another method would be for the MCU to store the time that the last scroll text was sent to Nextion and then if sufficient time had not passed (>= t0.tim) either delay the time needed to meet the required delay or try to send the text the next pass through the main loop.


My current project does use the simple method of delay immediately following sending the text to Nextion because I am using the scrolling text as feedback to the user during the MCU setup routines so the delay is much more helpful to allow the user to read the text before scrolling ... and most importantly, program flow and timing are not critical during the setup routines.

If my project utilized scrolling text during main code execution then I would use either:

1) Patricks method (except using timers instead of button/click because I have never been able to make them work).

2) Implement a buffered send and check if enough time has passed each pass through the main loop.

3) Utilize the scrolling text component in the Nextion firmware.


Obviously, the best method for any project is determined by whatever fits in the project design plans and the project's purpose for using scrolling text.


Hope that helps

Just a funny thought with Hollywood movie special effects:


- There's nothing like imitating 300 baud to represent hi-tech.

Of course, in my typewriter, the "scroll" was caused by responding to the return key.  No serial.

If we can get creative enough over serial ... just a thought ...


set a text variable va0 to the entire line of text you are send set .txt-maxl to length needed

create a numeric variable va1 to hold the char counter

create a text variable tmp to hold the substring

create a hotspot m0 to hold some code

set the numeric variable sys2 with its length using the strlen

then create a loop to print each letter out like teletype.  (I need to test this yet .. but)


placed in the hotspot m0 Touch event"

strlen(va0.txt,sys2)

for(sys0;sys0<=sys2;sys0++)

  {

     va1.val=sys2-sys0

     tmp.txt=va0.txt-va1.val

     t12.txt=tmp.txt

     delay=20

  }

t12.txt=va0.txt

Placed in the hotspot m0 Released event

t0.txt=t1.txt

t1.txt=t2.txt

t2.txt=t3.txt

t3.txt=t4.txt

t4.txt=t5.txt

t5.txt=t6.txt

t6.txt=t7.txt

t7.txt=t8.txt

t8.txt=t9.txt

t9.txt=t10.txt

t10.txt=t11.txt

t11.txt=t12.txt

t12.txt=""



sent over serial, va0.txt="This is the new line being added to the bottom line t12"

sent over serial, click m0,0

sent over serial, click m0,1


Might need some adjusting ...


Brilliant! Why didn't I think of that myself? :-) Since I exactly know when I need to scroll - why use a timer? Thanks a lot indeed!

Personally, if I were to have several lines that need to scroll ...

p6BdD6ir7tNeElGR2eynTCe6TTOyOoAMOw.png


I might take the approach triggering the scroll on the Nextion side

-- perhaps with a click m0,1 and put the code for t0.txt=t1.txt, t1.txt=t2.txt .... in hotspot m0 Pressed

and then send the final line t12.txt=" this is my line" over serial.

@Chris: Thanks a lot for your code - works!

I got a timing problem obviously, though. I am sending lines repeatedly to a screen with 12 lines, but only every second or so is shown. I think the copy routine takes too long to shift all 11 lines up before the next content is written to the trigger variable.

Any ideas how to speed up the scrolling on the Nextion?

 

@ambanmba, Why not transfer the scrolling function to the Nextion?

One simple way is to use a text variable to load the new line of text, then have a timer check for new data in the variable.  If new data is in the variable, transfer data from all lines up 1 line.  Not complex.

Here is how I do it with 5 scrolling lines for startup messages from the MCU.

--Nextion--

1) Create buffer variable. objname="startMsg", sta=String, txt-maxl=100, txt=""

2) Create 5 text elements on the page.  objname="startMsg1" to "startMsg5", sta=String, txt-maxl=100

3) Create a timer with tim=100, which contains the User Code:

if(startMsg.txt!="")
{
  startMsg1.txt=startMsg2.txt
  startMsg2.txt=startMsg3.txt
  startMsg3.txt=startMsg4.txt
  startMsg4.txt=startMsg5.txt
  startMsg5.txt=startMsg.txt
  startMsg.txt=""
}


--MCU--


 

 

void sendStartMsg (char* msg) {
  char endStr[3]{0xFF};
  Serial.print("startMsg.txt=\"");
  Serial.print(msg);
  Serial.print("\"");
  Serial.print(endStr);
}

That's all there is to it.

Each time you want to add a new line of text, simply call the sendStartMsg routine.


You can, of course, add as many lines as you want and adjust the Nextion code to meet your needs.


Cheers!

You need to connect the RX pin on the monitor to Pin 11 on the Arduino and the TX pin on the monitor to Pin 10 on the Arduino if you are using the code example above. 


This is like when hooking up a stereo... the IN of one device goes to the OUT of the other device. Similarly the TX of the monitor needs to go to the RX on the Arduino.

I connected the pin 10 to Arduino with RX, the pin 11 with TX.

Load the skatch but nothing happens on the screen, I use the default file

43.tft on the monitor, I think is the same as the 24.tft files with different resolution.

do you have any idea?

Thank you so much

I'm just using the native drivers that come with the Arduino IDE. Did you try swapping the RX, TX pins in case you have them crossed?

could you tell me which library you use?

you can attach the file?

it seems to me that my nextion not communicate with Arduino on that pin you connected rx and tx of nextion?

I tried it both on an Uno and Mega and it works fine.

do you have arduino UNO? becouse i have some problem whit nextion monitor on arduino UNO, i'm trying to fix the library, but I can not.

I have the NX3224T024_011 screen.


1 person likes this
Login or Signup to post a comment