Scrolling on 16x2 Serial LCD (need help with code)

my LCD is fixed now back to the original problem.

I have a 16x2 Sparkfun Serial LCD

I want to use it to scroll text left to right.

so if I have text, oh say 100 characters long it will scroll through the whole thing once and then stop.

If someone would be so kind as to point me in the right direction I would appreciate it.

there are scroll commands in the data sheet

Scroll Right 0x1C

Scroll Left 0x18

however I have not been able to figure out how to use them.

here is the code I wrote to do this so far

Clearly there has to be a better way to do this…

#include <NewSoftSerial.h>


NewSoftSerial LCD(0,5); // serial LCD connected to pin #5

int y = 15; // for scroll

void setup(){
  LCD.begin(9600);
}

void loop()
{
  goTo(y);
  LCD.print("The Quick Brown Fox Jumps Over The Lazy Dog...");
  y=y-1;
      
  if(y<0){
    y=15;
  }
  
  delay(250);
  clearLCD();
 
}
  
  



// LCD LCD COMMAND CODES
    // Initiates a function command to the display
      void serCommand() {
          LCD.print(0xFE, BYTE);
          }
    // Resets the display, undoing any scroll and removing all text
      void clearLCD() {
           serCommand();
           LCD.print(0x01, BYTE);
         }
    // Starts the cursor at the beginning of the first line (convienence method for goTo(0))
      void selectLineOne() {  //puts the cursor at line 0 char 0.
           serCommand();   //command flag
           LCD.print(128, BYTE);    //position
        }
    // Starts the cursor at the beginning of the second line (convienence method for goTo(16))
      void selectLineTwo() {  //puts the cursor at line 0 char 0.
           serCommand();   //command flag
           LCD.print(192, BYTE);    //position
        }
        // Sets the cursor to the given position
    // line 1: 0-15, line 2: 16-31, 31+ defaults back to 0
    void goTo(int position) {
      if (position < 16) { 
        serCommand();   //command flag
        LCD.print((position+128), BYTE);
      } else if (position < 32) {
        serCommand();   //command flag
        LCD.print((position+48+128), BYTE);
      } else { 
        goTo(0); 
      }
    }

ok now I managed to screw myself over. I accidentally left the serial line connected when uploading and now no matter what I do I cant get the screen to reset. anyone know what I can do to fix this or am I going to have to get a new one :confused:

Try sending a 18 (dec) @ 9600 baud when the splash screen is on.

If it’s the same device I just looked up, it should reset the display.

(ex.) → serial.print(18, DEC);

Dave

It is possible, but it’s a bit tricky:

  1. It requires you to send a CTL-R at 9600 baud as soon as the splash screen is displayed to reset the baud rate to 9600.

  2. Once this is done, you actually have to send the commands to physically set the baud-rate to 9600 baud, otherwise it won’t stick when you reboot the display.

  3. Then, you might have to reset the display brightness, cursor type, or other things.

The big problem with this is that you either have to have access to a serial terminal that can send commands to the LCD during it’s power-up, or if you were using an Arduino sketch, a way to sync power and the CTL-R command.

What I did to reset mine was to use a Seeed motor shield (to control power), and snippits of Sparkfun’s “Fake_Data” demo, to send commands to the LCD display. Even though I used the Seeed motor shield, (because it was what I had), you could probably do this with any motor shield that allows you to completely turn off power to the external device, and lets you tie the “device” power to the Arduino +5 since the current drain from the LCD is negligible.

Here is the sketch I used. It’s a bit long because I include a lot of explanatory text and comments.

/*
  ResetLCD uses code from both the LCD FakeData and Seeed stepper
  sketches to create a sketch to do a force-reset on the
  SparkFun 16x2 LCD display
  
Theory:
  If the SparkFun LCD display module gets fed garbage, it can get itself
  into a bizarre and unknown state - especially if the baud-rate gets
  set to something unknown.
  
  Within section 3.4, (Changing the LCD Baud Rate), of the SparkFun LCD
  datasheet, (SerLCD_V2_5.PDF at www.sparkfun.com), the datasheet tells
  us that we can reset the baud-rate to 9600 baud if we send a CTRL-R
  character during the LCD module's startup process - while the logo
  screen is, (should be), displayed.
  
  One issue is that the reset command has to be sent to the LCD very quickly
  after power has been applied in order for it to work properly.
  
  To accomplish this we used an Arduino Uno, an Arduino prototyping
  shield, and a Seeed Motor shield.
  
  The Arduino gives us a way to control both the LCD display module's
  power and the serial data sent to it.
  
  The prototyping shield gives us a place to attach the serial and ground
  wires from the LCD display module.
  
  The Seeed motor control shield allows us to apply, and remove, power
  under program control by connecting the LCD's power pin to pin 1 of
  the DC motor control power pins.
  
====================================================*/

// Use the softwareserial library to create a new "soft" serial port
// for the display. This prevents display corruption when uploading code.
#include <SoftwareSerial.h>

/* Define the motor power output control pins.
   These pins control power to the four DC motor control pins
   on the Seeed motor controller */
int power_1 = 8;       // This is the pin connected to the LCD
int power_2 = 11;      // But you could use any one of these you want
int power_3 = 12;      // If you use pins 3 or 4, you have to swap the
int power_4 = 13;      // two enable statements - a to off, b to on.

