Library that works fine on the NHD-0420CW-A*3

Comments

26 comments

  • Paul_B

    Hello George,

    Thanks for sharing and posting your solution!

    Regarding custom characters please have a look at the displays controller spec, see page 28. User defined characters can be loaded via 512 bits (8 characters) Character Generator RAM (CGRAM).

    Link: https://newhavendisplay.com/content/app_notes/US2066.pdf 

    You will need to call the Set CGRAM address command, also take a look at the command description listed on page 39.

    Hope this helps and please keep me posted on your progress :)

    0
  • wb2dyb

    Hi Paul, I understand that, but I'm not a programmer. I tried some copying from others for this same purpose but part of a different controller's library. (HD44780). But I just don't have what it takes to figure this out. Also, when I thought I had that part working I spent hours and just didn't see how to access a custom font. I know default CGROM is the third one "C", and eventually figured out how to change that, but I just didn't see how to get "at it". I'll eventually figure it out. And the project I wanted this for is now working on breadboard with the OLedI2C (modified for four line) library.

    It's fun anyhow! And at 62 I'm learning...

    GeorgeC

    0
  • Chris O.

    The only missing function, at least one I'd like to see is a custom character. Most controllers allow for this, and the NHD420CW does. Just not in this library. And I speak entirely about Arduino Uno. But it is doing what I needed, with the exception of needing 8 custom characters I need to represent with letters. I tried adding it but while I think I got the character creation right, for all I've looked, I cannot see how to select a custom character (anybody give me a pointer on THAT??

    Hi
    I hope this will help.
    It's for my arduino-matrixorbital
    A software emulator for Matrix Orbital character display commands on Arduino.
    Example sketch that uses Matrix Orbital type commands, look at case 78: // Define custom character

     

    NOTE: This is not a complete code its missing many commands.

     

    #include <OLEDFourBit.h> // Works with NewHAVEN NHD-0420DZW-AY5-ND
    // Added fixes by Chris O. to OLEDFourBit library, Compatibility with previous versions of IDE. NOTE tested on Aduino 023 IDE <---> Aduino 1.0.4 IDE
    // NOTE: Arduino Micro Pin Mapping i used.
    OLEDFourBit lcd(12, A0, A1, A2, A3, A4, A5); //with rw pin (12, 11, 10, 5, 4, 3, 2);
    //OLEDFourBit lcd(12, 14, 15, 16, 17, 18, 19);

    // these constants won't change.  But you can change the size of
    // your LCD using them:
    const int numRows = 4; // 4x20 LCD
    const int numCols = 20;
    //
    byte rxbyte = 0; // incoming data storage

    void setup() {
      Serial.begin(19200); // Default baudrate.
      lcd.begin(numCols, numRows); // Change this for other screen sizes. 
      lcd.print("Arduino Emulator for");
      lcd.setCursor(1, 1);
      lcd.print("Matrix Orbital!");
      lcd.setCursor(2, 2);
      lcd.print("Character Display!");
      lcd.command(0b00010000); //Moves the cursor back one space before the blinking cursor
      lcd.command(0b00001101); // 0b00001DCB Show Blinking Block Cursor with out Underscore

      delay(5000); //delay 5 sec
      // while (serial_getch() == 0 ){   //delay [ Wait for OS to load ]
      //   rxbyte = serial_getch();
      //}
      lcd.command(0b00001100); //Turn off the blinking cursor: on exit
      //lcd.noBlink(); // Turn off the blinking cursor: on exit / no good it will turn off the display ????????? lib. problem?

      lcd.clear(); // clear the screen
      lcd.setCursor(0,0);
    }
    void loop() {
      // incoming data storage
      byte temp; // Parameter storage
      byte temp2; //2nd Parameter storage

      rxbyte = serial_getch(); //get byte and store in rxbyte

      if (rxbyte == 254) { //Matrix Orbital uses 254 prefix for commands
        switch (serial_getch()) { //get byte

        case 71:  //set cursor position
          temp = (serial_getch() - 1);  //get column byte
          switch (serial_getch())  //get row byte
          {
            //line 1 is already set up
          case 2:
            temp += 0x40;
            break;
          case 3:
            temp += 0x14;
            break;
          case 4:
            temp += 0x54;
            break;
          default:
            break;
          }
          lcd.command(0b10000000 + temp);
          delay(1);
          break;

        case 72: // Cursor home (doesn't clear the screen!)
          //lcd.home();
          lcd.setCursor(0,0);
          break;

        case 76: // Move cursor left  0b00010000 / dec16 /hex10
          lcd.command(16);//Cursor/Display Shift  hex(0x10); //set cursor position one character to the left
          break;

        case 77: // Move cursor right 0b00010100 / dec20 /hex14
          lcd.command(20);
          break;

        case 78: // Define custom character (2 parameters, id, data)
          lcd.command(64 + (serial_getch() * 8));
          for (temp = 8; temp != 0; temp--) {
            lcd.write(serial_getch()); //works with Adafruit_CharacterOLED library
          }
          break;
        }
        return; // Stop and start again.
      }

      // Otherwise its a plain char so we print it to the LCD.
      //lcd.write(rxbyte);
      lcd.print((char)rxbyte);  //otherwise a plain char so we print it to lcd
    } // END of main loop

    // ***********************************************************************************************************
    // *           Get byte
    // *             
    // *           Waits for a byte to be available, reads and returns it.
    // *
    // ***********************************************************************************************************
    byte serial_getch() { // Get byte from Serial
      while (Serial.available() == 0);
      return Serial.read();
    }

    0
  • wb2dyb
    Chris, I found similar language from a VFD display using HD44780 controller.

     // Allows us to fill the first 8 CGRAM locations
    // with custom characters
    void OLedI2C::createChar(uint8_t location, uint8_t charmap[]) {
      location &= 0x7; // we only have 8 locations 0-7
      sendCommand(VFD_SETCGRAMADDR | (location << 3));
      for (int i=0; i<8; i++) {
       write(charmap);
     }

    My problem is that "write" isn't defined anywhere, and in the library it came from VFD_SPI.cpp it isn't defined, I just don't know where that would come from
    0
  • Chris O.

    Hmm ok
    Can you try this.

    #include <LiquidCrystal.h>

    LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

    byte newChar[8] = {
            B00000,
            B00000,
            B10101,
            B11101,
            B11101,
            B10101,
            B00000,
            B00000
    };

    void setup() {
        lcd.createChar(0, newChar);
        lcd.begin(20, 4);
        lcd.write(0);
    }

    void loop() {}
    0
  • Chris O.

    Two Custom Characters

     

    #include <OLEDFourBit.h> //  NewHAVEN NHD-0420DZW-AY5-ND
    //#include <LiquidCrystal.h>
    OLEDFourBit lcd(7, 4, 10, 5, A3, A4, A5);
    //LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

    byte newChar1[8] = {
      B00000,
      B00000,
      B10101,
      B11101,
      B11101,
      B10101,
      B00000,
      B00000
    };

    byte newChar2[8] = {
      B10000,
      B01000,
      B00101,
      B00100,
      B00100,
      B00101,
      B01000,
      B10000
    };

    void setup() {
      lcd.createChar(0, newChar1);
      lcd.createChar(1, newChar2);
      lcd.begin(20, 4);
     

    }
    void loop() {
      lcd.setCursor(2,0);
      lcd.write(0); //PRINT
      lcd.setCursor(2,1);
      lcd.write(1); //PRINT

      delay(1000);
    }
    0
  • Chris O.

    Liquid Crystal Display Custom Character Designer

    http://mikeyancey.com/hamcalc/lcd_characters.php

    0
  • Chris O.

    This is other way of printing a  char
    lcd.print((char)1); //print char

     

    #include <OLEDFourBit.h> // Works with NewHAVEN NHD-0420DZW-AY5-ND
    //#include <LiquidCrystal.h>
    OLEDFourBit lcd(7, 4, 10, 5, A3, A4, A5);
    //LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

    byte newChar0[8] = {
      B00000,
      B00000,
      B10101,
      B11101,
      B11101,
      B10101,
      B00000,
      B00000
    };

    byte newChar1[8] = {
      B10000,
      B01000,
      B00101,
      B00100,
      B00100,
      B00101,
      B01000,
      B10000
    };

    byte newChar15[8] = {
      B10001,
      B01010,
      B01110,
      B00100,
      B00100,
      B01110,
      B01010,
      B10001
    };
    void setup() {
      lcd.createChar(0, newChar0);
      lcd.createChar(1, newChar1);
      lcd.createChar(15, newChar15);
      lcd.begin(20, 4);


    }
    void loop() {
      lcd.setCursor(2,0); //line 1
      lcd.write(1); //PRINT
      lcd.setCursor(0,1); ////line 2

      lcd.write(0); //PRINT
      lcd.setCursor(0,2); //line 3
      lcd.print("lcd.print((char)15)");
      lcd.setCursor(10,3); //line 4
      lcd.print((char)15); //other way of printing a  char
      delay(1000);
    }
    0
  • wb2dyb

    Not sure if this makes a diff, but I'm using the OLedI2C library, needed to use no more then 3 lines to the diaplay. Though, what's in the cpp file for create craracter I did put in the OLedI2C.cpp file, but it errors on compile on the "write(charmap);" The library I used was for the one wire link. That part works fine, except the custom character part.Thanks for the poiinters, one of them has the lines I'm already trying to use, but I really need I2C communication.

    GeorgeC

    0
  • Chris O.

    Hi

    I do not own this display so it's hard to do testing.
    Please test this sketch for me, not sure if this will print H and then Clear the display.

     

    // Test print [ H ] and then Clear display with Wire Library.

    // Wire Library, This library allows you to communicate with I2C / TWI devices
    // Board           I2C / TWI pins
    // Uno, Ethernet   A4 (SDA), A5 (SCL)
    // Mega2560        20 (SDA), 21 (SCL)
    // Leonardo         2 (SDA),  3 (SCL)
    // Due             20 (SDA), 21 (SCL), SDA1, SCL1
    #include <Wire.h>
    #define I2C_ADDR 0x3c  // Define I2C Address, For the US2066 0x3c or 0x3d
    // NOTE: Important to include Wire.h before OLedI2C.h
    #include <OLedI2C.h>  // OLedI2C library http://gadjetsblog.blogspot.com/2013/09/oled-1602-display-and-library-for.html
    //library by Phil Grant 2013 www.gadjet.co.uk
    OLedI2C LCD;


    void setup() {
      Wire.begin(); // Start Wire Library
      LCD.init(); // initialize the lcd
    }

    void loop() {

      //Set cursor position to col and row, top row is 0, first col is 0
      // no longer required LCD.cursPos(4,0); //(col,row)
      LCD.sendString("Test print >", 4, 0);    //("String", col, row)
      delay(2000); //2sec

      // test 1 / print H
      // For the US2066, the slave address is either “b0111100”/0x3c or “b0111101”/0x3d
      Wire.beginTransmission(I2C_ADDR); // start condition + Define I2C Address where the US2066 is, and set  R/W# bit to logic “0” write mode.

      // 5) After the transmission of the slave address, either the control byte or the data byte may be sent across the SDA. A control
      // byte mainly consists of Co and D/C# bits following by six “0”’s.
      // a. If the Co bit is set as logic “0”, the transmission of the following information will contain data bytes only.
      // b. The D/C# bit determines the next data byte is acted as a command or a data. If the D/C# bit is set to logic “0”,
      // it defines the following data byte as a command. If the D/C# bit is set to logic “1”, it defines the following data
      // byte as a data which will be stored at the DDRAM. The DDRAM address counter will be increased by one
      // automatically after each data write.

      // Co bit is set as logic “0”data bytes only,  D/C# bit is set to logic “1”[data]
      ////////////cd+6“0”’s.  // Co & D/C# bits
      Wire.write(B01000000); // control byte or the data byte, Co and D/C# bits following by six “0”’s.
      Wire.write(B01001000); // print H  [8bit (hi bit 0100/low bit 1000
      Wire.endTransmission(); // stop condition, 7) The write mode will be finished when a stop condition is applied.
      delay(5000); // 5sec. delay

      // test 2 / Clear display
      LCD.sendString("Clear dis.in 2sec.", 1, 1);
      delay(2000);
      //Clear display
      Wire.beginTransmission(I2C_ADDR); //Define I2C Address where the US2066 is
      // control byte or the data byte, Co and D/C# bits following by six “0”’s.
      Wire.write(B10000000); //  Co bit is set to logic “1”, D/C# bit is set to logic “0”, it defines the following data byte as a command.
      Wire.write(B00000001);  // Clear display
      Wire.endTransmission(); // stop condition.
      delay(5000); // 5sec. delay
    }
    0
  • wb2dyb

    Chris, thanks for the effort. I need to figure out the addressing for this, how to store custom font data in those 8 memory locations. I am not 100% sure how to but I think I can see how to get them out after they are stored. But the command structure seems limited, or I'm just not getting how to set either/or IS RE SD RW or DC. I thank you for the help. I'm just not getting how to "command" it to store the 8 8(really 5) bit font info, and exactly how to get it back when writing text to the display. I think I see that I can use Wire.write to accomplish it, but now sure what the addressing would be then unsure of addressing or commands to use the character. You definitely seeded some ideas, but I fear I'm just not getting it.

    Thanks!

    GeorgeC

    0
  • Chris O.

    Hay, don't worry
    I was just trying to figure out how to use the i2c wire library,  it just a hobby of mine. 

    Does the arduino sketch work?
    Print H and then Clear the display?

    Yes / no ?

    0
  • Chris O.

    By the way  I've just spent a day trying to figure out how to use 1Mbit MR25H10MDF Magnetoresistive random-access memory (MRAM) with SPI on Teensy 3.0 ARM dev board..

    0
  • wb2dyb

    Thanks Chris. The first suggestions made earlier prompted me to just start fresh in a library directory. So made all those changes and now while it compiles nothing happens, and anything on display from previous helloworld stuff freezez till power cycle.

    Now the most recent suggestions gets this error:


    C:\Program Files (x86)\Arduino\libraries\OLedI2C\OLedI2C.cpp: In member function 'void OLedI2C::createChar(uint8_t, uint8_t*)':
    C:\Program Files (x86)\Arduino\libraries\OLedI2C\OLedI2C.cpp:206: error: invalid conversion from 'uint8_t*' to 'unsigned char'
    C:\Program Files (x86)\Arduino\libraries\OLedI2C\OLedI2C.cpp:206: error:   initializing argument 1 of 'void OLedI2C::sendData(unsigned char)'


    Line 206 is:
         sendData(charmap);      // call the virtual write method




    Totally lost now. I sorta followed what you were doing...

    GeorgeC

    0
  • wb2dyb

    I think I used the wrong OLedI2C.h file. I need to clean this mess up.

    So back to where it just sits there blank after loading your test file.

    GeorgeC

    0
  • Chris O.

    hmmm I see a bug.

    // NEW 03-31-2015
    // Allows us to fill the first 8 CGRAM locations
    // with custom characters
    void OLedI2C::createChar(uint8_t location, uint8_t charmap[])
    {
       location &= 0x7;            // we only have 8 locations 0-7
       
       sendCommand(0x40 | (location << 3));
       delayMicroseconds(30);
       
       for (int i=0; i<8; i++)
       {
          sendData(charmap[i]);      // you're missing [i] in you're code // call the virtual write method
          delayMicroseconds(40);
       }
    }
    0
  • wb2dyb

    Well, that was very different. Attached are pix of the two messages.

    What it is displaying is 0000:0000 and 0000:0001 from ROM C in the built in CG

    GeorgeC

    0
  • Chris O.

    OK
    Pictures are upside down but that's not a problem.

    So the print  Wire.write(Bxxxxxxxx); or  LCD.sendData(x); works good.

    Next custom font will be The infinity symbol ∞.
    // Zero-based numbering
    LCD.sendData(2); //Print custom font 3



    Look in US2066 datasheet P.56

    Now the problem is it did not store the custom fonts for some reasons.
    perhaps you should try to switch the ROM C to ROM A and then try again.

    0
  • wb2dyb

    I found this:
    http://www.circuitvalley.com/2012/02/lcd-custom-character-hd44780-16x2.html

    I know the way this is done is pretty much identical as in the HD44780 controller, among others.

    I have to study this more later. It looks like the part to store the character is pretty much the same. The getting it back out part is the issue...

    I have to run, back at it in about 5 hours

    George

    0
  • Chris O.

    Problem is ROM C
    It's actually in the datasheets
    P.29 Function Selection B
    zero CGRAM available.

    0
  • Chris O.

    What does CGRAM stand for?
    Acronym     Definition
    CGRAM     Character Generator RAM -Random-access memory

    In OLedI2C.cpp
    Yours is actually setting  // **** Set ROM A and 0 CGRAM / 256 CGROM
    But clearly it was on ROM C ?

    Change this:

    // **** CGROM/CGRAM Management *** //
     sendCommand(0x72);     // **** Set ROM
     sendData(B00000011);     // **** Set ROM A and 8 CGRAM This selects CGROM A, 00000000 selects CGROM C

    To:

      // CGROM/CGRAM Management
      sendCommand(0x72);     // **** Set ROM // Function Selection B
      sendData(B00000001);   // **** Set ROM A and 8 CGRAM / 248 CGROM

    Restart your Arduino IDE and try again.

    0
  • wb2dyb

    LCD.sendData(0)

    Sends that character from ROM C

    LCD.sendData(1)

    Likewise sends that from ROM C, if I make it

    LCD.sendData(

    It sends the lefty pointing arrow, etc

    George

    0
  • Chris O.

    I am not sure if it matters, but you change the i2c initialization sequence.

    // original:
     // **** Set OLED Characterization *** //
     // sendCommand(0x2A);   // **** Set "RE"=1
     // sendCommand(0x79);   // **** Set "SD"=1
     // **** CGROM/CGRAM Management *** //
     // sendCommand(0x72);   // **** Set ROM
     // sendCommand(0x00);   // **** Set ROM A and 8 CGRAM

     // **** CGROM/CGRAM Management *** //
     sendCommand(0x72);     // **** Set ROM
     sendData(B00000011);     // **** Set ROM A and 8 CGRAM This selects CGROM A, 00000000 selects CGROM C
     // **** Set OLED Characterization *** //
     sendCommand(0x2A);     // **** Set "RE"=1
     sendCommand(0x79);     // **** Set "SD"=1

    Perhaps setting the **** Set OLED Characterization *** should be first
    Then set the **** CGROM/CGRAM Management ***
    Just as it was in the original code.

    0
  • Chris O.

    New test  ;) code
    Let's try change Function Selection B on the fly, in void setup(); .

    // Test print [ custom fonts ].

    // Wire Library, This library allows you to communicate with I2C / TWI devices
    // Board           I2C / TWI pins
    // Uno, Ethernet   A4 (SDA), A5 (SCL)
    // Mega2560        20 (SDA), 21 (SCL)
    // Leonardo         2 (SDA),  3 (SCL)
    // Due             20 (SDA), 21 (SCL), SDA1, SCL1

    #include <Wire.h>
    #define I2C_ADDR 0x3c  // Define I2C Address, For the US2066 0x3c or 0x3d
    // NOTE: Important to include Wire.h before OLedI2C.h
    #include <OLedI2C.h>  // OLedI2C library http://gadjetsblog.blogspot.com/2013/09/oled-1602-display-and-library-for.html
    //library by Phil Grant 2013 www.gadjet.co.uk
    OLedI2C LCD;

    byte newChar0[8] = {
      B00000,
      B00000,
      B10101,
      B11101,
      B11101,
      B10101,
      B00000,
      B00000
    };

    byte newChar1[8] = {
      B10000,
      B01000,
      B00101,
      B00100,
      B00100,
      B00101,
      B01000,
      B10000
    };

    byte newChar2[8] = {
      B10001,
      B01010,
      B01110,
      B00100,
      B00100,
      B01110,
      B01010,
      B10001
    };

    byte newChar3[8] = {
      B11111,
      B11111,
      B11111,
      B00100,
      B00100,
      B11111,
      B11111,
      B11111
    };

    void setup() {
      Wire.begin(); // Start Wire Library
      LCD.init(); // initialize the lcd
     
     
      delay(100);
      // TEST
      // change Function Selection B on the fly
      // CGROM/CGRAM Management
      LCD.sendCommand(0x72);     // **** Set ROM // Function Selection B
      LCD.sendData(B00000001);   // **** Set ROM A and 8 CGRAM / 248 CGROM

      delay(100);
      LCD.createChar(0, newChar0); // Store custom font data in 420CW Oled
      delay(100);
      LCD.createChar(1, newChar1);
      delay(100);
      LCD.createChar(2, newChar2);
      delay(100);
      LCD.createChar(3,newChar3);
      delay(100);
    }

    void loop() {

      //Set cursor position to col and row, top row is 0, first col is 0
      // no longer required LCD.cursPos(4,0); //(col,row)
      LCD.sendString("test 1 Wire.h", 0, 0);    //("String", col, row)
      LCD.cursPos(1,1); //(col,row)
     
      // Test 1 / Print custom font 4
      Wire.beginTransmission(I2C_ADDR); // start condition + Define I2C Address where the US2066 is, and set  R/W# bit to logic “0” write mode.
      // Print custom font 4
      Wire.write(B01000000); // control byte or the data byte, Co and D/C# bits following by six “0”’s.
      Wire.write(B00000011); //DEC 3 // print custom font 4  [8bit (hi bit 0000/low bit 0011
      Wire.endTransmission(); // stop condition / 7) The write mode will be finished when a stop condition is applied.

      delay(3000); // 3sec. delay
      LCD.clearLcd();
      delay(1000);
     
      LCD.sendString("test 2 sendData", 0, 0);    //("String", col, row)
      LCD.cursPos(1,1); //(col,row)
      // Zero-based numbering
      LCD.sendData(0); //Print custom font 1
      LCD.sendData(char(1)); //Print custom font 2
     
      delay(3000); // 3sec. delay
      LCD.clearLcd();
      delay(1000);
    }
    0
  • wb2dyb

    Success! I was getting no results yet. So I cut and paste the init from the OLED pdf instead of what I had. Your last app ran first time, pictures enclosed...

    My cpp file: (it's a real mess, but it works

    // 1602-OLED-Arduino-Library/OLedI2C.cpp
    // keywords.txt / OLedI2C.cpp / OLedI2C.h
    // The 3 files should be in %your arduino dir%\libraries\OLedI2C\
    // The directory name must match the library name for libraries to work.

    /*
    This is my first Library to make writing to the OLED 1602
    Display much easier, the display is based on the SSD1311.
    The display has 16 characters and 2 lines.
    The library is far from complete and may be prone to errors.
    Feedback welcome, visit www.gadjet.co.uk
    Phil Grant 2013
    Scrolling contributed by Nathan Chantrell http://nathan.chantrell.net/
    Updated 06/11/2013 to include the cursPos data in the sendString function
    sendString("string", col, row)
    */
    #include "OLedI2C.h"

    // NEW
    #include <stdio.h>
    #include <string.h>
    #include <inttypes.h>
    #include "Arduino.h"

    #include "Wire.h"
    #define OLED_Address 0x3c
    #define OLED_Command_Mode 0x80
    #define OLED_Data_Mode 0x40

    OLedI2C::OLedI2C(){}
    OLedI2C::~OLedI2C(){}


    void OLedI2C::init() {
       // *** I2C initial *** //
     delay(100);
     sendCommand(0x2A); //function set (extended command set)
    sendCommand(0x71); //function selection A
    sendData(0x00); // disable internal VDD regulator (2.8V I/O). data(0x5C) = enable regulator (5V I/O)
    sendCommand(0x28); //function set (fundamental sendCommand set)
    sendCommand(0x08); //display off, cursor off, blink off
    sendCommand(0x2A); //function set (extended command set)
    sendCommand(0x79); //OLED command set enabled
    sendCommand(0xD5); //set display clock divide ratio/oscillator frequency
    sendCommand(0x70); //set display clock divide ratio/oscillator frequency
    sendCommand(0x78); //OLED command set disabled
    sendCommand(0x09); //extended function set 4 line
    sendCommand(0x06); //COM SEG direction
    sendCommand(0x72); //function selection B
    sendData(0x00); //ROM CGRAM selection
    sendCommand(0x2A); //function set (extended command set)
    sendCommand(0x79); //OLED command set enabled
    sendCommand(0xDA); //set SEG pins hardware configuration
    sendCommand(0x10); //set SEG pins hardware configuration
    sendCommand(0xDC); //function selection C
    sendCommand(0x00); //function selection C
    sendCommand(0x81); //set contrast control
    sendCommand(0x7F); //set contrast control
    sendCommand(0xD9); //set phase length
    sendCommand(0xF1); //set phase length
    sendCommand(0xDB); //set VCOMH deselect level
    sendCommand(0x40); //set VCOMH deselect level
    sendCommand(0x78); //OLED command set disabled
    sendCommand(0x28); //function set (fundamental command set)
    sendCommand(0x01); //clear display
    sendCommand(0x80); //set DDRAM address to 0x00
    sendCommand(0x0C); //display ON
     
     /*
    sendCommand(0x2A);  //function set (extended command set)
    sendCommand(0x71);  //function selection A, disable internal Vdd regualtor
    sendCommand(0x00);
    sendCommand(0x28);  //function set (fundamental command set)
    sendCommand(0x08);  //display off, cursor off, blink off
    sendCommand(0x2A);  //function set (extended command set)
    sendCommand(0x79);  //OLED command set enabled
    sendCommand(0x72);  //function selection B, disable internal Vdd regualtor
    sendCommand(0x00);     //ROM CGRAM selection
    sendCommand(0xD5);  //set display clock divide ratio/oscillator frequency
    sendCommand(0x70);  //set display clock divide ratio/oscillator frequency
    sendCommand(0x78);  //OLED command set disabled
    sendCommand(0x09);  //extended function set (4-lines)
            sendCommand(0x06);  //COM SEG direction
    sendCommand(0x72);  //function selection B, disable internal Vdd regualtor
    sendCommand(0x00);     //ROM CGRAM selection
    sendCommand(0x2A);  //function set (extended sendCommand set)
    sendCommand(0x79);  //OLED sendCommand set enabled
    sendCommand(0xDA);  //set SEG pins hardware configuration
    sendCommand(0x10);  //set SEG pins hardware configuration   // <--------- Change
    sendCommand(0xDC);  //function selection C
    sendCommand(0x00);  //function selection C
    sendCommand(0x81);  //set contrast control
    sendCommand(0xff);  //set contrast control
    sendCommand(0xD9);  //set phase length
    sendCommand(0xF1);  //set phase length
    sendCommand(0xDB);  //set VCOMH deselect level
    sendCommand(0x40);  //set VCOMH deselect level
    sendCommand(0x78);  //OLED sendCommand set disabled
    sendCommand(0x28);  //function set (fundamental sendCommand set)
    sendCommand(0x01);  //clear display
    sendCommand(0x80);  //set DDRAM address to 0x00
    sendCommand(0x0C);  //display ON
     */
     /*
     sendCommand(0x2A); // **** Set "RE"=1 00101010B
     sendCommand(0x71);
     sendCommand(0x5C);
     sendCommand(0x28);

     sendCommand(0x08); // **** Set Sleep Mode On
     sendCommand(0x2A); // **** Set "RE"=1 00101010B
     sendCommand(0x79); // **** Set "SD"=1 01111001B

     sendCommand(0xD5);
     sendCommand(0x70);
     sendCommand(0x78); // **** Set "SD"=0  01111000B

     sendCommand(0x09); // **** Set 5-dot, 3 or 4 line(0x09), 1 or 2 line(0x08)

     sendCommand(0x06); // **** Set Com31-->Com0  Seg0-->Seg99

     // original:
     // **** Set OLED Characterization *** //
     // sendCommand(0x2A);   // **** Set "RE"=1
     // sendCommand(0x79);   // **** Set "SD"=1
     // **** CGROM/CGRAM Management *** //
     // sendCommand(0x72);   // **** Set ROM
     // sendCommand(0x00);   // **** Set ROM A and 8 CGRAM

     // **** CGROM/CGRAM Management *** //
     sendCommand(0x72);     // **** Set ROM
     sendData(B00000011);     // **** Set ROM A and 8 CGRAM This selects CGROM A, 00000000 selects CGROM C
     // **** Set OLED Characterization *** //
     sendCommand(0x2A);     // **** Set "RE"=1
     sendCommand(0x79);     // **** Set "SD"=1

     sendCommand(0xDA);  // **** Set Seg Pins HW Config
     sendCommand(0x10);   

     sendCommand(0x81);   // **** Set Contrast
     sendCommand(0xFF);

     sendCommand(0xDB);   // **** Set VCOM deselect level
     sendCommand(0x30);   // **** VCC x 0.83

     sendCommand(0xDC);   // **** Set gpio - turn EN for 15V generator on.
     sendCommand(0x03);

     sendCommand(0x78);   // **** Exiting Set OLED Characterization
     sendCommand(0x28);
     sendCommand(0x2A);
     sendCommand(0x05);  // **** Set Entry Mode
     sendCommand(0x06);  // **** Set Entry Mode
     sendCommand(0x08); 
     sendCommand(0x28);  // **** Set "IS"=0 , "RE" =0 //28
     sendCommand(0x01);
     sendCommand(0x80);  // **** Set DDRAM Address to 0x80 (line 1 start)

     */
     
     
     delay(100);
     sendCommand(0x0C);   // **** Turn on Display
     }
     
     // void OLedI2C::cursPos(uint8_t col, uint8_t row)
     // {
     // int row_offsets[] = { 0x00, 0x40 };
     // sendCommand(0x80 | (col + row_offsets[row]));
     // }

     void OLedI2C::cursPos(uint8_t col, uint8_t row)
     {
     int row_offsets[] = { 0x00, 0x20, 0x40, 0x60 };// **************THIS WAS THE CHANGE FOR 4 LINES
     sendCommand(0x80 | (col + row_offsets[row])); //was 0x80
     }
     
     // NEW 03-23-2015
     // cloumn, row / setCursor
      //void OLedI2C::setCursor(uint8_t col, uint8_t row)
      //{
      // int row_offsets[] = { 0x00, 0x20, 0x40, 0x60 };// **************
      //sendCommand(0x80 | (col + row_offsets[row]));
      //}
     
    void OLedI2C::clearLcd()
    {
    sendCommand(0x01);
    }

    void OLedI2C::lcdOff()
    {
    sendCommand(0x08);   // **** Turn on Off
    }

    void OLedI2C::lcdOn()
    {
    sendCommand(0x0C);   // **** Turn on On
    }

     void OLedI2C::sendCommand(unsigned char command)
    {
        Wire.beginTransmission(OLED_Address);   // **** Start I2C
        Wire.write(OLED_Command_Mode);       // **** Set OLED Command mode
        Wire.write(command);
        Wire.endTransmission();                   // **** End I2C
          delay(10);
    }
    void OLedI2C::sendFloat(float digit, uint8_t dec, uint8_t nad, uint8_t col, uint8_t row)
    {
    char line[10];//Ten characters, I hope that's enough
    dtostrf(digit,dec,nad,line);//Convert the float value to a string
    sendString(line, col, row);

    }

     void OLedI2C::setContrast(unsigned char contrast) // contrast as 0x00 to 0xFF
    {
         //Set OLED Command set
    sendCommand(0x2A);
    sendCommand(0x79);

    sendCommand(0x81);   // Set Contrast
    sendCommand(contrast); // send contrast value
    sendCommand(0x78);   // Exiting Set OLED Command set
       sendCommand(0x28);

    }

    void OLedI2C::sendString(const char *String, uint8_t col, uint8_t row)
    {
      cursPos(col, row);
      unsigned char i=0;
      while(String[i])
      {
        sendData(String[i]);      // *** Show String to OLED
        i++;
      }
    }
    void OLedI2C::sendData(unsigned char data)
    {
      Wire.beginTransmission(OLED_Address);   // **** Start I2C
      Wire.write(OLED_Data_Mode);      // **** Set OLED Data mode
      Wire.write(data);
      Wire.endTransmission();                     // **** End I2C
    }
    void OLedI2C::scrollString(char* message, byte row, unsigned int time)//written by Nathan Chantrell http://nathan.chantrell.net/
    {
     char buffer[16];
     for (byte i=0;i<strlen(message)+16;i++) {
      byte pos = i+1;
      for (byte j=0;j<16;j++) {
       if ((pos<16)||(pos>strlen(message)+15)) { // pad and trail with blank spaces
         buffer[j]=' ';
       }
       else buffer[j]=message[pos-16];
       pos++;
      }
     //cursPos(0,row); removed by PG
     sendString(buffer, 0, row); //Edited by PG tho include the cursor pos within the sendString command
     delay(time);
     }
    }

    /*

    // NEW 03-23-2015
    // Allows us to fill the first 8 CGRAM locations
    // with custom characters
    void OLedI2C::createChar(uint8_t location, uint8_t charmap[])
    {
      location &= 0x7; // we only have 8 locations 0-7
      Wire.beginTransmission(OLED_Address);
        Wire.write(OLED_Data_Mode | (location << 3)); // SETCGRAMADDR 0x40  [ Wire.write(B01000000); ]
        delayMicroseconds(30);
        //Wire.write(location);
      for (uint8_t i = 0 ; i < 8 ; i++) {
        Wire.write(charmap[i]);
        //Wire.write(OLED_Data_Mode);
        delayMicroseconds(40);
      }
      Wire.endTransmission();
      delay(50);
    }
    */

    // NEW 03-31-2015
    // Allows us to fill the first 8 CGRAM locations
    // with custom characters
    void OLedI2C::createChar(uint8_t location, uint8_t charmap[])
    {
       location &= 0x7;            // we only have 8 locations 0-7
       
       sendCommand(0x40 | (location << 3));
       delayMicroseconds(30);
       
       for (int i=0; i<8; i++)
       {
          sendData(charmap[i]);      // you're missing [i] in you're code // call the virtual write method
          delayMicroseconds(40);
       }
    }

    Thank you very much.

    GeorgeC

    0
  • Chris O.

    :) 

    I'm glad you figured that out!  ;)

    0

Please sign in to leave a comment.