Shop OBEX P1 Docs P2 Docs Learn Events
Basic stamp, MAX7219, 7 segment display and custom characters, how? — Parallax Forums

Basic stamp, MAX7219, 7 segment display and custom characters, how?

CuriousOneCuriousOne Posts: 931
edited 2014-10-03 22:08 in BASIC Stamp
Hello.

I want to be able to display on 4 segment LED connected to BS2 via MAX7219 not only digits, but also some letters, which can be displayed, say A,C, H, L, P, E and some others. How should I?

I know that MAX7219 has so called "no decode" mode, which I already enabled, I'm using the code below for this:
' {$STAMP BS2}
' {$PBASIC 2.5}
 

Clk   PIN 10
DIN   PIN 12
CS    PIN 11
 
SWord VAR Word         'word which is shifted out to 7219
SWHi  VAR SWord.HIGHBYTE
SWLo  VAR SWord.LOWBYTE
Digit    VAR Word
cukuna VAR Word
begin:
HIGH  CS               'normally not selected
LOW   CLK              'make these outputs
LOW   DIN
SWord = $0C01                'shutdown register, normal operation
GOSUB DMX7219
SWord = $09ff                'decode register,  decode
GOSUB DMX7219
SWord = $0B07                'scan limit, all rows
GOSUB DMX7219
SWord = $0A05                'intensity register, medium
GOSUB DMX7219

Drive:                      'display seven thru zero
FOR Digit = 0 TO 3           'go from right to left
SWHi = (digit+1)
SWLo = digit
GOSUB DMX7219
NEXT
END

DMX7219:                     'drive MX 7219
LOW   CS                                           'enable
SHIFTOUT DIN, CLK, MSBFIRST, [SWord \16]           'shift out 16 bits
HIGH  CS                                           'it loads and executes
RETURN


The code, as posted, displays "1234". However, despite my attempts, I was not able to make it display any other chars. Only when I enable no decode mode and assign various digits to SWHi and SWLo, several random segments come on, but MAX7219 stucks after that, and I have to cycle power to make it responsive again.

