Author Topic: NHD-C12864B2Z-RN-FBW Arduino Uno  (Read 8089 times)

simonp54

  • Newbie
  • *
  • Posts: 4
  • Karma: 2
    • View Profile
NHD-C12864B2Z-RN-FBW Arduino Uno
« on: March 18, 2014, 03:59:49 PM »
Hello again...
After this board has had all its content dropped, I thought I should post again to see if you can help me further.
As you know I am struggling to get this screen to work.  I am now using an I2C I/O expander and two 4050 chips to do the logic conversion to 3.3V I have debugged the outputs using LEDs and I am confident that the code which I attach is sending the correct stuff to the interface (through a NHD-FFC28).  I have checked and double checked everything and still I get nothing from the screen.  When I test without the screen connected it all looks correct, when the screen is inserted into the FFC28 the LEDs dont flash the same way at all...
I am using capacitors from Farnell part number (8126933).

Code is as follows:
Code: [Select]
#include <Wire.h>

#define IO_I2C_ADDR 0x20
#define IO_DIRA_REG 0x00
#define IO_DIRB_REG 0x01
#define IO_ALL_OUTPUTS 0x00
#define IO_ALL_INPUTS 0xFF
#define IO_ADDR_PORT_A 0x12
#define IO_ADDR_PORT_B 0x13

#define RD_PIN 4
#define WR_PIN 3
#define A0_PIN 2

void writeCom(byte bits)
{
  digitalWrite( A0_PIN, LOW );     // A0 - set LOW
  digitalWrite( RD_PIN, HIGH );    // aka E - set HIGH
  digitalWrite( WR_PIN, LOW );     // aka RW - set LOW

  Wire.beginTransmission(IO_I2C_ADDR);
  Wire.write(IO_ADDR_PORT_A);              // address port A
  Wire.write(bits);
  Wire.endTransmission();

  digitalWrite( RD_PIN, LOW );    // aka E - set LOW
  digitalWrite( WR_PIN, LOW );    // aka RW - set LOW
}

void writeData(byte bits)
{
  digitalWrite( A0_PIN, HIGH );    // A0 - set HIGH
  digitalWrite( WR_PIN, LOW );     // aka RW - set LOW
  digitalWrite( RD_PIN, HIGH );    // aka E - set HIGH
 
  Wire.beginTransmission(IO_I2C_ADDR);
  Wire.write(IO_ADDR_PORT_A);              // address port A
  Wire.write(bits);
  Wire.endTransmission();
 
  digitalWrite( RD_PIN, LOW );    // aka E - set LOW
  digitalWrite( WR_PIN, LOW );    // aka RW - set LOW
}



void initScreen()
{
  digitalWrite( WR_PIN, LOW );      // aka RW - set RW to LOW
  digitalWrite( A0_PIN, LOW );      // aka RS - set RS to LOW
                                    // RESTB ?aka RST? - wired to VDD
                                    // CS1B - wired to VSS
  digitalWrite( RD_PIN, LOW );      // aka E - set E to LOW
  delay(22);                        //wait 22ms

  writeCom( 0xA2 );    // 1/9 bias
  writeCom( 0xA0 );    // ADC SELECT NORMAL
  writeCom( 0xC8 );    // COM OUTPUT REVERSE
  writeCom( 0xA4 );    // DISPLAY ALL POINTS NORMAL
  writeCom( 0x40 );    // DISPLAY START LINE SET
  writeCom( 0x25 );    // INTERNAL RESISTOR RATIO
  writeCom( 0x81 );    // ELECTRONIC VOLUME MODE SET
  writeCom( 0x10 );    // ELECTRONIC VOLUME
  writeCom( 0x2F );    // POWER CONTROLLER SET
  writeCom( 0xAF );    // DISPLAY ON
}

//***************************************************
//The setup() function is called
//when a sketch starts. Use it to
//initialize variables, pin modes,
//start using libraries, etc. The
//setup function will only run once,
//after each powerup or reset of the Arduino board.
//***************************************************
void setup()
{
  Serial.begin(9600);

  Wire.begin();

  Wire.beginTransmission(IO_I2C_ADDR);
  Wire.write(IO_DIRA_REG);              // IDDIRA register
  Wire.write(IO_ALL_OUTPUTS);              // set all port A to outputs
  Wire.endTransmission();

  Wire.beginTransmission(IO_I2C_ADDR);
  Wire.write(IO_DIRB_REG);              // IDDIRB register
  Wire.write(IO_ALL_OUTPUTS);              // set all port B to outputs
  Wire.endTransmission();
 
  pinMode( WR_PIN, OUTPUT );    // aka RW
  pinMode( A0_PIN, OUTPUT );    // aka RS
  pinMode( RD_PIN, OUTPUT );    // aka E
 
  initScreen(); 
}


