Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Messages - Chris O.

Pages: [1] 2 3
1
OLEDs / Re: NHD-3.12-25664UCB2 Problem Displaying Text
« on: June 27, 2017, 08:40:36 PM »
Quote
Does anyone have a snippet or library to do this? It seems like there is a library for every other display except this one. I am using an Arduino Mega 2560.

I did use u8glib library before on NHD-3.12-25664UMB3 OLED 256 x 64 with great success.
https://github.com/olikraus/u8glib

The author (Olikraus) also released newer version of this Library u8g2 which I have no experience with.
https://github.com/olikraus/u8g2

u8glib frames per second example:
NOTE:  tested on u8glib version 1.15
Code: [Select]
/*

  FPS.pde
 
  >>> Before compiling: Please remove comment from the constructor of the
  >>> connected graphics display (see below).
 
  Universal 8bit Graphics Library, http://code.google.com/p/u8glib/
 
  Copyright (c) 2012, olikraus@gmail.com
  All rights reserved.

  Redistribution and use in source and binary forms, with or without modification,
  are permitted provided that the following conditions are met:

  * Redistributions of source code must retain the above copyright notice, this list
    of conditions and the following disclaimer.
   
  * Redistributions in binary form must reproduce the above copyright notice, this
    list of conditions and the following disclaimer in the documentation and/or other
    materials provided with the distribution.

  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
  CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
  INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
  ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 

  ST7920_192X32, SPI:    FPS: Box=7.6   @=9.8                iFPS: Box=11.4  @=14.7
  ST7920_192X32, 8Bit:   FPS: Box=6.2   @=7.5                iFPS: Box=9.3 @=11.2
  DOGM128 SW SPI:        FPS: Box=5.1   @=5.9  Pix=2.6       iFPS: Box=10.2 @=11.8 Pix=5.2
  DOGM128 HW SPI:        FPS: Box=5.5   @=6.3                iFPS: Box=11.0 @=12.6
  DOGXL160 SW SPI:       FPS: Box=1.7   @=1.9                iFPS: Box=6.9 @=7.7
  DOGXL160 HW SPI:       FPS: Box=1.8   @=2.1               
 
  NHD27OLED_BW,       SW SPI: FPS: Box=3.0  @=3.7
  NHD27OLED_BW,       HW SPI: FPS: Box=3.5  @=4.5
  NHD27OLED_2X_BW,    SW SPI: FPS: Box=3.8  @=4.9
  NHD27OLED_2X_BW,    HW SPI: FPS: Box=4.6  @=6.4
 
  30 Sep 2012
  NHD27OLED_BW, SW SPI: FPS: Clip=9.2 Box=3.9  @=4.4 NEW_CODE
  NHD27OLED_BW, SW SPI: FPS: Clip=9.2 Box=3.6  @=4.5
  NHD27OLED_BW, HW SPI: FPS: Clip=16.3 Box=4.7  @=5.6
  NHD27OLED_2X_BW, SW SPI: FPS: Clip=9.7 Box=4.5  @=5.8
  NHD27OLED_2X_BW, SW SPI: FPS: Clip=18.0 Box=5.8  @=7.9

  1 Oct 2012
  ST7920_192X32, 8Bit:   FPS: Box=7.2   @=10.0               
  DOGM128 SW SPI:         FPS: Box=5.2   @=6.6  Pix=2.6               
  DOGM128 HW SPI:         FPS: Clip=33.2 Box=5.5   @=7.1
  DOGXL160 SW SPI:         FPS: Box=1.7   @=2.0
  DOGXL160 HW SPI:         FPS: Box=1.8   @=2.2

  DOGXL160 GR SW SPI:         FPS: Box=1.1   @=1.3

  1 Mar 2013
  ST7920_192X32_1X, SPI:    FPS: Clip=10.3 Box=5.5  @=7.2 Pix=3.9
  ST7920_192X32_4X, SPI:    FPS: Clip=10.9 Box=6.7  @=8.8 Pix=7.4
  ST7920_192X32_1X, 8Bit:    FPS: Clip=14.2 Box=6.1  @=8.4 Pix=4.2
  ST7920_192X32_4X, 8Bit:    FPS: Clip=14.2 Box=7.8  @=10.7 Pix=8.7
  ST7920_192X32_1X, HW SPI:    FPS: Clip=14.2 Box=6.3  @=8.7 Pix=4.3
  ST7920_192X32_4X, HW SPI:    FPS: Clip=15.3 Box=8.0  @=11.2 Pix=9.0

  2 Jun 2013
  U8GLIB_DOGM128 SW SPI:                                          FPS: Clip=23.9 Box=4.5  @=6.6  Pix=2.1
  U8GLIB_DOGM128_2X SW SPI:                                       FPS: Clip=28.5 Box=6.6  @=9.7  Pix=3.9
  U8GLIB_DOGM128_2X HW SPI:                                       FPS: Clip=40.8 Box=7.1  @=10.8 Pix=4.1
 
  3 Jun 2013
  U8GLIB_ST7920_192X32_1X -Os                             SW SPI  FPS: Clip=11.0 Box=5.4  @=7.1 Pix=3.9  Size=11828
  U8GLIB_ST7920_192X32_1X -O3                             SW SPI  FPS: Clip=10.9 Box=5.6  @=7.5 Pix=4.0  Size=13800
  U8GLIB_ST7920_192X32_1X -Os                             SW SPI  FPS: Clip=16.8 Box=6.7  @=9.6 Pix=4.5  Size=11858  (new seq data output)
  U8GLIB_ST7920_192X32_1X -Os                             HW SPI  FPS: Clip=25.7 Box=7.5  @=11.3 Pix=4.8             (new seq data output)
 
  6 Jun 2013
  U8GLIB_DOGS102 u8g(13, 11, 10, 9);                 STD SW SPI  FPS: Clip=9.5  Box=7.6   @=8.2  Pix=6.2 Size=15652
  U8GLIB_DOGS102 u8g(13, 11, 10, 9);                     SW SPI  FPS: Clip=19.1 Box=12.8  @=14.0 Pix=9.2 Size=15532


  12 Jun 2013
  SSD1351_128X128_332                                        SW SPI FPS: Clip=1.3 Box=0.7  @=0.9 Pix=0.4
  SSD1351_128X128_332                                        HW SPI FPS: Clip=3.6 Box=1.1  @=1.5 Pix=0.5

  24 Jun 2013
  Uno SSD1351_128X128_332                                    SW SPI FPS: Clip=1.4 Box=0.8  @=0.9 Pix=0.4
 
  Uno SSD1351_128X128_332                                    HW SPI FPS: Clip=4.4 Box=1.2  @=1.6 Pix=0.5
  Uno SSD1351_128X128_HICOLOR                                HW SPI FPS: Clip=3.7 Box=0.8  @=1.0 Pix=0.3

  Mega2560 SSD1351_128X128_332                               HW SPI FPS: Clip=4.4 Box=1.2  @=1.6 Pix=0.5
  Mega2560 SSD1351_128X128_4X_332                            HW SPI FPS: Clip=4.6 Box=2.3  @=2.8 Pix=1.5
  Mega2560 SSD1351_128X128_HICOLOR                           HW SPI FPS: Clip=3.6 Box=0.8  @=1.0 Pix=0.3
  Mega2560 SSD1351_128X128_4X_HICOLOR                      HW SPI FPS: Clip=4.2 Box=1.7  @=2.1 Pix=1.0

  Due SSD1351_128X128_332                                    HW SPI     FPS: Clip=24.6  Box=6.3   @=7.8  Pix=2.8
  Due SSD1351_128X128_4X_332                                 HW SPI     FPS: Clip=28.1  Box=13.0  @=15.1 Pix=8.5
  Due SSD1351_128X128_HICOLOR                                HW SPI     FPS: Clip=20.8  Box=3.4   @=4.5  Pix=1.4
  Due SSD1351_128X128_4X_HICOLOR                             HW SPI     FPS: Clip=26.3  Box=8.9   @=11.1 Pix=4.8

  Due SSD1351_128X128_4X_HICOLOR                             SW SPI     FPS: Clip=0.4   Box=0.4   @=0.4  Pix=0.4
 
  Due DOGS102 u8g(13, 11, 10, 9);                            SW SPI     FPS: Clip=19.1  Box=13.1  @=14.3 Pix=9.4
  Due DOGS102 u8g(10, 9);                                    HW SPI     FPS: Clip=128.9 Box=30.7  @=40.6 Pix=15.4

  Due NHD27OLED_BW u8g(10, 9)                                HW SPI     FPS: Clip=53.0  Box=19.6  @=23.8 Pix=10.6
  Due NHD27OLED_2X_BW u8g(10, 9)                             HW SPI     FPS: Clip=57.0  Box=25.3  @=31.7 Pix=18.1
  Due NHD27OLED_GR u8g(10, 9)                                HW SPI     FPS: Clip=34.1  Box=11.7  @=13.7 Pix=5.6
  Due NHD27OLED_2X_GR u8g(10, 9)                             HW SPI     FPS: Clip=38.1  Box=15.5  @=20.0 Pix=8.8
 
  01 Jun 2014
  16 Bit mode: NHD-3.12-25664UMB3 OLED 256 x 64 pixel resolution
  Teensy 3.0 (CPU SPEED 96Mhz) NHD31OLED_BW u8g(13, 11, 10, 9) SW SPI   FPS: Clip=2.5   Box=2.1   @=2.2  Pix=1.8
  Teensy 3.0 (CPU SPEED 48Mhz) NHD31OLED_BW u8g(10, 9)         HW SPI   FPS: Clip=37.2  Box=7.7   @=10.0 Pix=4.1
  Teensy 3.0 (CPU SPEED 96Mhz) NHD31OLED_BW u8g(10, 9)         HW SPI   FPS: Clip=46.3  Box=9.5   @=11.3 Pix=5.2
  Teensy 3.0 (CPU SPEED 96Mhz) NHD31OLED_2X_BW u8g(10, 9)      HW SPI   FPS: Clip=49.6  Box=13.3  @=16.3 Pix=9.2
  Teensy 3.0 (CPU SPEED 96Mhz) NHD31OLED_2X_GR u8g(10, 9)      HW SPI   FPS: Clip=37.6  Box=8.4   @=10.4 Pix=4.5
 
  Improved performance:
  For Teensy 3.x, there is a digitalWriteFast(pin, value) function that will compile to the fastest possible ARM code
  using only a single bus cycle. http://forum.pjrc.com/threads/23431-Teensy-3-using-IO-pins
  For improved performance replace digitalWrite with digitalWriteFast in ...\arduino-1.0.5\libraries\U8glib\utility\u8g_com_arduino_common.c
 
  Teensy 3.0 (CPU SPEED 96Mhz) NHD31OLED_2X_BW u8g(10, 9)      HW SPI   FPS: Clip=50.7  Box=13.4  @=16.4 Pix=9.2
*/

