Nokia LCD display shield question

Hi all,
I'm under the impression that the sparkfun color LCD shield doesn't work with liquidcrystal library.
I understand that it comes with it's own library that does lots of fancy stuff in the demos.
None of the example codes seems to tell me how to use it to print serial information.

All I need it for is to display the serial so I don't have to plug the arduino into a pc.

Does anyone know where to find a demonstration, or can you provide a demonstration of how to print serial data to the LCD shield and not have it stack letters up (when using print(F("word"));, not print blabla, all the problems I've hit already.
Visual learner, could do with a demo.

From the tutorial at Sparkfun.com...

One final feature of the library allows you to add text to the LCD. There's the setChar function, which allows you to place one, and only one, character at specified coordinates. Then there's the setStr function, which will place a string of characters on the screen.

Scroll down a little over half-way and you'll see the above text, after it will be a screenshoot of example code in the Arduino IDE. If you can convert the data you want to display into characters or strings this should work for you.

I guess you mean something like a terminal emulator for an LCD screen (Terminal emulator - Wikipedia). I did something very simple in that direction here: Google Code Archive - Long-term storage for Google Code Project Hosting.. It takes input from serial and outputs it on the LCD. Maybe a starting point for you.

Oliver

Far-seeker:
From the tutorial at Sparkfun.com...

One final feature of the library allows you to add text to the LCD. There's the setChar function, which allows you to place one, and only one, character at specified coordinates. Then there's the setStr function, which will place a string of characters on the screen.

Scroll down a little over half-way and you'll see the above text, after it will be a screenshoot of example code in the Arduino IDE. If you can convert the data you want to display into characters or strings this should work for you.

I think that will work and possibly look better than a scrolling serial data actually.

Thanks for both responses. Very helpful.

Glad to be of assistance.

Hi Again,
I just ran a quick test to get everything laid out properly and I hit a problem while integrating it into my main sketch.

This worked fine

#include <gLCD.h>

const char RST = 8;
const char CS = 9;
const char Clk = 13;
const char Data = 11;
gLCD graphic(RST,CS,Clk,Data,HIGH_SPEED); //High speed

char wt[] = "LOW";

void setup() {  
 graphic.begin(0,2,0,PHILLIPS_1); 
 graphic.setBackColour(1,1,1);
 graphic.Box(0,0,6100,6100,4);
   graphic.setFont(0);

}
void loop() {
  //call
  graphic.setForeColour(15,15,15); //Text is coloured Blue
  graphic.setCoordinate(1,1);
  graphic.print("Connected to server:"); //Normal sized text, no background. Hello and World will be printed on seperate lines
  //resp
  graphic.setCoordinate(1,10);
  graphic.setForeColour(0,15,0); //Text is coloured Blue
  graphic.print("TRUE"); //Normal
  
  
  //call
  graphic.setForeColour(15,15,15); //Text is coloured Blue
  graphic.setCoordinate(1,20);
  graphic.print("Standards:"); //Normal
  //resp
  graphic.setCoordinate(1,30);
  graphic.setForeColour(15,0,0); //Text is coloured Blue
  graphic.print(wt); //Normal
  
  //call
  graphic.setForeColour(15,15,15); //Text is coloured Blue
  graphic.setCoordinate(1,40);
  graphic.print("Burgervan tadpole?:"); //Normal
  //resp
  graphic.setCoordinate(1,50);
  graphic.setForeColour(15,0,15); //Text is coloured Blue
  graphic.print("Maybe"); //Normal
}

But the second I slot it into my code, it doesn't print the text. Just the stuff in the initial setup.

// Include description files for other libraries used (if any)
#include <Twitter.h>
#include <gLCD.h>
#include <Ethernet.h>
#include <SPI.h>
#include <EthernetUdp.h>
#include <PString.h>

// Define Constants
// Max string length may have to be adjusted depending on data to be extracted
#define MAX_STRING_LEN  80

const char RST = 8;
const char CS = 9;
const char Clk = 13;
const char Data = 11;
gLCD graphic(RST,CS,Clk,Data,HIGH_SPEED); //High speed

// Setup vars
char tagStr[MAX_STRING_LEN] = ""; //to contain the XML tags for comparison
char dataStr[MAX_STRING_LEN] = ""; //to store information between hashtags
char tmpStr[MAX_STRING_LEN] = ""; //temporary string for something.. I dunno
char prevStr[MAX_STRING_LEN] = ""; //to compare tweets to their previous, stops repeat functions
char buffer[MAX_STRING_LEN] = ""; // for PString... maybe Concatenate if it still jams up.
char endTag[3] = {'<', '/', '\0'};  //to recognise the ends of chars, XML tags and strings
char makeCoffee[] = "make me coffee"; // trigger text for incoming tweets
boolean firstTweetRead = false;  //to stop make() on first tweet read
PString tweetString(buffer, sizeof(buffer)); //contains the tweet
long randNumber; //to make the tweets unique
int len;               //No idea
int totalCount = 1;  //to count connect attempts 
int ledPin = 3;      //to control the relay


// Flags to differentiate XML tags from document elements (ie. data)
boolean tagFlag = false;     
boolean dataFlag = false;

// Ethernet vars
byte mac[] = { 0x90, 0xA2, 0xDA, 0x0D, 0x13, 0x1D };  //Arduino MAC
byte ip[] = {78,147,235,111 };                        //My home IP
byte server[] = { 199,59,149,232 }; // Twitter IP
Twitter twitter("794475482-XuCh0IVm8nTRcTAxkV6Gpx6VkdElWsww1Ns11n8x");


// Start ethernet client
EthernetClient client;

void setup()
{ 
 graphic.begin(0,2,0,PHILLIPS_1); 
 graphic.setBackColour(1,1,1);
 graphic.Box(0,0,6100,6100,4);
 graphic.setFont(0);
   
  pinMode (ledPin, OUTPUT);
  randomSeed(analogRead(5));
  
  Serial.begin(9600);
  //Ethernet Client
  // attempt a DHCP connection:
  Serial.println(F("setup"));
  if (!Ethernet.begin(mac)) {
    // if DHCP fails, start with a hard-coded address:
    Serial.println(F("failed, trying manually"));
    Ethernet.begin(mac, ip);
  }
  

 connectToServer();
}

void loop() {
  
    screen();

    while (client.connected()) {
    while (client.available()) { 

    serialEvent();
        screen();

    }
  }

  if (!client.connected()) {

    Serial.println();
    Serial.println(F("=========Disconnected=========="));
    Serial.println("");
    client.stop();
    client.flush();
        screen();

    // Time until next update
    //Serial.println("Waiting");
    for (int t = 1; t <= 30; t++) {
      delay(1000); // 1/2 minute
    }
        screen();
connectToServer();
}

}



void screen(){
  


  //call
  graphic.setForeColour(15,15,15); //Text is coloured Blue
  graphic.setCoordinate(1,1);
  graphic.print("Connected to server:"); //Normal sized text, no background. Hello and World will be printed on seperate lines
  //resp
  graphic.setCoordinate(1,10);
  graphic.setForeColour(0,15,0); //Text is coloured Blue
  graphic.print("TRUE"); //Normal
  
  
  //call
  graphic.setForeColour(15,15,15); //Text is coloured Blue
  graphic.setCoordinate(1,20);
  graphic.print("Water Level:"); //Normal
  //resp
  graphic.setCoordinate(1,30);
  graphic.setForeColour(15,0,0); //Text is coloured Blue
  graphic.print("LOW"); //Normal
  
  //call
  graphic.setForeColour(15,15,15); //Text is coloured Blue
  graphic.setCoordinate(1,40);
  graphic.print("Making Coffee:"); //Normal
  //resp
  graphic.setCoordinate(1,50);
  graphic.setForeColour(15,0,15); //Text is coloured Blue
  graphic.print("FALSE"); //Normal
}

Why is this?

is it a possibility that the color LCD shield is clashing with the Ethernet shield? I can't see why it wouldn't work unless the shield needs the entire loop function to itself.

Just so you know, this:

 graphic.Box(0,0,6100,6100,4);

Will take an awfully long time to execute as the display is only 128x128 and you are trying to print a box 6101 pixels square (starting at (0,0) ending at (6100,6100)).
If you just want to clear the screen, you can use this:

 graphic.Clear();

Which will set all pixels to be the background colour

Secondly, and most importantly, the Ethernet sheild uses pin 13 and pin 11.
What I did with my LCD shield is to cut the traces going to these pins and added jumper wires to pin 7 and pin 6. The you would just have to change your code to be:
const char Clk = 7;
const char Data = 6;
I found sparkfuns choice to use the SPI pins for this display rather unhelpful as we cant use the hardware SPI for it anyway (it uses a funny 9 bit SPI communication).


As a couple of side notes, but not related to your problem:

You can get rid of that White bar at the top of the screen by correctly setting the screen offset coordinate. The begin function is specified as: begin(xOffset, yOffset, InvertColour, Driver);
So by the looks of things, your screen (unlike mine) is perfectly aligned at the origin, so to get rid of those two pixels, change this:
graphic.begin(0,2,0,PHILLIPS_1);
Changes to:
graphic.begin(0,0,0,PHILLIPS_1);

You can also now use predefined colours for easy reading:

graphic.setForeColour(15,15,15); //While this is perfectly acceptable...
graphic.setForeColour(GLCD_WHITE); //This does the same thing, but is easier to follow

You don't have to use these colours and the way you are doing it will work absolutely fine, but based on the the comments next to setting colours in your code, it may be easier to read.
This is a full list of colours defined in the header file.

	#define GLCD_WHITE 0x0F0F0F
	#define GLCD_BLACK 0x000000
	#define GLCD_GREEN 0x000F00
	#define GLCD_LIME 0x080F00
	#define GLCD_BLUE 0x00000F
	#define GLCD_RED 0x0F0000
	#define GLCD_GREY 0x080808
	#define GLCD_ORANGE 0x0F0800
	#define GLCD_CYAN 0x000F0F
	#define GLCD_YELLOW 0x0F0F00
	#define GLCD_LEMON 0x0F0F08
	#define GLCD_MAGENTA 0x0F000F
	#define GLCD_PINK 0x0F0808

Thanks Tom,
That's a lot of help. I'll set it up as you say tomorrow and see if it works with the Ethernet shield.

I was wondering about the pixel lines at the top. There are three different libraries suggested for this shield. gLCD seemed to be best but it left the lines at the top. I guess I overlooked comparing gLCD with the others.

I've just ordered another LCD off of ebay. I hope this works though. It would give me something to do tomorrow. If there is one thing I've learned about dabbling, it's that it's good to have parts lying around everywhere.

Regards

Stu

Is there something I am missing when it comes to re-printing information to the screen?
When the server is disconnected I want the void screen(); to run again replacing the TRUE with a FALSE.
This doesn't work.

// Include description files for other libraries used (if any)
#include <Twitter.h>
#include <gLCD.h>
#include <Ethernet.h>
#include <SPI.h>
#include <EthernetUdp.h>
#include <PString.h>



// Define Constants
// Max string length may have to be adjusted depending on data to be extracted
#define MAX_STRING_LEN  80

const char RST = 8;
const char CS = 9;
const char Clk = 7;
const char Data = 6;
gLCD graphic(RST,CS,Clk,Data,HIGH_SPEED); //High speed

boolean cts;
boolean mknc;

// Setup vars
char tagStr[MAX_STRING_LEN] = ""; //to contain the XML tags for comparison
char dataStr[MAX_STRING_LEN] = ""; //to store information between hashtags
char tmpStr[MAX_STRING_LEN] = ""; //temporary string for something.. I dunno
char prevStr[MAX_STRING_LEN] = ""; //to compare tweets to their previous, stops repeat functions
char buffer[MAX_STRING_LEN] = ""; // for PString... maybe Concatenate if it still jams up.
char endTag[3] = {'<', '/', '\0'};  //to recognise the ends of chars, XML tags and strings
char makeCoffee[] = "make me coffee"; // trigger text for incoming tweets
boolean firstTweetRead = false;  //to stop make() on first tweet read
PString tweetString(buffer, sizeof(buffer)); //contains the tweet
long randNumber; //to make the tweets unique
int len;               //No idea
int totalCount = 1;  //to count connect attempts 
int ledPin = 3;      //to control the relay


// Flags to differentiate XML tags from document elements (ie. data)
boolean tagFlag = false;     
boolean dataFlag = false;

// Ethernet vars
byte mac[] = { 0x90, 0xA2, 0xDA, 0x0D, 0x13, 0x1D };  //Arduino MAC
byte ip[] = {78,147,235,111 };                        //My home IP
byte server[] = { 199,59,149,232 }; // Twitter IP
Twitter twitter("794475482-XuCh0IVm8nTRcTAxkV6Gpx6VkdElWsww1Ns11n8x");


// Start ethernet client
EthernetClient client;

void setup()
{ 
 graphic.begin(0,0,0,PHILLIPS_1); 
 graphic.setBackColour(GLCD_BLACK);
 graphic.Clear();
 graphic.setFont(0);
 
 cts = false;
 mknc = false;
 screen();

   
  pinMode (ledPin, OUTPUT);
  randomSeed(analogRead(5));
  
  Serial.begin(9600);
  //Ethernet Client
  // attempt a DHCP connection:
  Serial.println(F("setup"));
  if (!Ethernet.begin(mac)) {
    // if DHCP fails, start with a hard-coded address:
    Serial.println(F("failed, trying manually"));
    Ethernet.begin(mac, ip);
  }
  
   connectToServer();
}

void loop() {
    while (client.connected()) {
    while (client.available()) {
    cts = true;
    serialEvent();
    }
  }

  if (!client.connected()) {
    Serial.println();
    cts = false;     // This should trigger.....
    Serial.println(F("=========Disconnected=========="));
    screen();     //THIS to change TRUE to FALSE  but it doesn't.  :(
    Serial.println("");
    client.stop();
    client.flush();
    // Time until next update
    //Serial.println("Waiting");
    for (int t = 1; t <= 30; t++) {
      delay(1000); // 1/2 minute
    }
connectToServer();
}
screen();

}



void screen(){
  graphic.Clear();
  
  //call
  graphic.setForeColour(15,15,15); //Text is coloured white
  graphic.setCoordinate(1,1);
  graphic.print("Connected to server:"); 
  //resp
 
 
  if (cts = true){
  graphic.setCoordinate(1,10);
  graphic.setForeColour(0,15,0); //Text is coloured green
  graphic.print("TRUE"); 
  }
  
  if (cts = false){
  graphic.setCoordinate(1,10);
  graphic.setForeColour(15,0,0); //Text is coloured green
  graphic.print("False"); 
  }
  
  //call
  graphic.setForeColour(15,15,15); //Text is coloured white
  graphic.setCoordinate(1,20);
  graphic.print("Water Level:"); 
  //resp
  graphic.setCoordinate(1,30);
  graphic.setForeColour(15,0,0); //Text is coloured Red
  graphic.print("LOW"); 
  
  //call
  graphic.setForeColour(15,15,15); //Text is coloured white
  graphic.setCoordinate(1,40);
  graphic.print("Making Coffee:"); 
  //resp
  
  if (mknc = false){
  graphic.setCoordinate(1,50);
  graphic.setForeColour(15,0,15); //Text is coloured Purple
  graphic.print("FALSE"); 
  }
  
  else if (mknc = true){
  graphic.setCoordinate(1,50);
  graphic.setForeColour(GLCD_LEMON); //Text is coloured lemon
  graphic.print("True"); //This keeps displaying even though it is false
  }
}

I don't get why these Booleans aren't working with this shield.
I know another method would be to replace sections of the screen with black and then write on top of them but that's a bit messy isn't it?

PS, the jumpers work just fine. Thanks

Never mind. I'm going to do away with the void and call it all when I need it like this

    graphic.Box (1,10,128,19,0);
    graphic.setCoordinate(1,10);
    graphic.setForeColour(15,0,0); //Text is coloured Red
    graphic.print("False"); //Normal

If you go through that function and find stuff like this:

if (cts = true){
 //always called as assignment returns true
}

if (cts = false){
 //neve called as assignment returns true
}

It is wrong. It should be like this:

if (cts == true){
 //called when cts is true
}

if (cts == false){
 //called when cts is false
}

Can you see the difference?

Your code is using an assignment (set cts to equal true) which regardless of the math you do always returns true.
The second code block is using an equality operator - the statement is true if this IS EQUAL to that, else it is false.

For cases where you are checking if something is true or false, you are best using this:

if (cts){
 //called when cts is true
}

if (!cts){
  //called when cts is NOT true, i.e. false
}

This is important as when something returns true you can't guarantee that it is == to 0x01 (which is what true is defined as). In the world of C/C++, boolean true is anything which is not 0.

That makes a lot of sense. I knew it ffs. I just keep forgetting.

Another issue, If I need to display 140 characters on one line, how do I make it scroll across the screen?
Is it a case of wiping the screen, deleting the first char and repeating until the message has gone?

Yep. there is no funtion buoy in to do that so you will have to do it manually. I have some code from a previous project which I can find for you if you would like.

Sure. I'll give you a copy of what I'm making when I'm done... probably this week.

Thanks very much.

I'd like a little guidance with how to write this if that is okay. I'm going to type it out how I think it should be structured (to get text scrolling).

We don't know how big the char string will be as it is variable in length depending on the tweet we are displaying.
We are printing at the following location

graphic.Box (1,70,128,79,0);
      graphic.setForeColour(GLCD_CYAN); //Text is coloured CYAN
      graphic.setCoordinate(1,70);
      graphic.print(dataStr); //This is stationary text

so I think it should go like this (roughly). .

graphic.setForeColour(GLCD_CYAN); //set the text colour
graphic.setCoordinate(1,70); //set the coordinates for the string to be drawn
tempString = dataStr[i+1]; //create a temporary string to use as the display. Put an extra character on the end

while (tempString >1 char in length){
graphic.Box (1,70,128,79,0); //first clear the screen section from the last tweet
graphic.print(tempString); //print the tempString
tempString (Magically cut the first char out of the tempString) //perform magic
}

As you can see, help. Please. Thank you.

I have simplified one of the functions from my my MP3 Player. This basically displays data from a string which you supply, scrolling it around by 1 character each time the function is called.

//Scroll through songInfo, shifting 1 characters each time
void printScroll(char* songInfo, byte infoLength, boolean start = false);
void printScroll(char* songInfo, byte infoLength, boolean start){
  static unsigned int tagPosition = 0;
  if(start){
    tagPosition = 0;
  }
  
  char stringRecover[23] = {0};
  strncpy(stringRecover,&songInfo[tagPosition], 22); //22 character substring starting at [tagPosition]
  
  graphic.setCoordinate(0,70);
  graphic.print(stringRecover);
  
  tagPosition += 1;
  if (tagPosition >= infoLength - 21){ //subtracting 21 as the last 21 characters are the same as the first. 
    tagPosition = 0;
  }
}

The function does not check the length of the string you supply (I took too much time for my particular project), so you need to ensure that the string is at least 43 characters long, and that the last 21 characters are the same as the first. For example:

"Hello, this string is more than 22 characters longHello, this string is"; //Noting that the last 21 characters are the same as the first.
"Hello, Hello, "; //This string is padded with spaces to ensure that it is the correct length.

You could use something like this function to automatically format the string and scroll it:

....
  //This code calls the scroll funtion
  char string[] = "Hello, this is the string I wan't to scroll around the screen";
  scrollString(string, 50); //scroll the string 50 places to the right (will loop around as necessary).

...

void scrollString(char* suppliedString, byte n){ //Formats then scrolls the string around the screen n times.
  int length = strlen(suppliedString);

  char string[length < 22? 44: length + 22];  //create a longer buffer of minimum size 44 characters (22 + 21 + null).

  strcpy(string, suppliedString); //Copy the supplied string into the new buffer

  //check the length of the string:
  if (length < 22){
    //String is too short!
    memset(string + length, ' ', 22 - length); //so pad with spaces up to the required length
    string[22] = 0; //re null terminate (we just overwrote the null with a ' ')
    length = 22; //string is now 22 characters long
  }
  
  //Now append the first 21 characters to the end to allow wrap around (so the string can scroll around the screen continuously)
  char stringRecover[22] = {0};
  strncpy(stringRecover,string,21);
  sprintf(string + length,"%s",stringRecover); //Add the first 21 chars onto the end of songInfo to make it easier to loop through later

  length = strlen(string);
  printScroll(string, length, true); //initial print to the screen, reset loop position to the start.

  for (byte i = 0; i < n - 1; i++){
     printScroll(string, length); //shift around the screen n times.
  }
}

(Just to note, the formatting function hasn't been tested beyond it compiling as I don't have a screen to hand, but I know the printing function works).

Hey Guys...

With this tutorial (Link) i put the LCD to work, however everything appears in mirror and upside down. How can I solve this problem?

Gratz
NesquickPT

Are you using their library (ColorLCDShield), or mine (gLCD)?