//***************************************************
//the loop() function does precisely what its name suggests,
//and loops consecutively, allowing your program to change
//and respond. Use it to actively control the Arduino board.
//***************************************************
void loop()
{
  writeCom( B10100110 );
  delay(1000);
  writeCom( B10100111 );
  delay(1000);
}

Michael_L

  • Administrator
  • Hero Member
  • *****
  • Posts: 356
  • Karma: 33
    • View Profile
Re: NHD-C12864B2Z-RN-FBW Arduino Uno
« Reply #1 on: March 18, 2014, 04:33:21 PM »
I noticed you are using an i2c interface, and I just want to make sure you know this display only has a parallel interface.  I see you mentioned you are using an i2c I/O expander, so I will assume this is converting your i2c data into 8 separate bits and putting the byte on the display's data bus.  If this is the case, then when I looked at your code I noticed you are using 6800 mode protocol for the parallel interface, when this display is actually only 8080 mode.  You will need to modify your write command/data functions to correct this.  I actually have some Arduino code for our NHD-C12864KGZ display, which uses the same controller.  The code will work for the display you are using too, but more importantly, you can use it as reference to correctly write commands and data in your software.

Code: [Select]
//---------------------------------------------------------
/*
NHD_C12864KGZ_mega.ino
Program for writing to Newhaven Display 128x64 COG graphic LCD with ST7565R controller

(c)2013 Mike LaVine - Newhaven Display International, LLC.

        This program is free software; you can redistribute it and/or modify
        it under the terms of the GNU General Public License as published by
        the Free Software Foundation; either version 2 of the License, or
        (at your option) any later version.

        This program is distributed in the hope that it will be useful,
        but WITHOUT ANY WARRANTY; without even the implied warranty of
        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
        GNU General Public License for more details.
*/
//---------------------------------------------------------

// The 8 bit data bus is connected to PORTA of the Arduino Mega2560
// 5V voltage regulator on Arduino Mega has been replaced with a 3.3V regulator to provide 3.3V logic

int RS = 30;      // RS (A0) signal connected to Arduino digital pin 30
int WR = 31;      // /WR signal connected to Arduino digital pin 31
int RD = 32;      // /RD signal connected to Arduino digital pin 32
int RES = 33;     // /RES signal connected to Arduino digital pin 33

// /CS signal tied to GND

void comm_out(unsigned char c)
{
  digitalWrite(RS, LOW);      //A0 = L = command
  PORTA = c;
  digitalWrite(WR, LOW);
  digitalWrite(WR, HIGH);
}

void data_out(unsigned char d)
{
  digitalWrite(RS, HIGH);     //A0 = H = data
  PORTA = d;
  digitalWrite(WR, LOW);
  digitalWrite(WR, HIGH);
}
void disp()
{
unsigned int i, j;
        unsigned char page=0xB0;
for(i=0;i<8;i++)           //fill display with checkerboard pattern
{
            comm_out(0x10);        //set column address
            comm_out(0x00);        //set column address
    comm_out(page);        //set page address
            for(j=0;j<64;j++)
            {
               data_out(0xAA);
               data_out(0x55);
            }
            page++;
}
}

void setup()
{
  DDRC = 0xFF;         //set PORTC (control signals) as output
  PORTC = 0x00;
  DDRA = 0xFF;         //set PORTA (data signals) as output
  PORTA = 0x00;
  digitalWrite(RD, HIGH);
  digitalWrite(WR, HIGH);
  digitalWrite(RES, LOW);
  delay(150);
  digitalWrite(RES, HIGH);
  delay(150);
 
  comm_out(0xA2);      //added 1/9 bias
 
  comm_out(0xA0);      //ADC segment driver direction (A0=Normal)
 
  comm_out(0xC0);      //COM output scan direction (C0=Normal)
 
  comm_out(0x25);      //resistor ratio
 
  comm_out(0x81);      //electronic volume mode set
 
  comm_out(0x15);      //electronic volume register set
 
  comm_out(0x2F);      //operating mode
 
  comm_out(0x40);      //start line set
 
  comm_out(0xAF);      //display ON
 
  delay(10);
}

void loop()
{
  disp();
  delay(1000);
}

simonp54

  • Newbie
  • *
  • Posts: 4
  • Karma: 2
    • View Profile
Re: NHD-C12864B2Z-RN-FBW Arduino Uno
« Reply #2 on: March 18, 2014, 06:20:03 PM »
Hi Michael,

Thanks for the response and code.. Yes I know its parallel, and the IO expander I am using is designed to do just this kind of update of all the pins at the same time... so we are ok there.

my code now looks like this
Code: [Select]
#include <Wire.h>

