The Beginning of the 16 Row Display.

The parts have arrived for the interface board and I was able to squeeze enough time to begin the next step, making the display double tall – 16 rows.

I knew the 1st hurdle was going to be hardware so that was where I concentrated my effort for this 1st step.  My goal was to build an interface that would go between my micro-controller and the display.  This interface would have the row decoders on it as well as the differential line driver IC for the clock and data lines.

Luckily, the logic for this circuit would be pretty simple.  By using a 74HC238 3 to 8 decoder I could take a 3 bit binary output from the micro-controller and turn on a single output representing that number.  By cascading these, I could double the amout of ouputs to 16 and only need a 4 bit binary number.  This will be the way I go for the row drivers.

The 74HC238 has 3 address inputs, 3 enable lines, and 8 outputs (active High).  Two of the enables are active low while 1 is active high.  Using these 3 enables you can cascade the decoder to create a larger decoder.

This is the pinout of the 74HC238.

And the Chip layout.

To cascade the 3 to 8 into a 4 to 16, you simply connect the enables as follows:

Connect E1 on both chips to Ground, Connect E2 on IC1 to E3 on IC2, Connect E3 on IC1 to VCC, Connect E2 on IC2 to Ground.  The E2/E3 connection becomes your 4th address input.  When this connection is logic low, IC1 will be active and IC2 will be off, when this connection goes logic High, IC1 will be off while IC2 is active.  I also used E1 as an enable input for both chips so for my circuit, I did not tie these to ground.  Instead I ran them to the micro-controller to allow me to turn off all rows of the display during data transfer.

The other chip I put on the board was the SN75183 differential driver that I described in an earlier post.  Beyond that, just 3 bypass caps and some headers and wire finished the board out.

Here is a schematic of the final prototype.

You can get a better view of how the decoders are cascaded and the connection of the SN75183.  The Clock and Data lines are just paralleled between the two output connectors (SV2 & SV3).  Each out put connector though gets it’s own row data from one of the two decoders.

The input connector pinout is as follows:

  • Pin 1  –  GND
  • Pin 2  –  A0
  • Pin 3  –  A1
  • Pin 4  –  A2
  • Pin 5  –  A3
  • Pin 6  –  VCC (5V)
  • Pin 7  –  CLK
  • Pin 8  –  Data
  • Pin 9  –  Enable

This board reduces the amount of outputs needed while giving me more versatility.

This is the soldered up prototype.

And a back side View.

Here’s a couple more photo’s of the board installed.

Here you can see the board wired between my breadboard and the display boards.

I accidentally wired my displays backward and put the upper output harness on the lower display and the lower on the upper display…  It was just a proof of concept test run anyway :D.


Here is my breadboard with the micro-controller.  The red and green jumpers on the right are providing the 5V to the logic portion of the displays.  I have a 2.5A 5V supply powering the the LED drivers on the displays.  The connections from the micro to the protoype board are similar to the prior setup except I use PC4 as my enable line and no longer use PORTD for anything.

  • PB3  – CLK
  • PB5  – Data
  • PC0  – A0
  • PC1  – A1
  • PC2  – A2
  • PC3  – A3
  • PC4  – Enable

The software is just in the proof of concept stage.  I wanted to be sure the driver worked hardware wise before devoting a lot of time to the software.  So far the only software changes I have made is re-defining my ROWS and COLS to 16 and 40 respectively, Changed la_data to uint16_t to allow for the extra data width.  And I re-wrote the logic in the initialization  and interrupt functions.

// - ISR(TIMER0_OVF_vect)  
// -  	Timer interrupt that actually shifts 
// -	the array data to the display
// -  Returns - nothing

ISR(TIMER0_OVF_vect) {

  // Turn off all rows
  PORTC = 0x10;

  // increment row number
  if(++la_row == ROWS)
    la_row = 0;

  uint8_t j, data=0;

    //fill columns

    for(j=1; j<=COLS; j++) {

	  // Set data line high or low depending on value in array
		  PORTB |= (1<< PB5);}
		  PORTB &= ~(1<< PB5);}
	  // Toggle Clock to shift data into register
		PORTB |= (1<< PB3);
	    PORTB &= ~(1<< PB3);
	// Activate driver for current row
    PORTC |= (la_row);
	// Turn on rows
	PORTC &= ~(1<<PC4);

// - ledarray_init() 
// -  	Sets up the timer, and configures
// -	the ports to drive the display.
// -  Returns - nothing

void ledarray_init() {
  // Timer0 CK/64 
  TCCR0B = (1<<CS01) | (1<<CS00);
  TIMSK0 = (1<<TOIE0);

  // Set the port c to output  
  DDRC |= (1<<PC0)|(1<<PC1)|(1<<PC2)|(1<<PC3)|(1<<PC4); // set PortC as output

  // Blank All Rows  
  PORTC = 0x10;
  DDRB |= (1<<PB3)|(1<<PB5);

Lastly, here is a static image of the display in operation at 16 wide.  As you can see, there is an issue with the additional rows in the various functions that will have to be addressed.  But it appears that the hardware side of things is working as expected.  🙂

That’s all for now,  as you can see from the video, I have some software to sort out.  Until then…


This entry was posted in News. Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *