ST7066U compatibility issues

Tjoek

New member
We recently bought or first set of CFAH1602B-YTI-JT character displays for use in our outdoor lasertag system. But where the -JP display worked nicely, the new -JT type does not. The newer display remains in an uninitialized state.
The new ST7066U controller seems to behave differently then it's predecessor, although they should both be HD44780 compatible.

Does anyone know were this problem may be related to? Or can anyone tell me how they initialized this new controller? We use a PIC 18F2525 microcontroller to control or display.

Kind Regards,

Joost Carpaij
Looking for additional LCD resources? Check out our LCD blog for the latest developments in LCD technology.
 

CF Tech

Administrator
The initialization routines should be pretty close, or identical.

Are you using 4-bit or 8-bit?

Can you post your initialization routine?

Have you checked that adjusting the contrast (Pin 3) does not fix it?
 

Tjoek

New member
No it has nothing to do with the contrast, as it was the first thing I checked.

My code is in PIC asm, but I can tell you what I do step by step.
By the way I use the Display in 4 bit mode.

1.) Lower the RS line and wait for 127 msec

2.) Put 0011 on the 4 data lines and directly raise the Enable line

3.) After 0.5 usec I lower the Enable line and wait for 5 msec

4.) Put 0011 on the 4 data lines and directly raise the Enable line

5.) After 0.5usec I lower the Enable line and wait for 1 msec

6.) Put 0011 on the 4 data lines and directly raise the Enable line

7.) After 0.5 usec I lower the Enable line and wait for 41.5 usec

8.) Put 0010 on the 4 data lines and directly raise the Enable line

9.) After 0.5 usec I lower the Enable line and wait for 41.5 usec

// set LCD to 4 bit 2 line 5X8 matrix characters
10.) Put 0010 on the 4 data lines and directly raise the Enable line

11.) After 0.5 usec I lower the Enable line and directly put 1000 on the 4 data lines and raise the Enable line

12.) After 0.5 usec I lower the Enable line and wait for 41.5 usec

Hopefully the above initialization steps give you enough information to help me out with this problem.
As we didn't have this problem with a couple of other displays even from other companies.
 

CF Tech

Administrator
Here is a bit of 8-bit C code I made for a PIC:
Code:
typedef unsigned char ubyte;
typedef signed char sbyte;
typedef unsigned short word;
typedef unsigned long dword;
//============================================================================
ubyte Read_LCD_Address(void)
  {
  ubyte
    return_value;
  ubyte
    timeout;
  //Poll the LCD's busy line until it is clear.
  //Make register select 0
  porta&=~PORTA_LCD_RS;
  //Make R/W 1=read, update physical port.
  PORTA=(porta|=PORTA_LCD_RW);
  //Set PORTB to all inputs.
  TRISB=(trisb=0xFF);
  //Enable the controller's data onto the bus.
  PORTA=(porta|=PORTA_LCD_E);
  //Test the port's bit, wait for the bit to go low
  if(PORTB&PORTB_LCD_DATA_BUSY)
    for(timeout=255;(PORTB&PORTB_LCD_DATA_BUSY)&&timeout;timeout--);
  //Read the LCD controller's data, mask off the busy bit.
  return_value=PORTB&0x7F;
  //Get the bus back from the controller
  PORTA=(porta&=~PORTA_LCD_E);
  //Turn port B back to its default output state.
  TRISB=(trisb=0);
  return(return_value);
  }
//============================================================================
void Write_LCD_Data(ubyte data)
  {
  ubyte
    timeout;
  //Poll the LCD's busy line until it is clear.
  //Make register select 0
  porta&=~PORTA_LCD_RS;
  //Make R/W 1=read, update physical port.
  PORTA=(porta|=PORTA_LCD_RW);
  //Set PORTB to all inputs.
  TRISB=(trisb=0xFF);
  //Enable the controller's data onto the bus.
  PORTA=(porta|=PORTA_LCD_E);
  //Test the port's bit, wait for the bit to go low
  if(PORTB&PORTB_LCD_DATA_BUSY)
    for(timeout=255;(PORTB&PORTB_LCD_DATA_BUSY)&&timeout;timeout--);
  //Get the bus back from the controller
  PORTA=(porta&=~PORTA_LCD_E);
  //Turn port B back to its default output state.
  TRISB=(trisb=0);
  //Write the data to the port.
  PORTB=data;
  //Make register select 1
  porta|=PORTA_LCD_RS;
  //Make R/W 0=write, update physical port.
  PORTA=(porta&=~PORTA_LCD_RW);
  //Strobe enable
  PORTA=(porta|=PORTA_LCD_E);
  PORTA=(porta&=~PORTA_LCD_E);
  }