#define IO_I2C_ADDR 0x20
#define IO_DIRA_REG 0x00
#define IO_DIRB_REG 0x01
#define IO_ALL_OUTPUTS 0x00
#define IO_ALL_INPUTS 0xFF
#define IO_ADDR_PORT_A 0x12
#define IO_ADDR_PORT_B 0x13

#define RES_PIN 5
#define RD_PIN 4
#define WR_PIN 3
#define A0_PIN 2

void writeCom(byte bits)
{
  digitalWrite( A0_PIN, LOW );     // A0 - set LOW

  Wire.beginTransmission(IO_I2C_ADDR);
  Wire.write(IO_ADDR_PORT_A);              // address port A
  Wire.write(bits);
  Wire.endTransmission();

  digitalWrite( WR_PIN, LOW );    // aka RW - set LOW
  digitalWrite( WR_PIN, HIGH );    // aka RW - set LOW
}

void writeData(byte bits)
{
  digitalWrite( A0_PIN, HIGH );    // A0 - set HIGH
 
  Wire.beginTransmission(IO_I2C_ADDR);
  Wire.write(IO_ADDR_PORT_A);              // address port A
  Wire.write(bits);
  Wire.endTransmission();
 
  digitalWrite( WR_PIN, LOW );    // aka RW - set LOW
  digitalWrite( WR_PIN, HIGH );    // aka RW - set LOW
}



void initScreen()
{
  digitalWrite( RD_PIN, HIGH );      // aka E - set E to HIGH
  digitalWrite( WR_PIN, HIGH );      // aka RW - set RW to HIGH
  digitalWrite( RES_PIN, LOW );
  delay(150);
  digitalWrite( RES_PIN, HIGH );
  delay(150);
 
  writeCom( 0xA2 );    // 1/9 bias
  writeCom( 0xA0 );    // ADC SELECT NORMAL
  writeCom( 0xC0 );    // COM OUTPUT NORMAL
  writeCom( 0x25 );    // INTERNAL RESISTOR RATIO
  writeCom( 0x81 );    // ELECTRONIC VOLUME MODE SET
  writeCom( 0x15 );    // ELECTRONIC VOLUME
  writeCom( 0x2F );    // POWER CONTROLLER SET
  writeCom( 0x40 );    // DISPLAY START LINE SET
  writeCom( 0xAF );    // DISPLAY ON
 
  delay(10);
}

void disp()
{
unsigned int i, j;
        unsigned char page=0xB0;
for(i=0;i<8;i++)           //fill display with checkerboard pattern
{
            writeCom(0x10);        //set column address
            writeCom(0x00);        //set column address
    writeCom(page);        //set page address
            for(j=0;j<64;j++)
            {
               writeData(0xAA);
               writeData(0x55);
            }
            page++;
}
}


//***************************************************
//The setup() function is called
//when a sketch starts. Use it to
//initialize variables, pin modes,
//start using libraries, etc. The
//setup function will only run once,
//after each powerup or reset of the Arduino board.
//***************************************************
void setup()
{
  Serial.begin(9600);

  Wire.begin();

  Wire.beginTransmission(IO_I2C_ADDR);
  Wire.write(IO_DIRA_REG);              // IDDIRA register
  Wire.write(IO_ALL_OUTPUTS);              // set all port A to outputs
  Wire.endTransmission();

  Wire.beginTransmission(IO_I2C_ADDR);
  Wire.write(IO_DIRB_REG);              // IDDIRB register
  Wire.write(IO_ALL_OUTPUTS);              // set all port B to outputs
  Wire.endTransmission();
 
  pinMode( WR_PIN, OUTPUT );    // aka RW
  pinMode( A0_PIN, OUTPUT );    // aka RS
  pinMode( RD_PIN, OUTPUT );    // aka E
  pinMode( RES_PIN, OUTPUT );   // aka RESTB
 
  initScreen(); 
}


//***************************************************
//the loop() function does precisely what its name suggests,
//and loops consecutively, allowing your program to change
//and respond. Use it to actively control the Arduino board.
//***************************************************
void loop()
{
  disp();
  delay(10000);
}

But still no joy.
Brings me back to my original question about checking the power supply is operating correctly???
« Last Edit: March 19, 2014, 02:44:53 AM by simonp54 »

Michael_L

  • Administrator
  • Hero Member
  • *****
  • Posts: 356
  • Karma: 33
    • View Profile
Re: NHD-C12864B2Z-RN-FBW Arduino Uno
« Reply #3 on: March 19, 2014, 09:02:05 AM »
The code that I sent you is working code, I tested it this morning to be 100% certain.  Therefore, the problem should not lie within your software.  As for your power supply concern, what exactly do you mean?  I assume you are powering the display with 3.3V, and all 9 capacitors are in the appropriate places and soldered properly (this can be seen on page 4 of the datasheet).  Are you making sure to align the display's FFC cable to whatever side of the NHD-FFC28 you are using as pin 1?  The display is 27-pin, and the breakout board is 28, so you need to be very careful ensuring it is aligned in the connector properly.

