Interfacing Arduino to LCD Screen w/4bit data.

Hello all forum members,

I am having trouble to make my LCD screen work with Arduino. As mem pointed out, it is a good idea start a new thread here, as many may bring their experience and many may benefit from the discussion.

The LCD I am using is a Xiamen Ocular GDM 1602K, 2 x 16.

The wiring scheme I am using is this:

There are at least other two wiring schemes here:

One of the lines of the screen is filled with black blocks, but no figures. The program is up and running.

Any contribution to make it work?

Thank you all in advance,

Old Beaver

Oldbeaver, if you place the image links within img tags (third icon from the lift in the post reply toolbar) then they will show up on the thread.

can you post your test sketch?

At present a new error showed up:

The program cannot be uploaded to the board.

When I tried, an error message appear on the bottom, asking to visit arduino.cc/en/.../throbleshooting#upload

Then, I need to remember which one was the last sketch I uploaded to the board, or try to upload again.

Give me a couple of minutes...

This is the sketch which is working:

#include <LCD4Bit.h>
#undef int() //hack for arduino 0011 to allow use of stdio:
#include <stdio.h> //gives us function sprintf

//create object to control an LCD.

LCD4Bit lcd = LCD4Bit(2); //2 lines

int sec=0;
int min=0;
int hour=0; //keep track of time
int amin=0;
int ahour=22; //keep track of alarmtime

char time[9]; //string thats pushed to LCD

void setup() {
pinMode(13, OUTPUT); //we’ll use the debug LED to output a heartbeat
pinMode(3, OUTPUT); // connected with buzzer
lcd.init();
lcd.clear();
//optionally, now set up our application-specific display settings, overriding whatever the lcd did in lcd.init()
//lcd.commandWrite(0x0F);//cursor on, display on, blink on. (nasty!)
}

char* inctime() {

sec=sec+1;

if(sec==60) {
min=min+1;
sec=0;
}
if(min==60) {
hour=hour+1;
min=0;
}
if(hour==24) {
hour=0;
}

if(sec%2==0) { //true if sec is even number
lcd.cursorTo(1,0);
lcd.printIn(“Time”);
lcd.cursorTo(1,6);
sprintf(time, “%2d:%2d:%2d”, hour, min, sec); //shows blinking : every even sec
} else {
lcd.cursorTo(1,6);
sprintf(time, “%2d %2d %2d”, hour, min, sec); // : are off every uneven sec
}

return time;
}

void loop() {
unsigned long msbegin=millis();
unsigned long msafter;
digitalWrite(13, HIGH); //light the debug LED

lcd.cursorTo(1, 0); //line=1, x=0.
lcd.printIn(inctime());
digitalWrite(13, LOW); //13 is heartbeat pin

lcd.cursorTo(2, 0);
lcd.printIn(“Alarm”);
if(ahour==hour && amin==min){ // alarm goes off for 60 secs
//during alarm effect of “vanishing” characters from left to right
lcd.cursorTo(2, 7); // sec%9 is rest of integer division sec/9
lcd.printIn(" "); //moving space sign that covers the letters

digitalWrite(3, HIGH); //buzzer on
}

lcd.cursorTo(2, 7);
sprintf(time, “%2d:%2d”, ahour, amin);
lcd.printIn(time);

digitalWrite(3, LOW); //buzzer off
msafter=millis();
if (msafter<msbegin) { //millis reset to zero after 9 hours
delay(1000);
}
else;
{
delay(1000-(msafter-msbegin));
}
}

It is a kind of clock.

Dear mem,

The sketch that is upload has the following lines:

#include <LCD4Bit.h>
#undef int() //hack for arduino 0011 to allow use of stdio:
#include <stdio.h> //gives us function sprintf

//create object to control an LCD.

LCD4Bit lcd = LCD4Bit(2); //2 lines

However, what I was using in my sketches is:

//--------------------------------------------------------------------
#include <DateTime.h>
#include <LiquidCrystal.h>