/* Define the two enable pins on the Seeed motor controller shield
   The two enable pins enable the motor power pairs 1 - 2 and 3 - 4
   respectively
   enable_a enables the 1&2 pair
   enable_b enables the 3&4 pair
*/
int enable_a = 9;
int enable_b = 10;

// We define certain command and control constants here

int cntrl_r = 18;      // CTRL-R = 0x12 or decimal 18
int display_cfg = 124; // Begins a display configuration command
int display_fmt = 254; // Begins a display formatting command
int lcdbright = 142;   // Sets backlight brightness 128 - 157 (142 is half-bright)
int firstline = 128;   // Beginning of first line on first row
int lcdoff = 0x08;     // Disable display
int lcdon = 0x0C;      // Re-enable display and turn off anything fancy

// Attach the serial display's RX line to digital pin 2
SoftwareSerial mySerial(3,2); // pin 2 = TX, pin 3 = RX (unused)

// The setup routine only runs once when you press reset.

void setup() {                

// initialize the four coil control pins as outputs on the Arduino
  pinMode(power_1, OUTPUT);     
  pinMode(power_2, OUTPUT);     
  pinMode(power_3, OUTPUT);     
  pinMode(power_4, OUTPUT);

// initialize the two enable control pins as outputs too.
  pinMode(enable_a, OUTPUT);
  pinMode(enable_b, OUTPUT);

// set all power output pins low - nothing turned on yet
  digitalWrite(power_1, LOW);
  digitalWrite(power_2, LOW);
  digitalWrite(power_3, LOW);
  digitalWrite(power_4, LOW);

/* set enable a high and enable b low - we only need pair 1-2 active
   to control power to the LCD module. */
  digitalWrite(enable_a, HIGH);
  digitalWrite(enable_b, LOW);

  mySerial.begin(9600); // set up serial port for 9600 baud
}  //  End "setup" block

/*
The "loop" structure works identically to a forever loop;
for(ever), if(1), while(1), etc., as it repeats the block of code
until reset - or Hell freezes!
*/

void loop() {

/*
This first part applies power to the LCD display module, and while the
module is doing its "initialize" thing - we bit-bang it with the baud-rate
reset command.

If we're lucky, the LCD module will catch this and reset itself.
*/

//  We start by turning power on to the LCD so we can start the reset process
  digitalWrite(power_1, HIGH);  // Turn on +5 to LCD

//  Next we "bit-bang" CTRL-R repeatedly to reset the baud rate
//  (The number of iterations here was entirely arbitrary.)
  mySerial.write(cntrl_r); // attempt to clear baud rate to 9600
  mySerial.write(cntrl_r);
  mySerial.write(cntrl_r);
  mySerial.write(cntrl_r);
  mySerial.write(cntrl_r);
  mySerial.write(cntrl_r);
  mySerial.write(cntrl_r);
  mySerial.write(cntrl_r);
  mySerial.write(cntrl_r);
  mySerial.write(cntrl_r); // and hope it sticks!
  
/*
It appears that the baud-rate force-reset, (CTRL-R), only performs a *SOFT* baud-rate reset.
Apparently, after soft-resetting the baud rate to something sane, you must also
"formally" set the baud rate using a standard display mode set command emitting a CTRL-M,
otherwise the reset baud-rate is not committed to EEPROM memory.
*/

/* First, we set and **commit** the correct default baud-rate (9600) by emitting a 
   CTRL-M (0x0D) after giving the chip some settling time.
*/
  delay(500);
  mySerial.write(display_cfg);
  mySerial.write(0x0D);  //  Set and commit baud rate to 9600

  delay(1000); // give the command time to finish.

// Next, we cycle the display enable to reset the display and clear any fancy settings
  mySerial.write(display_fmt); // Signal display format command
  mySerial.write(lcdoff);  // Set LCD off
  delay(500);
  mySerial.write(display_fmt); // Signal display format command
  mySerial.write(lcdon);  // Set LCD back on again
  delay(500);

// Then, we increase the display brightness in case it was turned off
  mySerial.write(display_cfg); // Signal display function command
  mySerial.write(lcdbright);  // Set backlight brightness
  delay(500);

// Here we restart the LCD to verify that the settings were committed.
  digitalWrite(power_1, LOW);  // Turn off +5 to LCD
  delay(1000);
  digitalWrite(power_1, HIGH);  // Turn on +5 to LCD

//  Once we've done that, we need to give the LCD module time to catch
//  its breath and restart.
  delay(1500);
  
/*
At this point - if all has gone well - we should be back in business!
so we try to indicate this by displaying something "normal"
*/

//  Here we try to display a success message
  mySerial.write(display_fmt); // move cursor to beginning of first line
  mySerial.write(firstline);

  mySerial.write("                "); // clear display
  mySerial.write("                ");

  mySerial.write(display_fmt); // move cursor to beginning of first line
  mySerial.write(firstline);
 
  mySerial.write(" Display Reset  "); // display success
  mySerial.write(" is Successful! "); // message
  delay(2000);  // give the display time to be read before trying again

  mySerial.write(display_fmt); // move cursor to beginning of first line
  mySerial.write(firstline);
 
  mySerial.write("Remove Power and"); // display success
  mySerial.write(" Disconnect LCD "); // message
  delay(2000);  // give the display time to be read before trying again
  
  digitalWrite(power_1, LOW);  // Turn the display back off so we can try again
  delay(2000);
}                              // . . . and so on.

Hopefully this will do someone some good.

Jim (JR)