If all of the above is verified to be correct, and your connections are all correct, then the only other thing to troubleshoot would be your I/O expander and level shifters.  Since you are using the Arduino, could you try using the Arduino's parallel port instead?  It would be PORTD[7..0], (digital pins [7..0]).  I am trying to eliminate any possible causes of error from your setup, since the code is verified to be correct.

simonp54

  • Newbie
  • *
  • Posts: 4
  • Karma: 2
    • View Profile
Re: NHD-C12864B2Z-RN-FBW Arduino Uno
« Reply #4 on: March 19, 2014, 01:37:11 PM »
Hey Michael, just before anything else... I appreciate the help and I am very pleased with your responses so far.  I am however a bit disappointed with the misleading information in the Datasheet document (particularly the example code applying to a scheme that the device doesnt support 8080 vs 6800 i just followed the example thinking it was right and the commented out little bits didn't make that any easier either)...

To answer your question, I have rechecked all the wiring and I have been very aware of the 27 vs 28 pin issue and also if you remember emailed you on the orientation of the connector which I understand is "pins" down towards the board...  (btw yes have offset the ribbon to pin 2 - 28, and checked all connections again).

I had written a long number of questions.... but as I have now got the code and screen working!!!!! I don't need them answered.

The problems were two fold..

1) I hadn't level shifted the control lines... only the DB0-7 lines.... DOH
2) I was debugging the "on off" states of the pins by putting LEDs on the driven side of the level shifter... this dragged the voltages down to an unacceptable level for them to be considered "HIGH" etc...

Thanks so much for all the help... are there any "low level" functions that I can grab to drive the screen to do simple tasks like fill an area (rectangle) etc...  and write text on it????
THANKS again.

and for anyone else...
Code: [Select]
// this code expects an IO expander (MCP23017) on the I2C bus at address 0x20
// two level shifters (74HC4050) are used to migrate the levels from 5v to 3.3v
// pins for the control lines are self explanitory

#include <Wire.h>

#define IO_I2C_ADDR 0x20
#define IO_DIRA_REG 0x00
#define IO_DIRB_REG 0x01
#define IO_ALL_OUTPUTS 0x00
#define IO_ALL_INPUTS 0xFF
#define IO_ADDR_PORT_A 0x12
#define IO_ADDR_PORT_B 0x13

#define RES_PIN 5
#define RD_PIN 4
#define WR_PIN 3
#define A0_PIN 2

void writeCom(byte bits)
{
  digitalWrite( A0_PIN, LOW );     // A0 - set LOW

  Wire.beginTransmission(IO_I2C_ADDR);
  Wire.write(IO_ADDR_PORT_A);              // address port A
  Wire.write(bits);
  Wire.endTransmission();

  digitalWrite( WR_PIN, LOW );    // aka RW - set LOW
  digitalWrite( WR_PIN, HIGH );    // aka RW - set HIGH
}

void writeData(byte bits)
{
  digitalWrite( A0_PIN, HIGH );    // A0 - set HIGH
 
  Wire.beginTransmission(IO_I2C_ADDR);
  Wire.write(IO_ADDR_PORT_A);              // address port A
  Wire.write(bits);
  Wire.endTransmission();
 
  digitalWrite( WR_PIN, LOW );    // aka RW - set LOW
  digitalWrite( WR_PIN, HIGH );    // aka RW - set HIGH
}



void initScreen()
{
  digitalWrite( RD_PIN, HIGH );      // aka E - set E to HIGH
  digitalWrite( WR_PIN, HIGH );      // aka RW - set RW to HIGH
  digitalWrite( RES_PIN, LOW );      // reset pin set LOW
  delay(150);
  digitalWrite( RES_PIN, HIGH );     // reset pin set HIGH
  delay(150);
 
  writeCom( 0xA2 );    // 1/9 bias
  writeCom( 0xA0 );    // ADC SELECT NORMAL
  writeCom( 0xC0 );    // COM OUTPUT NORMAL
  writeCom( 0x25 );    // INTERNAL RESISTOR RATIO
  writeCom( 0x81 );    // ELECTRONIC VOLUME MODE SET
  writeCom( 0x15 );    // ELECTRONIC VOLUME
  writeCom( 0x2F );    // POWER CONTROLLER SET
  writeCom( 0x40 );    // DISPLAY START LINE SET
  writeCom( 0xAF );    // DISPLAY ON
 
  delay(10);
}

void disp()
{
unsigned int i, j;
        unsigned char page=0xB0;
for(i=0;i<8;i++)           //fill display with checkerboard pattern
{
            writeCom(0x10);        //set column address
            writeCom(0x00);        //set column address
    writeCom(page);        //set page address
            for(j=0;j<64;j++)
            {
               writeData(0xAA);
               writeData(0x55);
            }
            page++;
}
}


