1

I'm trying to scroll a string in the second row of the LCD while letting the string on the first row stay intact. I use Serial to run that part of the code as you can see. It work at first but when I try to make it run again it doesn't display anything on the second row.

I borrowed the code from :

http://code.nishantarora.in/arduino-lcd-projects/src/3f10686e7464665c5c59d7be772c00af7a4a93e8/scrollOneLine/scrollOneLine.ino?at=master

And made some changes:

// include the library
#include <LiquidCrystal.h>

// init the lcd display according to the circuit
LiquidCrystal lcd(9, 8, 7, 6, 5, 4);

// it's a 16x2 LCD so...
int screenWidth = 16;
int screenHeight = 2;

String line1;
String line2;

int stringStart, stringStop = 0;
int scrollCursor = screenWidth;

String CompleteString;
String stringArray[] = {"s=Plane", "i=Car", "h=Boat", "u=Rocket", "d=Jet",  "p=Submarine", "l=Truck", "b=Bicycle", "m=Skate", "enter=Train"};

String string1 = "String";

int countMovement=0;
int arraylimit = 9;

void setup() {

   lcd.begin(screenWidth,screenHeight);
   Serial.begin(9600);

}

void loop(){

   char ser = Serial.read();

   if ( ser == 'c' ) {  
     CompleteString="";

     for (int i = 0 ; i <= arraylimit; i++) {
        CompleteString += stringArray[i] + " "; // Convert String Array To Single String
     }

     roop(string1,CompleteString);
  }

}

void roop(String line1, String line2) {

  countMovement = 0;

  while ( ( countMovement ) < (line2.length() + screenWidth )  ) {

     lcd.setCursor(scrollCursor, 1);
     lcd.print(line2.substring(stringStart,stringStop));
     lcd.setCursor(4, 0); // 1 = word eat array of words very cool
     lcd.print(line1);
     delay(300);
     lcd.clear();

     if(stringStart == 0 && scrollCursor > 0){
        // Serial.println(scrollCursor);     
        scrollCursor--;
        stringStop++;
     } else if (stringStart == stringStop){
        stringStart = stringStop = 0;
        scrollCursor = screenWidth;
     } else if (stringStop == line1.length() && scrollCursor == 0) {
        stringStart++;
     } else {
       stringStart++;
       stringStop++;
     }

     countMovement++;

  }

  lcd.setCursor(4, 0);
  lcd.print(line1);

}