/* ------------- reset pins, define pins, variables ---------------- */
int resetPin = 3; // pin 3 resets the time

float tank;
float x;

/* ------- create object to control an LCD GMD1602K -------*/
LiquidCrystal lcd(12, 11, 6, 7, 8, 9, 10);
//-----------------------------------------------------------------------

Why the difference when including (#) the LCD routine?

The sketches use different libraries. LiquidCrystal is the official Arduino Library.. lcd4bit is the older playground library. Why not use the Arduino library and test with the 'Hello World' example sketch.

Done,

I uploaded the Hello World sketch to the board. For that, I had to disconnect my shield, and the program got up ok.

Then I connected the shield which inlcudes the LCD Display, and what is shown on it are just black boxes, here or ther, showing up, and dissapearing, moving around. The cursor shows from time to time.

What I discovered is that the sketches do not upload if I have the LCD connected!

I am having a problem which may be caused by the shield or the LCD display, or the wiring.

At least, my Arduino board is working ok.

OldBeaver :(

This is the wiring I am using:

This is the shield I made that is probably causing the trouble:

Does your shield make use of either pin 0 or 1 of the Arduino?

Sorry, I see the schematics now. On one picture, you have pin 6 of the Arduino connected to pin 3 on your LCD. If you use:

for (i = 0; i < 255; i++) {
    analogWrite(6, i);
    delay(20);
  }

your contrast will fade in or out depending on the direction you go. This eliminates the 10k pot from the circuit and allows your code to fully control the contrast for some cool fade effects. I think that anything above 130 was a blank screen(it’s been a while I’m not sure which direction was which). You can use any open PWM pin to control the contrast on pin 3 of your LCD.

You should be able to use any pins so long as your 4 pins used for DB4 - 7 are in order. I believe this is necessary due to how the library loops through them during setup.

While the library worked perfectly for the LCD modules I have, I had a similar problem with a oLED module I tried. The modules look for instructions when powered up and the library provides these. It sends a power-on-reset command followed by a series of others to set data length - 4 or 8 bit, cursor type, number of lines, cursor or display shift, memory information and a bunch of other stuff. If the timing or order of these commands is off, you get blocks and junk on your screen. With my oLED module I had to tweak the library to get it to work at all and I always had to reset the Arduino after uploading a sketch once I did get it to work.

The LCDs worked perfectly though.

I always hate this answer but, I found the most useful information in the datasheets for the module I was working with. Also, check “arduino## > hardware > libraries > LiquidCrystal > LiquidCrystal.cpp” which can be opened with notepad. Between that and your datasheet you might be able to find where the problem is. I am leaning toward the timing of the power on reset. Hmmn…

Unclebone:

Yes, I am using Arduino digital pin 0, for inputting some signal. However, nothing is inputted by now, as I am in my desk.

Should I use another pin?

With regard of the contrast issue, I will have it present and try to change that when I have my LCD working again. Or, do you think this may be affecting LCD behavior?

I will look on the other guides you mentioned.

Thank you much.

Mem:

I uploaded the hello world sketch, but results on the screen are the same: blocks here and there.

Besides, I disconnected all digital input cables, but nothing changed, so, I re-connected all again.

Will check the info on the IDE.

Thank you much again,

OldBeaver

Best not to have anything connected to digital pins 0 and/or 1 until after your sketch is loaded. These are the RX and TX used for serial and also loading the sketch.

Pin 3 should not affect behavior. If you can see anything on the screen it's a good start. Definitely try with 1 and 0 disconnected though, and use other pins if needed.

UncleBone,
Mem,

The Forum,

Well, one problem at a time: I disconnected the input I had on pin 1, and now I can upload sketchs to the Arduino board easily. Tks for that!

Second: the enable cable was missing: I had only 6 cables connected.
RW pin was connected to earth. Now it is connected to pin 10 on the Arduino board.

Furthermore, I visited the Arduino/Hardware/Code/LCD where there is a clear explanation about using the LCD Library.

Then I entered the link http://www.arduino.cc/en/Reference/LiquidCrystal

It says this:

LiquidCrystal()
Description

Creates a variable of type LiquidCrystal.

Syntax

LiquidCrystal(rs, rw, enable, d4, d5, d6, d7)
LiquidCrystal(rs, rw, enable, d0, d1, d2, d3, d4, d5, d6, d7)

Parameters

rs: the number of the Arduino pin that is connected to the RS pin on the LCD

rw: the number of the Arduino pin that is connected to the RW pin on the LCD

enable: the number of the Arduino pin that is connected to the enable pin on the LCD

I followed almost exactly the instructions, only changed the data pins.

Here is the code of my checking routine:

#include <LiquidCrystal.h>

// LiquidCrystal display with:
// rs on pin 12
// rw on pin 11
// enable on pin 10
// db4, db5, db6, db7 on pins 9, 8, 7, 6
LiquidCrystal lcd(12, 11, 10, 9, 8, 7,6);
int ledPin = 13; // LED connected to digital pin 13
int x; // check variable x
void setup()
{
// Print a message to the LCD.
lcd.setCursor(0,0);
lcd.print(“hello, world!”);
pinMode(ledPin, OUTPUT); // sets the digital pin as output
}

void loop()
{
digitalWrite(ledPin, HIGH); // sets the LED on
lcd.setCursor(0,1);
lcd.print(x);
x=x+1; // increments x by one
delay(500); // waits 500 milliseconds
digitalWrite(ledPin, LOW); // sets the LED off
delay(500); // waits 500 milliseconds
}

Results:

Now I get nice contrast, nitide figures, no black blocks anymore, but, instead of numbers and letters strange characters are displayed.

Further ideas?

Try changing the order of your data pins. instead of 9,8,7,6 try 6,7,8,9 in the sketch and make sure the wiring matches.

UncleBone,

Do you mean change the declared order on the sketch and what else?

Is it a matter of naming them or should I make some physical change on wiring? If so, how, where? I am slow today...

I mean, they match: they are 9, 8, 7, 6 or, 6, 7, 8, 9.

I have never seen the LCD data wires twisted with the others, if you mean that.

Here is my new shield wiring:

http://www.flickr.com/photos/33747648@N05/3665765703/

test image:

Instead of:

LiquidCrystal lcd(12, 11, 10, 9, 8, 7,6);

Try:

LiquidCrystal lcd(12, 11, 10, 6, 7, 8, 9);

with: Digital pin 6 physically connected to d4 Digital pin 7 connected to d5 Digital pin 8 connected to d6 Digital pin 9 connected to d7

UncleBone,

Ok, tks. I made the change in both, the sketch and the physicall connections.

Results: well, two lines of strange characters like:

Interrogation signs "?" Zeros "0" Capital O's with two points on top (like in German) Kind of french c with tail, but facing left instead than facing right A moving cursor and some spaces between characters, moving also.

Look like the sketch is using a wrong set of characters.

Will check the library. Maybe will download version 13 of the software.

Looking forward to further ideas,

OldBeaver

UncleBone,

Here is my code:

#include <LiquidCrystal.h>

// LiquidCrystal display with:
// rs on pin 12
// rw on pin 11
// enable on pin 10
// db4, db5, db6, db7 on pins 6, 7, 8, 9)
LiquidCrystal lcd(12, 11, 10, 6, 7, 8, 9);
int ledPin = 13; // LED connected to digital pin 13
int x; // check variable x
void setup()
{
// Print a message to the LCD.
lcd.setCursor(0,0);
lcd.print(“hello, world!”);
pinMode(ledPin, OUTPUT); // sets the digital pin as output
}

void loop()
{
digitalWrite(ledPin, HIGH); // sets the LED on
lcd.setCursor(0,1);
lcd.print(x);
x=x+1; // increments x by one
delay(500); // waits 500 milliseconds
digitalWrite(ledPin, LOW); // sets the LED off
delay(500); // waits 500 milliseconds
}

UncleBone,

I already upgraded my Arduino compiler version, from v.12to v. 16. Didn´t know that much updates!

The LCD is still giving the same strange characters. I will take a picture of it and upload to flickr ... a couple of minutes please ..

Well, so far, so bad.

The characters that my LCD screen displays are over ASCII 128, from what I understood from sites read.

I don´t know why it is behavioring so weird. Never happen before. Hope I can fix this up, or I cannot progress.

The other solution is pour this project to the garbage, and start again with a more stable platform.

It is really crazy, and very dissapointing. Of course. Many has tried to help me, and they did. But there is some more step pending.

This same Arduino and LCD was wired very bad before, but, at least, worked. Now that I improved wiring and soldering, the thing don´t want to work.

UncleBone,

You wrote: "I always hate this answer but, I found the most useful information in the datasheets for the module I was working with. Also, check "arduino## > hardware > libraries > LiquidCrystal > LiquidCrystal.cpp" which can be opened with notepad. Between that and your datasheet you might be able to find where the problem is. I am leaning toward the timing of the power on reset. "

I checked the datasheet, it helped to understand better the LCD connections.

I will edit that LiquidCrystal.cpp file, to see if I can go further or not.

I will let you know.

OldBeaver

You could try the following change in LiquidCrystal.cpp. Open the file in a text editor like notepad. Find the function that looks like this:

LiquidCrystal::LiquidCrystal(uint8_t rs, uint8_t rw, uint8_t enable,
  uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3) :
  _four_bit_mode(1), _rs_pin(rs), _rw_pin(rw), _enable_pin(enable)
{
  _data_pins[0] = d0;
  _data_pins[1] = d1;
  _data_pins[2] = d2;
  _data_pins[3] = d3; 
  
  pinMode(_rs_pin, OUTPUT);
  pinMode(_rw_pin, OUTPUT);
  pinMode(_enable_pin, OUTPUT);
  
  for (int i = 0; i < 4; i++)
    pinMode(_data_pins[i], OUTPUT);
 
  command(0x28);  // function set: 4 bits, 1 line, 5x8 dots
  command(0x0C);  // display control: turn display on, cursor off, no blinking
  command(0x06);  // entry mode set: increment automatically, display shift, right shift
  clear();
}

and replace that code with this:

LiquidCrystal::LiquidCrystal(uint8_t rs, uint8_t rw, uint8_t enable,
  uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3) :
  _four_bit_mode(1), _rs_pin(rs), _rw_pin(rw), _enable_pin(enable)
{
  _data_pins[0] = d0;
  _data_pins[1] = d1;
  _data_pins[2] = d2;
  _data_pins[3] = d3; 
  
  pinMode(_rs_pin, OUTPUT);
  pinMode(_rw_pin, OUTPUT);
  pinMode(_enable_pin, OUTPUT);
  
  for (int i = 0; i < 4; i++)
    pinMode(_data_pins[i], OUTPUT);

  command(30);
  delayMicroseconds(5000);
  command(30);
  delayMicroseconds(100);
  command(30);
  delayMicroseconds(100);
  command(20);
  delayMicroseconds(100);
  
  command(0x28);        //Function Set, D=0, N=1, F=0 (4 bits, 2 line, 5x8 dots)
  delayMicroseconds(80);
  command(0x08);        //Display ON/OFF Control', D=0, C=0, B=0 (display off, cursor off, blink off)
  delayMicroseconds(80);
  command(0x01);            //Clear Display
  delayMicroseconds(5000); 
  command(0x06);            //Entry Mode Set, I/D=1, S=0 (increment addresses, do not shift display)
  delayMicroseconds(80);  
  command(0x0C);            //Display ON/OFF Control, D=1, C=0, B=0 (display on, cursor off, blink off)
  delayMicroseconds(80);

}

note that there are two similar functions, one has eight data pins the other has four, you want the one with four (its the second one).
delete the LiquidCrystal.o file and recompile your sketch.

Good Luck