Comments

  • tomcrawfordtomcrawford Posts: 1,129
    edited 2014-09-23 09:27
    CuriousOne:
    You really need to study the MX7219 data sheet to understand how to program the chip. Here is a pointer to a page that will take you to it.

    http://www.maximintegrated.com/en/products/power/display-power-control/MAX7219.html

    Go to that page now, find the data sheet, download it and print it out. Do that now, before you continue with this message.

    OK, got the data sheet in from of you? Look at Table 2 on page seven. This corresponds to SWHI in your code fragment. It specifies what register in the chip you are writing to. Addresses xxxx_0001 thru xxxx_1000 specify one of the eight digits.

    Now look at table 6 on page 8. This corresponds to SWLO. In no-decode mode, each bit directly controls one segment (or DP).

    So to write a "P" to digit three, I would program

    [code]
    SWHI = $03
    SWLO = %01100111 'segments A, B, F, G, E
    GOSUB DMX7219
  • PublisonPublison Posts: 12,366
    edited 2014-09-23 09:57
    And if you want to do custom digits, you must turn decode off.
    [COLOR=#333333][FONT=Parallax]SWord = $0900          'decode register, no decode[/FONT][/COLOR]
    
  • CuriousOneCuriousOne Posts: 931
    edited 2014-09-24 00:05
    Thanks, tried above but:

    1. It displays two additional segments in 4th digit
    2. To update display, I have to turn off power, wait some time for capacitor discharge and then run code again. If not, then display won't get updated and it'll stuck.
  • tomcrawfordtomcrawford Posts: 1,129
    edited 2014-09-24 09:12
    I think your getting stuck may be due to not having a pullup on CS. I use a 20K to +5V.

    As to extra segments, they may well be left over from before you turned decode off or however the MX7219 powered up. Here is a re-do of the code fragment that clears the display for sure and then programs four digits to letters. I'm sure you will know when it works.
    ' {$STAMP BS2}
    ' {$PBASIC 2.5}
    ' {$PORT COM14}
    
    Clk   PIN 10
    DIN   PIN 12
    CS    PIN 11
    
    SWord     VAR Word         'word which is shifted out to 7219
    Digit     VAR SWord.HIGHBYTE
    Segments  VAR SWord.LOWBYTE
    Work      VAR  Byte
    
    begin:
    HIGH  CS               'normally not selected
    LOW   CLK              'make these outputs
    LOW   DIN
    
    SWord = $0C01                'shutdown register, normal operation
    GOSUB DMX7219
    SWord = $0900                'decode register, no decode
    GOSUB DMX7219
    SWord = $0B07                'scan limit, all rows
    GOSUB DMX7219
    SWord = $0A08                'intensity register, medium
    GOSUB DMX7219
    FOR digit = 1 TO 8           'make sure all segments of all digits are off
       Segments = 0
       GOSUB DMX7219
       NEXT
    
    Digit = 3
    Segments = %01100111      'letter P on digit 3
    GOSUB DMX7219
    digit = 4
    Segments = %01001111       'letter E on digit 4
    GOSUB DMX7219
    digit = 2
    Segments = %00110000
    GOSUB DMX7219
    digit = 1
    Segments = %01001110
    GOSUB DMX7219
    
    END
    
    
    DMX7219:                     'drive MX 7219
    LOW   CS                                           'enable
    SHIFTOUT DIN, CLK, MSBFIRST, [SWord \16]           'shift out 16 bits
    HIGH  CS                                           'it loads and executes
    RETURN
    
    

    I see we have parallel threads on two forums. I am continuing on just this thread; the other will naturally go away.
    Also, I changed the labels on the two halves of SWORD to make them a little more mnemonic.
  • CuriousOneCuriousOne Posts: 931
    edited 2014-09-28 00:10
    pullup resistor is not an isue, since in decode mode, everything works just fine.
  • tomcrawfordtomcrawford Posts: 1,129
    edited 2014-09-29 09:00
    I decided to try to implement alphanumerics on one of these seven-segment sticks.

    1. FONT
    Google "seven-segment font images" to get a look at the various attempts to build recognizable characters. Some look just fine, like numerics and "ACEFHLP"; some letters are lower case, like "bdgjnr"; some are just horrible, like "mn"; and some are ambiguous "IOKZ". I think my take-away is "A lot of people won't like it". The characters in my font are in ASCII order except I replaced the punctuation between "9" and "@" with the hex characters "A..F" which appear twice.

    2. MX7219 Control
    I think the MX7219 can very easily come up in a very bad state. I have a pullup on CS AND a pull-down on DataIn and it still likes to come up in lamp test. I have very carefully coded it to get out of lamp test and that appears to work reliably. Here is a pointer to a demo. As always, the video is over-exposed.

    https://www.youtube.com/watch?v=X8szESJvHAw&feature=youtu.be

    Here is the code, including the font:
    ' {$STAMP BS2}
    ' {$PBASIC 2.5}
    ' {$PORT COM4}
    
    Font30 DATA %01111110, %00110000, %01101101, %01111001, %00110011, %01011011, %01011111, %01110000  '0..7
    Font38 DATA %01111111, %01111011, %01110111, %00011111, %01001110, %00111101, %01001111, %01000111  '8..F
    Font40 DATA 0, %01110111, %00011111, %01001110, %00111101, %01001111, %01000111, %01111011          '(@) A..g
    Font48 DATA %00110111, %00110000, %00111100, %00110111, %00001110, %01010100, %00010101, %01111110  'H..O
    Font50 DATA %01100111, %01110011, %00000101, %01011011, %00001111, %00111110, %00011100, %00101010   'P..w
    Font58 DATA %00110111, %00111011, %01101101    'XYZ
    
    M0     DATA "Hello world     ", 0
    M1     DATA "0123456789ABCDEF     ", 0
    M2     DATA "ABCDEFGHIJKLMNOPQRSTUVWXYZ     ", 0
    M3     DATA "The quick brown fox jumped over the lazy dogs back     ", 0
    M4     DATA "Now is the time for all good men to come to the aid of their country    ", 0                                                       
    M5     DATA "Four score and seven years ago   ", 0
    
    Clk   PIN 10
    DIN   PIN 12
    CS    PIN 11
    
    SWord     VAR Word            'word which is shifted out to 7219
    Digit     VAR SWord.HIGHBYTE  'typically a register address
    Segments  VAR SWord.LOWBYTE   'data for the register
    Ascii     VAR  Byte           'Ascii character
    Mess      VAR  Nib            'message number we are currently processing
    TextPoint VAR  Word           'pointer into current message
    Buffer    VAR  Byte(8)        'letters being displayed (in the form of segments)
    GoesInAt  VAR  Nib            'buffer input pointer
    ComesOutAt VAR  Nib            'buffer output pointer
    
    begin:
    HIGH  CS               'normally not selected
    LOW   CLK              'make these outputs
    LOW   DIN
    
    Initialize:                  'try to get control of MX7219 no matter how it comes up
    SWord = 0                    'a nop, get it in sync with my commands
    GOSUB DMX7219
    SWord = $0C00                'shutdown register, shutdown
    GOSUB DMX7219
    SWord = $0F00                'not lamp test
    GOSUB DMX7219
    
    SWord = $0C01                'shutdown register, normal operation
    GOSUB DMX7219
    SWord = $0900                'decode register, no decode
    GOSUB DMX7219
    SWord = $0B07                'scan limit, all rows
    GOSUB DMX7219
    SWord = $0A02                'intensity register, medium
    GOSUB DMX7219
    FOR digit = 1 TO 8           'make sure all segments of all digits are off
       Segments = 0
       GOSUB DMX7219
       NEXT
    
    top:
    FOR Mess = 0 TO 5                   'do each of the messages in order
        LOOKUP Mess, [M0, M1, M2, M3, M4, M5], TextPoint
        GOSUB DoMessage
        PAUSE 2000
        NEXT
    GOTO top
    
    DoMessage:
       READ TextPoint, Ascii                     'get one Ascii character
       IF Ascii > 91 THEN Ascii = Ascii - 32     'convert lower case to upper case
       IF Ascii = 0 THEN RETURN                  'end of message
       PAUSE 150                                 'not so fast
       IF Ascii = " "  THEN
           segments = 0                          'treat blank as a special case
       ELSE
           READ Font30+(Ascii-"0"), segments     'look up font
       ENDIF
       GOSUB DoChar                              'insert one char into buffer and display entire buffer
       TextPoint = TextPoint + 1                 'on to next character
       GOTO DoMessage
    
    DoChar:
       buffer(GoesInAt) = Segments          'insert new one
       ComesOutAt = (GoesInAt + 1) & %111    'modulo seven
       FOR digit = 8 TO 1                    'now write from left to right
          segments = buffer(ComesOutAt)      'get the font
          GOSUB DMX7219                      'send to display
          ComesOutAt = (ComesOutAt) + 1 &%111   'to next entry in buffer modulo 7
          NEXT                                'for each digit
       GoesInAt = (GoesInAt + 1) &%111        'next char will go at next slot (modulo 7)
       RETURN
    
    
    DMX7219:                     'drive MX 7219
    LOW   CS                                           'enable
    SHIFTOUT DIN, CLK, MSBFIRST, [SWord \16]           'shift out 16 bits
    HIGH  CS                                           'it loads and executes
    RETURN
    

    Oddly enough, I struggled with the circular buffer. For a while I had convinced myself that, with such a short buffer, it was more efficient to actually shift the contents than to keep recomputing the output pointer.
  • CuriousOneCuriousOne Posts: 931
    edited 2014-10-03 22:08
    Thanks, will give it a try and report later.
Sign In or Register to comment.