// SPI Library
#include <SPI.h> //IMPORTANT NOTE: Needed for hw spi on teensy 3.x with Hoss U8G modify Library.
// http://forum.pjrc.com/threads/23445-Teensy-3-0-and-u8glib/page3

#include "U8glib.h"

// setup u8g object, please remove comment from one of the following constructor calls
// IMPORTANT NOTE: The following list is incomplete. The complete list of supported
// devices with all constructor calls is here: http://code.google.com/p/u8glib/wiki/device
//U8GLIB_NHD27OLED_BW u8g(13, 11, 10, 9); // SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9
//U8GLIB_NHD27OLED_2X_BW u8g(13, 11, 10, 9); // SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9
//U8GLIB_NHD27OLED_GR u8g(13, 11, 10, 9); // SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9
//U8GLIB_NHD27OLED_2X_GR u8g(13, 11, 10, 9); // SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9
//U8GLIB_NHD27OLED_BW u8g(10,9);              // HW SPI Com: CS = 10, A0 = 9 (Hardware Pins are  SCK = 13 and MOSI = 11)
//U8GLIB_NHD27OLED_2X_BW u8g(10,9);           // HW SPI Com: CS = 10, A0 = 9 (Hardware Pins are  SCK = 13 and MOSI = 11)
//U8GLIB_NHD27OLED_GR u8g(10,9);              // HW SPI Com: CS = 10, A0 = 9 (Hardware Pins are  SCK = 13 and MOSI = 11)
//U8GLIB_NHD27OLED_2X_GR u8g(10,9);           // HW SPI Com: CS = 10, A0 = 9 (Hardware Pins are  SCK = 13 and MOSI = 11)

//U8GLIB_NHD31OLED_BW u8g(13, 11, 10, 9); // SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9
//U8GLIB_NHD31OLED_2X_BW u8g(13, 11, 10, 9); // SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9
//U8GLIB_NHD31OLED_GR u8g(13, 11, 10, 9); // SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9
//U8GLIB_NHD31OLED_2X_GR u8g(13, 11, 10, 9); // SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9
//U8GLIB_NHD31OLED_BW u8g(10,9);       // HW SPI Com: CS = 10, A0 = 9 (Hardware Pins are  SCK = 13 and MOSI = 11)
//U8GLIB_NHD31OLED_2X_BW u8g(10, 9);          // HW SPI Com: CS = 10, A0 = 9 (Hardware Pins are  SCK = 13 and MOSI = 11)
//U8GLIB_NHD31OLED_GR u8g(10, 9);             // HW SPI Com: CS = 10, A0 = 9 (Hardware Pins are  SCK = 13 and MOSI = 11)
//U8GLIB_NHD31OLED_2X_GR u8g(10, 9);          // HW SPI Com: CS = 10, A0 = 9 (Hardware Pins are  SCK = 13 and MOSI = 11)

/*
 IMPORTANT NOTE: Needed 16 Bit mode for NHD-3.12-25664UMB3 OLED 256 x 64 pixel resolution
 16 Bit mode: U8glib can be put into 16 Bit mode. Remove comment from {{{#define U8G_16BIT 1}}} in ...\arduino-1.0.5\libraries\U8glib\utility\u8g.h
 
    -------------------> My Pinout connections for NHD-3.12-25664UMB3 OLED <------------------------------------
    Teensy 3.x <--wire-connection--to-> NHD-3.12-25664UMB3 OLED
                                       4-wire Serial Interface:
    PIN-13 -> SCK -------------------> PIN-7  SCLK  Serial Clock signal.          (Hardware Pins are SCK = 13)
    PIN-11 -> DOUT, MOSI ------------> PIN-8  SDIN  Serial Data Input signal.     (Hardware Pins are MOSI = 11)
    PIN-10 -> CS, Select Device -----> PIN-16 CS    Active LOW Chip Enable signal.
    PIN-9  -> D/C, A0 ---------------> PIN-4  D/C   Register select signal. D/C=0: Command, D/C=1: Data
    PIN-3.3v+(100 mA max)-> /Reset --> PIN-15 /RES  Active LOW Reset signal. (Connect to Teensy 3.x 3.3v+)
   
    PIN-GND --to Uno GND to ---------> PIN-1 VSS    Power Supply Ground (-)
                                       IMPORTANT NOTE: needs 3.3v Power Supply other then teensy (100 mA max).
                                                       I had been using Arduino Uno 3.3v out (Connect Uno GND to Teensy GND)
    Arduino Uno 3.3v out (+) --------> PIN-2 VDD    Power Supply Supply Voltage for OLED and logic 3.3V (+)
                                       PIN-3 NC     No Connect
                                       PIN-5        VSS Power Supply Ground (-)
                                       PIN-6        VSS Power Supply Ground (-)
                                       PIN-9 NC     No Connect
                                       PIN-10>14    VSS Power Supply Ground (-)
                                       PIN-17 BS1   GND / 4-wire Serial Interface / MPU Interface Select signal.
                                       PIN-18 BS0   GND / 4-wire Serial Interface / MPU Interface Select signal.
                                       PIN-19>22 NC No Connect / Multi-font IC   
 */
 
#define SECONDS 10
uint8_t flip_color = 0;
uint8_t draw_color = 1;

void draw_set_screen(void) {
  // graphic commands to redraw the complete screen should be placed here 
  if ( u8g.getMode() == U8G_MODE_HICOLOR ) {
    if ( flip_color == 0 )
      u8g.setHiColorByRGB(0,0,0);
    else
      u8g.setHiColorByRGB(255,255,255);
  }
  else {
    u8g.setColorIndex(flip_color);
  }
  u8g.drawBox( 0, 0, u8g.getWidth(), u8g.getHeight() );
}

void draw_clip_test(void) {
  u8g_uint_t i, j, k;
  char buf[3] = "AB";
  k = 0;
  if ( u8g.getMode() == U8G_MODE_HICOLOR ) {
    u8g.setHiColorByRGB(255,255,255);
  }
  else {
    u8g.setColorIndex(draw_color);
  }
  u8g.setFont(u8g_font_6x10);
 
  for( i = 0; i  < 6; i++ ) {
    for( j = 1; j  < 8; j++ ) {
      u8g.drawHLine(i-3, k, j);
      u8g.drawHLine(i-3+10, k, j);
     
      u8g.drawVLine(k+20, i-3, j);
      u8g.drawVLine(k+20, i-3+10, j);
     
      k++;
    }
  }
  u8g.drawStr(0-3, 50, buf);
  u8g.drawStr180(0+3, 50, buf);
 
  u8g.drawStr(u8g.getWidth()-3, 40, buf);
  u8g.drawStr180(u8g.getWidth()+3, 40, buf);

  u8g.drawStr90(u8g.getWidth()-10, 0-3, buf);
  u8g.drawStr270(u8g.getWidth()-10, 3, buf);

  u8g.drawStr90(u8g.getWidth()-20, u8g.getHeight()-3, buf);
  u8g.drawStr270(u8g.getWidth()-20, u8g.getHeight()+3, buf);
 
}

void draw_char(void) {
  char buf[2] = "@";
  u8g_uint_t i, j;
  // graphic commands to redraw the complete screen should be placed here 
  if ( u8g.getMode() == U8G_MODE_HICOLOR ) {
    u8g.setHiColorByRGB(255,255,255);
  }
  else {
    u8g.setColorIndex(draw_color);
  }
  u8g.setFont(u8g_font_6x10);
  j = 8;
  for(;;) {
    i = 0;
    for(;;) {
      u8g.drawStr( i, j, buf);
      i += 8;
      if ( i > u8g.getWidth() )
        break;
    }
    j += 8;
    if ( j > u8g.getHeight() )
      break;
  }
 
}