//============================================================================
void Write_LCD_Control(ubyte data)
  {
  ubyte
    timeout;
  //Poll the LCD's busy line until it is clear.
  //Make register select 0
  porta&=~PORTA_LCD_RS;
  //Make R/W 1=read, update physical port.
  PORTA=(porta|=PORTA_LCD_RW);
  //Set PORTB to all inputs.
  TRISB=(trisb=0xFF);
  //Enable the controller's data onto the bus.
  PORTA=(porta|=PORTA_LCD_E);
  //Test the port's bit, wait for the bit to go low
  if(PORTB&PORTB_LCD_DATA_BUSY)
    for(timeout=255;(PORTB&PORTB_LCD_DATA_BUSY)&&timeout;timeout--);
  if(PORTB&PORTB_LCD_DATA_BUSY)
    for(timeout=255;(PORTB&PORTB_LCD_DATA_BUSY)&&timeout;timeout--);
  if(PORTB&PORTB_LCD_DATA_BUSY)
    for(timeout=255;(PORTB&PORTB_LCD_DATA_BUSY)&&timeout;timeout--);
  //Get the bus back from the controller
  PORTA=(porta&=~PORTA_LCD_E);
  //Turn port B back to its default output state.
  TRISB=(trisb=0);
  //Write the data to the port.
  PORTB=data;
  //Make R/W 0=write
  PORTA=(porta&=~PORTA_LCD_RW);
  //Strobe enable
  PORTA=(porta|=PORTA_LCD_E);
  PORTA=(porta&=~PORTA_LCD_E);
  }
//============================================================================
void Blind_Write_LCD_Control(ubyte data)
  {
  //Make register select 0, Make R/W 0=write
  PORTA=(porta&=~(PORTA_LCD_RS|PORTA_LCD_RW));
  //Write the data to the port.
  PORTB=data;
  //Strobe enable
  PORTA=(porta|=PORTA_LCD_E);
  PORTA=(porta&=~PORTA_LCD_E);
  }
//============================================================================
void LCD_Initialize(void)
  {
  static const char
    default_special_characters[8][8]=
      {
        {0, 8,12,14,15,14,12, 8},  //right arrow
        {0, 1, 3, 7,15, 7, 3, 1},  //left arrow
        {0, 4, 4,14,14,31,31, 0},  //up arrow
        {0,31,31,14,14, 4, 4, 0},  //down arrow
        {0, 0,14,31,31,31,14, 0},  //circle
        {0, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 0, 0}
      };
  ubyte
    i;
  ubyte
    j;

  PWM_Initilaize();
  //This sequence is from the initialization on page 45 of the HD44780U
  //data sheet.
  DelayMs(20);
  Blind_Write_LCD_Control(0x30);
  //Yes, the data sheet says write it twice.
  DelayMs(5);
  Blind_Write_LCD_Control(0x30);
  //Yes, the data sheet says write it three times.
  DelayUs(125);
  Blind_Write_LCD_Control(0x30);
  //Yes, the data sheet says write it four times, but at least this one counts.
  //038h is Function set:
  //8 bit,
  //2 line
  //F = (5x8)
  DelayUs(125);
  Blind_Write_LCD_Control(0x38);
  //"Display off"
  Write_LCD_Control(0x08);
  //"Display clear"
  Write_LCD_Control(0x01);
  //This delay is needed  for the Sitronix ST7066 Display. No reasonable
  //explanation, I found it empirically.
  DelayMs(2);
  //006h is Entry mode set, increment, no shift
  Write_LCD_Control(0x06);
  //Display on, cursor on, blinking
  Write_LCD_Control(0x0F);
  //Clear the display again. This seems to fix a power-up problem
  //where the display shows "{{{{{" in a couple of places.
  Write_LCD_Control(0x01);
  //Why is this needed?
  DelayMs(2);
  //Initialize the first 7 custom characters.
  //Address the data area for the custom character 0.
  Write_LCD_Control(0x40);
  for(j=0;j<=7;j++)
    for(i=0;i<=7;i++)
      Write_LCD_Data(default_special_characters[j][i]);
  }
