Author Topic: NHD-0420D3Z-FL-GWB-V3 no I2C code example for Arduino??  (Read 488 times)

yanard

  • Newbie
  • *
  • Posts: 1
  • Karma: 0
    • View Profile
NHD-0420D3Z-FL-GWB-V3 no I2C code example for Arduino??
« on: June 07, 2017, 08:24:24 PM »
I am looking for a basic code sample that connects the NHD-0420D3Z-FL-GWB-V3 display to my Arduino Uno using the I2C protocol. There doesn't appear to be one :( I am new so I may have missed it somewhere and any help pointing me in the right direction even if it is to teach me is appreciated.
Thanks

Ted_M

  • Administrator
  • Newbie
  • *****
  • Posts: 8
  • Karma: 1
    • View Profile
Re: NHD-0420D3Z-FL-GWB-V3 no I2C code example for Arduino??
« Reply #1 on: June 08, 2017, 08:50:29 AM »
Here is some example Arduino code for a 2x16 display using I2C that may help to get you started.

/******************************************************
 * Using i2c on NHD 0216KZ3
 * ARDUINO MEGA
 */

#define SCLK 21
#define SDO 20



const char Slave    = 0x50;

const char t1[]=("Newhaven Display");
const char t2[]=("    LINE  2     ");

void I2C_out(unsigned char j){
  int n;
  unsigned char d;
  d=j;
  for(n = 0; n<8; n++){
    if((d&0x80) == 0x80)
      digitalWrite(SDO, HIGH);
    else
      digitalWrite(SDO, LOW);
    d = (d<<1);
    digitalWrite(SCLK, LOW);
    delay(10);
    digitalWrite(SCLK, HIGH);
    delay(5);
    digitalWrite(SCLK, LOW);
    delay(10);
  }
  digitalWrite(SCLK, HIGH);
  delay(1);
  while(SDO ==1){
   
    digitalWrite(SCLK, LOW);
    //delay(1);
    digitalWrite(SCLK, HIGH);
    //delay(1);
   
  }
  digitalWrite(SCLK, LOW);
}
void I2C_Start(){
  digitalWrite(SCLK, HIGH);
  digitalWrite(SDO, HIGH);
  digitalWrite(SDO, LOW);
  digitalWrite(SCLK, LOW);
}

void I2C_Stop(){
  digitalWrite(SDO, LOW);
  digitalWrite(SCLK, LOW);
  digitalWrite(SCLK, HIGH);
  digitalWrite(SDO, HIGH);
}
void disp(const char *text)
{
  int n;
  for(n=0;n<16;n++)
  {
    I2C_Start();
    delay(5);
    I2C_out(Slave);
    delay(5);
    I2C_out(*text);
    text++;
    I2C_Stop();
    delay(10);
  }
}

void setup() {
  // put your setup code here, to run once:
  pinMode(SDO, OUTPUT);
  pinMode(SCLK, OUTPUT);
  digitalWrite(SCLK, LOW);
  digitalWrite(SDO, LOW);
 
  I2C_Start();
  delay(1);
  I2C_out(0x50);
  delay(1);
 
  delay(10);
  I2C_out(0xFE);
  I2C_out(0x51);
  I2C_Stop();
  delay(100);
  I2C_Start();
  delay(5);
  I2C_out(Slave);
  delay(5);
  I2C_out(0xFE);
  I2C_out(0x46);
  delay(10);
  I2C_Stop();
  delay(100);
  I2C_Start();
  delay(5);
  I2C_out(Slave);
  delay(5);
  I2C_out(0xFE);
  I2C_out(0x47);
 

  delay(100);
  I2C_Stop();
  delay(10);
  I2C_Start();
    delay(5);
    I2C_out(Slave);
    delay(5);
    I2C_out(0xFE);
    I2C_out(0x52);
    delay(5);
    I2C_out(40);
    delay(5);
    I2C_Stop();
    delay(250);
 
 
}