void draw_pixel(void) {
  u8g_uint_t x, y, w2, h2;
  if ( u8g.getMode() == U8G_MODE_HICOLOR ) {
    u8g.setHiColorByRGB(255,255,255);
  }
  else {
    u8g.setColorIndex(draw_color);
  }
  w2 = u8g.getWidth();
  h2 = u8g.getHeight();
  w2 /= 2;
  h2 /= 2;
  for( y = 0; y < h2; y++ ) {
    for( x = 0; x < w2; x++ ) {
      if ( (x + y) & 1 ) {
        u8g.drawPixel(x,y);
        u8g.drawPixel(x,y+h2);
        u8g.drawPixel(x+w2,y);
        u8g.drawPixel(x+w2,y+h2);
      }
    }
  }
}

// returns unadjusted FPS
uint16_t picture_loop_with_fps(void (*draw_fn)(void)) {
  uint16_t FPS10 = 0;
  uint32_t time;
 
  time = millis() + SECONDS*1000;
 
  // picture loop
  do {
    u8g.firstPage(); 
    do {
      draw_fn();
    } while( u8g.nextPage() );
    FPS10++;
    flip_color = flip_color ^ 1;
  } while( millis() < time );
  return FPS10; 
}

const char *convert_FPS(uint16_t fps) {
  static char buf[6];
  strcpy(buf, u8g_u8toa( (uint8_t)(fps/10), 3));
  buf[3] =  '.';
  buf[4] = (fps % 10) + '0';
  buf[5] = '\0';
  return buf;
}

void show_result(const char *s, uint16_t fps) {
  // assign default color value
  if ( u8g.getMode() == U8G_MODE_HICOLOR ) {
    u8g.setHiColorByRGB(255,255,255);
  }
  else {
    u8g.setColorIndex(draw_color);
  }
  u8g.setFont(u8g_font_8x13B);
  u8g.firstPage(); 
  do {
    u8g.drawStr(0,12, s);
    u8g.drawStr(0,24, convert_FPS(fps));
  } while( u8g.nextPage() );
}

void setup(void) {
  // flip screen, if required
  // u8g.setRot180();
 
  // assign default color value
  if ( u8g.getMode() == U8G_MODE_R3G3B2 )
    draw_color = 255;     // white
  else if ( u8g.getMode() == U8G_MODE_GRAY2BIT )
    draw_color = 3;         // max intensity
  else if ( u8g.getMode() == U8G_MODE_BW )
    draw_color = 1;         // pixel on
  else if ( u8g.getMode() == U8G_MODE_HICOLOR ) {
    u8g.setHiColorByRGB(255,255,255);
  }
}

void loop(void) {
  uint16_t fps;
  fps = picture_loop_with_fps(draw_clip_test);
  show_result("draw clip test", fps);
  delay(5000);
  fps = picture_loop_with_fps(draw_set_screen);
  show_result("clear screen", fps);
  delay(5000);
  fps = picture_loop_with_fps(draw_char);
  show_result("draw @", fps);
  delay(5000); 
  fps = picture_loop_with_fps(draw_pixel);
  show_result("draw pixel", fps);
  delay(5000);
}

2
OLEDs / Re: NHD-0216AW-IB3 with Arduino Uno Code example?
« on: May 26, 2017, 07:31:08 PM »
Sorry for the late reply but it does appear you have the library not installed correctly.

Quote
Is there a more effective way to give you the compilation log?
You can enabled this; Show verbose output during Compilation and Upload enabled in File > Preferences.

The undefined reference to OLedI2C::OLedI2C() seems to be showing up because the example is trying to look for OLedI2C in nhd-i2c folder.
This is the last four lines of my successful compilation:
Code: [Select]
Using library Wire at version 1.0 in folder: C:\Documents and Settings\USER NAME HERE\Desktop\arduino-1.8.1\hardware\arduino\avr\libraries\Wire
Using library OLedI2C in folder: C:\Documents and Settings\USER NAME HERE\Desktop\arduino-1.8.1\libraries\OLedI2C (legacy)
Sketch uses 3640 bytes (11%) of program storage space. Maximum is 32256 bytes.
Global variables use 294 bytes (14%) of dynamic memory, leaving 1754 bytes for local variables. Maximum is 2048 bytes.

Test code used:
Code: [Select]
// library by Phil Grant 2013 www.gadjet.co.uk
// OLedI2C library http://gadjetsblog.blogspot.com/2013/09/oled-1602-display-and-library-for.html

// I2C Wire Library Newhaven Display NHD-0420CW OLED TEST

// 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
//Teensy 3.0/3.1   18 (SDA), 19 (SCL),Back Side 30 (SDA1), 29 (SCL1)

#include <Wire.h>

#define I2C_ADDR 0x3c  // Define I2C Address, 0x3c or 0x3d
#include <OLedI2C.h>
OLedI2C LCD;

// custom font arrays
byte newChar1[8] = {
  B11011,
  B11111,
  B11111,
  B11111,
  B11111,
  B11111,
  B11111,
  B10101
};

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

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

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

byte newChar5[8] = { // 5TH custom font
  B10101,
  B10000,
  B10110,
  B00001,
  B00000,
  B10001,
  B01010,
  B00000
};

void setup() {
  Wire.begin(); // Start Wire Library
  LCD.init(I2C_ADDR); // initialize the lcd with I2C Address
  //delay(1000);
  // Store custom font data in 420CW Oled
  LCD.createChar(0, newChar1);
  LCD.createChar(1, newChar2);
  LCD.createChar(2, newChar3);
  LCD.createChar(3, newChar4);
  LCD.createChar(4, newChar5);
  LCD.createChar(5, newChar5);
  LCD.createChar(6, newChar5);
  LCD.createChar(7, newChar5);


  LCD.sendString("SETUP ()", 0, 0);    //("String", col, row)
  delay(1000);
}

void loop() {
  //////////// set Contrast test 1 ////////////////
  LCD.sendString("set Contrast test DW", 0, 0);    //("String", col, row)
  for (int Contrast = 255; Contrast > 0; Contrast = Contrast-- / 2 ) {
    LCD.setContrast(Contrast); // Set Contrast (Minimum allowed 0) 0~255
    LCD.setCursor(9, 1); //(col,row)
    LCD.print(Contrast);
    LCD.print("    "); //clear
    delay(300); //delay not necessary as its sending a lot of Commands wich has delay inside the lib.

  }
  delay(2000); // 2sec. delay

  LCD.clearLcd();
  LCD.sendString("set Contrast test UP", 0, 0);    //("String", col, row)
  for (int Contrast = 0; Contrast < 510; Contrast = Contrast++ * 2 ) {
    LCD.setContrast(Contrast); // Set Contrast (Minimum allowed 0) 0~255
    LCD.cursPos(9, 1); //(col,row)
    LCD.print(Contrast);
    LCD.print("    "); //clear
    delay(300); //delay not necessary as its sending a lot of Commands wich has delay inside the lib.
  }
  delay(2000); // 2sec. delay
  LCD.clearLcd();

  // Double Height(4-line) Test
  LCD.sendString("Double Height(4x20)", 0, 0);
  LCD.sendString("Test", 8, 1);
  delay(2000); // 2sec. delay
  LCD.setDoubleH(1);
  LCD.sendString("MODE 1", 0, 2);
  delay(1000); // 1sec. delay
  LCD.setDoubleH(2);
  LCD.sendString("MODE 2", 0, 2);
  delay(1000); // 1sec. delay
  LCD.setDoubleH(3);
  LCD.sendString("MODE 3", 0, 1);
  delay(1000); // 1sec. delay
  LCD.sendString("      ", 0, 1); // clear MODE 3 from Oled

  LCD.setDoubleH(4);
  LCD.sendString("MODE 4", 0, 2);
  delay(1000); // 1sec. delay
  LCD.setDoubleH(0); //back to 4x20
  LCD.sendString("MODE 0 (4-line)", 0, 2);
  delay(3000); // 3sec. delay
  LCD.clearLcd();

  //////////// Print custom font Using Wire.h Library test 2 ////////////////
  LCD.setDoubleH(3); // MODE 1
  LCD.sendString("Print custom font / Wire Library", 0, 0);    //("String", col, row)
  LCD.sendString("custom font -->", 0, 3);
  delay(3000); // 1sec. delay
  LCD.setDoubleH(0);
  delay(1000); // 1sec. delay
  LCD.cursPos(16, 3); //(col,row) / set up position
  // Test  / Print custom font 5 using Wire.h Library
  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
  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.write(4); //DEC 4 / 5th custom font (Zero based array indexing.....)
  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); //1sec. delay

  //////////// Print 2 custom font Using LCD.sendData test 3 ////////////////
  LCD.sendString(" Print two custom   fonts / LCD.sendData", 0, 0);    //("String", col, row)
  LCD.cursPos(2, 2); //(col,row)
  LCD.print("---> ");
  delay(1000); // 1sec. delay
  LCD.sendData(0); //Print custom font 1 (Zero based array indexing.....)
  LCD.print(" <---> ");
  delay(1000); // 1sec. delay
  LCD.sendData(char(1)); //Print custom font 2
  delay(3000); // 3sec. delay
  LCD.clearLcd();
  delay(1000);

  //LCD.scrollString("test", 2, 100);

  //////////// command test ////////////////
  /*
    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-lines) / last bit=1 : 3-line or 4-line display mode
    sendCommand(0x06); //COM SEG direction
    sendCommand(0x72); //function selection B
    sendData(B00000000);   //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

    delay(150);
    sendCommand(0x0C);  // **** Turn on Display
    delay(150);*/
}

