Offline
Newbie
Karma: 0
Posts: 5
|
 |
« on: February 26, 2013, 06:51:03 am » |
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. 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
Faraday Member
Karma: 17
Posts: 3507
|
 |
« Reply #1 on: February 26, 2013, 09:04:35 am » |
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
Newbie
Karma: 0
Posts: 5
|
 |
« Reply #2 on: February 26, 2013, 06:34:46 pm » |
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
Faraday Member
Karma: 17
Posts: 3507
|
 |
« Reply #3 on: February 26, 2013, 06:54:18 pm » |
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.#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
Newbie
Karma: 0
Posts: 5
|
 |
« Reply #4 on: February 27, 2013, 06:38:35 pm » |
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: #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
Faraday Member
Karma: 17
Posts: 3507
|
 |
« Reply #5 on: February 27, 2013, 08:40:18 pm » |
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
Newbie
Karma: 0
Posts: 5
|
 |
« Reply #6 on: February 27, 2013, 10:05:40 pm » |
Thanks for the clarification and help. I redid the code to just send characters: #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
Faraday Member
Karma: 17
Posts: 3507
|
 |
« Reply #7 on: February 27, 2013, 11:17:13 pm » |
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
Newbie
Karma: 0
Posts: 5
|
 |
« Reply #8 on: February 28, 2013, 06:36:41 am » |
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
|
|
|
|
|
|