NHD-0216SZW - pixels instead of characters?
Hi, we're using an NHD-0216SZW-BY5-Rev1A OLED in 8-bit mode in a new product. When we power it up at the same time as the rest of our prototype hardware, then follow the initialization sequence in the datasheet, then try to write characters to DDRAM, we get vertical columns of 8 pixels instead of characters, with the pixels corresponding to the binary value of the character. If we power up the OLED after the rest of the system, it works as expected. It looks to me like we are accidentally entering some kind of undocumented pixel graphics mode? Has anyone else seen this problem? Thanks!
-
Hi,
We have not encountered this type of issue before. Could you please provide an image of the display screen that is not functioning properly? To troubleshoot the issue, could you please share the initialization section of your code? If possible, could you please try swapping a different display to see if the issue persists?
0 -
Hi, here's a photo of the OLED after initialization and some text has been written to DDRAM.
Our initialization code looks something like this:
/*! Command used to set DDRAM address position. */
#define CMD_SET_DDRAM_ADDR (0x80U)
/*! Command used to set display on. */
#define CMD_DISPLAY_DISP_ON (0x04U)
/*! Command used to set cursor on. */
#define CMD_DISPLAY_CURS_ON (0x02U)
/*! Command used to set blink on. */
#define CMD_DISPLAY_BLNK_ON (0x01U)
/*! Command used to control display. */
#define CMD_DISPLAY_CONTROL (0x08U)
/*! Command to select data interface (8 bits) and font table 1 (Western European table 1) */
#define CMD_FUNCTION_SET (0x39U)
/*! Command to clear display. */
#define CMD_CLEAR_DISPLAY (0x01U)
/*! Command to home display. */
#define CMD_HOME_DISPLAY (0x02U)
/*! Command to set entry mode, auto-increment no shift. */
#define CMD_ENTRY_MODE (0x06U)
/*! Command to shift display. */
#define CMD_SHIFT_CONTROL (0x10U)
/*! Command to shift display left. */
#define CMD_SHIFT_LEFT (0x08U)
/*! State bit indicating LCD is busy. */
/*! @brief Initialises a GPIO output line.
* @param pName - Text name for the GPIO.
* @param ppLine - Pointer to gpiod line pointer.
* @param pChipName - Chip name of the gpiod line.
* @param gpio - Index number of the gpiod line.
* @param init - Initial value of the line. */
static void CLCD_InitialiseGPIO(const char* pName, struct gpiod_line** ppLine,
const char* pChipName, int gpio, int init)
{
/* Only attempt to open the gpio once. */
if (*ppLine == 0)
{
/* Open GPIO chip. */
struct gpiod_chip* pChip = gpiod_chip_open_by_name(pChipName);
if (pChip)
{
/* Allocate the line. */
*ppLine = gpiod_chip_get_line(pChip, gpio);
if(*ppLine)
{
gpiod_line_request_output(*ppLine, pName, init);
}
}
}
}
/*! @brief Writes control commands to the LCD display.
* @param command - the command to write. */
static void CLCD_controlWrite(unsigned char command)
{
/* Enable the LCD level-shifter. */
gpiod_line_set_value(lcdOE, DISPLAY_LCD_OE_ON);
/* Wait for the LCD to be ready. */
CLCD_BusyWait();
/* Set up the LCD for a control write. */
gpiod_line_set_value(lcdRS, DISPLAY_LCD_RS_CONT);
gpiod_line_set_value(lcdRDRW, DISPLAY_LCD_RD_RW_WRITE);
DataBusDirectionSet(DATA_BUS_WRITE);
/* Output the command. */
DataBusWrite(command);
/* Clock the data into the LCD. */
gpiod_line_set_value(lcdE, DISPLAY_LCD_E_HIGH);
BIT_OUTPUT_DELAY();
gpiod_line_set_value(lcdE, DISPLAY_LCD_E_LOW);
BIT_OUTPUT_DELAY();
/* Revert the bus to reading. */
DataBusDirectionSet(DATA_BUS_READ);
gpiod_line_set_value(lcdRDRW, DISPLAY_LCD_RD_RW_READ);
/* Disable the LCD level-shifter. */
gpiod_line_set_value(lcdOE, DISPLAY_LCD_OE_OFF);
}
/*! @brief Initialises display module. */
void CLCD_INITHARD(void)
{
/* Initialise all the GPIOs. */
CLCD_InitialiseGPIO("LCD_OE", &lcdOE,
DISPLAY_LCD_OE_CHIP,
DISPLAY_LCD_OE_GPIO,
DISPLAY_LCD_OE_OFF);
CLCD_InitialiseGPIO("LCD_E", &lcdE,
DISPLAY_LCD_E_CHIP,
DISPLAY_LCD_E_GPIO,
DISPLAY_LCD_E_HIGH);
CLCD_InitialiseGPIO("LCD_RS", &lcdRS,
DISPLAY_LCD_RS_CHIP,
DISPLAY_LCD_RS_GPIO,
DISPLAY_LCD_RS_CONT);
CLCD_InitialiseGPIO("LCD_RDRW", &lcdRDRW,
DISPLAY_LCD_RD_RW_CHIP,
DISPLAY_LCD_RD_RW_GPIO,
DISPLAY_LCD_RD_RW_READ);
/* Initialise the display. */
CLCD_controlWrite(CMD_FUNCTION_SET);
/* Display off, cursor off, blinking off. */
CLCD_controlWrite(CMD_DISPLAY_CONTROL);
CLCD_controlWrite(CMD_CLEAR_DISPLAY);
CLCD_controlWrite(CMD_ENTRY_MODE);
CLCD_controlWrite(CMD_HOME_DISPLAY);
/* Display on, cursor off, blinking off. */
CLCD_controlWrite(CMD_DISPLAY_CONTROL | CMD_DISPLAY_DISP_ON);
/* Set address to zero and home display. */
CLCD_controlWrite(CMD_SET_DDRAM_ADDR);
}I'll see if I can find another OLED to swap it with.
Thanks!0 -
Hi,
The initialization code seems to be correct. If you would like, you can test our sample code to determine if the problem lies with the display or your software. Can you please verify if you are allowing enough time delay before executing the commands?
0 -
HI, our initialization code is actually typically running several seconds or even minutes after power on. I don't have an Arduino to hand, but I will compare the sample code to our own.
0 -
I have now tested with a second OLED module, and it's exhibiting the same behavior.
0 -
Hi,
Sorry to hear that you are still experiencing issues with the display. Could you please confirm the voltage and current on the display before and after resetting your entire system?
0
Please sign in to leave a comment.
Comments
6 comments