You have reached the legacy GHI Electronics, LLC website, for the new website please visit here. For the new forum please visit here.

This legacy website will be taken offline at the end of this year. If there is anything that you would like to archive and save for future reference please do so.

Newhaven NHD-0420CW-A*3 Character-OLED via I2C by glx

Jul. 6, 2016   |   Snippet   |   Licensed as Apache 2.0   |   1470 views

I just wrote a basic driver for the NHD-0420CW displays using the I2C-Interface.
Maybe it's useful for someone, so i decided to share it with you. I tested it with a G80 and a G400-D using a NHD-0420CW-AY3 display.
You can pass a string-array or just a single string.
I wrote a small demo, so you can see how it can be used.

I'm not a professional programmer and it's my first Codeshare, so there may be much space for improvements, feel free to suggest things you notice.

Comments or questions?   Discuss on the forum.



Author Version Date
glx 1 07/06 '16 at 12:06pm
1 — Source
  1. /// A simple display-driver for the Newhaven NHD-0420CW-A*3 OLED-Display
  2. /// The communication-interface is hardware-I2C
  3. ///
  4. /// The init-sequence has been taken from the datasheet and the Newhaven Display Forum (http://www.newhavendisplay.com/NHD_forum/index.php?topic=914.0)
  5. /// By glx for the GHI-Community, fee free to use it :).
  6.  
  7. using System;
  8. using System.Collections;
  9. using System.Threading;
  10. using Microsoft.SPOT;
  11. using Microsoft.SPOT.Hardware;
  12.  
  13. namespace NH_OLED
  14. {
  15. public enum CodePage : byte
  16. {
  17. ROM_A = 0x02,
  18. ROM_B = 0x06,
  19. ROM_C = 0x0A
  20. }
  21. /// <summary>
  22. /// The default config is adress 0x3C and 400kHz. Run Init() first.
  23. /// Defaults are: 4 lines, 20 characters each line, ROM-B (see datasheet)
  24. /// </summary>
  25. class CharDisplay
  26. {
  27.  
  28. public I2CDevice.Configuration I2C_CFG = new I2CDevice.Configuration(0x3C, 400); //if SA0 is LOW the adress is 0x3C, if it is HIGH it's 0x3D
  29. public int I2C_TIMEOUT = 500;
  30. public int DISPLAY_LINES = 4;
  31. public int DISPLAY_CHARS = 20;
  32. public byte CODEPAGE = (byte)CodePage.ROM_B;
  33.  
  34. private byte[] Line_Adresses = { 0x80, 0xA0, 0xC0, 0xE0 }; // RAM addresses for line 0-3
  35.  
  36. public int SendCommand(I2CDevice I2C_DEV, byte Command)
  37. {
  38. I2C_DEV.Config = I2C_CFG;
  39. I2CDevice.I2CTransaction[] Transaction = new I2CDevice.I2CTransaction[1];
  40. Transaction[0] = I2CDevice.CreateWriteTransaction(new byte[] { 0x00, Command });
  41. return I2C_DEV.Execute(Transaction, I2C_TIMEOUT);
  42. }
  43.  
  44. public int SendData(I2CDevice I2C_DEV, byte Data)
  45. {
  46. I2C_DEV.Config = I2C_CFG;
  47. I2CDevice.I2CTransaction[] Transaction = new I2CDevice.I2CTransaction[1];
  48. Transaction[0] = I2CDevice.CreateWriteTransaction(new byte[] { 0x40, Data });
  49. return I2C_DEV.Execute(Transaction, I2C_TIMEOUT);
  50. }
  51.  
  52. /// <summary>
  53. /// Display a single line, the screen is not clared, so it also can be used to update a single line.
  54. /// </summary>
  55. /// <param name="I2C_DEV"></param>
  56. /// <param name="Line"></param>
  57. /// <param name="LineID"></param>
  58. public void DisplayLine(I2CDevice I2C_DEV, string Line, int LineID)
  59. {
  60. if (LineID >= DISPLAY_LINES || LineID < 0) { LineID = 0; } //Makes sure, the LinID has a valid value
  61. while (Line.Length < DISPLAY_CHARS) { Line = Line + " "; } //Makes sure, the rest of the line is blank, if you use this to update a line.
  62. char[] cha = Line.ToCharArray();
  63. SendCommand(I2C_DEV, Line_Adresses[LineID]);
  64. int CharID = 0;
  65. foreach (char c in cha)
  66. {
  67. if (CharID >= DISPLAY_CHARS) break;
  68. SendData(I2C_DEV, (byte)c);
  69. CharID++;
  70. }
  71.  
  72. }
  73.  
  74. /// <summary>
  75. /// Displays a string-array with up to four strings (can be more, but only the first four lines will be displayed).
  76. /// If there are less than four lines, the content is aligned at the top.
  77. /// </summary>
  78. /// <param name="Display"></param>
  79. public void DisplayAll(I2CDevice I2C_DEV, string[] Display)
  80. {
  81. ArrayList AList = new ArrayList();
  82. foreach (string s in Display) { AList.Add((char[])s.ToCharArray()); }
  83. SendCommand(I2C_DEV, 0x01);
  84. int LineID = 0;
  85. foreach(char[] cha in AList)
  86. {
  87. if (LineID >= DISPLAY_LINES) break;
  88. SendCommand(I2C_DEV, Line_Adresses[LineID]);
  89. int CharID = 0;
  90. foreach(char c in cha)
  91. {
  92. if (CharID >= DISPLAY_CHARS) break;
  93. SendData(I2C_DEV, (byte)c);
  94. CharID++;
  95. }
  96. LineID++;
  97. }
  98. }
  99.  
  100. /// <summary>
  101. /// Initial setup, call this first before using the display.
  102. /// </summary>
  103. /// <param name="I2C_DEV"></param>
  104. public void Init(I2CDevice I2C_DEV)
  105. {
  106. byte rows = 0x08;
  107.  
  108. if (DISPLAY_LINES == 2 || DISPLAY_LINES == 4)
  109. rows = 0x08; // Display mode: 2/4 lines
  110. else
  111. rows = 0x00; // Display mode: 1/3 lines
  112.  
  113. SendCommand(I2C_DEV, (byte)(0x22 | (int)rows)); // Function set: extended command set (RE=1), lines #
  114. SendCommand(I2C_DEV, 0x71); // Function selection A:
  115. SendCommand(I2C_DEV, 0x5C); // enable internal Vdd regulator at 5V I/O mode (def. value) (0x00 for disable, 2.8V I/O)
  116. SendCommand(I2C_DEV, (byte)(0x20 | (int)rows)); // Function set: fundamental command set (RE=0) (exit from extended command set), lines #
  117. SendCommand(I2C_DEV, 0x08); // Display ON/OFF control: display off, cursor off, blink off (default values)
  118. SendCommand(I2C_DEV, (byte)(0x22 | (int)rows)); // Function set: extended command set (RE=1), lines #
  119. SendCommand(I2C_DEV, 0x79); // OLED characterization: OLED command set enabled (SD=1)
  120. SendCommand(I2C_DEV, 0xD5); // Set display clock divide ratio/oscillator frequency:
  121. SendCommand(I2C_DEV, 0x70); // divide ratio=1, frequency=7 (default values)
  122. SendCommand(I2C_DEV, 0x78); // OLED characterization: OLED command set disabled (SD=0) (exit from OLED command set)
  123.  
  124. if (DISPLAY_LINES > 2)
  125. SendCommand(I2C_DEV, 0x09); // Extended function set (RE=1): 5-dot font, B/W inverting disabled (def. val.), 3/4 lines
  126. else
  127. SendCommand(I2C_DEV, 0x08); // Extended function set (RE=1): 5-dot font, B/W inverting disabled (def. val.), 1/2 lines
  128.  
  129. SendCommand(I2C_DEV, 0x06); // Entry Mode set - COM/SEG direction: COM0->COM31, SEG99->SEG0 (BDC=1, BDS=0)
  130. SendCommand(I2C_DEV, 0x72); // Function selection B:
  131. SendData(I2C_DEV, CODEPAGE); // ROM/CGRAM selection: CGROM=250, CGRAM=6 (ROM=10, OPR=10) ROM: A: 0x02, B: 0x06, C: 0x0A
  132. SendCommand(I2C_DEV, 0x79); // OLED characterization: OLED command set enabled (SD=1)
  133. SendCommand(I2C_DEV, 0xDA); // Set SEG pins hardware configuration:
  134. SendCommand(I2C_DEV, 0x10); // alternative odd/even SEG pin, disable SEG left/right remap (default values)
  135. SendCommand(I2C_DEV, 0xDC); // Function selection C:
  136. SendCommand(I2C_DEV, 0x00); // internal VSL, GPIO input disable
  137. SendCommand(I2C_DEV, 0x81); // Set contrast control:
  138. SendCommand(I2C_DEV, 0x7F); // contrast=127 (default value)
  139. SendCommand(I2C_DEV, 0xD9); // Set phase length:
  140. SendCommand(I2C_DEV, 0xF1); // phase2=15, phase1=1 (default: 0x78)
  141. SendCommand(I2C_DEV, 0xDB); // Set VCOMH deselect level:
  142. SendCommand(I2C_DEV, 0x40); // VCOMH deselect level=1 x Vcc (default: 0x20=0,77 x Vcc)
  143. SendCommand(I2C_DEV, 0x78); // OLED characterization: OLED command set disabled (SD=0) (exit from OLED command set)
  144. SendCommand(I2C_DEV, (byte)(0x20 | (int)rows)); // Function set: fundamental command set (RE=0) (exit from extended command set), lines #
  145. SendCommand(I2C_DEV, 0x01); // Clear display
  146. Thread.Sleep(1); // After a clear display, a minimum pause of 1-2 ms is required
  147. SendCommand(I2C_DEV, 0x80); // Set DDRAM address 0x00 in address counter (cursor home) (default value)
  148. SendCommand(I2C_DEV, 0x0C); // Display ON/OFF control: display ON, cursor off, blink off
  149. Thread.Sleep(100); // Waits for stabilization purpose after display on
  150.  
  151. if (DISPLAY_LINES == 2)
  152. Line_Adresses[1] = 0xC0; // DDRAM address for each line of the display (only for 2-line mode)
  153. }
  154.  
  155. /// <summary>
  156. /// As the function-name tells you, this clears the screen.
  157. /// </summary>
  158. /// <param name="I2C_DEV"></param>
  159. public void ClearScreen(I2CDevice I2C_DEV)
  160. {
  161. SendCommand(I2C_DEV, 0x01);
  162. }
  163. }
  164.  
  165. }