User avatar
SavagePi
Posts: 42
Joined: Mon Mar 31, 2014 7:34 pm
Location: Staffordshire, England

35 LED or Relay Outputs - 2 GPIO's

Sun Jun 29, 2014 11:44 am

Here's a design using an old and probably little known IC these days - the MM5451N.
It's probably obsolete now, but you can still get hold of it. It was originally designed to drive the cathodes of 35 LED's, more specifically, five 7-segment LED displays and was widely used in automation because of its easy 2-wire interface and the simplest form of serial data. Using a simple transistor circuit it could switch up to 35 relays instead.
MM5451N_1.gif
Basic circuit for the MM5451N
MM5451N_1.gif (31.71 KiB) Viewed 1201 times
MM5451N_2.gif
Driving LED displays with the MM5451N
MM5451N_2.gif (35.07 KiB) Viewed 1201 times
MM5451N_3.gif
MM5451N Relay interface
MM5451N_3.gif (10.58 KiB) Viewed 1201 times
I know lots of people use the MAX7219 these days to drive 7-segment displays, but the MM5451N is different. It uses static outputs (not multiplexed) and is capable of displaying alpha-numeric characters. Here's some code for the above circuits...

Simple LED and/or relay control...

Code: Select all

# *********************************
# * Program to light up 35 LED's  *
# * using MM5451 and 2 GPIO ports *
# *********************************
#
import time                                 # Import the time module
#
import RPi.GPIO as GPIO                     # Import GPIO module as 'GPIO'
#
GPIO.setmode (GPIO.BCM)                     # Set GPIO mode to BCM numbering
#
clock_in = 25                               # GPIO Clock bit for the MM5451N
data_in = 24                                # GPIO Data bit for the MM5451N
#
GPIO.setup (clock_in,GPIO.OUT)
GPIO.setup (data_in,GPIO.OUT)               # Set both bits as outputs
GPIO.output (data_in,False)
GPIO.output (clock_in,False)                # Initially, turn them both off
#
#
# *********************************
# * Terminate the program cleanly *
# *********************************
#
def terminate():
    print ("\nInput Error.  ")+\
          ("Program Terminated.\n\n")       # Print a termination message
    GPIO.cleanup()                          # Restore the GPIO ports
    exit()                                  # Quit the program
#
#
# *********************************
# * Turn on or off the LED's      *
# *********************************
#
def light_up(value):
    global clock_in, data_in                # Allow access to external constants
    b = bin (value)                         # Convert value into a binary string
    b = b [2:len(b)]                        # Strip off the '0b' from the start
    b = b.zfill(35)                         # If needed, pad it out with zero's
    print ("\nDecimal Value:"), value       # Delete line for no screen output
    print ("Binary Value: "),b              # Delete line for no screen output
    b = b + "1"                             # Add the MM5451N 'Start' bit
    for z in range (36):
        GPIO.output (data_in,int(b[35-z]))  # Set the Data in pin high or low
        GPIO.output (clock_in,True)
        GPIO.output (clock_in,False)        # Clock all 36 bits into the MM5451N
    return ()
#
#
# *********************************
# * Test it using keyboard input. *
# * Delete EVERYTHING below if    *
# * Keyboard Input isn't required *
# *********************************
#
while True:                                 # Start an infinite loop
    try:
        x = int (input ("\n\nPlease enter a number: "))
        while x > 2**35-1:
            print ("\nValue out of range (> 35 bits)")
            print ("All outputs will be turned off.")
            x = 0                           # Use zero if the value's too high
        light_up (x)                        # Light up the LED's
#
# Trap a few common input errors
#
    except KeyboardInterrupt:
        terminate()
    except ValueError:
        terminate()
    except TypeError:
        terminate()
    except NameError:
        terminate()
    except SyntaxError:
        terminate()
Driving 7-segment displays...

Code: Select all

# *********************************
# * Program to light up 5 seven - *
# * segment LED displays using the*
# * MM5451N and just 2 GPIO ports *
# *********************************
# * MM5451N output order and the  *
# * seven segment assignments     *
# *********************************
# * Output:  1  2  3  4  5  6  7  *
# *          |  |  |  |  |  |  |  *
# * Segment: b  c  a  d  f  e  g  *
# *********************************
#
import RPi.GPIO as GPIO                     # Import GPIO module as 'GPIO'
#
GPIO.setmode (GPIO.BCM)                     # Set GPIO mode to BCM numbering
#
clock_in = 25                               # GPIO Clock bit for the MM5451N
data_in = 24                                # GPIO Data bit for the MM5451N
#
GPIO.setup (clock_in,GPIO.OUT)
GPIO.setup (data_in,GPIO.OUT)               # Set both GPIO bits as outputs
GPIO.output (data_in,False)
GPIO.output (clock_in,False)                # Initially, turn them both off
#
#
# Bit pattern lookup table for all
# ASCII values between 32 - 126
# Any characters that cannot be
# displayed on a seven-segment
# display will be defined as a
# blank character (space).  Any
# character that can only be
# displayed in one form (the 
# letter 'a' for instance), will
# be displayed in the only form
# possible (a capital 'A').
# The entire 95 character set is
# defined as follows...
#
# [SPACE]  !  "  #  $  %  &  '
# (  )  *  +  ,  -  .  /
# 0  1  2  3  4  5  6  7
# 8  9  :  ;  <  =  >  ?
# @  A  B  C  D  E  F  G
# H  I  J  K  L  M  N  O
# P  Q  R  S  T  U  V  W
# X  Y  Z  [  \  ]  ^  _
# `  a  b  c  d  e  f  g
# h  i  j  k  l  m  n  o
# p  q  r  s  t  u  v  w
# x  y  z  {  |  }  ~
#
#
char = [0, 0, 0, 0, 0, 0, 0, 16, +\
        60, 15, 0, 0, 32, 64, 0, 0, +\
        63, 3, 109, 79, 83, 94, 126, 7, +\
        127, 95, 0, 0, 0, 0, 0, 101, +\
        0, 119, 127, 60, 63, 124, 116, 126, +\
        115, 48, 43, 0, 56, 0, 55, 63, +\
        117, 87, 52, 94, 120, 59, 0, 0, +\
        0, 91, 109, 60, 0, 15, 0, 8, +\
        16, 119, 122, 104, 107, 124, 116, 95, +\
        114, 2, 43, 0, 48, 0, 98, 106, +\
        117, 87, 96, 94, 120, 42, 0, 0, +\
        0, 91, 109, 0, 48, 0, 0]
#
#
# *********************************
# * Terminate the program cleanly *
# *********************************
#
def terminate():
    print ("\n\nProgram Terminated.\n\n")   # Print a message
    GPIO.cleanup()                          # Reset the GPIO ports
    exit()                                  # Quit the program
#
#
# *********************************
# * Initialise the 5451 (sync it) *
# * This is optional but it might *
# * be useful in some instances   *
# *********************************
#
def init_display():
    global clock_in, data_in                # Access the external constants
    b = bin (2**36)                         # Prepare 36 zero's and a start bit
    b = b [2:len(b)]                        # Strip off the '0b' from the front
    for x in range (2):                     # Transmit this value twice
        for z in range (len(b)):
            GPIO.output (data_in,int(b[z]))
            GPIO.output (clock_in,True)
            GPIO.output (clock_in,False)    # Clock all bits into the MM5451N
    return()
#
#
# *************************
# * Light up the segments *
# *************************
#
def light_up(value):
    global clock_in, data_in, char          # Access the external constants
    value = str (value)                     # Convert value to a string
    value = value [0:5]                     # Truncate it if it's too long
    while len (value) < 5:                  # Pad out the left hand side with 
        value = " " + value                 # spaces if it's too short
    b = 0                                   # Start the accumulative value
    for z in range (5):                     # Move through all 5 characters
        x = ord (value [z]) - 32            # Get offset into lookup table
        if x < 0 or x > 95:                 # If the character is out of range
            x = 0                           # then replace it with a space
        b = b + char [x]                    # Add the character bit pattern
        if z < 4:                           # Shift it left 7 places if it's
            b = b <<(7)                     # not the last required character
    b = bin (b)                             # Convert final value to binary
    b = b [2:len(b)]                        # Strip off the '0b' from the start
    b = b.zfill(35)                         # Pad it out with zero's if needed
    print ("\nString Value:"),value         # Delete line for no screen output
    print ("\nMM5451 Value:"),b             # Delete line for no screen output
    b = b + "1"                             # Add the MM5451N 'Start' bit
    for z in range (36):
        GPIO.output (data_in,int(b[35-z]))  # Set the Data in pin high or low
        GPIO.output (clock_in,True)
        GPIO.output (clock_in,False)        # Clock all bits into the MM5451N
    GPIO.output (data_in, False)            # Set the Data in pin low on exit
    return ()
#
#
# *********************************
# *   START OF THE MAIN PROGRAM   *
# *********************************
#
# init_display()                            # Optional startup call
#
#
# *********************************
# * Test using keyboard input.    *
# * Delete EVERYTHING below if    *
# * Keyboard input isn't required *
# *********************************
#
while True:                                 # Start an infinite loop
    try:
        x = raw_input("\n\nEnter something: ")
        light_up (x)                        # Light up the displays
    except KeyboardInterrupt:
        terminate()                         # Quit if [CTRL+C] pressed
I've written a complete tutorial for the MM5451N here...
http://www.carol-anne-dolls.co.uk/MM5451N_Tutorial.pdf

Hope you find this useful.
Electronics... It's what I do!

User avatar
Douglas6
Posts: 4676
Joined: Sat Mar 16, 2013 5:34 am
Location: Chicago, IL

Re: 35 LED or Relay Outputs - 2 GPIO's

Sun Jun 29, 2014 2:54 pm

Interesting, thanks for this. It's sad that support for seven segment displays is dwindling. As you mention the MAX7219 is popular, but getting more and more expensive. I suppose SSDs will go the way of the Pixie tube eventually.

User avatar
SavagePi
Posts: 42
Joined: Mon Mar 31, 2014 7:34 pm
Location: Staffordshire, England

Re: 35 LED or Relay Outputs - 2 GPIO's

Sun Jun 29, 2014 3:06 pm

Douglas6 wrote:Interesting, thanks for this. It's sad that support for seven segment displays is dwindling. As you mention the MAX7219 is popular, but getting more and more expensive. I suppose SSDs will go the way of the Pixie tube eventually.
Good heavens, I'd forgotten about pixie tubes. That'll be my next project then ;)
I suppose I was actually hoping to demonstrate how to use multiple relays really.
Electronics... It's what I do!

Return to “Automation, sensing and robotics”