3
OLEDs / Re: NHD-0216AW-IB3 with Arduino Uno Code example?
« on: May 10, 2017, 06:20:20 PM »
Whoops it appears I have more than one of these libraries all over in different Arduino installations  :-[.
Well this time I did test it and it compiles, i hate to do this to you but you have to try again with these files.

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.

OLedI2C.cpp
Code: [Select]
// 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"

#if (ARDUINO <  100)
#include <WProgram.h>
#else
#include <Arduino.h>
#endif

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

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

uint8_t _OLED_Address; //global variable initialization

void OLedI2C::init(uint8_t OLED_Address) {

  _OLED_Address = OLED_Address;

  // *** 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

  delay(150);
  sendCommand(0x0C);  // **** Turn on Display
  delay(150);
}

// 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);
}

// arduino com.
void OLedI2C::clear() // *********Compatible with LiquidCrystal lib.
{
  sendCommand(0x01);
}

void OLedI2C::home()
{
  sendCommand(0x02);
}

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

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

void OLedI2C::noDisplay() // *********Compatible with LiquidCrystal lib.
{
  sendCommand(0x08);  // **** Turn on Off
}

void OLedI2C::display() // *********Compatible with LiquidCrystal lib.
{
  sendCommand(0x0C);  // **** Turn on On
}

// Turns the underline cursor on/off
void OLedI2C::noCursor() {
  sendCommand(0x0C);   // **** Turn Off underline cursor
}
void OLedI2C::cursor() {
  sendCommand(0x0E);  // **** Turn On underline cursor
}

// Turn on and off the blinking cursor
void OLedI2C::noBlink() {
  sendCommand(0x0C);  // **** Turn Off blinking cursor
}
void OLedI2C::blink() {
  sendCommand(0x0D);  // **** Turn On blinking cursor
}


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
}

// ARDUINO 0.23 ~ ARDUINO 1.0.0 and Up ======= Print ==============================================
#if (ARDUINO <  100)
inline void OLedI2C::write(uint8_t value) {
  sendData(value);
}
#else
inline size_t OLedI2C::write(uint8_t value) {
  sendData(value);
}
#endif

void OLedI2C::setDoubleH(uint8_t MODE) // 09-19-2015 / Double Height Display MODE 0~4
// MODE: "0"=Normal 4-line, "1"=Bottom half Double Height, "2"=Middle Double Height, "3"=Top/Bottom Double Height, "4"=Top Double Height
{
  sendCommand(0x2A);// Function Set  (extended command set / Extension register, RE ("1")set) B00101010
  sendCommand(B00001001);//Extended Function Set (FW = "0": 5-dot font width, black/white invert cursor DIS,NW = "1": 3-line or 4-line display mode)
  switch (MODE) {
  case 0:    //MODE 0 4x20-line
    sendCommand(0x28);// Function Set (Go Back to Fundamental Command Set)//101000
    break;
  case 1:    //MODE 1 0x10 / Double Height (4-line)/Display-dot shift
    sendCommand(B00010000); //MODE 2
    sendCommand(0x2C);//101100 Function Set ( when (N=1 :4-line )and(NW=1), Double height =1 Enable, Extension register, RE"0", Extension register, IS"0" )
    break;
  case 2:    //MODE 2 0x14 / Double Height (4-line)/Display-dot shift
    sendCommand(B00010100);   //MODE 2 0x14 / Double Height (4-line)/Display-dot shift
    sendCommand(0x2C);//101100 Function Set ( when (N=1 :4-line )and(NW=1), Double height =1 Enable, Extension register, RE"0", Extension register, IS"0" )
    break;
  case 3:    //MODE 3 0x18 / Double Height (4-line)/Display-dot shift (DH’ = "0": dot scroll enable (POWER UP))
    sendCommand(B00011000);
    //sendCommand(B00011001); //MODE 3 0x19 / Double Height (4-line)/Display-dot shift (DH’ = "1": display shift enable)
    sendCommand(0x2C);//101100 Function Set ( when (N=1 :4-line )and(NW=1), Double height =1 Enable, Extension register, RE"0", Extension register, IS"0" )
    break;
  case 4:
    sendCommand(B00011100);  //MODE 4 0x1C / Double Height (4-line)/Display-dot shift(DH’ = "0": display shift DIS)
    sendCommand(0x2C);//101100 Function Set ( when (N=1 :4-line )and(NW=1), Double height =1 Enable, Extension register, RE"0", Extension register, IS"0" )
    break;
  }
}

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);        //Function Set  N = 1, BE = 0, RE = 1 Set, REV = "0": normal display (POR)  B00101010
  sendCommand(0x79);        //OLED Characterization / 0x79 B1111001 =  OLED command set is enabled
  sendCommand(0x81);  // Set Contrast
  sendCommand(contrast); // send contrast value
  sendCommand(0x78);  // OLED Characterization / 0x78 B1111000 =Exiting Set OLED Command set disabled (POR)
  sendCommand(0x28);       // Function Set / B101000 (Go Back to Fundamental Command Set)
}

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);
  }
}




//#define OLED_Command_Mode 0x80
//#define OLED_Data_Mode 0x40
// 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); ]
  //Wire.endTransmission();

  Wire.beginTransmission(_OLED_Address); // **** Start I2C
  Wire.write(OLED_Command_Mode); // 0x80
  Wire.write(0x40 | (location << 3));      // **** Set OLED Command mode
  Wire.endTransmission();                  // **** End I2C
 

  for (uint8_t i = 0 ; i < 8 ; i++) {
    Wire.beginTransmission(_OLED_Address); // **** Start I2C
    Wire.write(OLED_Data_Mode);      // **** Set OLED Data mode
    Wire.write(charmap[i]);
    Wire.endTransmission();                     
  }
}
 
/*
// 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));

  for (int i=0; i<8; i++)
  {
    sendData(charmap[i]);      // call the virtual write method
  }
}
*/

OLedI2C.h
Code: [Select]
// 1602-OLED-Arduino-Library/OLedI2C.h

/*
OLedI2C.h
OLED 1602 Library for the I2C
OLED display from WIDE.HK
Also my first attempt at a Library
Phil Grant Sept 2013
www.gadjet.co.uk
Scrolling contributed by Nathan Chantrell http://nathan.chantrell.net/
Updated 06/11/2013 to include the cursPos data within the sendString function.
*/
#ifndef OLedI2C_h
#define OLedI2C_h
#include "Arduino.h"
#include "Wire.h" // NEED FIX
//#include <i2c_t3.h> //Enhanced I2C library for Teensy 3.0/3.1/LC devices

#include "Print.h"


class OLedI2C : public Print {
public:
OLedI2C();
~OLedI2C();
// void init(); // OLD
            void init(uint8_t OLED_Address);
void sendCommand(unsigned char command);
void sendString(const char *String, uint8_t col, uint8_t row);
void sendFloat(float digit, uint8_t dec, uint8_t nad, uint8_t col, uint8_t row);
void sendData(unsigned char data);
void clearLcd();
            void clear();
            void home();
            void noDisplay();
            void display();
            void noCursor();
            void cursor();
            void noBlink();
            void blink();
void cursPos(uint8_t, uint8_t); // cloumn, row
            void setCursor(uint8_t, uint8_t); // *********Compatible with LiquidCrystal lib.
            void setCursor2(uint8_t, uint8_t); // 03-23-2015 / cloumn, row / setCursor
void scrollString(char* message, byte row, unsigned int time); //written by Nathan Chantrell http://nathan.chantrell.net/
void lcdOff();
void lcdOn();
            void setDoubleH(uint8_t); // 09-19-2015 / Double Height Display MODE 0~4
void setContrast(uint8_t contrast); // contrast should be the hex value between 0x00 and 0xFF
            void createChar(uint8_t, uint8_t[]); // NEW 03-23-2015 / Allows us to fill the first 8 CGRAM locations with custom characters

            // Compatible = ARDUINO= 0.23 = 1.6.5 ================
            #if (ARDUINO <  100)
            virtual void write(uint8_t);
            #else
            virtual size_t write(uint8_t);
            #endif // my code ==========================
};
#endif

keywords.txt
Code: [Select]
#######################################
# Syntax Coloring Map For OLedI2C
#######################################

#######################################
# Datatypes (KEYWORD1)
#######################################

OLedI2C KEYWORD1

#######################################
# Methods and Functions (KEYWORD2)
#######################################

init KEYWORD2
sendCommand KEYWORD2
sendData KEYWORD2
sendString KEYWORD2
sendFloat KEYWORD2
clearLcd KEYWORD2
clear KEYWORD2
home KEYWORD2
noDisplay KEYWORD2
display KEYWORD2
noCursor KEYWORD2
cursor KEYWORD2
noBlink KEYWORD2
blink KEYWORD2
cursPos KEYWORD2
setCursor KEYWORD2
createChar KEYWORD2
scrollString KEYWORD2
lcdOn KEYWORD2
lcdOff KEYWORD2
setContrast KEYWORD2
setDoubleH KEYWORD2

