Go Down

Topic: Running Text on a 16x2 LCD (Read 14 times) previous topic - next topic

davekw7x

#10
Feb 03, 2011, 07:18 pm Last Edit: Feb 03, 2011, 07:34 pm by davekw7x Reason: 1

I wanted to push up the second line on the first and continue to write on the second line. So I had to erase the first, copy the second to the first,  erase the 2. and continue to write on the second....Anyway I found some other useful code


Instead of "finding" some code why not just implement your scheme as you articulated it.  I mean, my observation is that the hardware "autoscroll" function hardly ever does what people think it should do, but doing things like you need in software is straightforward.

Maybe something like the following
Code: [Select]

//
// Simple line-by-line scrolling for LCD with two rows
//
// davekw7x
//
#include <LiquidCrystal.h>

const int NROWS = 2;
const int NCOLS = 16;

LiquidCrystal lcd(7, 6, 5, 4, 3, 2); // Customize for your connections.

void setup()
{
   lcd.begin(NCOLS, NROWS); // This clears the LCD
   lcd.setCursor(0, 1);     // Start on the second row
}

int counter = 1;
void loop()
{
   char buffer[17];

   sprintf(buffer, "  Loop %d: ", counter);
   sendmsg(buffer);
   ++counter;
   for (char alpha = 'a'; alpha <= 'z'; ++alpha) {
       buffer[0] = alpha;
       buffer[1] = '\0';
       sendmsg(buffer);
       delay(300);
   }
   delay(2000);
}


void LcdClearLine(int r)
{
   lcd.setCursor(0,r);
   for (int i = 0; i < NCOLS; i++) {
       lcd.print(" ");
   }
}

char line[NCOLS];
char col;   // The compiler makes sure this is initialized to zero.

void sendmsg(char *str)
{
   while (*str) {
       if (col >= 16) {
           //Serial.println("Scrolling"); // Uncomment for debugging
           // Print the line contents to the first row
           lcd.setCursor(0, 0);
           for (int i = 0; i < NCOLS; i++) {
               lcd.print(line[i]);
           }
           LcdClearLine(1);     // Spaces to second row
           lcd.setCursor(0, 1); // set cursor to beginning of second row
           col = 0;
       }
       line[col] = toupper(*str);
       lcd.print(line[col++]);
       ++str;
   }
}


Regards,

Dave

Footnote:
"quasi-code" for the functionality could be added as comments:
Code: [Select]

Suppose we have an LCD that has two rows.  Each row has NCOLS
columns.

Here is a way to scroll the way that you indicated

/*
   There is a static array that holds characters of
   the current line:
*/

char line[NCOLS];

/*
   There is a static integer used to keep track of the
   column position for the next character.  This is
   also used as an index to store the character in
   the array.
*/

int col; // Initialized to zero

/*
   sendmsg gets a pointer to char (the "string pointer")
   For each character in the "string," here's what the function
   does:
   1.
       If the array is full (col equal to NCOLS), it copies the
       contents of the array to the first line of the the LCD and
       clears the second line of the LCD. It sets col to zero

   2.
       It stores the character in the array and prints the char
       to the LCD.

   3.
       It increments the column counter and it increments the "string pointer"

*/


LeseLaster

Quote
Sometimes I just can't help myself.


.. but you certainly helped another one...  :)

Thanks for the pseudo-code and the real one. I learned:
- internal variables,
- predeclared functions
- ...

Still have problems with pointer and why you have filled the buffer[17] with   buffer[1] = '\0';
I thought that was not needed for the LCD.

No excuse, but I stopped about 15 years ago programming in Smalltalk and Prolog and started now again with C. So going is slow and I learn quicker by example when I am unsure about the syntax.

Again thanks for your help.
---
... indessen wandelt harmlos droben das Gestirn

liudr


Quote
Sometimes I just can't help myself.


.. but you certainly helped another one...  :)

Thanks for the pseudo-code and the real one. I learned:
- internal variables,
- predeclared functions
- ...

Still have problems with pointer and why you have filled the buffer[17] with   buffer[1] = '\0';
I thought that was not needed for the LCD.

No excuse, but I stopped about 15 years ago programming in Smalltalk and Prolog and started now again with C. So going is slow and I learn quicker by example when I am unsure about the syntax.

Again thanks for your help.


It is because a C string needs to be zero-terminated. Does that ring a bell? If a string is not terminated, the print doesn't know when to stop printing and will continue to print beyond the string and read sections of memory that's totally not string so you will get junk and sometimes freeze up. If you define a string like char a[]="hello"; the compiler helps you attach a zero in the end.

LeseLaster

This is the one for whom the bell tolls - it did.  :smiley-red:

Thanks liudr - now I try to integrate the modified code into the program and go on until I get the blue screen  ]:)
---
... indessen wandelt harmlos droben das Gestirn

liudr

Good approach! In the 90s when I was experimenting on 386 assembly i got blue screen (prior to windows there were no blue screen but I intend to use this expression for cpu freeze) very often :)

I'm just glad my code is useful to others.

Go Up