0

Blue Character OLED 16X2 Intensity
Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.

Blue Character OLED 16X2 Intensity

by tstover2015zz on Sun Aug 04, 2019 2:56 pm

Hi,
I'm using this Adafruit part and it works well with the Adafruit library. Question: is it possible to vary the LED intensity? I've read through the two WS documents (WS0010 Specification) referenced on the product listing page and can't find any mention of LED intensity. I'm using the display as alarm clock display in a bedroom and want to adjust the LED intensity as function of ambient lighting. Thanks.

tstover2015zz
 
Posts: 4
Joined: Tue Sep 25, 2018 12:32 pm

Re: Blue Character OLED 16X2 Intensity

by adafruit_support_bill on Sun Aug 04, 2019 3:20 pm

These do not have any control for the display intensity. You could use one of the 'negative' LCD displays. While not quite as crisp as the OLEDs, you do have control over the backlight intensity.
https://www.adafruit.com/product/399

adafruit_support_bill
 
Posts: 74020
Joined: Sat Feb 07, 2009 10:11 am

Re: Blue Character OLED 16X2 Intensity

by tstover2015zz on Wed Aug 14, 2019 12:39 am

Hi, Thanks for the reply.

A question about the display and Adafruit library.
I'm using the display with a metro mini and the Adafruit_CharacterOLED library. I noticed two standard LCD commands (listed in the Adafruit_CharacterOLED.cpp file) do not work or cause a compile error. The command lcd.cursor() causes a compile error. The command lcd.blink() causes the display to go dark. To demonstrate, I added these cmds to the HelloOLEDWorld.ino file included with the Adafruit_CharacterOLED library; see the function void Setup(). Also, I think the keyword.txt file has an error, tab character is missing in the line "Adafruit_CharacterOLED KEYWORD1", so no highlighting on that keyword.

Please let me know if I've misunderstood. Does Adafruit have a list of commands that are not operative in the Adafruit_CharacterOLED.cpp?

