Setting the cursor position for a Serial LCD

I recently purchased Sparkfun’s serial back pack for my HD44780 LCD (4x20) to free up some pins on my Arduino Uno. To make a long story short, I am in the process of rewriting a lot of my code because my sketch was written for the LiquidCrystal library. Anyway to make a long story short, I don’t like the way you set the cursor position (line and column) for Sparkfun’s serial back. I’ve also looked at the different libraries in the playground section, but none of them are even close to the way the LiquidCrystal library handles cursor position.

I forget whicj library this is from, but this is an example how it's done for sparkfun's serial back pack.

//position = line 1: 0-19, line 2: 20-39,etc, 79+ defaults back to 0
void goTo(int position)	{ 
if (position<20)	{
	Serial.print(0xFE, BYTE);   //command flag
	Serial.print((position+128), BYTE);    //position
}else if (position<40)	{
	Serial.print(0xFE, BYTE);   //command flag
        Serial.print((position+128+64-20), BYTE);    //position
}else if (position<60)	{
	Serial.print(0xFE, BYTE);   //command flag
        Serial.print((position+128+20-40), BYTE);    //position
}else if (position<80)	{
	Serial.print(0xFE, BYTE);   //command flag
        Serial.print((position+128+84-60), BYTE);    //position
} else { 
	goTo(0);
  }

I took a look at the setCursor code, but I couldn’t figure out what was going on. Does anyone have any idea’s on how I can rewrite the above code to so that I could pass it the line and column numbers?

There is a close relationship between position and row, column, so you could multiply (row-1) by 20, and add column to get position.

But, what that code is doing is the reverse operation, to get row and column, so why not just use row and column. Each if block there specifies the action for one row.

Do I understand that you do not like to write goTo(34) to go the the 14th column on the 2nd line, but would prefer to write goTo2(2,14)?

void goTo2(int L, int C) {
 gotTo( (L-1)*20+C ) ; 
}

Have you looked at http://openmoco.org/node/153 ? The SparkSoftLCD library, has the function cursorTo(row, col) - it would be extremely simple to reverse these arguments in the library, to match the order of arguments in liquidcrystal library (col, row).

Of course, if you just want to figure out how to set the row and column, this may be more instructive than your example (from the above library) :

   switch(line) {
   	   case 1:
   	   	 break;
	   case 2:
		 pos += 64;
		 break;
	   case 3:
		 pos += 20;
		 break;
	   case 4:
		 pos += 84;
		 break;	 
	   default:
	 	 return;
   }
  
   
   pos += 128;   
   
   sendControl( pos );

!c

Wow, thanks guys. That's why I love this community, everyone helps each other out. I've spent a few days searching the internet for something similar to LiquidCrystal library and looks like the SparkSoftLCD library is pretty close. I think I'll probably use the SparkSoftLCD library because I wouldn't have to make too many changes to my sketch. Thanks for the other suggestion; it had me pulling my hair out last night. it kind of makes sense now.

JRMN:
Wow, thanks guys. That's why I love this community, everyone helps each other out. I've spent a few days searching the internet for something similar to LiquidCrystal library and looks like the SparkSoftLCD library is pretty close. I think I'll probably use the SparkSoftLCD library because I wouldn't have to make too many changes to my sketch. Thanks for the other suggestion; it had me pulling my hair out last night. it kind of makes sense now.

No problem at all =) Glad to be of service!

If you have any issues with the library, let me know. (Disclosure: I'm the author =)

!c

Looks like your library supports 16x2 and 20x2, but doesn't not support 20x4 LCDs.

I use this :

#include <LiquidCrystal.h>    // include the library code:
LiquidCrystal lcd(2, 3, 4, 5, 6, 7);

void setup() {
  lcd.begin(16, 4);
  lcd.print("hello, world!");
}

void LCDpos(int Lcol, int Lrow) {
  lcd.setCursor(Lcol, Lrow);
  if(Lrow > 1) lcd.setCursor(Lcol + 16, Lrow - 2);
}

void loop() {

  LCDpos(0,1); lcd.print("Line 1");
  LCDpos(0,2); lcd.print("Line 2");
  LCDpos(0,3); lcd.print("Line 3");
  LCDpos(0,4); lcd.print("Line 4");

}

How are you using the LiquidCrystal library with a serial LCD, wouldn't you still have 6 pins tied up?

Hi JRMN

Yes, it does still use 6 pins, but I didn't think that the pins used was the subject of the thread - it was to do with the cursor position. Did I mis-understand what you were looking for ?

JRMN:
Looks like your library supports 16x2 and 20x2, but doesn't not support 20x4 LCDs.

It is supposed to support 20x4, what's not working for you?

!c

@DaveO, I bought the serial backpack because I need to free up some pins

@Drone, sorry for the late response, but my house was hit pretty hard by Irene. As soon as I set my computer back up I will let you know the issues I experienced. I have a lot on my mind right now and can’t think clearly.

You're right, it does work for 20x4 LCDs.

This didn't work:

#define LCD_WIDTH 20
SparkSoftLCD lcd = SparkSoftLCD(LCD_TX_PIN, LCD_WIDTH);

This worked:

SparkSoftLCD lcd = SparkSoftLCD(LCD_TX);

I did notice something weird though. I am able to create and use custom characters with the SerLCD, however, if leave the Arduino Uno unplugged for awhile and then plug it back in, my sketch doesn't run correctly. Right now I am only using custom characters.

JRMN:
This didn't work:

#define LCD_WIDTH 20

SparkSoftLCD lcd = SparkSoftLCD(LCD_TX_PIN, LCD_WIDTH);




This worked:


SparkSoftLCD lcd = SparkSoftLCD(LCD_TX);




I did notice something weird though. I am able to create and use custom characters with the SerLCD, however, if leave the Arduino Uno unplugged for awhile and then plug it back in, my sketch doesn't run correctly. Right now I am only using custom characters.

That's odd that the constructor didn't work for you - I suppose it gave a compile error, about not having a matching prototype... It may be resolved by saying:

SparkSoftLCD lcd = SparkSoftLCD(LCD_TX, (uint8_t) LCD_WIDTH);

Either way, it's not actuallly necessary since there is effectively no difference in how it drives the LCD with or without the width argument - that's likely an artifact from early on when it appeared the positioning arithmetic was different based on different widths. It's not actually, and you can see in the cursorTo method it behaves the same given any width (I should remove the spurious inclusion of 'lenAdd').

Sorry to hear about the damage Irene did, haven't had to deal with a hurricane around here since Ike, and that was a pretty big clean-up. Wouldn't wish that on anyone!

!c