void loop() {
  unsigned char x = 0x21;
  int i;
  I2C_Start();
  delay(5);
  I2C_out(Slave);
  delay(5);
  I2C_out(0xFE);
  I2C_out(0x51);
  I2C_Stop();
  double a;
  char buff[10];
  a = 2.523;

  sprintf(buff, "%g" , a);
  int n = 0;
  /*
    for (n = 0; n < 8 ; n ++){
      I2C_Start();
  delay(1);
  I2C_out(Slave);
  delay(1);
    I2C_out(buff[n]);
    delay(1);
    I2C_Stop();
    delay(1);
  }
 
  delay (2500);*/
  disp(t1);
  delay(100);

  delay(100);
  I2C_Start();
  delay(5);
  I2C_out(Slave);
  delay(5);
  I2C_out(0xFE);
  I2C_out(0x45);
  //delay(10);
  I2C_out(0x40);
  delay(10);
  I2C_Stop();
  delay(10);
  disp(t2);
  I2C_Stop();
  delay(1000);
  do{
   delay(10);
  for( i = 0 ; i < 50 ; i++){
    I2C_Start();
    delay(5);
    I2C_out(Slave);
    delay(5);
    I2C_out(0xFE);
    I2C_out(0x52);
    delay(5);
    I2C_out(i);
    delay(5);
    I2C_Stop();
    delay(5);
  }
  int b;
  for( i = 0 ; i < 51 ; i++){
    I2C_Start();
    delay(5);
    I2C_out(Slave);
    delay(5);
    I2C_out(0xFE);
    I2C_out(0x52);
    delay(5);
    b = 50 - i;
    I2C_out(b);
    delay(5);
    I2C_Stop();
    delay(25);
  }
  }while(1);
  /*for(i = 0; i < 57; i++){
    I2C_Start();
    delay(5);
    I2C_out(Slave);
    delay(5);
    I2C_out(x);
    x++;
    I2C_Stop();
    delay(10);
  }
// delay(5000);
 
  I2C_Start();
  delay(5);
  I2C_out(Slave);
  delay(5);
  I2C_out(0xFE);
 
  I2C_out(0x51);
  delay(10);

    I2C_out(0xFE);
  I2C_out(0x4B);
  delay(10);
  I2C_out(0xFE);
  I2C_out(0x46);
  delay(10);
  I2C_Stop();
  disp(t1);
  delay(1000);
  for( i = 0 ; i < 50 ; i++){
    I2C_Start();
    delay(5);
    I2C_out(Slave);
    delay(5);
    I2C_out(0xFE);
    I2C_out(0x52);
    delay(5);
    I2C_out(i);
    delay(5);
    I2C_Stop();
    delay(250);
  }
   I2C_Start();
    delay(5);
    I2C_out(Slave);
    delay(5);
    I2C_out(0xFE);
    I2C_out(0x52);
    delay(5);
    I2C_out(40);
    delay(5);
    I2C_Stop();
    delay(250);
 
  while(1);*/
 
}
« Last Edit: June 08, 2017, 08:58:57 AM by Ted_M »

BenB2000

  • Newbie
  • *
  • Posts: 2
  • Karma: 0
    • View Profile
Re: NHD-0420D3Z-FL-GWB-V3 no I2C code example for Arduino??
« Reply #2 on: June 28, 2017, 03:07:20 PM »
Hi I am using the Newhaven NHD-0216S3Z-FL-GBW-V3 16x2 Character display
using an Arduino Leonardo, with I2C communication

For this display it is important to set the Arduino's I2C communication speed to 100Khz

One way to do this is with the following statement, in void setup():

   TWBR = 100000; //sets I2C spaeed to 100kHz very important

The NHD-0216S3Z-FL-GBW-V3 manual states the default I2C address is 0x50, but it was actually 0x28

This code works for the NHD-0216S3Z-FL-GBW-V3 on the I2C bus:

// ----------------------------------------------------------------
#include <Wire.h> //I2C library
const byte LCDa = 0x28; //LCD address on I2C bus

void setup()  {
   TWBR = 100000; //sets I2C speed to 100kHz very important
   
        LCDclear();
        delay(500);     // for observation only can be removed
         
        LCDline1col1(); // position cursor Line #1, col#1
       
        Wire.beginTransmission(LCDa); // Write to LCD Line #1, col#1             
        Wire.write("Hello World 2017");     
        Wire.endTransmission();
     
         LCDline2col1(); // position cursor Line #2, col#1
               
        Wire.beginTransmission(LCDa); // Write to LCD Line #2, col#1               
        Wire.write("Welcome Home eh?");             
        Wire.endTransmission();

  }

void loop()
  { 
  }

  // Clear the NHD Extended LCD Screen
void LCDclear() {
  Wire.beginTransmission(LCDa);
  Wire.write (0xFE);
  Wire.write(0x51);
  Wire.endTransmission();
  delay(2);
}

  // Set Cursor to Line #1, Col #1 NHD Extended LCD Screen
void LCDline1col1() {
  Wire.beginTransmission(LCDa);
  Wire.write (0xFE);
  Wire.write(0x45);
  Wire.write(0x00);   
  Wire.endTransmission();
  delay(2);
}

  // Set Cursor to Line #2, Col #1 NHD Extended LCD Screen