Thanks for your help.
Code: Select all | TOGGLE FULL SIZE
//
Based on the LiquidCrystal Library - Hello World
 
 Demonstrates the use a Winstar 16x2 OLED display.  These are similar, but
 not quite 100% compatible with the Hitachi HD44780 based LCD displays.
 
 This sketch prints "Hello OLED World" to the LCD
 and shows the time in seconds since startup.
 
  The circuit:
 * LCD RS pin to digital pin 6
 * LCD R/W pin to digital pin 7
 * LCD Enable pin to digital pin 8
 * LCD D4 pin to digital pin 9
 * LCD D5 pin to digital pin 10
 * LCD D6 pin to digital pin 11
 * LCD D7 pin to digital pin 12

 There is no need for the contrast pot as used in the LCD tutorial
 
 Library originally added 18 Apr 2008
 by David A. Mellis
 library modified 5 Jul 2009
 by Limor Fried (http://www.ladyada.net)
 example added 9 Jul 2009
 by Tom Igoe
 modified 22 Nov 2010
 by Tom Igoe
 Library & Example Converted for OLED
 by Bill Earl 30 Jun 2012
 
 This example code is in the public domain.
 */

// include the library code:
#include <Adafruit_CharacterOLED.h>

// initialize the library with the OLED hardware
// version OLED_Vx and numbers of the interface pins.
// OLED_V1 = older, OLED_V2 = newer. If 2 doesn't work try 1 ;)
Adafruit_CharacterOLED lcd(OLED_V2, 6, 7, 8, 9, 10, 11, 12);

void setup()
{
  // Print a message to the LCD.
  lcd.begin(16, 2);
  lcd.print("hello OLED World");
  //lcd.cursor();
  //lcd.blink();
}

void loop()
{
  // set the cursor to column 0, line 1
  // (note: line 1 is the second row, since counting begins with 0):
  lcd.setCursor(0, 1);
  // print the number of seconds since reset:
  lcd.print(millis()/1000);
}
Last edited by adafruit_support_bill on Wed Aug 14, 2019 7:28 am, edited 1 time in total.
Reason: fixed [code] tags

tstover2015zz
 
Posts: 4
Joined: Tue Sep 25, 2018 12:32 pm

Re: Blue Character OLED 16X2 Intensity

by adafruit_support_bill on Wed Aug 14, 2019 7:55 am

As noted in the comments of the example code. The Winstar OLED displays are not quite compatible with the industry standard Hitachi HD44780 LCD display protocol. For that matter, they are not even compatible with their own published documentation. To further compound the problem, there have been several variations on the Winstar controller chip - all with identical markings but somewhat different behavior. These are beautiful displays, but can be quite frustrating to work with.

Code: Select all | TOGGLE FULL SIZE
The command lcd.cursor() causes a compile error.

What compile error are you getting? I'm not able to reproduce that here.

Code: Select all | TOGGLE FULL SIZE
The command lcd.blink() causes the display to go dark.

Blinking and scrolling seem to be weak points of these displays. Some variants seem to handle it better than others.

adafruit_support_bill
 
Posts: 74020
Joined: Sat Feb 07, 2009 10:11 am

Re: Blue Character OLED 16X2 Intensity

by tstover2015zz on Wed Aug 14, 2019 2:37 pm

Hi, Thanks for the quick reply.

I tried the modified example again and can't duplicate the compile error. It was late in the evening when I saw the compile error, which didn't include an error number. This morning both commands lcd.cursor() and lcd.blink() make the display dark.

Based on your comments, the mfg quality of this part is inconsistent, which Adafruit can't manage that directly. Its a pity, the display has sharp characters, black is black and I like the shade of blue. I don't see many OLED character displays for sale on internet. Is an OLED TFT graphic displays the best alternative if I want OLED?

tstover2015zz
 
Posts: 4
Joined: Tue Sep 25, 2018 12:32 pm

Re: Blue Character OLED 16X2 Intensity

by adafruit_support_bill on Wed Aug 14, 2019 4:32 pm

It is unfortunate, but true. The last time I looked, Winstar was the only manufacturer of OLED character displays. They are some of the nicest looking character displays out there - provided that you don't need anything more than the basic display functions.

We have a number of graphical OLED displays - both monochrome and color: https://www.adafruit.com/?q=OLED

If you need the contrast for outdoor visibility reasons, the paper-white reflective displays are another option: https://www.adafruit.com/?q=epaper
These are the ultimate low-power display. You can completely power them down and they will retain the image for years.

adafruit_support_bill
 
Posts: 74020
Joined: Sat Feb 07, 2009 10:11 am

Re: Blue Character OLED 16X2 Intensity

by tstover2015zz on Sat Aug 17, 2019 7:50 pm

Hi, Thanks for the quick reply.

About the OLED 16x2 display from winstar. I looked at the the WS0010 (controller) data sheet and the Adafruit library files. I was able to find the problem causing some library user commands to not work. This includes : lcd.display(), lcd.noDisplay(), lcd.cursor(), lcd.noCursor(), lcd.blink(), lcd.noBlink()..... The variable _displaycontrol was never initialized in Adafruit_characterOLED.cpp. So, any subsequent user display commands disabled the display (displayOn bit to zero). The user commands use bitwise logic to preserve previous display states (like keep the display on) while enabling cursor, or character flashing. I've attached the fix (one missing line). With the updated .ccp file these commands now work. I've marked the line with a comment. To test the update, I used the OLED example file (hello_world), commented out the void Loop() and tested the commands just below the command that send "hello world' to the LCD.

Winstar has published a newer version of the WS0010 manual, revision B. The version on Adafruit is revision 1 (2 back). I've attached the file. I hope Adafruit is able add this file to your website.

One other interesting issue. Before I found the problem in the .ccp, I was changing display control codes in the .h file and stumbled on a reduced intensity mode. The display entered the mode during reset, after I sent a new control code. I had to pwr cycle the display to exit the mode. So, I don't know how to enter the mode directly, but made me think Winstar has an unpublished command to control display intensity.

Thanks for your help.

Code: Select all | TOGGLE FULL SIZE
// Derived from LiquidCrystal by David Mellis
// With portions adapted from Elco Jacobs OLEDFourBit
// Modified for 4-bit operation of the Winstar 16x2 Character OLED
// By W. Earl for Adafruit - 6/30/12
// Initialization sequence fixed by Technobly - 9/22/2013

#include "Adafruit_CharacterOLED.h"

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

// On power up, the display is initilaized as:
// 1. Display clear
// 2. Function set:
//    DL="1": 8-bit interface data
//    N="0": 1-line display
//    F="0": 5 x 8 dot character font
// 3. Power turn off
//    PWR=”0”
// 4. Display on/off control: D="0": Display off C="0": Cursor off B="0": Blinking off
// 5. Entry mode set
//    I/D="1": Increment by 1
//    S="0": No shift
// 6. Cursor/Display shift/Mode / Pwr
//    S/C=”0”, R/L=”1”: Shifts cursor position to the right
//    G/C=”0”: Character mode
//    Pwr=”1”: Internal DCDC power on
//
// Note, however, that resetting the Arduino doesn't reset the LCD, so we
// can't assume that its in that state when a sketch starts (and the
// LiquidCrystal constructor is called).

Adafruit_CharacterOLED::Adafruit_CharacterOLED(uint8_t ver, uint8_t rs, uint8_t rw, uint8_t enable,
              uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7)
{
  init(ver, rs, rw, enable, d4, d5, d6, d7);
}

void Adafruit_CharacterOLED::init(uint8_t ver, uint8_t rs, uint8_t rw, uint8_t enable,
          uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7)
{
  _oled_ver = ver;
  if(_oled_ver != OLED_V1 && _oled_ver != OLED_V2) {
    _oled_ver = OLED_V2; // if error, default to newer version
  }
  _rs_pin = rs;
  _rw_pin = rw;
  _enable_pin = enable;
 
  _data_pins[0] = d4;
  _data_pins[1] = d5;
  _data_pins[2] = d6;
  _data_pins[3] = _busy_pin = d7;

  pinMode(_rs_pin, OUTPUT);
  pinMode(_rw_pin, OUTPUT);
  pinMode(_enable_pin, OUTPUT);
 
  _displayfunction = LCD_FUNCTIONSET | LCD_4BITMODE;
   
  begin(16, 2); 
}

void Adafruit_CharacterOLED::begin(uint8_t cols, uint8_t lines)
{
  _numlines = lines;
  _currline = 0;
 
  pinMode(_rs_pin, OUTPUT);
  pinMode(_rw_pin, OUTPUT);
  pinMode(_enable_pin, OUTPUT);
 
  digitalWrite(_rs_pin, LOW);
  digitalWrite(_enable_pin, LOW);
  digitalWrite(_rw_pin, LOW);
 
  delayMicroseconds(50000); // give it some time to power up
 
  // Now we pull both RS and R/W low to begin commands
 
  for (int i = 0; i < 4; i++) {
    pinMode(_data_pins[i], OUTPUT);
    digitalWrite(_data_pins[i], LOW);
  }

  // Initialization sequence is not quite as documented by Winstar.
  // Documented sequence only works on initial power-up. 
  // An additional step of putting back into 8-bit mode first is
  // required to handle a warm-restart.
  //
  // In the data sheet, the timing specs are all zeros(!).  These have been tested to
  // reliably handle both warm & cold starts.

  // 4-Bit initialization sequence from Technobly
  write4bits(0x03); // Put back into 8-bit mode
  delayMicroseconds(5000);
  if(_oled_ver == OLED_V2) {  // only run extra command for newer displays
    write4bits(0x08);
    delayMicroseconds(5000);
  }
  write4bits(0x02); // Put into 4-bit mode
  delayMicroseconds(5000);
  write4bits(0x02);
  delayMicroseconds(5000);
  write4bits(0x08);
  delayMicroseconds(5000);
 
  command(0x08);   // Turn Off
  delayMicroseconds(5000);
  command(0x01);   // Clear Display
  delayMicroseconds(5000);
  command(0x06);   // Set Entry Mode
  delayMicroseconds(5000);
  command(0x02);   // Home Cursor
  delayMicroseconds(5000);
  command(0x0C);   // Turn On - enable cursor & blink
  delayMicroseconds(5000);

 // The following cmd was missing from released version.  Since _displaycontrol was never initialized
 // subsequent display commands lcd.cursor(), lcd.blink() are not operative. -----------------------t.stover
 // turn the display on with no cursor or blinking default
  _displaycontrol = LCD_DISPLAYON | LCD_CURSOROFF | LCD_BLINKOFF; 

}

/********** high level commands, for the user! */
void Adafruit_CharacterOLED::clear()
{
  command(LCD_CLEARDISPLAY);  // clear display, set cursor position to zero
  //  delayMicroseconds(2000);  // this command takes a long time!
}

void Adafruit_CharacterOLED::home()
{
  command(LCD_RETURNHOME);  // set cursor position to zero
  //  delayMicroseconds(2000);  // this command takes a long time!
}

void Adafruit_CharacterOLED::setCursor(uint8_t col, uint8_t row)
{
  uint8_t row_offsets[] = { 0x00, 0x40, 0x14, 0x54 };
  if ( row >= _numlines )
  {
    row = 0;  //write to first line if out off bounds
  }
 
  command(LCD_SETDDRAMADDR | (col + row_offsets[row]));
}

// Turn the display on/off (quickly) ------------------ON/OFF-------------------------
void Adafruit_CharacterOLED::noDisplay()
{
  _displaycontrol &= ~LCD_DISPLAYON;
  command(LCD_DISPLAYCONTROL | _displaycontrol);
}
void Adafruit_CharacterOLED::display()
{
  _displaycontrol |= LCD_DISPLAYON;
  command(LCD_DISPLAYCONTROL | _displaycontrol);
}

// Turns the underline cursor on/off  ---------------------CURSOR------------------------------------
void Adafruit_CharacterOLED::noCursor()
{
  _displaycontrol &= ~LCD_CURSORON;
  command(LCD_DISPLAYCONTROL | _displaycontrol);
}
void Adafruit_CharacterOLED::cursor()
{
  _displaycontrol |= LCD_CURSORON;
  command(LCD_DISPLAYCONTROL | _displaycontrol);
}

// Turn on and off the blinking cursor -------------------------BLINK------------------------
void Adafruit_CharacterOLED::noBlink()
{
  _displaycontrol &= ~LCD_BLINKON;
  command(LCD_DISPLAYCONTROL | _displaycontrol);
}
void Adafruit_CharacterOLED::blink()
{
  _displaycontrol |= LCD_BLINKON;
  command(LCD_DISPLAYCONTROL | _displaycontrol);
}

// These commands scroll the display without changing the RAM
void Adafruit_CharacterOLED::scrollDisplayLeft(void)
{
  command(LCD_CURSORSHIFT | LCD_DISPLAYMOVE | LCD_MOVELEFT);
}
void Adafruit_CharacterOLED::scrollDisplayRight(void)
{
  command(LCD_CURSORSHIFT | LCD_DISPLAYMOVE | LCD_MOVERIGHT);
}

// This is for text that flows Left to Right
void Adafruit_CharacterOLED::leftToRight(void)
{
  _displaymode |= LCD_ENTRYLEFT;
  command(LCD_ENTRYMODESET | _displaymode);
}

// This is for text that flows Right to Left
void Adafruit_CharacterOLED::rightToLeft(void)
{
  _displaymode &= ~LCD_ENTRYLEFT;
  command(LCD_ENTRYMODESET | _displaymode);
}

// This will 'right justify' text from the cursor
void Adafruit_CharacterOLED::autoscroll(void)
{
  _displaymode |= LCD_ENTRYSHIFTINCREMENT;
  command(LCD_ENTRYMODESET | _displaymode);
}

// This will 'left justify' text from the cursor
void Adafruit_CharacterOLED::noAutoscroll(void)
{
  _displaymode &= ~LCD_ENTRYSHIFTINCREMENT;
  command(LCD_ENTRYMODESET | _displaymode);
}

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

/*********** mid level commands, for sending data/cmds */

inline void Adafruit_CharacterOLED::command(uint8_t value)
{
  send(value, LOW);
  waitForReady();
}

inline size_t Adafruit_CharacterOLED::write(uint8_t value)
{
  send(value, HIGH);
  waitForReady();
}

/************ low level data pushing commands **********/

// write either command or data
void Adafruit_CharacterOLED::send(uint8_t value, uint8_t mode)
{
  digitalWrite(_rs_pin, mode);
  pinMode(_rw_pin, OUTPUT);
  digitalWrite(_rw_pin, LOW);
 
  write4bits(value>>4);
  write4bits(value);
}

void Adafruit_CharacterOLED::pulseEnable(void)
{
  digitalWrite(_enable_pin, HIGH);
  delayMicroseconds(50);    // Timing Spec?
  digitalWrite(_enable_pin, LOW);
}

void Adafruit_CharacterOLED::write4bits(uint8_t value)
{
  for (int i = 0; i < 4; i++)
  {
    pinMode(_data_pins[i], OUTPUT);
    digitalWrite(_data_pins[i], (value >> i) & 0x01);
  }
  delayMicroseconds(50); // Timing spec?
  pulseEnable();
}

// Poll the busy bit until it goes LOW
void Adafruit_CharacterOLED::waitForReady(void)
{
  unsigned char busy = 1;
  pinMode(_busy_pin, INPUT);
  digitalWrite(_rs_pin, LOW);   
  digitalWrite(_rw_pin, HIGH);     
  do
  {
     digitalWrite(_enable_pin, LOW);
     digitalWrite(_enable_pin, HIGH);

     delayMicroseconds(10);
     busy = digitalRead(_busy_pin);
     digitalWrite(_enable_pin, LOW);
     
     pulseEnable();      // get remaining 4 bits, which are not used.
  }
  while(busy);
 
  pinMode(_busy_pin, OUTPUT);
  digitalWrite(_rw_pin, LOW);
}


WS0010_RevB.pdf
(1.13 MiB) Not downloaded yet

tstover2015zz
 
Posts: 4
Joined: Tue Sep 25, 2018 12:32 pm

Please be positive and constructive with your questions and comments.