//============================================================================
void LCD_Position_Cursor(ubyte x, ubyte y)
  {
  //Valid x is 0-15, valid y is 0-1
  if((x<=15)&&(y<=1))
    Write_LCD_Control(0x80|(y<<6)|x);
  }
//============================================================================
//Could make this aware of display size & wrapping.
void LCD_puts(const char *input_string)
  {
  while(*input_string)
    Write_LCD_Data(*input_string++);
  }
//============================================================================
void LCD_Clear(void)
  {
  //Clears the LCD & positions the cursor at 0,0
  Write_LCD_Control(0x01);
  }
//============================================================================
//Prints a 3 character string of input at the current location.
void LCD_put_dec(ubyte input)
  {
  ubyte
    digit;
  ubyte
    no_blank;
  digit=input/100;
  if(digit)
    {
    Write_LCD_Data(digit+'0');
    no_blank=1;
    }
  else
    {
    Write_LCD_Data(' ');
    no_blank=0;
    }
  input%=100;
  digit=input/10;
  if(digit|no_blank)
    Write_LCD_Data(digit+'0');
  else
    Write_LCD_Data(' ');
  Write_LCD_Data(input%10+'0');
  }
//============================================================================
Here is some 4-bit C code that is not for a PIC, but once the macros are ported to your platform, it should work too:
Code:
//============================================================================
typedef unsigned char ubyte;
typedef signed char sbyte;
typedef unsigned short word;
typedef unsigned long dword;
/============================================================================
//LCD Control line macros
#define SET_LCD_E \
  { \
  /* fill out with your port access code */ \
  }
#define CLEAR_LCD_E \
  { \
  /* fill out with your port access code */ \
  }
#define SET_LCD_RS \
  { \
  /* fill out with your port access code */ \
  }
#define CLEAR_LCD_RS \
  { \
  /* fill out with your port access code */ \
  }
#define SET_LCD_RW \
  { \
  /* fill out with your port access code */ \
  }
#define CLEAR_LCD_RW \
  { \
  /* fill out with your port access code */ \
  }

//Apply the high 4 bits of data to the low four bits of the port.
#define OUT_HIGH_NIBBLE (PRT1DR=(port1=(port1&0xF0)|(data>>4)))

//Apply the low 4 bits of data to the low four bits of the port.
#define OUT_LOW_NIBBLE (PRT1DR=(port1=(port1&0xF0)|(data&0x0F)))

//Read the high nibble of the data is on the low nibble of Port 1.
//Mask off the lower bits and store it.
#define IN_HIGH_NIBBLE (read_data=(PRT1DR&0x0F)<<4)

//Read the low nibble of the data is on the low nibble of Port 1.
#define IN_LOW_NIBBLE (read_data|=PRT1DR&0x0F)

#define SET_PORT1_FOR_LCD_WRITE \
  { \
  /* fill out with your port access code */ \
  }

#define SET_PORT1_FOR_LCD_READ \
  { \
  /* fill out with your port access code */ \
  }

#define PORT1_LCD_DATA_BUSY 0x08
//============================================================================
void Wait_For_Not_Busy(void)
  {
  uword
    timeout;
  //Poll the LCD's busy line until it is clear.
  //Make register select 0
  CLEAR_LCD_RS;
  //Make R/W 1=read.
  SET_LCD_RW;
  //Change the data bits to inputs.
  SET_PORT1_FOR_LCD_READ;
  //Enable the controller's data onto the bus.
  SET_LCD_E;
  //Test the port's bit, wait for the bit to go low
  if(PRT1DR&PORT1_LCD_DATA_BUSY)
    for(timeout=1000;(PRT1DR&PORT1_LCD_DATA_BUSY)&&timeout;timeout--);
  }
//============================================================================
ubyte Read_LCD_Address(void)
  {
  ubyte
    read_data;
  Wait_For_Not_Busy();
  //Now the high nibble of the address is on the low nibble of Port 2.
  //Mask off the busy bit and the upper bits and store it.
  IN_HIGH_NIBBLE;
  //Finish the high nibble clock cycle.
  CLEAR_LCD_E;
  //Strobe enable to clock in the low nibble--finishing the read.
  SET_LCD_E;
  //Now the low nibble of the address is on the low nibble of Port 2.
  //Mask the upper bits and add it to the result.
  IN_LOW_NIBBLE;
  CLEAR_LCD_E;
  //Turn the data bits back to their default output state.
  SET_PORT1_FOR_LCD_WRITE;
  return(read_data);  
  }
//============================================================================
void Write_LCD_Data(ubyte data)
  {
  Wait_For_Not_Busy();
  //Finish the high nibble clock cycle.
  CLEAR_LCD_E;
  //Strobe enable to clock in the low nibble--finishing the read.
  SET_LCD_E;
  CLEAR_LCD_E;
  //Turn the data bits back to their default output state.
  SET_PORT1_FOR_LCD_WRITE;
  //Make R/W 0=write.
  CLEAR_LCD_RW;
  //Make register select 1
  SET_LCD_RS;
  //Apply the high 4 bits of data to the low four bits of the port.
  OUT_HIGH_NIBBLE;
  //Strobe enable to clock in the high nibble.
  SET_LCD_E;
  CLEAR_LCD_E;
  //Apply the low 4 bits of data to the low four bits of the port.
  OUT_LOW_NIBBLE;
  //Strobe enable to clock in the low nibble.
  SET_LCD_E;
  CLEAR_LCD_E;  
  }
//============================================================================
void Write_LCD_Control(ubyte data)
  {
  Wait_For_Not_Busy();
  //Finish the high nibble clock cycle.
  CLEAR_LCD_E;
  //Strobe enable to clock in the low nibble--finishing the read.
  SET_LCD_E;
  CLEAR_LCD_E;
  //Turn the data bits back to their default output state.
  SET_PORT1_FOR_LCD_WRITE;
  //Make R/W 0=write.
  CLEAR_LCD_RW;
  //Apply the high 4 bits of data to the low four bits of the port.
  OUT_HIGH_NIBBLE;
  //Strobe enable to clock in the high nibble.
  SET_LCD_E;
  CLEAR_LCD_E;
  //Apply the low 4 bits of data to the low four bits of the port.
  OUT_LOW_NIBBLE;
  //Strobe enable to clock in the low nibble.
  SET_LCD_E;
  CLEAR_LCD_E;
  }
//============================================================================
void Read_LCD_Data(ubyte length,ubyte address,ubyte *destination)
  {
  uword
    timeout;
  ubyte
    read_data;
  //First we need to write the address to the LCD.
  //0x40 is first CGRAM
  //0x80 is first DDRAM
  Write_LCD_Control(address);
  while(length--)
    {
    Wait_For_Not_Busy();
    //Finish the high nibble clock cycle.
    CLEAR_LCD_E;
    //Strobe enable to clock in the low nibble--finishing the read.
    SET_LCD_E;
    CLEAR_LCD_E;
    //Make register select 1, selecting the data instead of the address.
    SET_LCD_RS;
    //Enable the controller's data onto the bus.
    SET_LCD_E;
    //Now the high nibble of the data is on the low nibble of Port 2.
    //Mask off the lower bits and store it.
    IN_HIGH_NIBBLE;
    //Finish the high nibble clock cycle.
    CLEAR_LCD_E;
    //Strobe enable to clock in the low nibble--finishing the read.
    SET_LCD_E;
    //Now the low nibble of the data is on the low nibble of Port 1.
    IN_LOW_NIBBLE;
    CLEAR_LCD_E;
    //Store the data
    *destination++=read_data;
    }
  //Turn the data bits back to their default output state.
  SET_PORT1_FOR_LCD_WRITE;
  }
//============================================================================
//does an "8-bit" write (as seen by the LCD)
void Blind_Write_LCD_Upper_Control_Nibble(ubyte data)
  {
  //Make R/W 0=write
  CLEAR_LCD_RW;
  //Make register select 0
  CLEAR_LCD_RS;
  //Apply the high 4 bits of data to the low four bits of the port.
  OUT_HIGH_NIBBLE;
  //Strobe enable to clock in the high nibble.
  SET_LCD_E;
  CLEAR_LCD_E;
  }
//============================================================================
void LCD_Position_Cursor(ubyte x, ubyte y)
  {
  //Valid x is 0-15, valid y is 0-1
  if((x<16)&&(y<2))
    Write_LCD_Control(0x80|(y<<6)|x);
  }
//============================================================================
//Could make this aware of display size & wrapping.
void LCD_puts(const char *input_string)
  {
  while(*input_string)
    Write_LCD_Data(*input_string++);
  }
//============================================================================
void LCD_put_dec_3(ubyte input)
  {
  ubyte
    digit;
  ubyte
    no_blank;
  digit=input/100;
  if(digit)
    {
    Write_LCD_Data(digit+'0');
    no_blank=1;
    }
  else
    {
    Write_LCD_Data(' ');
    no_blank=0;
    }
  input%=100;
  digit=input/10;
  if(digit|no_blank)
    Write_LCD_Data(digit+'0');
  else
    Write_LCD_Data(' ');
  Write_LCD_Data(input%10+'0');
  }
//============================================================================
void LCD_Initialize(void)
  {
  ubyte
    i;
  ubyte
    j;

  SET_PORT1_FOR_LCD_WRITE;

  //This sequence is from the initialization on page 46 of the HD44780U
  //data sheet.
  delay_mS(40);
  Blind_Write_LCD_Upper_Control_Nibble(0x30);
  //Yes, the data sheet says write it twice.
  delay_mS(5);
  Blind_Write_LCD_Upper_Control_Nibble(0x30);
  //Yes, the data sheet says write it three times.
  delay_mS(1);
  Blind_Write_LCD_Upper_Control_Nibble(0x30);
  //Yes, the data sheet says write it four times, but at least this one counts.
  //020h is Function set:
  //4 bit,
  //2 line
  //F = (5x8)
  delay_mS(1);
  //This is last 8-bit write, which is an instruction to put the LCD into 4-bit mode.
  Blind_Write_LCD_Upper_Control_Nibble(0x20);
  //Here is the 4-bit instruction to set the font and number of lines.
  Write_LCD_Control(0x28);

  //"Display off"
  Write_LCD_Control(0x08);
  //"Display clear"
  Write_LCD_Control(0x01);
  //This delay is needed for at least one version of the Sitronix
  //ST7066 Controller. No reasonable explanation, I found it
  //empirically.
  delay_mS(2);
  //006h is Entry mode set, increment, no shift
  Write_LCD_Control(0x06);
  //Display on, cursor on, blinking
  Write_LCD_Control(Cursor_Style=0x0F);
  //Clear the display again. This seems to fix a power-up problem
  //where the display shows "{{{{{" in a couple of places.
  Write_LCD_Control(0x01);
  //Why is this needed? Apparently not needed on the 635.
  //delay_mS(2);
  }
//============================================================================
 
Last edited:

Tjoek

New member
Thanks for the code examples but it doesn't give any difference. Besides the fact that I have longer delays (which cannot be the problem) I have the same initialization procedure. After seeing your code examples I played with timing and the order of commands which tell the display how to behave (this is the initialization part after setting the display to 4 bit mode).

I also noticed in the datasheet of CFAH1602BYTIJ that the ST7066U has a completely different initialization routine. This can be found in appendix C (page 57) which say 26/42 on the bottom of the page.
A also tried this non HD44780U method bit it doesn't work either.

The last thing that I can think of is the fact that the 4 unused data lines need to be grounded instead of N.C.
But this wasn't the case with the previous controllers...
 

CF Tech

Administrator
I matched up your code with my code, and it does match in the beginning. However at the end I do a bunch of stuff you do not. Have you tried adding in the Off, Clear, etc?
Code:
[COLOR="DarkGreen"]1.) Lower the RS line and wait for 127 msec[/COLOR]
[COLOR="Blue"]  //This sequence is from the initialization on page 46 of the HD44780U
  //data sheet.
  delay_mS(40);[/COLOR]

[COLOR="DarkGreen"]2.) Put 0011 on the 4 data lines and directly raise the Enable line
3.) After 0.5 usec I lower the Enable line and wait for 5 msec[/COLOR]
[COLOR="Blue"]  Blind_Write_LCD_Upper_Control_Nibble(0x30);
  //Yes, the data sheet says write it twice.
  delay_mS(5);[/COLOR]