#######################################
# Constants (LITERAL1)
#######################################

Another example
Code: [Select]
/*
  Example sketch to display Strings and float values on the OLED
  1602 display  from Wide.HK. This uses a Lbrary that I've
  put together containing some basic functions.
  The I2C Address is set to 0x3C in OLedI2C.cpp
  Phil Grant 2013 www.gadjet.co.uk  07/11/13
*/

#include "Wire.h"
#include "OLedI2C.h"
OLedI2C LCD;
#define I2C_ADDR 0x3c  // Define I2C Address, 0x3c or 0x3d

float digit; //Variable to hold sample temperature value

void setup()
{
  Wire.begin();
  LCD.init(I2C_ADDR); // initialize the lcd with I2C Address
  digit = 21.6; //This would normally be the float value returned from a temp sensor or other sensor
}
void loop()
{
  LCD.sendString("Temp", 0, 0); //Now includes the cursor position data (col, row)
  LCD.sendFloat(digit, 5, 2, 7, 0); //Send the float value to the display starting
  //at col 7 row 1 with 5 digits and 2 decimal places
  while (1);
}


Also the I2C address 0x3c may need to be edit for the screen you use.
Just run this and open the serial monitor it should show you the correct address.
 i2c_scanner
Code: [Select]
// i2c_scanner
 //
 // This program (or code that looks like it)
 // can be found in many places.
 // For example on the Arduino.cc forum.
 // The original author is not know.
 //
 // This sketch tests the standard 7-bit addresses
 // from 0 to 127. Devices with higher bit address
 // might not be seen properly.
 //
 // Adapted to be as simple as possible by Arduino.cc user Krodal
 //
 // June 2012
 // Using Arduino 1.0.1
 //
#include <Wire.h>
void setup()
 {
   Wire.begin();
 
  Serial.begin(9600);
   Serial.println("\nI2C Scanner");
 }
void loop()
 {
   byte error, address;
   int nDevices;
 
  Serial.println("Scanning...");
 
  nDevices = 0;
   for(address = 0; 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(8000);           // wait 8 seconds for next scan
 }


4
OLEDs / Re: NHD-0216AW-IB3 with Arduino Uno Code example?
« on: May 09, 2017, 09:57:30 PM »
Edit:
Please do not use this use the one on Reply #5

library by Phil Grant 2013  www.gadjet.co.uk
OLedI2C library http://gadjetsblog.blogspot.com/2013/09/oled-1602-display-and-library-for.html

Perhaps this will be of help.
Been long time since I used this Library, createChar function contributed by me.

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.

NOTE: this is set up for 04x20 oled now.
Look for this in OLedI2C.cpp perhaps you can edit that line for 02x16.
 int row_offsets[] = { 0x00, 0x20, 0x40, 0x60 };// **************THIS WAS THE CHANGE FOR 4 LINES.

keywords.txt
Code: [Select]
#######################################
# Syntax Coloring Map For OLedI2C
#######################################

#######################################
# Datatypes (KEYWORD1)
#######################################

OLedI2C KEYWORD1

#######################################
# Methods and Functions (KEYWORD2)
#######################################

init KEYWORD2
sendCommand KEYWORD2
sendString KEYWORD2
sendData KEYWORD2
clearLcd KEYWORD2
cursPos KEYWORD2
setCursor KEYWORD2
createChar KEYWORD2

#######################################
# Constants (LITERAL1)
#######################################


OLedI2C.cpp
Code: [Select]
// 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); // **** 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(0x08); // **** 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-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]);      // call the virtual write method
      delayMicroseconds(40);
   }
}

OLedI2C.h
Code: [Select]
// 1602-OLED-Arduino-Library/OLedI2C.h

/*
OLedI2C.h
OLED 1602 Library for the I2C
OLED display from WIDE.HK
Also my first attempt at a Library
Phil Grant Sept 2013
www.gadjet.co.uk
Scrolling contributed by Nathan Chantrell http://nathan.chantrell.net/
Updated 06/11/2013 to include the cursPos data within the sendString function.
*/
#ifndef OLedI2C_h
#define OLedI2C_h
#include "Arduino.h"
#include "Wire.h"

class OLedI2C {
public:
OLedI2C();
~OLedI2C();
void init();
void sendCommand(unsigned char command);
void sendString(const char *String, uint8_t col, uint8_t row);
void sendFloat(float digit, uint8_t dec, uint8_t nad, uint8_t col, uint8_t row);
void sendData(unsigned char data);
void clearLcd();
void cursPos(uint8_t, uint8_t); // cloumn, row
void setCursor(uint8_t, uint8_t); // NEW 03-23-2015 / cloumn, row / setCursor
void scrollString(char* message, byte row, unsigned int time); //written by Nathan Chantrell http://nathan.chantrell.net/
void lcdOff();
void lcdOn();
void setContrast(unsigned char contrast); // contrast should be the hex value between 0x00 and 0xFF
void createChar(uint8_t, uint8_t[]); // NEW 03-23-2015 / Allows us to fill the first 8 CGRAM locations with custom characters
};
#endif

Example
Code: [Select]
// I2C Wire Library Newhaven Display NHD-0420CW OLED TEST

// 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
//Teensy 3.0/3.1   18 (SDA), 19 (SCL),Back Side 30 (SDA1), 29 (SCL1)

#include <Wire.h> 

#define I2C_ADDR 0x3c  // Define I2C Address, 0x3c or 0x3d
#include <OLedI2C.h> 
OLedI2C LCD;

// custom font arrays
byte newChar1[8] = {
  B11011,
  B11111,
  B11111,
  B11111,
  B11111,
  B11111,
  B11111,
  B10101
};

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

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

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

byte newChar5[8] = { // 5TH custom font
  B10101,
  B10000,
  B10110,
  B00001,
  B00000,
  B10001,
  B01010,
  B00000
};

void setup() {
  Wire.begin(); // Start Wire Library
  LCD.init(I2C_ADDR); // initialize the lcd with I2C Address
//delay(1000);
  // Store custom font data in 420CW Oled
  LCD.createChar(0, newChar1);
  LCD.createChar(1, newChar2);
  LCD.createChar(2, newChar3);
  LCD.createChar(3, newChar4);
  LCD.createChar(4, newChar5);
  LCD.createChar(5, newChar5);
  LCD.createChar(6, newChar5);
  LCD.createChar(7, newChar5);

   
   LCD.sendString("SETUP ()", 0, 0);    //("String", col, row)
   delay(1000);
}

void loop() {
  //////////// set Contrast test 1 ////////////////
  LCD.sendString("set Contrast test DW", 0, 0);    //("String", col, row)
    for (int Contrast = 255; Contrast > 0; Contrast = Contrast-- / 2 ) {
    LCD.setContrast(Contrast); // Set Contrast (Minimum allowed 0) 0~255
    LCD.setCursor(9,1); //(col,row)
    LCD.print(Contrast);
    LCD.print("    "); //clear
    delay(300); //delay not necessary as its sending a lot of Commands wich has delay inside the lib.
   
  }
  delay(2000); // 2sec. delay
 
  LCD.clearLcd();
  LCD.sendString("set Contrast test UP", 0, 0);    //("String", col, row)
  for (int Contrast = 0; Contrast < 510; Contrast = Contrast++ * 2 ) {
    LCD.setContrast(Contrast); // Set Contrast (Minimum allowed 0) 0~255
    LCD.cursPos(9,1); //(col,row)
    LCD.print(Contrast);
    LCD.print("    "); //clear
    delay(300); //delay not necessary as its sending a lot of Commands wich has delay inside the lib.
  }
  delay(2000); // 2sec. delay
  LCD.clearLcd();
 
  // Double Height(4-line) Test
  LCD.sendString("Double Height(4x20)", 0, 0);
  LCD.sendString("Test", 8, 1);
  delay(2000); // 2sec. delay
  LCD.setDoubleH(1);
  LCD.sendString("MODE 1", 0, 2);
  delay(1000); // 1sec. delay
  LCD.setDoubleH(2);
  LCD.sendString("MODE 2", 0, 2);
  delay(1000); // 1sec. delay
  LCD.setDoubleH(3);
  LCD.sendString("MODE 3", 0, 1);
  delay(1000); // 1sec. delay
  LCD.sendString("      ", 0, 1); // clear MODE 3 from Oled
 
  LCD.setDoubleH(4);
  LCD.sendString("MODE 4", 0, 2);
  delay(1000); // 1sec. delay
  LCD.setDoubleH(0); //back to 4x20
  LCD.sendString("MODE 0 (4-line)", 0, 2);
  delay(3000); // 3sec. delay
  LCD.clearLcd();

  //////////// Print custom font Using Wire.h Library test 2 ////////////////
  LCD.setDoubleH(3); // MODE 1
  LCD.sendString("Print custom font / Wire Library", 0, 0);    //("String", col, row)
  LCD.sendString("custom font -->", 0, 3);
  delay(3000); // 1sec. delay
  LCD.setDoubleH(0);
  delay(1000); // 1sec. delay
  LCD.cursPos(16,3); //(col,row) / set up position 
  // Test  / Print custom font 5 using Wire.h Library
  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
  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.write(4); //DEC 4 / 5th custom font (Zero based array indexing.....)
  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); //1sec. delay

  //////////// Print 2 custom font Using LCD.sendData test 3 ////////////////
  LCD.sendString(" Print two custom   fonts / LCD.sendData", 0, 0);    //("String", col, row)
  LCD.cursPos(2,2); //(col,row)
  LCD.print("---> ");
  delay(1000); // 1sec. delay
  LCD.sendData(0); //Print custom font 1 (Zero based array indexing.....)
  LCD.print(" <---> ");
  delay(1000); // 1sec. delay
  LCD.sendData(char(1)); //Print custom font 2
  delay(3000); // 3sec. delay
  LCD.clearLcd();
  delay(1000);
 
  //LCD.scrollString("test", 2, 100);

  //////////// command test ////////////////
  /*
  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-lines) / last bit=1 : 3-line or 4-line display mode
  sendCommand(0x06); //COM SEG direction
  sendCommand(0x72); //function selection B
  sendData(B00000000);   //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

  delay(150);
  sendCommand(0x0C);  // **** Turn on Display
  delay(150);*/

 
 
 
 
}