From what I can see using Serial as debugging is that the problem resides in the function "roop" and in specific the line:

 if(stringStart == 0 && scrollCursor > 0){

It seems that the statement is being pass on and so it doesn't move the string as it's suppose to. I could be wrong but placing a Serial call in there yields no result the second time the function is called but the first time it did.

Any help would be much appreciated! And I know the community will be grateful too since it's difficult from what I can see in post to achieve this and make it autonomous so that no big modifications needs to be done.

2
  • You may add the LiquidCrystal.h/.cpp code to your project and modify it if necessary.
    – Thomas S.
    Commented Aug 28, 2014 at 15:26
  • Why do I need to do that? I'm almost there. I know it only needs a little bit of understanding and a simple explanation to make it work. Someone to point what's wrong in the code.
    – DarkXDroid
    Commented Aug 28, 2014 at 16:52

2 Answers 2

1

You need to reset the stringStart, stringStop and scrollCursor at the beginning of the roop function.

void roop(String line1, String line2) {

  countMovement = 0;
  stringStart = 0;
  stringStop = 0;
  scrollCursor = screenWidth;

  ...

I think you also need to move the lcd.clear up. Or else the screen will be blanked when the roop function is done scrolling.

...

  while ( ( countMovement ) < (line2.length() + screenWidth )  ) {

     lcd.clear();
     lcd.setCursor(scrollCursor, 1);
     lcd.print(line2.substring(stringStart,stringStop));
     lcd.setCursor(4, 0); // 1 = word eat array of words very cool
     lcd.print(line1);
     delay(300);

...
2
  • 1
    Seriously man that's what I was talking about! A simple mistake with an easy solution. I found another code that does the same in both directions so I'll be posting both codes for future reference. Thanks 4 your time
    – DarkXDroid
    Commented Aug 30, 2014 at 15:08
  • Great! Glad to have helped.
    – Gerben
    Commented Aug 30, 2014 at 17:45
0

The answer from the user Gerben worked perfect. So I'll be posting another solution I came upon and the one from my original question for feature reference.

Original Code:

// include the library
#include <LiquidCrystal.h>

// init the lcd display according to the circuit
LiquidCrystal lcd(9, 8, 7, 6, 5, 4);

// it's a 16x2 LCD so...
int screenWidth = 16;
int screenHeight = 2;

String line1;
String line2;

int stringStart, stringStop = 0;
int scrollCursor = screenWidth;

String CompleteString;
String stringArray[] = {"s=Plane", "i=Car", "h=Boat", "u=Rocket", "d=Jet", "p=Submarine", "l=Truck", "b=Bicycle", "m=Skate", "enter=Train"};
String string1 = "String";
boolean ArrayRead = true;
int countMovement=0;
int arraylimit = 9;

// most of the part is pretty basic
void setup() {

   lcd.begin(screenWidth,screenHeight);
   Serial.begin(9600);

}

void loop(){

   char ser = Serial.read();

   if ( ser == 'c' ) {  
      CompleteString="";

      for (int i = 0 ; i <= arraylimit; i++) {
         CompleteString += stringArray[i] + " "; // Convert String Array To Single String
      }

      roop(string1,CompleteString);
   }

}

void roop(String line1, String line2) {

   countMovement = 0;
   stringStart = 0;
   stringStop = 0;
   scrollCursor = screenWidth;

   while ( ( countMovement ) < (line2.length() + screenWidth )  ) {

      lcd.clear();
      lcd.setCursor(scrollCursor, 1);
      lcd.print(line2.substring(stringStart,stringStop));
      lcd.setCursor(5, 0); // 1 = word eat array of words very cool
      lcd.print(line1);
      delay(300);
      lcd.clear();
      if(stringStart == 0 && scrollCursor > 0){     
         scrollCursor--;
         stringStop++;
      } else if (stringStart == stringStop){
         stringStart = stringStop = 0;
         scrollCursor = screenWidth;
      } else if (stringStop == line1.length() && scrollCursor == 0) {
         stringStart++;
      } else {
         stringStart++;
         stringStop++;
      }

      countMovement++;

   }

   lcd.setCursor(4, 0);
   lcd.print(line1);

}

The other code provided by the user "HazardsMind" for I2C LCD Module: The changes made are Serial communication and adapted for the 6 pin LCD Module.

// include the library
#include <LiquidCrystal.h>

// init the lcd display according to the circuit
LiquidCrystal lcd(9, 8, 7, 6, 5, 4);

//char * SerialComm[70];
//{"s = Plane i=Car h=Boat u=Rocket d=Jet p=Submarine l=Truck b=Bicycle m=Skate enter=Train"};

#define N_CHARS  ((sizeof(MessageOut)/sizeof(MessageOut[0]))-1)
#define N_CHARS2  ((sizeof(MessageOut2)/sizeof(MessageOut2[0]))-1)

//int len = strlen(SerialComm);

char MessageOut[30];
char MessageOut2[30];



int index = 19, index2 = 0;
unsigned long oldTime = 0, oldTime2 = 0;

byte indexer = 0; // Index into array; where to store the character
char inData[58]; // Allocate some space for the string
char inChar; // Where to store the character read



void setup()
{
   Serial.begin(9600);
   lcd.begin(16, 2);                      // initialize the lcd  
}

void loop() 


  while(Serial.available() > 0) // Don't read unless
                                              // there you know there is data
  {
      if(indexer < 57) // One less than the size of the array
      {
         inChar = Serial.read(); // Read a character
         inData[indexer] = inChar; // Store it
         indexer++; // Increment where to write next
         inData[indexer] = '\0'; // Null terminate the string
      }
  }
  // Now do something with the string (but not using ==)

  // Serial.print(inData);
  setHeadingRight("Royal", 0, 500);
  setHeadingLeft(inData, 1, 500);

  //setHeadingRight("Hello Welcome", 0, 1000); // message, row, duration
  // setHeadingLeft("Welcome", 1, 500);
}

void setHeadingRight(char * msg, byte row, unsigned long duration) 
{
   strncpy(MessageOut, msg, sizeof(MessageOut));
   if(millis() - oldTime > duration) // check the difference of the current time "millis()" to the previous time "oldTime" against the duration you want.
   {
      oldTime = millis(); // update oldTime with the current time
      if(index >= 0) // make sure the index does not go under 0
      { 
        index--; // decrecment index by 1
        for (int i = 0; i < N_CHARS; i++) // this part here displays the message on the display
        {
           lcd.setCursor(i,row); // set the column to show the element in the array
           if(index == N_CHARS) index = 0; // set index back to 0 if the index has reached the arrays max size.

              if(MessageOut[index++] != NULL) // if the element @ index is anything but NULL, show it.
                  lcd.print(MessageOut[index-1]);
              else 
                  lcd.print(' '); // if the element @ index is NULL, display a space.   
        }
      }
   else index = 19; // if index is less than 0, then set it back to 19
 }
}

void setHeadingLeft(char * msg, byte row, unsigned long duration2) 
{
  strncpy(MessageOut2, msg, sizeof(MessageOut2));
  if(millis() - oldTime2 > duration2)
  {
     oldTime2 = millis();
     if(index2 < 20) // check to see if index2 is under the array max size
     {
        index2++; // increment index
        for (int i = 0; i < N_CHARS2; i++) // same as above
        {
           lcd.setCursor(i,row);
           if(index2 == N_CHARS2) index2 = 0;

              if(MessageOut2[index2++] != NULL)
                 lcd.print(MessageOut2[index2-1]);
              else 
                 lcd.print(' ');    
              }
           }
           else index2 = 0; // otherwise set it back to 0
     }
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.