NHD-0420D3Z-FL-GWB-V3 no I2C code example for Arduino??

Comments

3 comments

  • Ted M.
    NHD Staff

    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);*/
     
    }
    0
  • BenB2000

    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

    0
  • BenB2000

    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

    0

Please sign in to leave a comment.