Scrolling input text

Hello!

I would like some guidance with respect to scrolling text.

The idea is to get a text string through serial input, and then print it onto a 16X2 Lcd.

I would like the text string to scroll only on the first line, how ever long( ie, not wrap if it’s greater than 42 characters) ( I am yet to implement this )

Here is the sketch I am using right now.

#include <LiquidCrystal.h>

LiquidCrystal lcd(8,9,10,11,12,13);

void setup()
{
  lcd.begin(16,2);
  Serial.begin(9600);
  Serial.print("On");
}

String serialinput = "";
String toprint = "";

void loop()
{
  while (Serial.available()>0)
  {
    char c = Serial.read();
    serialinput += c;
    if ( c == 13)
    {
      Serial.println("CR");
      serialinput.trim();
      processinput();
    }
  }

  printOutput();
  delay(500);
  //Serial.println("No data");
}

void processinput()
{
  if (serialinput  == "clear")
  {
    lcd.clear();
    toprint="";
  }
  else
  {  
    toprint = serialinput;
  }
  serialinput = "";

}

void printOutput()
{

  lcd.clear(); 
  lcd.print(toprint);
  int len = toprint.length();
  if (len>16)
  {  
    for(int i=0;i<len;i++)
    {
      lcd.scrollDisplayLeft();
      delay(250);
    }
  }
}

My issue is that the string scrolls, then rests to zero ( the loops is over printOutput() is called again)
So it looks like this,
This is a long long string
|This is a long |
|a long long str|
|ng string |
| This is|
and then it just resets back to the home position.
|This is a long |

What is the most efficient way to approach this?

I would like the watch for incoming data in the loop() function, then process that data else where, and then print it out, scrolling continuously until a second input is received, or a clear command is received.

Regards!

So I did a bit of reading up and realized I could use timers to achieve my goal.

So here is a bit of the new code.

#include <SimpleTimer.h>
#include <LiquidCrystal.h>

LiquidCrystal lcd(8,9,10,11,12,13);
SimpleTimer timer;
static char input[50];
char printdata[50];
void get_serial_data()
{

static unsigned int pos = 0;
Serial.println(“Get_serial_data”);
while (Serial.available()>0)
{
char inByte = Serial.read();

switch(inByte)
{
case ‘/n’:
input[pos] = 0;
Serial.println(“gotdata”);
process_data(input);
pos=0;
break;
case ‘/r’:
break;
default:
if (pos<50-1)
input[pos++] = inByte;
break;
}
}
}

void process_data(char * processdata)
{
Serial.println(“Processdata”);
if(strcmp(processdata,“clear”) == 0)
lcd.clear();
timer.setInterval(1000, print_data);

}

void print_data()
{
strcpy(printdata,input);
unsigned int l = strlen(printdata);
unsigned int x,y;
lcd.setCursor(0,0);
if (l <=16)
{
delay(100);
lcd.print(printdata);
return;
}
for ( x=0; x<l-16;x++)
{
for(y=x;y<x+16;y++)
{
lcd.print(printdata[y]);
}
if ( x == 0) delay(800);
delay(200);
lcd.home();
}
delay(800);
}
void setup()
{
Serial.begin(9600);
lcd.begin(16,2);
timer.setInterval(1000, get_serial_data);
}

void loop()
{
timer.run();

}

But I think I have a few issues with the char array I am trying to print. I am getting one long array of all my serial input commands.

Would really appreciate inputs as to how to approach this!

Thanks!

My error was in the new line character in the switch.

it should be /n instead of \n.

I now have a new problem!

I am able to send a string to the print_data function, but sometimes, as the text is scrolling, The get_serial data seems to hang. Am I doing something wrong? or is there a simpler way to achieve this? also, there seems to a lot of lag between the inputs, how can I clean up all the delays in between?

Thanks!

I think I’ve got it to work! :slight_smile:

What would be the best way to tighten this code up?

#include <SimpleTimer.h>
#include <LiquidCrystal.h>

LiquidCrystal lcd(8,9,10,11,12,13);
SimpleTimer timer;
static char input[50];
char  printdata[50];
int timer_prt_Id;
void get_serial_data()
{

  static unsigned int pos = 0;
  Serial.println("Get_serial_data");
  while (Serial.available()>0)
  {
    Serial.println("Data Available!");
    char inByte = Serial.read();

    switch(inByte)
    {
    case '\n':
      input[pos] = 0;
      Serial.println("gotdata");
      timer.disable(timer_prt_Id);
      lcd.clear();
      process_data(input);
      pos=0;
      break;
    case '\r':
      Serial.print("Enter");
      break;
    default:
      if (pos<50-1)
      {
        input[pos++] = inByte;
        Serial.println(inByte);
      }
      break;
    }

  }
}

void process_data(char * processdata)
{
  Serial.println("Processdata");
  if(strcmp(processdata,"clear") == 0)
  {
    lcd.clear();
    timer.disable(timer_prt_Id);
  }
  timer.enable(timer_prt_Id); 
  strcpy(printdata,input);


}

void print_data()
{
  unsigned int l = strlen(printdata);
  unsigned int x,y;

  lcd.setCursor(0,0);
  if (l <=16)
  {
    delay(100);
    lcd.print(printdata);
    return;
  }
  for ( x=0; x<l-16;x++)
  {
    for(y=x;y<x+16;y++)
    {
      lcd.print(printdata[y]);
    }
    if ( x == 0) delay(300);
    delay(200);
    lcd.home();
  }

}
void setup()
{
  Serial.begin(9600);
  lcd.begin(16,2);
  timer.setInterval(1000, get_serial_data);
  timer_prt_Id = timer.setInterval(100, print_data);

}

void loop()
{
  timer.run();

}

My ultimate aim is to interface it with my system to notify me of particular events.