void LCDline2col1() {
  Wire.beginTransmission(LCDa);
  Wire.write (0xFE);
  Wire.write(0x45);
  Wire.write(0x40);   
  Wire.endTransmission();
  delay(2);
}


Scanner code to read all I2C devices attaced that worked for me is:

/*****************************************************
 * name:I2C_Address
 * function:read the address's of the I2C devices
 * Connection:
 * I2C                 Leonardo
 * GND                 GND
 * VCC                  5V
 * SDA                  2 Leonardo (UNO A4) (pin20 in mega2560)
 * SCL                  3 Leonardo (UNO A5) (pin21 in mega2560)
 ********************************************************/

#include <Wire.h>

void setup()
{

  TWBR = 100000; //sets I2C spaeed to 100kHz very important
 
  Wire.begin();
  Serial.begin(9600);
  Serial.println("\nI2C Scanner");
}
void loop()
{
  byte error, address;
  int nDevices;
  Serial.println("Scanning...");
  nDevices = 0;
  for(address = 1; address < 127; address++ )
  {
    // The i2c_scanner uses the return value of
    // the Write.endTransmisstion to see if
    // a device did acknowledge to the address.
    Wire.beginTransmission(address);
    error = Wire.endTransmission();
    if (error == 0)
    {
      Serial.print("I2C device found at address 0x");
      if (address<16)
        Serial.print("0");
      Serial.print(address,HEX);
      Serial.println(" !");
      nDevices++;
    }
    else if (error==4)
    {
      Serial.print("Unknow error at address 0x");
      if (address<16)
        Serial.print("0");
      Serial.println(address,HEX);
    }
  }
  if (nDevices == 0)
    Serial.println("No I2C devices found\n");
  else
    Serial.println("done\n");
  delay(5000); // wait 5 seconds for next scan
}

Newhaven should publish better Arduino Code examples, and reminding people that the manual states 100Khz max,

I spent several hours on this before I found this on the Arduino Forum

  TWBR = 100000; //sets I2C speed to 100kHz very important


BenB2000

  • Newbie
  • *
  • Posts: 2
  • Karma: 0
    • View Profile
Re: NHD-0420D3Z-FL-GWB-V3 no I2C code example for Arduino??
« Reply #3 on: July 27, 2017, 10:35:19 AM »
Hi All, just an amendment to the last code

the statement TWBR = 100000, is incorrect

see http://www.gammon.com.au/i2c

Where the TWBR value is defined in the formula
I2C freq = CPU Clock / ( 16+(2*TWBR*Prescaler)

Default Prescaler =1 and the formula I2C freq = 16000000/(16+144) = 100000

For a TWBR = 12, Prescaler =1, I2C freq = 400 kHz
For a TWBR = 32, Prescaler =1, I2C freq = 200 kHz
For a TWBR = 72, Prescaler =1, I2C freq = 100 kHz
For a TWBR = 152, Prescaler =1, I2C freq = 50 kHz

I installed Arduino v1.8.3 and tried to compile the code with TWBR = 100000
and got a warning that the TWBR value was not correct and was truncated, posibly to 100 since all values of TWBR are under 255

the statement
TWBR = 152; //sets I2C speed to 50kHz for NHD LCD display compiled OK with out any warnings, and the display ran OK

Under Reference in the Wire Library, the I2C command

Wire.setClock(100000); // is valid for I2C speed of 100 KHz

In my case with the NHD-0216S3Z-FL-GBW-V3 16 x 2 Display, with builtin I2C,
would only work properly if the  I2C frequency value
was set at or below 70000, anything higher, and the display would not show all of the characters sent properly, some characters would be missing, and others in the wrong location.

Wire.setClock(100000); // did not work
Wire.setClock(90000); // did not work
Wire.setClock(80000); // did not work

but
Wire.setClock(70000); // did work

So there are two ways to change the I2C clock speed

 

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

Started by c2hollowBoard Character LCDs

Replies: 9
Views: 8252
Last post July 10, 2014, 08:46:06 AM
by Michael_L
Sample Code Question for NHD‐C0220BiZ‐FS(RGB)‐FBW‐3VM LCD

Started by SteveCBoard Character LCDs

Replies: 2
Views: 2893
Last post July 31, 2014, 08:44:29 PM
by SteveC
MOVED: 320x240 sunlight readable dispaly to arduino + library

Started by Michael_LBoard Customer Projects

Replies: 0
Views: 2303
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: 2870
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: 2861
Last post March 23, 2016, 03:38:11 PM
by Paul_B