//***************************************************
//The setup() function is called
//when a sketch starts. Use it to
//initialize variables, pin modes,
//start using libraries, etc. The
//setup function will only run once,
//after each powerup or reset of the Arduino board.
//***************************************************
void setup()
{
  Serial.begin(9600);

  Wire.begin();

  Wire.beginTransmission(IO_I2C_ADDR);
  Wire.write(IO_DIRA_REG);              // IDDIRA register
  Wire.write(IO_ALL_OUTPUTS);              // set all port A to outputs
  Wire.endTransmission();

  Wire.beginTransmission(IO_I2C_ADDR);
  Wire.write(IO_ADDR_PORT_A);              // address port A
  Wire.write(0x00);
  Wire.endTransmission();
 
  pinMode( WR_PIN, OUTPUT );    // aka RW
  pinMode( A0_PIN, OUTPUT );    // aka RS
  pinMode( RD_PIN, OUTPUT );    // aka E
  pinMode( RES_PIN, OUTPUT );   // aka RESTB

  digitalWrite( WR_PIN, LOW );
  digitalWrite( A0_PIN, LOW );
  digitalWrite( RD_PIN, LOW );
  digitalWrite( RES_PIN, LOW );
 
  initScreen(); 
}


//***************************************************
//the loop() function does precisely what its name suggests,
//and loops consecutively, allowing your program to change
//and respond. Use it to actively control the Arduino board.
//***************************************************
void loop()
{
  disp();
  delay(1000);
}

simonp54

  • Newbie
  • *
  • Posts: 4
  • Karma: 2
    • View Profile
Re: NHD-C12864B2Z-RN-FBW Arduino Uno
« Reply #5 on: March 20, 2014, 03:53:45 AM »
Actually I now do have some questions, because the ST7565R documentation is so difficult to follow...

how do i achieve a "Read Data" and a "Read Status" from a point of view of the control lines...

I am not sure how the code you have given relates to the table of commands, because the documents don't show the transitions required on the control pins to achieve them. ( and I am not entirely convinced by the timing diagram because it seems like a general setup?)  Is it just a case of having the WR PIN in the opposite state?  In which case for (7) Display data read I will need A0 to be HIGH, RD LOW, and WR HIGH... we never toggled RD before... should the WriteData and WriteCommand functions now make sure of the state of RD?

Of course... with my unidirectional level shifters...  I wont be able to read the status of the pins...  But I would like to know the correct approach for doing readData and readStatus
« Last Edit: March 20, 2014, 06:13:09 AM by simonp54 »

Michael_L

  • Administrator
  • Hero Member
  • *****
  • Posts: 356
  • Karma: 33
    • View Profile
Re: NHD-C12864B2Z-RN-FBW Arduino Uno
« Reply #6 on: March 20, 2014, 08:54:48 AM »
Thanks so much for all the help... are there any "low level" functions that I can grab to drive the screen to do simple tasks like fill an area (rectangle) etc...  and write text on it????
THANKS again.

I have quickly made a function for you that will write text to the desired location of the display.  It uses a font table in software, and I have provided both the function and font table below:

