Need help/wisdom using the new NHD-0420CW-xxx
Hi everyone. This new display is so much what I needed for a project. I have been using a Noritake Character VFD which proved to be too delicate and large, then one of the many SD1322 2.8" Graphic Oled display, which almost fit, but the Atmel 328 that it runs on just struggles and as a result the display will sometimes update very slowly after a command is given to the remote gear it talks to sends a reply. But it was the best I could do. So I bought a couple of the new NHD-0420CW devices from Mouser. And since it did SPI, and since the commands for the VFD looked identical to the NHD unit I figured it to be a drop in on a unit that was using the VFD version. But I can't get that to work. I first make this all work on an Arduino Uno then move that processor to the target hardware .
I probably have ten or more hours in on this already. Trying various LCD SPI sample programs. Cant find anything for the US2066 or the KS0066, which is supposedly the same. But since I compared US2066 instructions to the Noritake and others I figured it ought to work. I have tried SPI (what I need) then I2C.
Can anybody point me at sample code and driver for arduino for this? Should it work with something like the VFD code?
I really appreciate any input on this as I need to get back to my life and my day job. And this is the second night I'm up to 2:30 on this...
Thanks folks.
George Csahanin
Austin, TX
-
Hello George,
I actually have some example code I can share with you. It is written for the Arduino Mega. See below:
https://github.com/NewhavenDisplay/NHD_US2066-Arduino-Mega
Hope this helps and please keep me posted on your progress!« Last Edit: February 09, 2015, 08:43:55 AM by Paul_B »0 -
Paul, thanks, I'll give it a shot. I tried all sorts of SPI "hello world" stuff but nothing lit it up. Tried a second display (I bought three for playing) and same thing. Tried 3.3V, 5V, Mega, Uno, zip, nada. But I'll let you know how this works. I'm doing some travel, it might be several days.
Again, thanks
GeorgeC0 -
I couldn't wait, just tried it. Well, they lit up. Looks like the CGRAM is clocked wrong, each "dot" in a horizontal line is one on, blank space, one on, blank space, etc. But the words are in there two lines at a time (it's a 0420)
So I know this is going to work. Now I may try adapting to a Uno, though that may be over my head.
Thanks for the code and a nudge in the right direction. Here's the part where I get to wish I had learned to program at an early age.
:-)
GeorgeC0 -
No problem George, happy coding!
0 -
OK. I'm trying to understand what is going on in NHD_US2066.cpp, but being an RF jockey by trade, not really following this code. I know my problem is in there. After using the mentioned code from github, I have a display that lights. It prints a line of double sized characters, a second line of gibberish, waits two seconds and prints two lines of gibberish, waits two seconds and starts over. What I'm probably puzzling over is:
void output() //what is this doing?
{
int i;
command(0x01); //what is this doing?
delay(2);
for(i=0;i<20;i++){
data(text1);
}
command(0xa0); //what is this doing?
for(i=0;i<20;i++){
data(text2);
}
delay(2000);
command(0x01); //what is this doing?
delay(2);
for (i=0;i<20;i++){
data(text3);
}
command(0xA0); //what is this doing?
for (i=0;i<20;i++){
data(text4);
}
}
void outputTest() //what is this doing? And what is different from void output above?
{
int i;
command(0x01);
delay(2);
data('N');
while(1);
for(i=0;i<20;i++){
data(text1);
}
command(0xA0);
for(i=0;i<20;i++){
data(text2);
}
delay(2000);
command(0x01);
delay(2);
for (i=0;i<20;i++){
data(text3);
}
command(0xA0);
for (i=0;i<20;i++){
data(text4);
}
}
void blocks()
{
int i;
command(0x01);
delay(2);
for(i=0;i<20;i++){
data(0x1F);
}
command(0xA0);
for(i=0;i<20;i++){
data(0x1F);
}
}
void setup()
{
init16x2();
}
_____________________________________________
Has anybody worked on a NHD-0420CW/US2066 library set for Arduino similar to SPI_VFD, CUU, or LiquidCrystal? For me that would be so wonderful.
Anyhow, I know when I get this working in my project I can get rid of the big 4X20 VFD and the graphic oled currently in use. The graphics part with the u8glib library is just plain slow. The VFD is fast, but too big, fragile, uses 36 volts and has a filament...
Thanks y'all.
George Csahanin
Cedar Park, TX0 -
Hello,
void output() //This function is used to display an Array of text on the screen.
{
int i;
command(0x01); //This is clearing the display
delay(2);
for(i=0;i<20;i++){ // loops through Array text1
data(text1);
}
command(0xa0); // Send cursor to line 2
for(i=0;i<20;i++){
data(text2);
}
......
void outputTest() // You can ignore this function, it isn't actually called. This function was written to test the output.
{
int i;
command(0x01);
delay(2);
data('N');
while(1);
for(i=0;i<20;i++){
data(text1);
}
command(0xA0);
for(i=0;i<20;i++){
data(text2);
}
delay(2000);
command(0x01);
delay(2);
for (i=0;i<20;i++){
data(text3);
}
command(0xA0);
for (i=0;i<20;i++){
data(text4);
}
}
Please try the code below (I have modified it for the 4x20 instead of 2x16):#include <Wire.h>
//#include <SPI.h>
int RS = 30;
int E = 31;
int RES = 32;
int CS = 33;
int ASDA = 20;
int ASCL = 21;
int SCLK = 52;
int SDIN = 51;
int SDOUT = 50;
// R/W signal tied LOW (always write)
unsigned char tx_packet[]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
const char slave2w = 0x3C; //3C or 78
unsigned char mode = 0; // 0 = 8-bit parallel 6800 mode; 1 = i2c mode; 2 = SPI mode;
unsigned char text1[] = {"Newhaven Display----"};
unsigned char text2[] = {"Test----------------"};
unsigned char text3[] = {"16/20 Characters----"};
unsigned char text4[] = {"!@#$%^&*()_+{}[]<>?~"};
void command(unsigned char c)
{
unsigned char i, temp;
switch(mode)
{
case 0: digitalWrite(CS, LOW);
PORTA = c;
digitalWrite(RS, LOW);
digitalWrite(E, HIGH);
delay(1);
digitalWrite(E, LOW);
digitalWrite(CS, HIGH);
break;
case 1: tx_packet[0] = 0x00;
tx_packet[1] = c;
send_packet(2);
break;
case 2:
temp = 0xF8;
for(i=0;i<8;i++)
{
digitalWrite(SCLK, LOW);
if((temp&0x80)>>7==1)
{
digitalWrite(SDIN, HIGH);
}
else
{
digitalWrite(SDIN, LOW);
}
temp = temp << 1;
digitalWrite(SCLK, HIGH);
}
for(i=0;i<4;i++)
{
digitalWrite(SCLK, LOW);
if((c&0x01)==1)
{
digitalWrite(SDIN, HIGH);
}
else
{
digitalWrite(SDIN, LOW);
}
c = c >> 1;
digitalWrite(SCLK, HIGH);
}
for(i=0;i<4;i++)
{
digitalWrite(SCLK, LOW);
digitalWrite(SDIN, LOW);
digitalWrite(SCLK, HIGH);
}
for(i=0;i<4;i++)
{
digitalWrite(SCLK, LOW);
if((c&0x10)==0x10)
{
digitalWrite(SDIN, HIGH);
}
else
{
digitalWrite(SDIN, LOW);
}
c = c >> 1;
digitalWrite(SCLK, HIGH);
}
for(i=0;i<4;i++)
{
digitalWrite(SCLK, LOW);
digitalWrite(SDIN, LOW);
digitalWrite(SCLK, HIGH);
}
break;
}
}
void data(unsigned char d)
{
unsigned char i, temp;
switch(mode)
{
case 0: digitalWrite(CS, LOW);
PORTA = d;
digitalWrite(RS, HIGH);
digitalWrite(E, HIGH);
delay(1);
digitalWrite(E, LOW);
digitalWrite(CS, HIGH);
break;
case 1: tx_packet[0] = 0x40;
tx_packet[1] = d;
send_packet(2);
break;
case 2:
temp = 0xFA;
for(i=0;i<8;i++)
{
digitalWrite(SCLK, LOW);
if((temp&0x80)>>7==1)
{
digitalWrite(SDIN, HIGH);
}
else
{
digitalWrite(SDIN, LOW);
}
temp = temp << 1;
digitalWrite(SCLK, HIGH);
}
for(i=0;i<4;i++)
{
digitalWrite(SCLK, LOW);
if((d&0x01)==1)
{
digitalWrite(SDIN, HIGH);
}
else
{
digitalWrite(SDIN, LOW);
}
d = d >> 1;
digitalWrite(SCLK, HIGH);
}
for(i=0;i<4;i++)
{
digitalWrite(SCLK, LOW);
digitalWrite(SDIN, LOW);
digitalWrite(SCLK, HIGH);
}
for(i=0;i<4;i++)
{
digitalWrite(SCLK, LOW);
if((d&0x10)==0x10)
{
digitalWrite(SDIN, HIGH);
}
else
{
digitalWrite(SDIN, LOW);
}
d = d >> 1;
digitalWrite(SCLK, HIGH);
}
for(i=0;i<4;i++)
{
digitalWrite(SCLK, LOW);
digitalWrite(SDIN, LOW);
digitalWrite(SCLK, HIGH);
}
break;
}
}
void send_packet(unsigned char x)
{
unsigned char ix;
Wire.beginTransmission(slave2w);
for(ix=0;ix<x;ix++)
{
Wire.write(tx_packet[ix]);
}
Wire.endTransmission();
}
void output()
{
int i;
command(0x01);
delay(2);
for(i=0;i<20;i++){
data(text1[i]);
}
command(0xA0);
for(i=0;i<20;i++){
data(text2[i]);
}
command(0xC0);
for(i=0;i<20;i++){
data(text3[i]);
}
command(0xE0);
for(i=0;i<20;i++){
data(text4[i]);
}
delay(2000);
command(0x01);
delay(2);
for (i=0;i<20;i++){
data(text3[i]);
}
command(0xA0);
for (i=0;i<20;i++){
data(text4[i]);
}
command(0xC0);
for (i=0;i<20;i++){
data(text1[i]);
}
command(0xE0);
for (i=0;i<20;i++){
data(text2[i]);
}
}
void outputTest()
{
int i;
command(0x01);
delay(2);
data('N');
while(1);
for(i=0;i<20;i++){
data(text1[i]);
}
command(0xA0);
for(i=0;i<20;i++){
data(text2[i]);
}
command(0xC0);
for(i=0;i<20;i++){
data(text3[i]);
}
command(0xE0);
for(i=0;i<20;i++){
data(text4[i]);
}
delay(2000);
command(0x01);
delay(2);
for (i=0;i<20;i++){
data(text3[i]);
}
command(0xA0);
for (i=0;i<20;i++){
data(text4[i]);
}
command(0xC0);
for (i=0;i<20;i++){
data(text1[i]);
}
command(0xE0);
for (i=0;i<20;i++){
data(text2[i]);
}
}
void blocks()
{
int i;
command(0x01);
delay(2);
for(i=0;i<20;i++){
data(0x1F);
}
command(0xA0);
for(i=0;i<20;i++){
data(0x1F);
}
}
void setup()
{
pinMode(ASCL, OUTPUT); //set Arduino I2C lines as outputs
pinMode(ASDA, OUTPUT); //
digitalWrite(ASCL, LOW); //
digitalWrite(ASDA, LOW); //
pinMode(SCLK, OUTPUT);
pinMode(SDIN, OUTPUT);
pinMode(SDOUT, INPUT);
digitalWrite(SCLK, HIGH);
digitalWrite(SDIN, HIGH);
DDRA = 0xFF;
PORTA = 0x00;
DDRC = 0xFF;
PORTC = 0x00;
digitalWrite(RES, HIGH);
delay(10);
Wire.begin();
delay(10);
//SPI.begin();
command(0x2A); //function set (extended command set)
command(0x71); //function selection A, disable internal Vdd regualtor
data(0x00);
command(0x28); //function set (fundamental command set)
command(0x08); //display off, cursor off, blink off
command(0x2A); //function set (extended command set)
command(0x79); //OLED command set enabled
command(0xD5); //set display clock divide ratio/oscillator frequency
command(0x70); //set display clock divide ratio/oscillator frequency
command(0x78); //OLED command set disabled
command(0x09); //extended function set (4-lines)
command(0x06); //COM SEG direction
command(0x72); //function selection B, disable internal Vdd regualtor
data(0x00); //ROM CGRAM selection
command(0x2A); //function set (extended command set)
command(0x79); //OLED command set enabled
command(0xDA); //set SEG pins hardware configuration
command(0x00); //set SEG pins hardware configuration ////////////////////////////////////0x10 on other slim char OLEDs
command(0xDC); //function selection C
command(0x00); //function selection C
command(0x81); //set contrast control
command(0x7F); //set contrast control
command(0xD9); //set phase length
command(0xF1); //set phase length
command(0xDB); //set VCOMH deselect level
command(0x40); //set VCOMH deselect level
command(0x78); //OLED command set disabled
command(0x28); //function set (fundamental command set)
command(0x01); //clear display
command(0x80); //set DDRAM address to 0x00
command(0x0C); //display ON
delay(100);
//Wire.begin();
//delay(10);
}
void loop()
{
while(1)
{
output();
//blocks();
while(1);
//outputTest();
delay(2000);
}
}0 -
Thanks Paul, I'll try that in a few. I am not as stupid as I thought. I had figured that 0x01 was to clear and that with r/e tied low then 0xa0 was "next line" because it changes the DDRAM address. Figure 5-22 on the US2066 spec sheet...did I get that correct? Thanks Paul, I'll try not to be a pest about this stuff...
GeorgeC0 -
Correct, give the new code a try and keep me posted :)
0 -
Well, it looks like it is really for I2C, seeing Wire.beginTransmission(slave2w),Wire.write(tx_packet[ix]);, Wire.endTransmission();, and when commenting out #Wire.h and un commenting #SPI.h get errors at "Wire". At line 330 I commented out Wire.h, which gave half as many errors. (the line 330 error goes away)The errors I get:
Arduino: 1.0.5 (Windows 7), Board: "Arduino Mega 2560 or Mega ADK"
sketch_feb16b.ino: In function 'void send_packet(unsigned char)':
sketch_feb16b:190: error: 'Wire' was not declared in this scope
sketch_feb16b.ino: In function 'void setup()':
sketch_feb16b:330: error: 'Wire' was not declared in this scope
I should try it in I2C, my project can do that with a few wire snips, but it is based on a ATMega328P (arduino Uno) and needs more adaptation.
Thanks, Paul
GeorgeC0 -
Well, I get 4 lines. The picture with the arrows are the code in SPI more, the two-wide gibberish is in I2C mode...I need to give my brain a rest...
GeorgeC
[attachment deleted by admin]0 -
it didn't upload the second pix...
[attachment deleted by admin]0 -
Hey George,
Do you have pull-up resistors on SDA and SCL (10k) when using I2C?
Also please try the code below in SPI, I have made some modifications (see comments):#include <Wire.h>
//#include <SPI.h>
int RS = 30;
int E = 31;
int RES = 32;
int CS = 33;
int ASDA = 20;
int ASCL = 21;
int SCLK = 52;
int SDIN = 51;
int SDOUT = 50;
// R/W signal tied LOW (always write)
unsigned char tx_packet[]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
const char slave2w = 0x3C; //3C or 78
unsigned char mode = 0; // 0 = 8-bit parallel 6800 mode; 1 = i2c mode; 2 = SPI mode;
unsigned char text1[] = {"Newhaven Display----"};
unsigned char text2[] = {"Test----------------"};
unsigned char text3[] = {"16/20 Characters----"};
unsigned char text4[] = {"!@#$%^&*()_+{}[]<>?~"};
void command(unsigned char c)
{
unsigned char i, temp;
switch(mode)
{
case 0: digitalWrite(CS, LOW);
PORTA = c;
digitalWrite(RS, LOW);
digitalWrite(E, HIGH);
delay(1);
digitalWrite(E, LOW);
digitalWrite(CS, HIGH);
break;
case 1: tx_packet[0] = 0x00;
tx_packet[1] = c;
send_packet(2);
break;
case 2:
temp = 0xF8;
for(i=0;i<8;i++)
{
digitalWrite(SCLK, LOW);
if((temp&0x80)>>7==1)
{
digitalWrite(SDIN, HIGH);
}
else
{
digitalWrite(SDIN, LOW);
}
temp = temp << 1;
digitalWrite(SCLK, HIGH);
}
for(i=0;i<4;i++)
{
digitalWrite(SCLK, LOW);
if((c&0x01)==1)
{
digitalWrite(SDIN, HIGH);
}
else
{
digitalWrite(SDIN, LOW);
}
c = c >> 1;
digitalWrite(SCLK, HIGH);
}
for(i=0;i<4;i++)
{
digitalWrite(SCLK, LOW);
digitalWrite(SDIN, LOW);
digitalWrite(SCLK, HIGH);
}
for(i=0;i<4;i++)
{
digitalWrite(SCLK, LOW);
if((c&0x1)==0x1) // <------- Change
{
digitalWrite(SDIN, HIGH);
}
else
{
digitalWrite(SDIN, LOW);
}
c = c >> 1;
digitalWrite(SCLK, HIGH);
}
for(i=0;i<4;i++)
{
digitalWrite(SCLK, LOW);
digitalWrite(SDIN, LOW);
digitalWrite(SCLK, HIGH);
}
break;
}
}
void data(unsigned char d)
{
unsigned char i, temp;
switch(mode)
{
case 0: digitalWrite(CS, LOW);
PORTA = d;
digitalWrite(RS, HIGH);
digitalWrite(E, HIGH);
delay(1);
digitalWrite(E, LOW);
digitalWrite(CS, HIGH);
break;
case 1: tx_packet[0] = 0x40;
tx_packet[1] = d;
send_packet(2);
break;
case 2:
temp = 0xFA;
for(i=0;i<8;i++)
{
digitalWrite(SCLK, LOW);
if((temp&0x80)>>7==1)
{
digitalWrite(SDIN, HIGH);
}
else
{
digitalWrite(SDIN, LOW);
}
temp = temp << 1;
digitalWrite(SCLK, HIGH);
}
for(i=0;i<4;i++)
{
digitalWrite(SCLK, LOW);
if((d&0x01)==1)
{
digitalWrite(SDIN, HIGH);
}
else
{
digitalWrite(SDIN, LOW);
}
d = d >> 1;
digitalWrite(SCLK, HIGH);
}
for(i=0;i<4;i++)
{
digitalWrite(SCLK, LOW);
digitalWrite(SDIN, LOW);
digitalWrite(SCLK, HIGH);
}
for(i=0;i<4;i++)
{
digitalWrite(SCLK, LOW);
if((d&0x1)==0x1) // <------- Change
{
digitalWrite(SDIN, HIGH);
}
else
{
digitalWrite(SDIN, LOW);
}
d = d >> 1;
digitalWrite(SCLK, HIGH);
}
for(i=0;i<4;i++)
{
digitalWrite(SCLK, LOW);
digitalWrite(SDIN, LOW);
digitalWrite(SCLK, HIGH);
}
break;
}
}
void send_packet(unsigned char x)
{
unsigned char ix;
Wire.beginTransmission(slave2w);
for(ix=0;ix<x;ix++)
{
Wire.write(tx_packet[ix]);
}
Wire.endTransmission();
}
void output()
{
int i;
command(0x01);
delay(2);
for(i=0;i<20;i++){
data(text1[i]);
}
command(0xA0);
for(i=0;i<20;i++){
data(text2[i]);
}
command(0xC0);
for(i=0;i<20;i++){
data(text3[i]);
}
command(0xE0);
for(i=0;i<20;i++){
data(text4[i]);
}
delay(2000);
command(0x01);
delay(2);
for (i=0;i<20;i++){
data(text3[i]);
}
command(0xA0);
for (i=0;i<20;i++){
data(text4[i]);
}
command(0xC0);
for (i=0;i<20;i++){
data(text1[i]);
}
command(0xE0);
for (i=0;i<20;i++){
data(text2[i]);
}
}
void outputTest()
{
int i;
command(0x01);
delay(2);
data('N');
while(1);
for(i=0;i<20;i++){
data(text1[i]);
}
command(0xA0);
for(i=0;i<20;i++){
data(text2[i]);
}
command(0xC0);
for(i=0;i<20;i++){
data(text3[i]);
}
command(0xE0);
for(i=0;i<20;i++){
data(text4[i]);
}
delay(2000);
command(0x01);
delay(2);
for (i=0;i<20;i++){
data(text3[i]);
}
command(0xA0);
for (i=0;i<20;i++){
data(text4[i]);
}
command(0xC0);
for (i=0;i<20;i++){
data(text1[i]);
}
command(0xE0);
for (i=0;i<20;i++){
data(text2[i]);
}
}
void blocks()
{
int i;
command(0x01);
delay(2);
for(i=0;i<20;i++){
data(0x1F);
}
command(0xA0);
for(i=0;i<20;i++){
data(0x1F);
}
}
void setup()
{
pinMode(ASCL, OUTPUT); //set Arduino I2C lines as outputs
pinMode(ASDA, OUTPUT); //
digitalWrite(ASCL, LOW); //
digitalWrite(ASDA, LOW); //
pinMode(SCLK, OUTPUT);
pinMode(SDIN, OUTPUT);
pinMode(SDOUT, INPUT);
digitalWrite(SCLK, HIGH);
digitalWrite(SDIN, HIGH);
DDRA = 0xFF;
PORTA = 0x00;
DDRC = 0xFF;
PORTC = 0x00;
digitalWrite(RES, HIGH);
delay(10);
Wire.begin();
delay(10);
//SPI.begin();
command(0x2A); //function set (extended command set)
command(0x71); //function selection A, disable internal Vdd regualtor
data(0x00);
command(0x28); //function set (fundamental command set)
command(0x08); //display off, cursor off, blink off
command(0x2A); //function set (extended command set)
command(0x79); //OLED command set enabled
command(0xD5); //set display clock divide ratio/oscillator frequency
command(0x70); //set display clock divide ratio/oscillator frequency
command(0x78); //OLED command set disabled
command(0x09); //extended function set (4-lines)
command(0x06); //COM SEG direction
command(0x72); //function selection B, disable internal Vdd regualtor
data(0x00); //ROM CGRAM selection
command(0x2A); //function set (extended command set)
command(0x79); //OLED command set enabled
command(0xDA); //set SEG pins hardware configuration
command(0x10); //set SEG pins hardware configuration // <--------- Change
command(0xDC); //function selection C
command(0x00); //function selection C
command(0x81); //set contrast control
command(0x7F); //set contrast control
command(0xD9); //set phase length
command(0xF1); //set phase length
command(0xDB); //set VCOMH deselect level
command(0x40); //set VCOMH deselect level
command(0x78); //OLED command set disabled
command(0x28); //function set (fundamental command set)
command(0x01); //clear display
command(0x80); //set DDRAM address to 0x00
command(0x0C); //display ON
delay(100);
//Wire.begin();
//delay(10);
}
void loop()
{
while(1)
{
output();
//blocks();
while(1);
//outputTest();
delay(2000);
}
}Thanks!« Last Edit: February 17, 2015, 08:27:37 AM by Paul_B »0 -
Using the I2C code provided by Paul, using a NHD-0420CW-AB3 display, I had to changed the following line to 0x10:
command(0x00); //set SEG pins hardware configuration ////////////////////////////////////0x10 on other slim char OLEDs
Then I got rid of the double width characters.
Jerry0 -
Success, enjoy the display George!
0 -
Paul, been down with a bug all week, finally tried this code, display's fine with 0x10 on other slim char OLEDs modification. Thanks, y'all!
I need to study what that all means now...
GeorgeC0
Please sign in to leave a comment.
Comments
15 comments