Menu

How to write to 8 digit led display connected to max7219

Help
2019-11-14
2019-11-15
  • Jim giordano

    Jim giordano - 2019-11-14

    I recently received one of the cheap 8 digit led displays run by a max7219.

    When I went looking for a demo, all I could find was demos for a max7219 hooked up to an 8x8 led matrix, and using the GLCD graphic display driver.

    I can see from these demos how to do the front end. Connect the spi pins for clock and data, and two random pins connected to cs and di. Since I'm not planning on reading the display, I guess DI is unnecessary. From one of the demos (comments are mine and may be incorrect) -

      'Set SPI pins for the Max7219
      #define Max7219_DO    portb.5  ' spi data as set in pps routine
      #define Max7219_SCK   portb.3  ' spi clock as set in pps routine
      #define Max7219_CS    portc.3  ' random pin connected to cs for library to use
      #define Max7219_DI    portb.4  ' do I need to connect a pin if I don't read?
    

    Then I am at a loss for what to do next. Since this not set up as an 8x8 matrix, it doesn't make sense to use the graphic GLCD display driver routines.

    What do I use to simply show a number on the display?

    I'm going to press on, and I'll figure it out in a few days, but I thought someone must have used one of these before and could save me some time.

     
  • Jim giordano

    Jim giordano - 2019-11-14

    edit - deleted as newer code shown later

     

    Last edit: Jim giordano 2019-11-15
  • stan cartwright

    stan cartwright - 2019-11-15

    I am stupid but shouldn't it be

    #chip 16F18325,32
    #option Explicit
    Dim dig(11)
             '76543210
    dig( 1)=b'00111111' '0       -      1
    dig( 2)=b'00000110' '1     |   |  6   2
    dig( 3)=b'01011011' '2       -      7
    dig( 4)=b'01001111' '3     |   |  5   3
    dig( 5)=b'01100110' '4       -      4
    dig( 6)=b'01101101' '5
    dig( 7)=b'01111101' '6
    dig( 8)=b'00000111' '7
    dig( 9)=b'01111111' '8
    dig(10)=b'01101111' '9
    dig(11)=b'10000000' '.
    

    I got same display but 4 connected and there's a scrolling demo but I never worked out what was happening..ie understood it.
    I have two that can be joined and wanted a pixel/led addressable 16x32 display...made from two 8x32.. each an 8x8 unit. Too hard for me.

     
  • mmotte

    mmotte - 2019-11-15

    I have been using these for a couple years. I almost made a library for them but was distracted and never finished. Just copy in the subs and use. This little project ,I was measuring a positive/ negative voltage on the input to a servo(not the toy ones).

    'Plus and minus voltage +-10 vdc input to the adc
    'using resistor network of  3 resistors   -  no opamps
    ' Vcc+5 -<22K >---adc input^|-----<12k>--gnd
    ' inputvoltage --<80K>------|
    '10bit adc reads 300 dec when input touched to gnd
    '
    ' MAX7219 Driver for Great Cow Basic
    '
    '    using Hardware SPI routines for Great Cow BASIC
    
    '    Copyright (C) 2016 - Mike Otte  ,PearlCity IL
    
    '    This library is free software; you can redistribute it and/or
    '    modify it under the terms of the GNU Lesser General Public
    '    License as published by the Free Software Foundation; either
    '    version 2.1 of the License, or (at your option) any later version.
    
    '    This library is distributed in the hope that it will be useful,
    '    but WITHOUT ANY WARRANTY; without even the implied warranty of
    '    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    '    Lesser General Public License for more details.
    
    '    You should have received a copy of the GNU Lesser General Public
    '    License along with this library; if not, write to the Free Software
    '    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
    
    '********************************************************************************
    'IMPORTANT:
    'THIS FILE IS ESSENTIAL FOR SOME OF THE COMMANDS IN GCBASIC. DO NOT ALTER THIS FILE
    'UNLESS YOU KNOW WHAT YOU ARE DOING. CHANGING THIS FILE COULD RENDER SOME GCBASIC
    'COMMANDS UNUSABLE!
    '********************************************************************************
    
    'Changes:  Aug 2016 written
    
    'Register Address map of commands
    'NO-OP    0xX0    0x00
    'Digit 0  0xX1    0x01
    'Digit 1  0xX2    0x02
    'Digit 2  0xX3    0x03
    'Digit 3  0xX4    0x04
    'Digit 4  0xX5    0x05
    'Digit 5  0xX6    0x06
    'Digit 6  0xX7    0x07
    'Digit 7  0xX8    0x08
    'Decode   0xX9    0x09
    'Intesity 0xXA    0x0A
    'ScanLim  0xXB    0x0B
    'Shutdown 0xXC    0x0C
    'DispTest 0xXF    0x0F
    
    ' 16 bits spi transfer for each digit/COMMANDS
    'clock rising - data read
    'Load pin low to allow clocked in data
    
    'Sub routines list
    'Initialize
    'set decode mode
    'set intensity of digit x
    'set san limit
    'writeToDigitX(address,data)
    'TurnOn Display
    
    
    'Changes:
    
    #chip 16F886, 8
    
    #define CS     PortA.5   ' out
    #define SCK    PortC.3   'clk out
    #define MOSI   PortC.4   'in
    #define MISO   PortC.5   'out
    
      CS = 1
    'Set SPI pin directions
    dir PORTC.5 out 'SDO
    dir PORTC.4 in  'SDI
    dir PORTC.3 out 'SCK
    dir PORTA.5 out 'SS   load
    
    Dim count,myValue as Word
    
    'Set SPI Mode to master, with fast clock
    'SPIMode MasterFast,0
    SPIMode ( MasterFast, SPI_CPOL_0 + SPI_CPHA_0 )
      'SSPSTAT = 0x40         ' spi mode was not set correctly in my GC compiler
      'SSPCON1 = 0x20
    
    InitMax7219_7seg
    
    do
      myValue = ReadAD10( AN1 )
      If  myValue >= 297  then
        myValue = (myValue -297)*10/16
        MLED_write(5 ,0x0F)
      else
        myValue = (297- myValue) *10/16
        MLED_write(5 ,0x0A)
      end if
    
    
      MLED_Dec(myValue , 4)
    
      wait 1 s
    
    Loop
    
    
    sub InitMax7219_7seg
    
        cs = 1
        wait 100 ms
        'set decode mode
        MLED_write( 0x09 , 0xFF)
        'set intensity 3/4
        MLED_write( 0x0A , 0x06)
        'set scan limit
        MLED_write( 0x0B , 0x07)
        'set display ON
        MLED_write( 0x0C , 0x01)
    
        For count= 1 to 8
          MLED_write(count,0x0F)  'Clear digits
        next
    
    end sub
    
    
    
    sub  MLED_write( cmd , dayta)#NR
      cs = 0
      serBuf = 0x00   'empty bucket
      SPITransfer cmd, serBuf
      serBuf = 0x00   'empty bucket
      SPITransfer dayta, serBuf
      cs = 1
    end sub
    
    Sub MLED_Int (In MLEDValue,In NumDig)
      MLEDValueTemp = 0
      MLED_write(NumDig,0x0F)
      MLED_write(NumDig-1,0x0F)
      MLED_write(NumDig-2,0x0F)
    
    
      IF MLEDValue >= 100 Then
        MLEDValueTemp = MLEDValue / 100
        MLEDValue = SysCalcTempX
        MLED_write(NumDig ,MLEDValueTemp)
        'NumDig--
      End If
      If MLEDValueTemp > 0 Or MLEDValue >= 10 Then
        MLEDValueTemp = MLEDValue / 10
        MLEDValue = SysCalcTempX
        MLED_write(NumDig-1 ,MLEDValueTemp)
        'NumDig--
      End If
        MLEDValueTemp = MLEDValue
        MLED_write(NumDig-2 ,MLEDValueTemp)
    
    End Sub
    
    Sub MLED_Dec (In MLEDValue as word,In NumDig)
      MLEDValueTemp = 0
      MLED_write(NumDig,0x0F)
      MLED_write(NumDig-1,0x0F)
      MLED_write(NumDig-2,0x0F)
      MLED_write(NumDig-3,0x0F)
    
      IF MLEDValue >= 1000 Then
        MLEDValueTemp = MLEDValue / 1000
        MLEDValue = SysCalcTempX
        MLED_write(NumDig ,MLEDValueTemp)
        'NumDig--
      End If
      IF MLEDValueTemp > 0 Or MLEDValue >= 100 Then
        MLEDValueTemp = MLEDValue / 100
        MLEDValue = SysCalcTempX
        MLED_write(NumDig-1 ,MLEDValueTemp)
        'NumDig--
      End If
      If MLEDValueTemp > 0 Or MLEDValue >= 10 Then
        MLEDValueTemp = MLEDValue / 10
        MLEDValue = SysCalcTempX
        MLED_write(NumDig-2 ,MLEDValueTemp +0x80)
        'NumDig--
      End If
        MLEDValueTemp = MLEDValue
        MLED_write(NumDig-3 ,MLEDValueTemp)
    
    End Sub
    

    Have fun!

     
    • Jim giordano

      Jim giordano - 2019-11-15

      Thanks for that, I'll give it a try shortly.

       
  • Jim giordano

    Jim giordano - 2019-11-15

    Well, I think this should work unless I'm missing something important. Or I misunderstand how it works in general.

    Yup, I was definately misunderstanding. Bad code deleted. Final working code below.

     

    Last edit: Jim giordano 2019-11-15
  • Jim giordano

    Jim giordano - 2019-11-15

    Well, I tried mmotte's program and got the same results. Any write to the max7219 results in all segments on, just as if I did a "display test ". Either a wiring error, which I've check multiple times, or this unit from China is just no good.

     
  • mmotte

    mmotte - 2019-11-15

    Might it be the PPS setup?

    • SDI must have corresponding TRIS bit set
    • SDO must have corresponding TRIS bit cleared
    • SCK (Master mode) must have corresponding
    TRIS bit cleared

    SDO instead of sda(i2c)

      #startup InitPPS, 85
        #define PPSToolPart 16F18325
    
        Sub InitPPS
    
                'Module: MSSP1
                RA0PPS = 0x0018    'SCK1 > RA0
                SSP1CLKPPS = 0x0000    'RA0 > SCK1 (bi-directional)
                RA1PPS = 0x0019    'SDO1 > RA1
    
        End Sub
    

    SPIMode gave me trouble those years ago. it is probably ironed out now.
    SPIMode Master in yours

    SPIMode ( MasterFast, SPI_CPOL_0 + SPI_CPHA_0 ) 'in all the examples in help
    

    --
    I see I must add #define SPI_HardwareSPI which we didn't need back then.

    73
    Mike

     
    • Jim giordano

      Jim giordano - 2019-11-15

      You are absolutely correct. I did have the pps screwed up. Too much cut and paste. At least I'm getting something now, not correct, but encouraging! Thanks.

       
  • Jim giordano

    Jim giordano - 2019-11-15

    And the final working solution :)

    later- nope, still had pps screwed up.
    Code deleted. New version farther down.

     

    Last edit: Jim giordano 2019-11-15
  • Anobium

    Anobium - 2019-11-15

    An insight

    #define SPI_HardwareSPI

    You will see this is most demos where SPI is used, or, can be used. There may be a variant of #define SPI_HardwareSPI for a specific device.

    What does this do? If you comment this out then the software SPI is supported. This means that you do not need PPS or any SPIMode commands. As software SPImode does not required PPS of the setting of SPMode.

    To complete the picture. Some SPI impmentations across the PIC range require SPIBAUD. The demos show how to use but essentially this is a speed adjuster.


    My rule of thumb advice.

    Always, always start with software SPI. Get the device operational then use hardware SPI.

     
  • Jim giordano

    Jim giordano - 2019-11-15

    New demo program. Finally got pps right (thanks mmotte)

    Edit- found undocumented mode MasterUltraFast, which at 32mhz no longer requires wait between sends, which makes the output MUCH faster.

    ' 8 digit led to Maxim 7219 demo program
    #option Explicit
    #chip 16F18325,32
    'Generated by PIC PPS Tool for Great Cow Basic for 16F18325
    #startup InitPPS, 85
    #define PPSToolPart 16F18325
    Sub InitPPS
      RC0PPS =     0x0018 'SCK1 > RC0
      SSP1CLKPPS = 0x0010 'RC0 > SCK1 (bi-directional)
      RC1PPS =     0x0019 'SDO1 > RC1
    End Sub
    
    #define SPI_HardwareSPI
    SPIMode MasterUltraFast, 0
    dir portc.0 out  ' clock  sck1
    dir portc.1 out  ' data out sdi1
    dir porta.2 out  ' cs
    
    #define SpiCS   porta.2  ' cs
    
    getsegs
    
    dim ii,kk
    Spics=1
    
    doit b'00001001',b'11111111'  ' decode mode=set all digits to BCD Code B
    doit b'00001011',b'00000111'  ' multiplex all eight digits
    doit b'00001010',b'00001111'  ' max intensity
    erasebcd  ' erase all digits
    doit b'00001100',b'00000001'  ' turn on display
    
    doit b'00001111',b'00000001'  ' display test all digits
    wait 1 s
    doit b'00001111',b'00000000'  ' turn off display test
    
    erasebcd ' clear all digits
    wait 500 ms
    
    for ii=1 to 8
      doit ii,ii-1  ' increasing from right to left using bcd
    next ii
    
    wait 2 s
    erasebcd  ' clear all digits
    wait 500 ms
    
    doit b'00001001',b'00000000'  ' set no-decode mode
    
    for ii=1 to 8
      doit ii,seg(9-ii)  ' increasing from left to right using non-bcd
    next ii
    
    wait 2 s
    erase 'clear all digits
    wait 500 ms
    
    doit 8,b'00000001'
    doit 7,b'00110111'
    doit 6,b'01001111'
    doit 5,b'00001110'
    doit 4,b'00001110'
    doit 3,b'01111110'
    doit 2,b'00000000'
    doit 1,b'00111110'
    
    wait 2 s
    erase ' clear all digits
    wait 500 ms
    
    doit b'00001001',b'11111111'  ' decode mode=set all digits to BCD Code B
    
    dim dig(9)  ' bcd value of digit
    for kk=1 to 8: dig(kk)=0: next kk
    do
      for kk=1 to 8
        dig(kk)++
        if dig(kk)<10 then
          doit kk,dig(kk)
          exit For  ' no more carrys
        end if
        dig(kk)=0
        doit kk,dig(kk)
      next kk  ' loop back and do carry
    loop
    
    sub doit(reg,value)
    ' wait 250 us  ' increase if digits misbehaving
    '      not necessary if using MasterUltraFast 
      spics=0
      FastHWSPITransfer reg
      FastHWSPITransfer value
      spics=1
    end sub
    
    dim ik
    sub erasebcd 'erase all digits when in decode bcd mode
      for ik=1 to 8: doit ik,b'1111': next ik
    end sub
    
    sub erase 'erase all digits in non-bcd mode
        for ik=1 to 8: doit ik,0: next ik
    end sub
    
    Dim seg(11)
    sub getsegs
    '         dABCDEFG
    seg( 1)=b'01111110' '0       -      1      A
    seg( 2)=b'00110000' '1     |   |  6   2  F   B
    seg( 3)=b'01101101' '2       -      7      G
    seg( 4)=b'01111001' '3     |   |  5   3  E   C
    seg( 5)=b'00110011' '4       -      4      E     dp
    seg( 6)=b'01011011' '5
    seg( 7)=b'01011111' '6
    seg( 8)=b'01110000' '7
    seg( 9)=b'01111111' '8
    seg(10)=b'01111011' '9
    seg(11)=b'10000000' '.
    
    end sub
    
     

    Last edit: Jim giordano 2019-11-15

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.