Code: [Select]
unsigned char Ascii_1[97][5]={     // Refer to "Times New Roman" Font Database...
                        //   Basic Characters
    {0xFF,0xFF,0xFF,0xFF,0xFF},     //   (  0)    - 0x0000 Empty set
    {0x00,0x00,0x4F,0x00,0x00},     //   (  1)  ! - 0x0021 Exclamation Mark
    {0x00,0x07,0x00,0x07,0x00},     //   (  2)  " - 0x0022 Quotation Mark
    {0x14,0x7F,0x14,0x7F,0x14},     //   (  3)  # - 0x0023 Number Sign
    {0x24,0x2A,0x7F,0x2A,0x12},     //   (  4)  $ - 0x0024 Dollar Sign
    {0x23,0x13,0x08,0x64,0x62},     //   (  5)  % - 0x0025 Percent Sign
    {0x36,0x49,0x55,0x22,0x50},     //   (  6)  & - 0x0026 Ampersand
    {0x00,0x05,0x03,0x00,0x00},     //   (  7)  ' - 0x0027 Apostrophe
    {0x00,0x1C,0x22,0x41,0x00},     //   (  8)  ( - 0x0028 Left Parenthesis
    {0x00,0x41,0x22,0x1C,0x00},     //   (  9)  ) - 0x0029 Right Parenthesis
    {0x14,0x08,0x3E,0x08,0x14},     //   ( 10)  * - 0x002A Asterisk
    {0x08,0x08,0x3E,0x08,0x08},     //   ( 11)  + - 0x002B Plus Sign
    {0x00,0x50,0x30,0x00,0x00},     //   ( 12)  , - 0x002C Comma
    {0x08,0x08,0x08,0x08,0x08},     //   ( 13)  - - 0x002D Hyphen-Minus
    {0x00,0x60,0x60,0x00,0x00},     //   ( 14)  . - 0x002E Full Stop
    {0x20,0x10,0x08,0x04,0x02},     //   ( 15)  / - 0x002F Solidus
    {0x3E,0x51,0x49,0x45,0x3E},     //   ( 16)  0 - 0x0030 Digit Zero
    {0x00,0x42,0x7F,0x40,0x00},     //   ( 17)  1 - 0x0031 Digit One
    {0x42,0x61,0x51,0x49,0x46},     //   ( 18)  2 - 0x0032 Digit Two
    {0x21,0x41,0x45,0x4B,0x31},     //   ( 19)  3 - 0x0033 Digit Three
    {0x18,0x14,0x12,0x7F,0x10},     //   ( 20)  4 - 0x0034 Digit Four
    {0x27,0x45,0x45,0x45,0x39},     //   ( 21)  5 - 0x0035 Digit Five
    {0x3C,0x4A,0x49,0x49,0x30},     //   ( 22)  6 - 0x0036 Digit Six
    {0x01,0x71,0x09,0x05,0x03},     //   ( 23)  7 - 0x0037 Digit Seven
    {0x36,0x49,0x49,0x49,0x36},     //   ( 24)  8 - 0x0038 Digit Eight
    {0x06,0x49,0x49,0x29,0x1E},     //   ( 25)  9 - 0x0039 Dight Nine
    {0x00,0x36,0x36,0x00,0x00},     //   ( 26)  : - 0x003A Colon
    {0x00,0x56,0x36,0x00,0x00},     //   ( 27)  ; - 0x003B Semicolon
    {0x08,0x14,0x22,0x41,0x00},     //   ( 28)  < - 0x003C Less-Than Sign
    {0x14,0x14,0x14,0x14,0x14},     //   ( 29)  = - 0x003D Equals Sign
    {0x00,0x41,0x22,0x14,0x08},     //   ( 30)  > - 0x003E Greater-Than Sign
    {0x02,0x01,0x51,0x09,0x06},     //   ( 31)  ? - 0x003F Question Mark
    {0x32,0x49,0x79,0x41,0x3E},     //   ( 32)  @ - 0x0040 Commercial At
    {0x7E,0x11,0x11,0x11,0x7E},     //   ( 33)  A - 0x0041 Latin Capital Letter A
    {0x7F,0x49,0x49,0x49,0x36},     //   ( 34)  B - 0x0042 Latin Capital Letter B
    {0x3E,0x41,0x41,0x41,0x22},     //   ( 35)  C - 0x0043 Latin Capital Letter C
    {0x7F,0x41,0x41,0x22,0x1C},     //   ( 36)  D - 0x0044 Latin Capital Letter D
    {0x7F,0x49,0x49,0x49,0x41},     //   ( 37)  E - 0x0045 Latin Capital Letter E
    {0x7F,0x09,0x09,0x09,0x01},     //   ( 38)  F - 0x0046 Latin Capital Letter F
    {0x3E,0x41,0x49,0x49,0x7A},     //   ( 39)  G - 0x0047 Latin Capital Letter G
    {0x7F,0x08,0x08,0x08,0x7F},     //   ( 40)  H - 0x0048 Latin Capital Letter H
    {0x00,0x41,0x7F,0x41,0x00},     //   ( 41)  I - 0x0049 Latin Capital Letter I
    {0x20,0x40,0x41,0x3F,0x01},     //   ( 42)  J - 0x004A Latin Capital Letter J
    {0x7F,0x08,0x14,0x22,0x41},     //   ( 43)  K - 0x004B Latin Capital Letter K
    {0x7F,0x40,0x40,0x40,0x40},     //   ( 44)  L - 0x004C Latin Capital Letter L
    {0x7F,0x02,0x0C,0x02,0x7F},     //   ( 45)  M - 0x004D Latin Capital Letter M
    {0x7F,0x04,0x08,0x10,0x7F},     //   ( 46)  N - 0x004E Latin Capital Letter N
    {0x3E,0x41,0x41,0x41,0x3E},     //   ( 47)  O - 0x004F Latin Capital Letter O
    {0x7F,0x09,0x09,0x09,0x06},     //   ( 48)  P - 0x0050 Latin Capital Letter P
    {0x3E,0x41,0x51,0x21,0x5E},     //   ( 49)  Q - 0x0051 Latin Capital Letter Q
    {0x7F,0x09,0x19,0x29,0x46},     //   ( 50)  R - 0x0052 Latin Capital Letter R
    {0x46,0x49,0x49,0x49,0x31},     //   ( 51)  S - 0x0053 Latin Capital Letter S
    {0x01,0x01,0x7F,0x01,0x01},     //   ( 52)  T - 0x0054 Latin Capital Letter T
    {0x3F,0x40,0x40,0x40,0x3F},     //   ( 53)  U - 0x0055 Latin Capital Letter U
    {0x1F,0x20,0x40,0x20,0x1F},     //   ( 54)  V - 0x0056 Latin Capital Letter V
    {0x3F,0x40,0x38,0x40,0x3F},     //   ( 55)  W - 0x0057 Latin Capital Letter W
    {0x63,0x14,0x08,0x14,0x63},     //   ( 56)  X - 0x0058 Latin Capital Letter X
    {0x07,0x08,0x70,0x08,0x07},     //   ( 57)  Y - 0x0059 Latin Capital Letter Y
    {0x61,0x51,0x49,0x45,0x43},     //   ( 58)  Z - 0x005A Latin Capital Letter Z
    {0x00,0x7F,0x41,0x41,0x00},     //   ( 59)  [ - 0x005B Left Square Bracket
    {0x02,0x04,0x08,0x10,0x20},     //   ( 60)  \ - 0x005C Reverse Solidus
    {0x00,0x41,0x41,0x7F,0x00},     //   ( 61)  ] - 0x005D Right Square Bracket
    {0x04,0x02,0x01,0x02,0x04},     //   ( 62)  ^ - 0x005E Circumflex Accent
    {0x40,0x40,0x40,0x40,0x40},     //   ( 63)  _ - 0x005F Low Line
    {0x01,0x02,0x04,0x00,0x00},     //   ( 64)  ` - 0x0060 Grave Accent
    {0x20,0x54,0x54,0x54,0x78},     //   ( 65)  a - 0x0061 Latin Small Letter A
    {0x7F,0x48,0x44,0x44,0x38},     //   ( 66)  b - 0x0062 Latin Small Letter B
    {0x38,0x44,0x44,0x44,0x20},     //   ( 67)  c - 0x0063 Latin Small Letter C
    {0x38,0x44,0x44,0x48,0x7F},     //   ( 68)  d - 0x0064 Latin Small Letter D
    {0x38,0x54,0x54,0x54,0x18},     //   ( 69)  e - 0x0065 Latin Small Letter E
    {0x08,0x7E,0x09,0x01,0x02},     //   ( 70)  f - 0x0066 Latin Small Letter F
    {0x06,0x49,0x49,0x49,0x3F},     //   ( 71)  g - 0x0067 Latin Small Letter G
    {0x7F,0x08,0x04,0x04,0x78},     //   ( 72)  h - 0x0068 Latin Small Letter H
    {0x00,0x44,0x7D,0x40,0x00},     //   ( 73)  i - 0x0069 Latin Small Letter I
    {0x20,0x40,0x44,0x3D,0x00},     //   ( 74)  j - 0x006A Latin Small Letter J
    {0x7F,0x10,0x28,0x44,0x00},     //   ( 75)  k - 0x006B Latin Small Letter K
    {0x00,0x41,0x7F,0x40,0x00},     //   ( 76)  l - 0x006C Latin Small Letter L
    {0x7C,0x04,0x18,0x04,0x7C},     //   ( 77)  m - 0x006D Latin Small Letter M
    {0x7C,0x08,0x04,0x04,0x78},     //   ( 78)  n - 0x006E Latin Small Letter N
    {0x38,0x44,0x44,0x44,0x38},     //   ( 79)  o - 0x006F Latin Small Letter O
    {0x7C,0x14,0x14,0x14,0x08},     //   ( 80)  p - 0x0070 Latin Small Letter P
    {0x08,0x14,0x14,0x18,0x7C},     //   ( 81)  q - 0x0071 Latin Small Letter Q
    {0x7C,0x08,0x04,0x04,0x08},     //   ( 82)  r - 0x0072 Latin Small Letter R
    {0x48,0x54,0x54,0x54,0x20},     //   ( 83)  s - 0x0073 Latin Small Letter S
    {0x04,0x3F,0x44,0x40,0x20},     //   ( 84)  t - 0x0074 Latin Small Letter T
    {0x3C,0x40,0x40,0x20,0x7C},     //   ( 85)  u - 0x0075 Latin Small Letter U
    {0x1C,0x20,0x40,0x20,0x1C},     //   ( 86)  v - 0x0076 Latin Small Letter V
    {0x3C,0x40,0x30,0x40,0x3C},     //   ( 87)  w - 0x0077 Latin Small Letter W
    {0x44,0x28,0x10,0x28,0x44},     //   ( 88)  x - 0x0078 Latin Small Letter X
    {0x0C,0x50,0x50,0x50,0x3C},     //   ( 89)  y - 0x0079 Latin Small Letter Y
    {0x44,0x64,0x54,0x4C,0x44},     //   ( 90)  z - 0x007A Latin Small Letter Z
    {0x00,0x08,0x36,0x41,0x00},     //   ( 91)  { - 0x007B Left Curly Bracket
    {0x00,0x00,0x7F,0x00,0x00},     //   ( 92)  | - 0x007C Vertical Line
    {0x00,0x41,0x36,0x08,0x00},     //   ( 93)  } - 0x007D Right Curly Bracket
    {0x02,0x01,0x02,0x04,0x02},     //   ( 94)  ~ - 0x007E Tilde
    {0x08,0x0C,0x0E,0x0C,0x08},     //   ( 95)  upward facing triangle/arrow
    {0x08,0x18,0x38,0x18,0x08},     //   ( 96)  downward facing triangle/arrow
};

