Pages: [1]   Go Down
Author Topic: Newhaven 0420D3Z Intermittent Garbled Display  (Read 1149 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 5
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I m using a Newhaven 0420D3Z-NSW-VM-V3 http://www.newhavendisplay.com/specs/NHD-0420D3Z-NSW-BBW-V3.pdf display, and occasionally get garbled results.
Sometimes the text will be on the wrong line, start in the wrong space, or miss characters.  Most of the time it seems fine.  This display has a processor in it, so characters are sent via I2C.  The code I'm using is below.  It seems the issue must either be communications, or some sort of bug in the display itseld, but maybe I've made an error that I just don't see, so I would appreciate any help or advice.

Code:
void LCDprint(char string[21], byte row, byte col)
{
  //send a string of characters to the LCD starting at specified row and column
  byte pos = 0;
  switch (row) {
  case 1:
    pos = 0;
    break;
  case 2:
    pos = 0x40;
    break;
  case 3:
    pos = 0x14;
    break;
  case 4:
    pos = 0x54;
    break;
  }
  pos = pos +(col-1);
  //set cursor position
  Wire.beginTransmission(LCDa);
  Wire.write (0xFE);
  Wire.endTransmission();
  Wire.beginTransmission(LCDa);
  Wire.write (0x45);
  Wire.endTransmission();
  Wire.beginTransmission(LCDa);
  Wire.write (pos);
  Wire.endTransmission();
  delayMicroseconds(105);
  //send characters
  int c=0;
  while(string[c] != 0){
    Wire.beginTransmission(LCDa);
    Wire.write(string[c]);
    Wire.endTransmission();
    delayMicroseconds(300);
    c++;
  }
}
Logged

Western New York, USA
Offline Offline
Faraday Member
**
Karma: 25
Posts: 4110
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Without seeing the the rest of your code we can't be sure that you aren't inadvertently sending out some more commands to the processor on the display, but that seems to be the most likely cause right now.

Can you pin down any set of circumstances that seems to trigger the error?


Don
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 5
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

There are no specific circumstances I can identify.  Essentially, if I have a loop of code the clears the screen and prints the same things inthe same positions, some times it will print correctly, but occasionally it will be off a line, shifted a character, or miss a character.
I can post the whole code if that helps, but it exhibited the same behavior with a simple "hello world" program.
Also, when loading custom characters, some characters will occasionally be off a line.  It is as if the display misses a byte or two of the transmission sometimes.  Searching lead me to add the delays to the functions, as not having them originally made the problem worse, which makes sense - if the display was still executing the last command, it could miss the next one.
Logged

Western New York, USA
Offline Offline
Faraday Member
**
Karma: 25
Posts: 4110
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Well we can keep guessing blindly or you can post some code so we can make our guesses a bit more educated.  I still have a hunch that it is what you are actually sending rather than when you are sending it (the timing) that is the problem.

Why don't you try sending a string of 80 printable ASCII characters and then stop (nothing in loop) and see what happens.  Here's the code for a regular parallel display, you will have to modify it a bit for yours.


Code:
#include <LiquidCrystal.h>

//LiquidCrystal lcd(rs,en,d4,d5,d6,d7);
  LiquidCrystal lcd(12, 11, 5, 4, 3, 2);       // put your pin numbers here

void setup()
  {
    lcd.begin(20, 4);                          // put your LCD parameters here
    for (char i=47; i<127; i++)                // send 80 consecutive displayable characters to the LCD
      {
        lcd.print(i);
        delay(100);                            // this delay allows you to observe the addressing sequence
      }
  }


void loop()
  { 
  }

Don
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 5
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Not sure exactly what this code is supposed to do, I assumed it should fill the display with characters so I translated it to this:
Code:
#include <Wire.h> //I2C library
const byte LCDa = 40; //LCD address on I2C bus

void setup()

  {
    byte row;
    byte col;
    Wire.begin(); // join i2c bus (address optional for master)
    LCDclear();
    for (row=1; row<5; row++)                // send 80 consecutive displayable characters to the LCD
      {
        for (col=1;col<21;col++)
        {
        LCDwrite(((row-1)*20+col+47),row,col);
        delay(100); // this delay allows you to observe the addressing sequence
        }       
      }
  }

void loop()
  { 
  }

void LCDwrite(byte c, byte row, byte col)
{
  //send a single characters to the LCD at specified row and column
  byte pos = 0;
  switch (row) {
  case 1:
    pos = 0;
    break;
  case 2:
    pos = 0x40;
    break;
  case 3:
    pos = 0x14;
    break;
  case 4:
    pos = 0x54;
    break;
  }
  pos = pos +(col-1);
  //set cursor position
  Wire.beginTransmission(LCDa);
  Wire.write (0xFE);
  Wire.write (0x45);
  Wire.write (pos);
  Wire.endTransmission();
  delayMicroseconds(105);
  //send character
  Wire.beginTransmission(LCDa);
  Wire.write(c);
  Wire.endTransmission();
  delayMicroseconds(200);
}

void LCDclear() {
  Wire.beginTransmission(LCDa);
  Wire.write (0xFE);
  Wire.write(0x51);
  Wire.endTransmission();
  delay(2);
}
Here is the result of 7 runs, random missing characters:
Logged

Western New York, USA
Offline Offline
Faraday Member
**
Karma: 25
Posts: 4110
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

That's better than before since you only have one type of error instead of three but you missed the point.

The whole idea is to send 80 characters to the display without interspersing any cursor positioning codes or any other control codes either.  Just send the 80 characters, one after the other, period.  You don't have to set the cursor position since we don't care where we start and you don't have to update the cursor position since that is done automatically by the LCD controller.  Well, it's done automatically by a standard LCD controller and I don't think the NHD controller is different in that respect.


Don
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 5
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks for the clarification and help.  I redid the code to just send characters:
Code:
#include <Wire.h> //I2C library
const byte LCDa = 40; //LCD address on I2C bus

void setup()

  {
    Wire.begin(); // join i2c bus (address optional for master)
    for (char i=47; i<127; i++)                // send 80 consecutive displayable characters to the LCD
      {
        Wire.beginTransmission(LCDa);
        Wire.write(i);
        Wire.endTransmission();
        delayMicroseconds(200);
        delay(100);                            // this delay allows you to observe the addressing sequence
      }
  }

void loop()
  { 
  }

It still occasionally misses characters, it missed a backslash, nothing, nothing, semicolon, T, Z, N & X, nothing.
Logged

Western New York, USA
Offline Offline
Faraday Member
**
Karma: 25
Posts: 4110
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I've never used the wire library but it seems to me that you should be able to send more than a single character between starting and ending a 'transmission'.

Don

Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 5
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I would think one should be able to send more data also.  When I move the Wire.begin() and Wire.endTransmission() statements outside the loop, the behavior changes.  Nothing displays until all the characters have been sent, there is only a single line (everything else must get truncated), and there are far more characters missed - a typical line is "/024579:<>@ACEFHJKMN".
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 2
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

reddogf5, did you ever find a resolution to this problem? I have the exact Newhaven display and am running into the exact problem you had. Even when trying to use the wire library to write "Hello World!" to the LCD, it only prints "Hllo Wrld". It is the oddest thing. It doesn't seem that anyone else has posted about this issue either. So I can't find any new information on what could be the problem.

I've also looked into other 4-byte LCDs hooked up to an Arduino, and even other 4-byte displays often have 16 pins on the LCD, whereas the Newhaven display we have only has 8 pins. I wish we could use the LiquidCrystal library on this LCD smiley-sad
Logged

Chicago
Offline Offline
Newbie
*
Karma: 1
Posts: 35
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I have the EXACT same issue with 2 different Newhaven LCD's.  Both LCD's work fine with serial communication, but when I try to use i2c, they miss characters.  I can't get it to display "Hello World!!"... instead it displays "loWrl!!" as an example.  What the heck is going on here?
Logged

Chicago
Offline Offline
Newbie
*
Karma: 1
Posts: 35
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I have figured out what the issue is.  The problem is the NewHaven displays can only handle i2c with a SCL clock rate of up to 100Khz, but no faster.  By default, the SCL clock rate on an Arduino UNO R3 is much faster than this.  You actually need to slow it down.  The easiest way to do this is to adjust the TWBR variable. 

I did this:
TWBR = 100000; 
This solved the problem for me.  Another person has suggested doing this, which would probably be a better way:

  TWBR = ((F_CPU / TWI_FREQ) - 16) / 2;
  TWBR = TWBR * 2;                             

Logged

Pages: [1]   Go Up
Jump to: