a thin LED display in SIP module format, much better than TIL311s to visualise your computer buses

Similar projects worth following
The purpose of this SIP module is to display the value of a 16-bits parallel bus.
* SIP format for easy prototyping on a breadboard
* compatible with 3.3V and 5V systems
* selectable output formats: hexadecimal or decimal
* signed or unsigned numbers
* leading 0s can be hidden
* very high contrast display, easy dimming
* three push-buttons select the display modes (with colored feedback)
* user controls are also available on the SIP header: just tie the pin to GND or +3V
* low-cost parts, easy to repair, tweak, hack...
* low power (to be measured, less than 10mA)
* the whole design is documented here on ;-)

This is a module that #Hackaday TTLers and other CPU makers often need: they can spy on an address or a data bus without the hassles of a logic analyzer. Which is fabulous when developing the #YGREC-РЭС15-bis or the #Discrete YASEP...

The PCB acts as a display panel with 5 7-segment digits, 3 push-buttons to select the modes, one adjustable resistor to set the brightness and a row of pins that connect to the circuit under examination. The interface is pretty simple:

Original sketch:Schematic with Eagle:

This is a sub-project of the #Discrete YASEP, which needs a dozen of displays that are

  • very thin
  • as cheap as possible
  • nice-looking
  • not power-hungry
  • easy to build/solder

I have looked at the different possibilities here, here, there, I've looked at the TIL311 integrated hexadecimal display and even started a project to create a modern, cheap clone (#PICTIL)

@al1 turned the #PICTIL into a very nice entry for the #The Square Inch Project but I need something different, not a faithful TIL311 drop-in replacement. Something that shows what we can actually do in 2015 ;-)

My requirements are fulfilled by the (niche) 4014 LED format. The comparison with the TIL311 proved promising so I made more experiments, resulting in a first prototype of 7 segments module.

I solved the decoding issue with a brute-force approach: a 1M×16 Flash chip. Some web-hunting found very cheap lots from brokers and it turned more flexible and cost-effective than other approaches (microcontrollers, CPLD...) thanks to the great pins-vs-price and combinatorial agility (and no need of VHDL or assembly language and proprietary probes to program it).

I found a little lot of very cheap AT49BV162A that have the very nice feature of being 5V compatible. It's an ideal match for this project: users don't need to worry about input voltages, it works with both 3.3V and 5V systems without adaptation. The other integrated circuits work with a wide voltage range. The module also operates with a power supply as low as 3V (it's actually limited by the LED's brightness). An integrated LDO limits the internal voltage to 3.2V.

Dimming is implemented with PWM with a semi-analog oscillator (using the cheap 74HC04). This also drives a divide-by-two counter (74HC74) for output multiplexing. This divider has complementary outputs that drive the appropriate MOSFET (which alternate in grounding their own phase rail).

The unused gates from the 74HC04 implement FlipFlops that select the display mode.

The sign bit is copied directly from the input's bit n°15, ANDed with the sign mode bit (trough a MUX2 in a 1G157 chip).

The last gotcha is the decimal mode which requires a fifth digit (ranging from 1 to 6). Compared to the previous hex-only design, the MOSFET are driven by the 74HC74 so this frees 2 data output lines, that turn into 4 lines when demuxed. A 74HC157 performs the additional decoding.

Also keep in mind, that members of the "puritan TTL Nerd fraction" may sneer at you for juggling with lookup tables beyond 1MB.

(c) Dieter Mueller 2004

1. Decoding the extra digit
2. Cost optimisation
3. Little enhancements
4. A dumb bistable
5. Adjustable PWM oscillator
6. Some updates
7. Preliminary layout
8. Stack-based programming
9. Tiny progress
10. Alternate uses
11. Small change
12. Other changes
13. New layout, new schematic
14. Dual-mode display
15. Autorouters are for the weak
16. Enhanced multiplexing
17. Another module
18. Generate the Flash's contents with a recursive algorithm
19. Bit shuffling: what goes where ?
20. Number conversion
21. File generation in C
22. Not a failure but not a success either
23. First prototype
24. Resuming
25. Decoupling
26. PCB rev.2
27. Another spinoff
28. New batch
29. New batch delivered !


Low-drop 3.2V linear regulator

Adobe Portable Document Format - 443.63 kB - 06/16/2018 at 10:39



Generates DYPLED.bin

x-c - 5.09 kB - 08/20/2016 at 20:50



Flash contents, 2M bytes, not tested

octet-stream - 2.00 MB - 08/20/2016 at 20:49



# run at your own risks # Proof-of-concept code for the recursive generation algorithm.

HyperText Markup Language (HTML) - 5.43 kB - 08/20/2016 at 02:18



1M×16 Flash, 3.3V with 5V-tolerant inputs

Adobe Portable Document Format - 530.88 kB - 01/12/2016 at 20:14


  • 1 × AT49BV162A Memory ICs / FLASH Memory
  • 1 × 74HC04 SOIC14 hex CMOS inverter
  • 1 × 74HC74 SOIC14 dual Flip-Flop with complementary outputs
  • 36 × white LED segments 4014 thin format, warm white
  • 4 × SMT LED, various colors, 0603 0603 format

View all 21 components

  • New batch delivered !

    Yann Guidon / YGDES07/30/2018 at 22:50 0 comments

    The PCB have finally arrived in the workshop :-)

    Tented vias are great :-D No more tricky isolation !

    This time I delivered GERBERs instead of EAGLE files and I triple-checked everything. The preview on the website is much better than for the first batch. Once again, DirtyPCB's subcontractor couldn't keep from adding their serial number in an awkward place, despite having left a blank area where it could fit. Next time I'll have to reverse all the layers so the marking doesn't appear on the front/top side...

    This time the PCB is thicker : 0.8mm, less fragile and easier to handle on a breadboard.

    The remaining space is used by some #4014 LED minimodule  as well as some proto strips for the BFS480 in SC70-6 used by #YGREC-ECL.

  • New batch

    Yann Guidon / YGDES06/16/2018 at 15:05 0 comments

    Thanks to the seed funds from the Hackaday Prize, I've submitted an order for another batch of DYPLED PCBs (and also some #4014 LED minimodules).

    It was long overdue but thanks to the logs, I have recovered the critical information and solved the previous problems. This time, no problem with tented vias because I generated a set of GERBER files that I carefully examined.

    I have also solved the decoupling issue and made several minor cosmetic tweaks.

    See you here in a few weeks...

  • Another spinoff

    Yann Guidon / YGDES06/13/2017 at 10:36 0 comments

    @bobricius has used the 4014 system for his #BPW34 solar powered led watch and the project has been covered by and Adafruit

    Congratulations ! I feel vindicated when others benefit from my ideas :-)

  • PCB rev.2

    Yann Guidon / YGDES04/24/2017 at 12:16 0 comments

    A new version should appear. Not only must it solve the tented vias problem and the decoupling problem, but also gain a bit of room for the added capacitors.

    There is one area with little usage near the brightness potentiometer. But it's far from the 3.2V rail. Another solution is to switch the 74HC04 package from SOIC to SSOP. I got some TC74VHC04FS but they are rated at 5V, I'll have to see how they behave when undervolted at 3.2V...

    OK, don't buy a part before looking at a datasheet, kids !

    In my case, I was lucky and it says :

    • High noise immunity: V NIH = V NIL = 28% V CC (min)
    • Wide operating voltage range: V CC (opr) = 2 V to 5.5 V

    I shoud probably add a bit of hysteresis...

  • Decoupling

    Yann Guidon / YGDES02/10/2017 at 18:23 4 comments

    Franck just spotted a pretty fumble : I have overlooked the bulk capacitors before and after the LP2981.

    I think I assumed that the voltage stability was not critical but usually I am very generous with capacitors.

    The other problem is : is there any room left ?

  • Resuming

    Yann Guidon / YGDES11/17/2016 at 15:30 0 comments

    The development of DYPLED had stalled for several reasons. Some were described here, such as the naked vias. There was work, too. And a big problem: the type of LED.

    The naked vias are just a matter of ordering yet another batch of PCB with the right GERBER.

    Work is done now (#PixelAvenue will open next week)

    The LEDs though are a different story. I needed to decide which type of LED I will commit to, from now on. With or without the integrated Zener ?

    • With Zener : the routing is much easier but must be re-done from scratch and luminosity is not as good.
    • Without Zener : No need to touch the tracks (less work) and everything works as expected, though routing could (and should) be optimised (next time).

    The choice does not depend on me though.

    The only way to decide was to see what type of LED I could use from now on. So I bought more of these : (note: I ordered "warm white", the Zener are in the earlier "cold white" order).

    They have been delivered and I just tested them : there is no reverse diode (just like the previous order). This means that the PCB requires no change and I can move forward, with enough stock to ... whatever :-D

  • First prototype

    Yann Guidon / YGDES09/06/2016 at 10:19 4 comments

    Today I decided that the first PCB was good enough to try to solder it. I know I have to order new PCBs but I want to be sure that I removed all the blunders...

    I started from the power supply, populated the analog parts then the ICs. This allowed me to locate a short between two pins of the '157 which drew about 50mA...

    Without the digital parts of the left, the circuit draws less than 200µA. This increases to almost 2mA with the status LEDs on. In particular the green LED draws about 1.2mA and is not very bright, I must change it... I suppose a recent µC could draw less than the discrete gates but at least it's reasonable and quite convenient :-)

    The oscillator (100K and 2.2nF) runs at about 4900Hz and the 74HC74 brings it down to 2450Hz : no flicker is expected.

    The circuit still works rather well under the 3V level. Some parameters change (frequency, brightness) but not significantly.

    I also tested the front panel interface:

    The LED's footrints are too tiny... I added some more soldering surface on the new version (booooh ugly, I should have modified the footprint instead... I'm lazy)

    The push-buttons are not insulated and there are interference by mere touching. But it works.

    The PWM adjustment works well, according to the ocilloscope :-)

    The LED's brightness is important. I've put 10K series resistors to reduce the emitted light but the green is under-efficient, I'll swap it with a true green or white LED...

    I also soldered all the parts of the user-facing side and the result is great (I'vewalready covered the problems in the previous log).

    Since the Flash chip is not yet soldered, I can individually test the LEDs.

    I changed the green LED with warm white. The luminosity is still too high with 10K in series. Trying with 30K.

    Note 1: Apparently, it's better to use blue-based LEDs (white, pink) rather than older generations, for better efficiency.

    Note 2: 0-extension is controlled by the 74HC74 and resets to set. OTOH the 74HC04 seems to keep the last value across short power outages. Good to know... Ideally, 0-ext should be off, right ? I'm going to update the schematics...

    As expected, the board is crazy thin : 3.5mm from the top of the adjustable resistor, to the top of the SOP16 parts.

    I don't know how to reduce the height of the resistor, thinner versions will be very hard to handle easily. It's not critical at this point.

    The buttons are ultra-thin as well. They are not electrically insulated. Thicker versions (with some plastic enclosure) would solve this problem.

  • Not a failure but not a success either

    Yann Guidon / YGDES08/28/2016 at 05:30 2 comments

    I received the latest PCB batch with the first DYPLED boards, and the issues are explained in this page.

    I don't think I can make the modules work completely as expected, mainly because of the unmasked vias that will create shorts with the thermal pads of the 4014 LEDS.

    At least I can validate other aspects of the module, such as the push-buttons, the PWM, solderability, etc.

    20160902: I tried to solder the first LED (when there is no via under them) and the result is pretty good, soldering is not hard (not easy but I didn't experience any difficulty). At least I don't have to change the footprints :-)

    Time to test the other circuits !

  • File generation in C

    Yann Guidon / YGDES08/20/2016 at 20:59 0 comments

    It took me 3h only (and I was not rushing) to translate the JS code into C and get a decent binary file. I've just uploaded the source and the generated file in the main page.

    C has its own gotchas but the many debug features I used in JS have been very useful in C so the port was a breeze. Compilation is easy:

    gcc -Wall -o shuffle shuffle.c
    Execution is pretty fast too:
    $ /usr/bin/time ./shuffle > DYPLED.bin
    0.85user 0.01system 0:00.88elapsed 99%CPU
    (0avgtext+0avgdata 1392maxresident)k
    0inputs+4096outputs (0major+111minor)pagefaults 0swaps
    And to check the output, add any argument on the command line.

    The source code is very flexible, allowing me to adjust and adapt the data, for any change during the first tests and for the next generation of displays derived from it.

  • Number conversion

    Yann Guidon / YGDES08/19/2016 at 02:06 0 comments

    The last log (Bit shuffling: what goes where ?) explains how the address bits are shuffled. Once the logical value and all the modes/options are obtained, these informations are compiled to generate a 32-bits word that is output to the file, which will program the Flash.

    There are two conversion functions : hexadecimal and decimal. They are very similar and in fact can be merged into one, since the base parameter can work very well with this system (I just realise that in ASCII systems, it's better to have separate conversion routines, but here it's pointless). So let's just forget about function pointers...

    Given the base parameter, it's easy to decompose the number into digits. There is only one corner case to deal with : what to display when the input is zero. Of course it should display ___0 (and not a void screen, or else people wonder if the circuit works at all) but there are 2 ways to achieve this :

    • initialise the display to ___0 and use a while(>0){} loop (which is not entered in the only case where it is zeo)
    • or initialise to nothing (____) and use a do..while (repeat...until) so the remainder of zero is written at least once.

    The 2nd choice is better because the init value is all-cleared and the corner case happens only once, the do-while loop is lighter.

    So we have the following code:

    DigitLUT=[ "0", "1", "2", "3", "4", "5", "6",
     "7", "8", "9", "A", "B", "C", "D", "E", "F"];
    // The previously described recursive function
    function recurse( index, logic, sign, zero_ext, base) {
      msg+=" "+logic;
      if (index>0){  //0) {
        var bit=BinLUT[index--];
        recurse(index, logic, sign, zero_ext, base);
        if (bit < 0) {
          // special code for the modes
          switch(bit) {
            case -1: sign=1;      break;
            case -2: zero_ext=42; break;
            case -3: base=16;     break;
          logic|= 1 << bit;
        recurse(index, logic, sign, zero_ext, base);
      else {
        // This is a "leaf" call,
        // where conversion takes place:
        var i=0; // index of the digit;
        var d;   // the digit
        var m="\n";
        do {
          d=(logic % base)|0;
          logic= (logic/base)|0;
        } while (logic > 0);
        msg+=" - "+m;

    This code seems to work pretty well (once you solve rounding/FP issues with JavaScript by ORing 0)

     ------ -1
     0 0 0 - 0
     16384 - 16384
     32768 32768 - 32768
     49152 - 49152
     ------ -3
     0 0 0 0 0 - 0
     16384 - 4000
     32768 32768 - 8000
     49152 - C000

    This code is directly inspired by traditional conversion functions from binary to ASCII. However our case differs substantially from an ASCII terminal because each new iteration writes to a different digit, corresponding to different codes.

    In JavaScript or other similar languages, this is where multi-dimensional arrays become useful: there are 5 arrays (one for each digit) with 16 sub-arrays (for all the values). The counter i starts to be useful...

    Well, being a rebel, I prefer to use a single array with 5×16 entries and increment i by 16.

    var i=0; // index of the digit;
    var d;   // the digit
    var m="\n";
    do {
      d=(logic % base)|0;
      logic= (logic/base)|0;
    } while (logic > 0);

    Then, it's "only a matter" of generating the rght bit pattern for each number.

    Yes, the time has come to work on this...

    The data pins are connected to the respective segments:

    D   1    2
     0    F2
     1    F1
     2  F3   A3
     3  G3   C3
     4  C1   G1
     5  B1   F0
     6  D1   E1
     7  C0   D0
     8  A2   B2
     9  A1   F1
    10  E3   D3
    11  F2   B3
    12  E2   G2
    13  G0   E0
    14  D2   C2
    15  B0   A0
    Conversely, and more interesting, the segments are connected to the following data pins (+16 means connected to phase F2)
    // A      B       C     D      E       F     G
     [ 15+16, 15   ,  7   ,  7+16, 13+16,  5+16, 13    ],
     [  9   ,  5   ,  4   ,  6   ,  6+16,  9+16,  4+16 ],
     [  8   ,  8+16, 14+16, 14   , 12   , 11   , 12+16 ],
     [  2+16, 11+16,  3+16, 10+16, 10   ,  2   ,  3],

    Let's combine these pin numbers with the list of active segments (0=A, 1=B, etc.)

         [ 0, 1, 2, 3, 4, 5    ], // 0
         [    1, 2             ], // 1
         [ 0, 1,    3, 4,    6 ], // 2
         [ 0, 1, 2, 3,       6 ], // 3
         [    1, 2,       5, 6 ], // 4
         [ 0,    2, 3,    5, 6 ], // 5
         [ 0,    2, 3, 4, 5, 6 ], // 6
         [ 0, 1, 2             ], // 7
         [ 0, 1, 2, 3, 4, 5, 6 ], // 8
    Read more »

View all 29 project logs

Enjoy this project?



Yann Guidon / YGDES wrote 08/20/2016 at 02:52 point

I just realised that "negative hexadecimal" is awkward...

Without the limitation of the 5th digit, I would implement an octal mode :-D

  Are you sure? yes | no

Yann Guidon / YGDES wrote 08/18/2016 at 02:26 point

I sent a first batch to fab ! 0.6mm thick, white mask, might be delivered in 2 weeks...

  Are you sure? yes | no

Eric Hertz wrote 08/17/2016 at 02:38 point

Hey, props on the blog-writeup! And looks like this is coming along nicely.

  Are you sure? yes | no

Yann Guidon / YGDES wrote 08/17/2016 at 02:43 point

You're welcome !

A surprise happened and... #4014 LED minimodule ! a sub-fork appeared :-D

  Are you sure? yes | no

Yann Guidon / YGDES wrote 07/04/2016 at 00:56 point

July 2016: I still haven't received the pull-down resistor networks. They are not essential but damnit... Why is it so hard to find 4×1M resistors in 1206 package ?
Ironicly, I have found a cut tape of 4×1M resistors but in a smaller, even-harder-to-solder package. Am I cursed ?

  Are you sure? yes | no

Yann Guidon / YGDES wrote 07/20/2016 at 00:52 point

I finally received a reel of 1206 resistor networks ! At last !

And now, what about completing the PCB layout ?...

  Are you sure? yes | no

Similar Projects

Does this project spark your interest?

Become a member to follow this project and never miss any updates