5
OLEDs / Re: Reg: NHD-0420DZW DZW SPI Interface with Arudino
« on: January 02, 2017, 09:06:02 AM »
I believe the examples for SPI on Arduino UNO are here:

NHD0420CW-Ax3 display with Arduino Uno - Tutorials
http://www.newhavendisplay.com/NHD_forum/index.php/topic,914.0.html

EDIT:
 Oops I'm sorry all, this is for the slim OLED display.

6
OLEDs / Re: NHD-3.12-25664UCB2-ND dim display with banding?
« on: April 26, 2016, 11:07:36 PM »
NHD-3.12-25664UCB2 Supply Voltage 3.3V Max
I hope you are not running the display without proper voltage level shifter in case of Arduino UNO 5v device.

I suggest checking out the u8glib library by Olikraus

olikraus/u8glib https://github.com/olikraus/u8glib/wiki

Supported Devices
SSD1306, 128x64
SSD1306, 128x32
SSD1306, 64x48
SSD1309, 128x64
SSD1322, 256x64 <-------- NHD-3.12-25664UCB2
SSD1325, 128x64
SSD1327, 96x96
SH1106, 128x64
UC1601, 128x32
UC1608, 240x64
UC1610, 160x104
UC1611, 240x64
UC1611, 240x128
UC1701, 128x64
UC1701, 102x64
ST7565, 128x64
ST7565, 128x32
ST7920, 128x64
ST7920, 192x32
ST7920, 202x32
LD7032, 60x32
PCD8544, 84x48
TLS8204 , 84x48
PCF8812 , 96x65
KS0108 , 128x64
T6963, 128x64
T6963, 128x128
T6963, 240x64
T6963, 240x128
SBN1661, 122x32
LC7981, 160x80
LC7981, 240x64
LC7981, 240x128
LC7981, 320x64
SSD1351
HT1632, 24x16
Flipdisk, 28x14
Virtual Screen Device

7
OLEDs / Re: NHD0420CW-Ax3 display with Arduino Uno - Tutorials
« on: April 03, 2016, 03:08:57 PM »
Hi

Can anyone help me test this code, simply don't have the 2 OLED displays hardware do to it right now.

Transactional SPI setup with 2  NHD0420CW-Ax3 OLED displays.
1st OLED running on 8MHz.
2nd OLED running on 4MHz.
 
Code: [Select]
/*
 * Demo_NHD0420CW-Ax3_SPI_HW.ino
 *
 * Tutorial sketch for use of character OLED slim display family by Newhaven with Arduino Uno, with
 * using HW SPI library.  Models: NHD0420CW-Ax3, NHD0220CW-Ax3, NHD0216CW-Ax3. Controller: US2066
 * in this example, the display is connected to Arduino via SPI interface.
 *
 * Displays on the OLED alternately a 4-line message and a sequence of character "block".
 * This sketch assumes the use of a 4x20 display; if different, modify the values of the two variables
 * ROW_N e COLUMN_N.
 * The sketch uses the minimum possible of Arduino's pins; if you intend to use also /RES or /CS lines,
 * the related instructions are already present, it's sufficient to remove the comment markers.
 *
 * The circuit:
 * OLED pin 1 (Vss)    to Arduino pin ground
 * OLED pin 2 (VDD)    to Arduino pin 5V
 * OLED pin 3 (REGVDD) to Arduino pin 5V
 * OLED pin 4 to 6     to Vss ground
 * OLED pin 7 (SCLK)   to Arduino pin D13 (SCK)
 * OLED pin 8 (SID)    to Arduino pin D11 (MOSI)
 * OLED pin 9 (SOD)    to Arduino pin D12 (MISO) (optional, can be not connected)
 * OLED pin 10 to 14   to Vss ground
 * OLED pin 15 (/CS)   to Vss ground (or to Arduino Pin D10(1st device) ~ Pin D9(2nd device), in case of use of more than one display)
 * OLED pin 16 (/RES)  to Arduino pin Reset or VDD 5V (or to Arduino pin D3, to control reset by sw)
 * OLED pin 17 (BS0)   to Vss ground
 * OLED pin 18 (BS1)   to Vss ground
 * OLED pin 19 (BS2)   to Vss ground
 * OLED pin 20 (Vss)   to Vss ground
 *
 * Original example created by Newhaven Display International Inc.
 * Modified and adapted to Arduino Uno 30 Mar 2015 by Pasquale D'Antini
 * Modified 19 May 2015 by Pasquale D'Antini
 * Modified to use hardware SPI 1 April 2016 by Joakim Sandström
 * HW SPI transaction 3 April 2016 by Cris O.
 *
 * This example code is in the public domain.
 */

// inslude the SPI library:
#include <SPI.h>

/*
 * The SPI protocol allows for a range of transmission speeds ranging from 1Mhz to 100MHz.
 * SPI slaves vary in the maximum speed at which they can reliably work.
 * For a SPI chip rated up to 20 MHz, use 20000000.
 * NOTE:
 * Arduino Pro Mini (3.3 V / 8MHz) can only have SPI at 4 MHz as fastest speed, 1/2 the system clock speed.
 * Arduino UNO (5 V / 16MHz) can only have SPI at 8 MHz as fastest speed, 1/2 the system clock speed.
 */
// Transactional SPI configuration
// Set up SPI transaction method for all devices
// Set up the speed, data order and data mode
SPISettings NHD0420CW_A(8000000, LSBFIRST, SPI_MODE3); // 8 MHz
SPISettings NHD0420CW_B(4000000, LSBFIRST, SPI_MODE3); // 4 MHz

/* Multiple SPI devices use the same SPI SCK, MISO and MOSI signals but each device will need it's own SS pin. */
// set the Slave Select Pins, using two SPI devices, A and B.
const int CS_A_Pin = 10; // (1st device)
const int CS_B_Pin = 9; // (2nd device)

/* Slave Select Signal:
* Any digital pin can be used for a SS (slave select) signal.
* The SPI library does not control the SS signals,
* because devices differ on when this is used,
* whether it is held low for multiple transfers or for each individual transfer,
* and so on. Control SS with digitalWrite().
* However, the SS pin must either be configured as an output,
* or if it is an input, it must remain low during the SPI transfer.
* Unconfigured pins default to input, and a pin with no signal can easily "float"
* to random voltages due to electrical noise.
* Always configure the SS pin as an output, or make sure it remains low.
*
* Most SPI devices are designed to work together with others,
* where SCK, MISO, and MOSI are shared. Each chip needs a separate SS signal.
* Only the selected chip will communicate. The others ignore SCK and MOSI,
* and avoid driving MISO when they are not selected.
*/

//const byte RES = 3;                 // Arduino's pin assigned to the Reset line (optional, can be always high)

// 1ST OLED
const byte ROW_N_1 = 4;                 // Number of display rows
const byte COLUMN_N_1 = 20;             // Number of display columns

const byte TEXT_1[4][21] = {"1-Newhaven Display--",
                            "2-------Test-Oled-1-",
                            "3-16/20-Characters--",
                            "4!@#$%^&*()_+{}[]<>?"
                           };         // Strings to be displayed

byte new_line_1[4] = {0x80, 0xA0, 0xC0, 0xE0};               // DDRAM address for each line of the display
byte rows_1 = 0x08;                     // Display mode: 1/3 lines or 2/4 lines; default 2/4 (0x08)

// 2ND OLED
const byte ROW_N_2 = 4;                 // Number of display rows
const byte COLUMN_N_2 = 20;             // Number of display columns

const byte TEXT_2[4][21] = {"1-Newhaven Display--",
                            "2-------Test-Oled-2-",
                            "3-16/20-Characters--",
                            "4!@#$%^&*()_+{}[]<>?"
                           };         // Strings to be displayed

byte new_line_2[4] = {0x80, 0xA0, 0xC0, 0xE0};               // DDRAM address for each line of the display
byte rows_2 = 0x08;                     // Display mode: 1/3 lines or 2/4 lines; default 2/4 (0x08)