void LCD_Text(unsigned char column, unsigned char page, unsigned char letter)
{
    unsigned char count, msb, lsb;
   
    lsb = ((column)&(0x0F));
    msb = ((column>>4)&(0x0F));
    msb |= 0x10;
    page |= 0xB0;
   
    comm_out(msb);
    comm_out(lsb);
    comm_out(page);

    for (count=0;count<5;count++)//each character is 8 px tall
    {
        data_out(Ascii_1[letter][count]);
    }
}

The "letter" parameter would be the number of what letter you want from the font table (the number in the parentheses).  For example, if you wanted to put the capital letter S in the top left corner of the display you would call LCD_Text(0,0,51);.

*For this to work in the correct orientation, you will to change a value in your initialization.  Where you call writeCom( 0xC0 ) you will need to change it to writeCom( 0xC8 ).*
« Last Edit: March 20, 2014, 09:14:59 AM by Michael_L »

Michael_L

  • Administrator
  • Hero Member
  • *****
  • Posts: 356
  • Karma: 33
    • View Profile
Re: NHD-C12864B2Z-RN-FBW Arduino Uno
« Reply #7 on: March 20, 2014, 09:10:34 AM »
Actually I now do have some questions, because the ST7565R documentation is so difficult to follow...

how do i achieve a "Read Data" and a "Read Status" from a point of view of the control lines...