[COLOR="DarkGreen"]4.) Put 0011 on the 4 data lines and directly raise the Enable line
5.) After 0.5usec I lower the Enable line and wait for 1 msec[/COLOR]
[COLOR="Blue"]  Blind_Write_LCD_Upper_Control_Nibble(0x30);
  //Yes, the data sheet says write it three times.
  delay_mS(1);[/COLOR]

[COLOR="DarkGreen"]6.) Put 0011 on the 4 data lines and directly raise the Enable line
7.) After 0.5 usec I lower the Enable line and wait for 41.5 usec[/COLOR]v
[COLOR="Blue"]  Blind_Write_LCD_Upper_Control_Nibble(0x30);
  //Yes, the data sheet says write it four times, but at least this one counts.
  //020h is Function set:
  //4 bit,
  //2 line
  //F = (5x8)
  delay_mS(1);[/COLOR]

[COLOR="DarkGreen"]8.) Put 0010 on the 4 data lines and directly raise the Enable line
9.) After 0.5 usec I lower the Enable line and wait for 41.5 usec[/COLOR]
[COLOR="Blue"]  //This is last 8-bit write, which is an instruction to put the LCD into 4-bit mode.
  Blind_Write_LCD_Upper_Control_Nibble(0x20);[/COLOR]

[COLOR="DarkGreen"]// set LCD to 4 bit 2 line 5X8 matrix characters
10.) Put 0010 on the 4 data lines and directly raise the Enable line
11.) After 0.5 usec I lower the Enable line and directly put 1000 on the 4 data lines and raise the Enable line
12.) After 0.5 usec I lower the Enable line and wait for 41.5 usec[/COLOR]
[COLOR="Blue"]  //Here is the 4-bit instruction to set the font and number of lines.
  Write_LCD_Control(0x28);[/COLOR]

  [COLOR="Red"]//"Display off"
  Write_LCD_Control(0x08);
  //"Display clear"
  Write_LCD_Control(0x01);
  //This delay is needed for at least one version of the Sitronix
  //ST7066 Controller. No reasonable explanation, I found it
  //empirically.
  delay_mS(2);
  //006h is Entry mode set, increment, no shift
  Write_LCD_Control(0x06);
  //Display on, cursor on, blinking
  Write_LCD_Control(Cursor_Style=0x0F);
  //Clear the display again. This seems to fix a power-up problem
  //where the display shows "{{{{{" in a couple of places.
  Write_LCD_Control(0x01);
  //Why is this needed? Apparently not needed on the 635.
  //delay_mS(2);[/COLOR]
 

Tjoek

New member
In my step by step initialization I only explained the steps to initialize the Display to 4 bit communication.
After these first steps I send the following commands:

// send data for display control (display on, cursor off, blink off)
0x0C
wait for 41.5 usec

// send data to clear display
0x01
wait for 1.54 sec

// set entry mode (cursor increment, display shift off)
0x06
wait for 41.5 usec

I also tried to implement exactly the same steps as you did, although the order in which these commands are executed shouldn't make a difference. The nice thing though is that all of the possibilities for do work for the older controller, but they all fail with the new ST7066U controller...
 

CF Tech

Administrator
Hmmm . . .

Do you have more than one display? Maybe that one is screwed up somehow. If it is your only one, let's get you a second one to test against.
 

Tjoek

New member
Unfortunatly the first 10 displays I tried do all behave the same.
So I can't imagine the first 10 displays were broken....

But the problems is starting to become a real problem as we already had to put our sales on hold as we ran out of the display with the previous controller. So I hope you can find an answer soon, or send a test display to verify if our batch is somehow wrong?
 
Does it make any difference if you power down and up the display (resetting it) before trying a new initialization sequence?
 

CF Tech

Administrator
I pulled one from small order inventory (which is where an order of 10 would come from), and watched while the tech plugged it into an EDP. It powered up, initialized and everything right away with no trouble.

I guess since we are running out of things to try, you might try fixing the D0-D3 to high. I know in at least one controller data sheet, the data lines show a slight pull-up in them. I have left them floating in several designs and never had problems. I am pretty sure the EDP leaves them open. Might be worth a try.
 

Tjoek

New member
@ CF Tech
The displays come from an order of 100, but I'm not sure if this is still called a small order from your point of view.
I will try fixing D3-D0 to high, although this will be a problem for our current stock of mass produced parts...

@ cosmicvoid
I'm using a 5 Volt power supply.
 
Top