// __
void command(byte c, byte device)                  // SUBROUTINE: PREPARES THE TRANSMISSION OF A COMMAND
{
  switch (device) {
    case 1:  // (1st device)
      SPI.beginTransaction(NHD0420CW_A);
      // take the CS pin low to select the chip:
      digitalWrite (CS_A_Pin, LOW); /* (most chips use LOW during the transfer) */
      SPI.transfer(0x1F);
      send_byte(c);                 // Transmits the byte
      // take the CS pin high to de-select the chip:
      digitalWrite (CS_A_Pin, HIGH);
      SPI.endTransaction();
      break;

    case 2: // (2nd device)
      SPI.beginTransaction(NHD0420CW_B);
      // take the CS pin low to select the chip:
      digitalWrite (CS_B_Pin, LOW); /* (most chips use LOW during the transfer) */
      SPI.transfer(0x1F);
      send_byte(c);                 // Transmits the byte
      // take the CS pin high to de-select the chip:
      digitalWrite (CS_B_Pin, HIGH);
      SPI.endTransaction();
      break;

    case 3:
      Serial.println("Error No device 3 specified");
      break;
    default:
      Serial.print("Error Unknown Device:");
      Serial.println(device);
      break;
  }
}
// _______________________________________________________________________________________

void data(byte d, byte device)
{
  switch (device) {
    case 1:  // (1st device)
      SPI.beginTransaction(NHD0420CW_A);
      // take the CS pin low to select the chip:
      digitalWrite (CS_A_Pin, LOW);
      SPI.transfer(0x5F);
      send_byte(d);
      // take the CS pin high to de-select the chip:
      digitalWrite (CS_A_Pin, HIGH);
      SPI.endTransaction();
      break;

    case 2: // (2nd device)
      SPI.beginTransaction(NHD0420CW_B);
      // take the CS pin low to select the chip:
      digitalWrite (CS_B_Pin, LOW); /* (most chips use LOW during the transfer) */
      SPI.transfer(0x5F);
      send_byte(d);
      // take the CS pin high to de-select the chip:
      digitalWrite (CS_B_Pin, HIGH);
      SPI.endTransaction();
      break;

    case 3:
      Serial.println("Error No device 3 specified");
      break;
    default:
      Serial.print("Error Unknown Device:");
      Serial.println(device);
      break;
  }
}
// _______________________________________________________________________________________

void send_byte(byte tx_b)
{
  //Split the bytes into two and pad the last four bits with 0s
  byte tx_b1 = tx_b & 0x0F;
  byte tx_b2 = (tx_b >> 4) & 0x0F;

  //Or together the bytes
  int tx_int = (tx_b2 << 8) | tx_b1;

  //transfer it
  SPI.transfer16(tx_int);
}

// _______________________________________________________________________________________

void output(byte device)                     // SUBROUTINE: DISPLAYS THE FOUR STRINGS, THEN THE SAME IN REVERSE ORDER
{
  // 1ST OLED ---------------------------------------------------------------------------------------
  if (device == 1) {
    unsigned long lastTime1 = 0;
    unsigned long temp1;
    byte r1 = 0;                        // Row index
    byte c1 = 0;                        // Column index

    command(0x01, device);                  // Clears display (and cursor home)
    delay(2);                          // After a clear display, a minimum pause of 1-2 ms is required

    for (r1 = 0; r1 < ROW_N_1; r1++)        // One row at a time,
    {
      command(new_line_1[r1], device);         //  moves the cursor to the first column of that line
      for (c1 = 0; c1 < COLUMN_N_1; c1++)   // One character at a time,
      {
        data(TEXT_1[r1][c1], device);            //  displays the correspondig string
      }
    }

    delay(2000);                       // Waits, only for visual effect purpose

    lastTime1 = millis();
    for (r1 = 0; r1 < ROW_N_1; r1++)        // One row at a time,
    {
      command(new_line_1[r1], device);           //  moves the cursor to the first column of that line
      for (c1 = 0; c1 < COLUMN_N_1; c1++)  // One character at a time,
      {
        data(TEXT_1[3 - r1][c1], device);        //  displays the correspondig string (in reverse order)
      }
    }
    temp1 = millis() - lastTime1;
    Serial.print("OLED 1: ");
    Serial.println(temp1);
  }

  // 2ND OLED -----------------------------------------------------------------------------------------
  if (device == 2) {
    unsigned long lastTime2 = 0;
    unsigned long temp2;
    byte r2 = 0;                        // Row index
    byte c2 = 0;                        // Column index

    command(0x01, device);                  // Clears display (and cursor home)
    delay(2);                          // After a clear display, a minimum pause of 1-2 ms is required

    for (r2 = 0; r2 < ROW_N_2; r2++)        // One row at a time,
    {
      command(new_line_2[r2], device);         //  moves the cursor to the first column of that line
      for (c2 = 0; c2 < COLUMN_N_2; c2++)   // One character at a time,
      {
        data(TEXT_2[r2][c2], device);            //  displays the correspondig string
      }
    }

    delay(2000);                       // Waits, only for visual effect purpose

    lastTime2 = millis();
    for (r2 = 0; r2 < ROW_N_2; r2++)        // One row at a time,
    {
      command(new_line_2[r2], device);           //  moves the cursor to the first column of that line
      for (c2 = 0; c2 < COLUMN_N_2; c2++)  // One character at a time,
      {
        data(TEXT_2[3 - r2][c2], device);        //  displays the correspondig string (in reverse order)
      }
    }
    temp2 = millis() - lastTime2;
    Serial.print("OLED 2: ");
    Serial.println(temp2);
  }
}
// _______________________________________________________________________________________

void blocks(byte device)                     // SUBROUTINE: FILLS THE ENTIRE DISPLAY WITH THE CHARACTER "BLOCK"
{
  // 1ST OLED ---------------------------------------------------------------------------------------
  if (device == 1) {
    byte r1 = 0;                        // Row index
    byte c1 = 0;                        // Column index

    command(0x01, device);                     // Clear display (and cursor home)
    delay(2);                          // After a clear display, a minimum pause of 1-2 ms is required

    for (r1 = 0; r1 < ROW_N_1; r1++)        // One row at a time,
    {
      command(new_line_1[r1], device);           //  moves the cursor to the first column of that line
      for (c1 = 0; c1 < COLUMN_N_1; c1++)  // One character at a time,
      {
        data(0xDB, device);                  //  displays the character 0xDB (block)
        delay(50);                   // Waits, only for visual effect purpose
      }
      delay(500);                     // Waits, only for visual effect purpose
    }
  }
  // 2ND OLED -----------------------------------------------------------------------------------------
  if (device == 2) {
    byte r2 = 0;                        // Row index
    byte c2 = 0;                        // Column index

    command(0x01, device);                     // Clear display (and cursor home)
    delay(2);                          // After a clear display, a minimum pause of 1-2 ms is required

    for (r2 = 0; r2 < ROW_N_2; r2++)        // One row at a time,
    {
      command(new_line_2[r2], device);           //  moves the cursor to the first column of that line
      for (c2 = 0; c2 < COLUMN_N_2; c2++)  // One character at a time,
      {
        data(0xDB, device);                  //  displays the character 0xDB (block)
        delay(50);                   // Waits, only for visual effect purpose
      }
      delay(500);                     // Waits, only for visual effect purpose
    }
  }
}
// _______________________________________________________________________________________

void setup(void)                      // INITIAL SETUP
{
  //   pinMode(RES, OUTPUT);            // Initializes Arduino pin for the Reset line (optional)
  //   digitalWrite(RES, HIGH);         // Sets HIGH the Reset line of the display (optional, can be always high)

  // set the Slave Select Pins as outputs:
  pinMode (CS_A_Pin, OUTPUT); // Pin 10
  pinMode (CS_B_Pin, OUTPUT); // Pin 9, optional 2ND device.
  // initialize SPI:
  SPI.begin();

  /* Deprecated SPI configuration
  Used by older versions of the SPI library, this method was not interrupt safe and
  depended on your sketch doing low-level SPI configuration management.
    SPI.setBitOrder(LSBFIRST);
    SPI.setClockDivider(SPI_CLOCK_DIV2);
    SPI.setDataMode(SPI_MODE3);
  */

  delayMicroseconds(200);            // Waits 200 us for stabilization purpose

  OledInit(1); // OLED init (1st device)
  OledInit(2); // OLED init (2nd device)

  Serial.begin(115200); //For performance measurement
}
// _______________________________________________________________________________________