I am not sure how the code you have given relates to the table of commands, because the documents don't show the transitions required on the control pins to achieve them. ( and I am not entirely convinced by the timing diagram because it seems like a general setup?)  Is it just a case of having the WR PIN in the opposite state?  In which case for (7) Display data read I will need A0 to be HIGH, RD LOW, and WR HIGH... we never toggled RD before... should the WriteData and WriteCommand functions now make sure of the state of RD?

Of course... with my unidirectional level shifters...  I wont be able to read the status of the pins...  But I would like to know the correct approach for doing readData and readStatus

There are two read commands available.  Status read, and Display data read.  This is the only time you would need to toggle the /RD signal as opposed to the /WR signal.  The way these signals work (how 8080 mode works) is after you have put a byte on the bus, you pull one low (active low signals, normally kept high; which one to pull low depends on if you want to write or read) and then bring it back high.  This is why typically if never reading anything from the display, you can keep /RD tied high and only toggle /WR when needing to write.  If you do need to read however, then you would just do the opposite.  You would need /WR to be held high, while /RD is the signal that is toggled.  The difference between the two read commands is the A0 signal.  If this signal is low, then the controller will read the status when you toggle the /RD signal.  If A0 is high, it will read the display data.  As for your question about the write functions making sure of the state of /RD, you may do so if you wish, but it is not necessary.  If after power on you simply set this signal high, you won't need to waste CPU cycles each time the function is called  :)

 

Arduino LCD library not working with newhaven display NHD‐0420H1Z‐FL‐GWB-3V3

Started by c2hollowBoard Character LCDs

Replies: 9
Views: 9253
Last post July 10, 2014, 08:46:06 AM
by Michael_L
MOVED: 320x240 sunlight readable dispaly to arduino + library

Started by Michael_LBoard Customer Projects

Replies: 0
Views: 2549
Last post October 23, 2015, 11:45:28 AM
by Michael_L
320x240 sunlight readable dispaly to arduino + library

Started by vonz66Board Graphic LCDs

Replies: 1
Views: 3217
Last post October 23, 2015, 11:46:04 AM
by Michael_L
Wiring connectiond between NHD-1.69-160128ASC3 SSD1351 and Arduino Nano

Started by amitkumarsharma008Board OLEDs

Replies: 3
Views: 3197
Last post March 23, 2016, 03:38:11 PM
by Paul_B
NHD-0420D3Z-NSW-BBW-V3 i2c display and Arduino missing characters

Started by 0miker0Board Character LCDs

Replies: 0
Views: 817
Last post July 06, 2017, 11:05:59 AM
by 0miker0