void OledInit(byte device)
{
  // OLED init

  // 1ST OLED
  if (ROW_N_1 == 2 || ROW_N_1 == 4)
    rows_1 = 0x08;                    // Display mode: 2/4 lines
  else
    rows_1 = 0x00;                    // Display mode: 1/3 lines

  // 2ND OLED
  if (ROW_N_2 == 2 || ROW_N_2 == 4)
    rows_2 = 0x08;                    // Display mode: 2/4 lines
  else
    rows_2 = 0x00;                    // Display mode: 1/3 lines

  if (device == 1) {
    command(0x22 | rows_1, device); // Function set: extended command set (RE=1), lines #

    command(0x71, device);        // Function selection A:
    data(0x5C, device);           //  enable internal Vdd regulator at 5V I/O mode (def. value) (0x00 for disable, 2.8V I/O)
    command(0x20 | rows_1, device); // Function set: fundamental command set (RE=0) (exit from extended command set), lines #
    command(0x08, device);        // Display ON/OFF control: display off, cursor off, blink off (default values)
    command(0x22 | rows_1, device); // Function set: extended command set (RE=1), lines #
    command(0x79, device);        // OLED characterization: OLED command set enabled (SD=1)
    command(0xD5, device);        // Set display clock divide ratio/oscillator frequency:
    command(0x70, device);        //  divide ratio=1, frequency=7 (default values)
    command(0x78, device);        // OLED characterization: OLED command set disabled (SD=0) (exit from OLED command set)

    if (ROW_N_1 > 2)
      command(0x09, device);  // Extended function set (RE=1): 5-dot font, B/W inverting disabled (def. val.), 3/4 lines
    else
      command(0x08, device);  // Extended function set (RE=1): 5-dot font, B/W inverting disabled (def. val.), 1/2 lines

    command(0x06, device);        // Entry Mode set - COM/SEG direction: COM0->COM31, SEG99->SEG0 (BDC=1, BDS=0)
    command(0x72, device);        // Function selection B:
    data(0x0A, device);           //  ROM/CGRAM selection: ROM C, CGROM=250, CGRAM=6 (ROM=10, OPR=10)
    command(0x79, device);        // OLED characterization: OLED command set enabled (SD=1)
    command(0xDA, device);        // Set SEG pins hardware configuration:
    command(0x10, device);        //  alternative odd/even SEG pin, disable SEG left/right remap (default values)
    command(0xDC, device);        // Function selection C:
    command(0x00, device);        //  internal VSL, GPIO input disable
    command(0x81, device);        // Set contrast control:
    command(0x7F, device);        //  contrast=127 (default value)
    command(0xD9, device);        // Set phase length:
    command(0xF1, device);        //  phase2=15, phase1=1 (default: 0x78)
    command(0xDB, device);        // Set VCOMH deselect level:
    command(0x40, device);        //  VCOMH deselect level=1 x Vcc (default: 0x20=0,77 x Vcc)
    command(0x78, device);        // OLED characterization: OLED command set disabled (SD=0) (exit from OLED command set)
    command(0x20 | rows_1 , device); // Function set: fundamental command set (RE=0) (exit from extended command set), lines #
    command(0x01, device);        // Clear display
    delay(2);             // After a clear display, a minimum pause of 1-2 ms is required
    command(0x80, device);        // Set DDRAM address 0x00 in address counter (cursor home) (default value)
    command(0x0C, device);        // Display ON/OFF control: display ON, cursor off, blink off
    delay(250);           // Waits 250 ms for stabilization purpose after display on
  }

  if (device == 2) {
    command(0x22 | rows_2, device); // Function set: extended command set (RE=1), lines #
   /*i had to remove the comments cause of
    The message exceeds the maximum allowed length (20000 characters).*/
    command(0x71, device);
    data(0x5C, device);
    command(0x20 | rows_2, device);
    command(0x08, device);
    command(0x22 | rows_2, device);
    command(0x79, device);
    command(0xD5, device);
    command(0x70, device);
    command(0x78, device);

    if (ROW_N_2 > 2)
      command(0x09, device);
    else
      command(0x08, device);

    command(0x06, device);
    command(0x72, device);
    data(0x0A, device);
    command(0x79, device);
    command(0xDA, device);
    command(0x10, device);
    command(0xDC, device);
    command(0x00, device);
    command(0x81, device);
    command(0x7F, device);
    command(0xD9, device);
    command(0xF1, device);
    command(0xDB, device);
    command(0x40, device);
    command(0x78, device);
    command(0x20 | rows_2 , device);
    command(0x01, device);
    delay(2);
    command(0x80, device);
    command(0x0C, device);
    delay(250);
  }

  if (ROW_N_1 == 2)
    new_line_1[1] = 0xC0;

  if (ROW_N_2 == 2)
    new_line_2[1] = 0xC0;
}
// _______________________________________________________________________________________

void loop(void)                      // MAIN PROGRAM
{
  output(1); // OLED 1                  Execute subroutine "output"
  output(2); // OLED 2
  delay(2000);                       // Waits, only for visual effect purpose
  blocks(1); // OLED 1                  Execute subroutine "blocks"
  blocks(2); // OLED 2
  delay(2000);                       // Waits, only for visual effect purpose
}


8
OLEDs / Re: NHD-0420CW-AB3 I2C Setup Question
« on: February 28, 2016, 07:39:23 PM »
I see.
On my setup i got the REGVDD connected to GND  for  3.3v.

  datasheet page 4  http://www.newhavendisplay.com/specs/NHD-0420CW-AB3.pdf
  [REGVDD=0V for 2.8V operation]

9
OLEDs / Re: NHD-0420CW-AB3 I2C Setup Question
« on: February 27, 2016, 11:31:04 PM »
Quick question?
Are you running the display on 5 volts or 3.3 volts?

10
OLEDs / Re: NHD-0420CW-AB3 I2C Setup Question
« on: February 27, 2016, 11:28:16 PM »
:)

11
OLEDs / Re: Scrolling on NHD-0420CW-AY3(US2066)
« on: January 29, 2016, 05:16:32 PM »
The IS logic bits are set by Function Set, p27(Bottom of the Page)
Please Note the continuation of Function Set is on the next page 28 (Top of the Page)
The RE logic bits are set on page 28.
Now comes the tricky part, as soon as you set the RE logic bit to 1, you're in control of the bits on page 28.

Hope this helps.

12
OLEDs / Re: Scrolling on NHD-0420CW-AY3(US2066)
« on: January 29, 2016, 04:25:27 PM »
How about Double Height (4-line) / Display-dot shift.
 
Code: [Select]
void OLedI2C::setDoubleH(uint8_t MODE) // 09-19-2015 Chris O. / Double Height Display MODE 0~4
/*---- MODE: "0"=Normal 4-line, "1"=Bottom half Double Height, "2"=Middle Double Height, "3"=Top/Bottom Double Height, "4"=Top Double Height ----*/
{
  sendCommand(0x2A); // Function Set  (extended command set / Extension register, RE ("1")set) B00101010
 //  i'm not sure if needed / Extended Function Set
  sendCommand(B00001001); //Extended Function Set (FW = "0": 5-dot font width, black/white invert cursor DIS,NW = "1": 3-line or 4-line display mode)
  switch (MODE) {
  case 0:    //MODE 0 4x20-line / MODE: "0"=Normal 4-line
    sendCommand(0x28);// Function Set (Go Back to Fundamental Command Set)//101000
    break;
  case 1:    //MODE 1 0x10 / Double Height (4-line)/Display-dot shift
    sendCommand(B00010000); //MODE 1
    sendCommand(0x2C);//101100 Function Set ( when (N=1 :4-line )and(NW=1), Double height =1 Enable, Extension register, RE"0", Extension register, IS"0" )
    break;
  case 2:    //MODE 2 0x14 / Double Height (4-line)/Display-dot shift
    sendCommand(B00010100);   //MODE 2 0x14 / Double Height (4-line)/Display-dot shift
    sendCommand(0x2C);//101100 Function Set ( when (N=1 :4-line )and(NW=1), Double height =1 Enable, Extension register, RE"0", Extension register, IS"0" )
    break;
  case 3:    //MODE 3 0x18 / Double Height (4-line)/Display-dot shift (DH’ = "0": dot scroll enable (POWER UP))
    sendCommand(B00011000);
    //sendCommand(B00011001); //MODE 3 0x19 / Double Height (4-line)/Display-dot shift (DH’ = "1": display shift enable)
    sendCommand(0x2C);//101100 Function Set ( when (N=1 :4-line )and(NW=1), Double height =1 Enable, Extension register, RE"0", Extension register, IS"0" )
    break;
  case 4:
    sendCommand(B00011100);  //MODE 4 0x1C / Double Height (4-line)/Display-dot shift(DH’ = "0": display shift DIS)
    sendCommand(0x2C);//101100 Function Set ( when (N=1 :4-line )and(NW=1), Double height =1 Enable, Extension register, RE"0", Extension register, IS"0" )
    break;
  }
}

13
OLEDs / Re: Scrolling on NHD-0420CW-AY3(US2066)
« on: January 29, 2016, 04:14:50 PM »
Let's start with an easy one. :P
SD logic bits are set by Extension register in OLED Characterization p.29 hex 0x78 b1111000 / 0x79 b1111001

example Set Contrast Control:

Code: [Select]
void OLedI2C::setContrast(unsigned char contrast) // contrast as 0x00 to 0xFF
{
  //Set OLED Command set
  sendCommand(0x2A);        //Function Set  N = 1, BE = 0, RE = 1 Set, REV = "0": normal display (POR)  B00101010
  sendCommand(0x79);        //OLED Characterization / 0x79 B1111001 =  OLED command set is enabled
  sendCommand(0x81);  // Set Contrast
  sendCommand(contrast); // send contrast value
  sendCommand(0x78);  // OLED Characterization / 0x78 B1111000 =Exiting Set OLED Command set disabled (POR)
  sendCommand(0x28);       // Function Set / B101000 (Go Back to Fundamental Command Set)
}

14
OLEDs / Re: Library that works fine on the NHD-0420CW-A*3
« on: April 02, 2015, 12:09:51 AM »
I'm glad you figured that out. ;)

15
OLEDs / Re: Library that works fine on the NHD-0420CW-A*3
« on: April 02, 2015, 12:00:38 AM »
 :o :)

Pages: [1] 2 3