7 segment digit problem (using Mister E's code)


Closed Thread
Results 1 to 8 of 8
  1. #1
    Join Date
    Feb 2004
    Location
    Michigan, USA
    Posts
    305

    Default 7 segment digit problem (using Mister E's code)

    I searched and found this code...

    ' Pulse counter
    '
    ' File name : Count_Display.bas
    ' Company : Mister E
    ' Programmer : Steve Monfette
    ' Date : 27/12/2004
    ' Device : PIC16F84A-20/P
    ' This program display to 3 x 7 segments dislay the result of
    ' pulses count on PORTA.4 pin/sec.
    '
    ' Hardware connection :
    ' ---------------------
    ' 1. 3 X 7 segments display on PORTB<7:0>
    ' 2. 3 X PNP transistor on PORTA<3:0> to drive common anode
    ' of each 7 segments display
    '
    ' Programming mode and PIC define
    ' -------------------------------
    '
    DEFINE OSC 20 '

    ' I/O Definition
    ' --------------
    '
    TRISA = %11111000 ' PORTA : <2:0> outputs to common Anode of 7 segment
    ' 1. PORTA.0 More significant
    ' 2. PORTA.2 Less significant
    ' : PORTA.4 input for signal
    '
    TRISB = 0 ' PORTB connected to 7 segments
    ' B0 : segment a
    ' B1 : segment b
    ' B2 : segment c
    ' B3 : segment d
    ' B4 : segment e
    ' B5 : segment f
    ' B6 : segment g
    ' B7 : segment decimal dot
    ' Internal EEPROM definition
    ' --------------------------
    '
    data @0,192,249,164,176,153,146,130,248,128,144 ' table to convert
    ' numbers to 7 segments
    ' pattern output when
    ' drive invert



    ' Interrupt and register definition
    ' ---------------------------------
    '
    OPTION_REG = %11101000 ' TMR0 clock source : RA4/T0CKI
    ' increment on low to high transition
    ' Prescaler assign to WDT
    ' WDT rate 1:1
    '
    INTCON = %10100000 ' Enable global interrupt
    ' Disable EE write interrupt
    ' Enable TMR0 overflow interrupt


    ' Variable definition
    ' -------------------
    '
    DisplayPort var PORTB ' Port for 7 Segments
    ClockInput var PORTA.4 ' Input pin for signal
    _7Seg1 con 14 ' enable more significant 7 segment display
    _7Seg2 con 13 ' enable mid significant 7 segment display
    _7Seg3 con 11 ' enable less significant 7 segment display
    Digit_1 var byte ' Hundreds digit
    Digit_2 var byte ' Tenth digit
    Digit_3 var byte ' Unit digit
    ToBeDisplay var word ' Result of count to be send to 7 segment display
    Display var byte ' Temp variable
    DisplayLoop var byte '
    Delay var word ' Variable for Delay loop
    OverFlowVar var word '
    Thousands var bit ' Flag for count >= 1000 & < 10 000
    TenThousands var bit ' Flag for count >= 10 000


    ' Variable and software initialisation
    ' ------------------------------------
    '
    tobedisplay = 0 ' set initial value of count
    TMR0 = $00 ' reset prescaller
    on interrupt goto SetVarToBeDisplay

    MainLoop:

    ' MainLoop
    ' ---------
    '
    ' 1. display the result of the count on RA4 pin
    ' 2. refresh display
    ' 3. reset Timer0
    ' 4. reload prescaler.
    '
    ' Duration of the procedure : 1 sec
    ' fine tuned by DelayBetweenEachDisplay Sub
    '
    ' Looping 1 sec and get results of the pulse count in
    ' TMR0 + OverFlowVar
    '
    DisplayRefresh:
    '
    ' Testing amount of count
    ' -----------------------
    '
    ' Get the result of count and place decimal point flag
    ' on the according 7 segments
    '
    If tobedisplay>=1000 then
    tobedisplay=tobedisplay/10
    if tobedisplay>=1000 then
    tobedisplay=tobedisplay/10
    Thousands=0
    TenThousands=1
    else
    TenThousands=0
    thousands=1
    endif
    else
    thousands=0
    tenthousands=0
    endif
    '
    ' convert digit to 7 segment output pattern
    ' -----------------------------------------
    display=ToBeDisplay dig 2 ' Read hundreds digit
    read display,digit_1 ' Convert hundreds
    if thousands==1 then digit_1=digit_1 & $7F ' enable decimal dot
    ' by clearing PORTB.7

    display=ToBeDisplay dig 1 ' Read tenths digit
    read display,digit_2 ' Convert tenths
    if tenthousands==1 then digit_2=digit_2 & $7F ' enable decimal dot '
    ' by clearing PORTB.7

    display=ToBeDisplay dig 0 ' Read units digit
    read display,digit_3 ' Convert units
    '
    '
    ' Send digit to 7 segments
    ' ------------------------
    for displayloop = 0 to 111 ' loop for about 1 sec

    ' display hundreds
    ' ----------------
    PORTA=_7seg1 ' enable hundreds 7 segment
    displayport=digit_1 ' display
    gosub DelayBetweenEachDigit

    ' display tenth
    ' -------------
    PORTA=_7seg2 ' enable tenth 7 segment
    displayport=digit_2 ' display
    gosub DelayBetweenEachDigit

    ' display units
    ' -------------
    PORTA=_7seg3 ' enable unit 7 segment
    displayport=digit_3 ' display
    gosub DelayBetweenEachDigit

    next
    tobedisplay = overflowvar + TMR0
    OverFlowVar = 0 ' Reset OverFlowVar
    INTCON.2 = 0 ' clear overflow flag
    TMR0 = $D9 ' reset prescaller
    goto displayrefresh


    DelayBetweenEachDigit:

    ' DelayBetweenEachDigit
    ' ---------------------
    ' Produce delay of about 3 mSec
    '
    ' Fine tuned with MPLAB StopWatch to get MainLoop = 1 sec
    '
    for delay=1 to 307
    @ nop
    next
    @ nop
    @ nop
    @ nop
    @ nop
    @ nop
    @ nop
    @ nop
    return


    disable
    SetVarToBeDisplay:
    '
    ' SetVarToBeDisplay
    ' -----------------
    ' interrupt routine of TMR0 overflow
    '
    ' Reset prescaller
    ' Reset overflow flag
    '
    OverFlowVar = OverFlowVar + 256
    INTCON.2 = 0 ' clear overflow flag
    TMR0 = $D9 ' reload TMR0
    resume
    enable

  2. #2
    Join Date
    Feb 2004
    Location
    Michigan, USA
    Posts
    305


    Did you find this post helpful? Yes | No

    Default

    /\/\/\
    I've modified it so that it no longer uses the interupt, but just loops and adds 1 at each loop.
    Its also modified to display on 5 displays, and I will add a 6th shortly. It currently ghosts the numbers on each digit. I played with the timing and cant resolve the problem. Also, what are the CON numbers doing, as I changed them and get different results based on their number? There are 10K pull downs on each base and every segment. There 4.7K's between the pic and the base of each 2n3906.

    Here is my code so far using a 16F818.......

    define OSC 10
    TRISA = %11100000
    TRISB = 0


    data @0,192,249,164,176,153,146,130,248,128,144 ' table to convert
    ' numbers to 7 segments


    DisplayPort var PORTB ' Port for 7 Segments
    ClockInput var PORTA.5 ' Input pin for signal
    _7Seg0 con 5 ' enable tenthousands 7 segment display
    _7Seg1 con 4 ' enable thousands 7 segment display
    _7Seg2 con 3 ' enable hundreds 7 segment display
    _7Seg3 con 2 ' enable tens 7 segment display
    _7Seg4 con 1 ' enable units 7 segment display
    Digit_0 var word ' tenthousands digit
    Digit_1 var word ' thousands digit
    Digit_2 var word ' hundreds digit
    Digit_3 var word ' tens digit
    Digit_4 var word ' Unit digit
    ToBeDisplay var word ' Result of count
    Display var word ' Temp variable
    DisplayLoop var word '
    Delay var word ' Variable for Delay loop
    OverFlowVar var word '
    Thousands var bit ' Flag for count >= 1000 & < 10 000
    TenThousands var bit ' Flag for count >= 10 000





    tobedisplay = 0 ' set initial value of count


    DisplayRefresh:

    ' convert digit to 7 segment output pattern
    ' -----------------------------------------
    display=ToBeDisplay dig 4 ' Read tenthousands digit
    read display,digit_0 ' Convert tenthousands
    if thousands==1 then digit_0=digit_0 & $7F ' enable decimal dot
    ' by clearing PORTB.7

    display=ToBeDisplay dig 3 ' Read thousands digit
    read display,digit_1 ' Convert thousands
    if thousands==1 then digit_1=digit_1 & $7F ' enable decimal dot
    ' by clearing PORTB.7

    display=ToBeDisplay dig 2 ' Read hundreds digit
    read display,digit_2 ' Convert hundreds
    if thousands==1 then digit_2=digit_2 & $7F ' enable decimal dot
    ' by clearing PORTB.7

    display=ToBeDisplay dig 1 ' Read tenths digit
    read display,digit_3 ' Convert tenths
    if tenthousands==1 then digit_3=digit_3 & $7F ' enable decimal dot
    ' by clearing PORTB.7

    display=ToBeDisplay dig 0 ' Read units digit
    read display,digit_4 ' Convert units
    '
    '
    ' Send digit to 7 segments
    ' ------------------------

    for displayloop = 1 to 53
    ' display tenthousands
    ' ----------------
    PORTA=_7seg0 ' enable tenthousands 7 segment
    displayport=digit_0 ' display
    gosub DelayBetweenEachDigit


    ' display thousands
    ' ----------------
    PORTA=_7seg1 ' enable thousands 7 segment
    displayport=digit_1 ' display
    gosub DelayBetweenEachDigit

    ' display hundreds
    ' ----------------
    PORTA=_7seg2 ' enable hundreds 7 segment
    displayport=digit_2 ' display
    gosub DelayBetweenEachDigit

    ' display tenth
    ' -------------
    PORTA=_7seg3 ' enable tenth 7 segment
    displayport=digit_3 ' display
    gosub DelayBetweenEachDigit

    ' display units
    ' -------------
    PORTA=_7seg4 ' enable unit 7 segment
    displayport=digit_4 ' display
    gosub DelayBetweenEachDigit

    next
    tobedisplay = tobedisplay + 1
    goto displayrefresh



    DelayBetweenEachDigit:

    for delay=1 to 307
    @ nop
    next
    @ nop
    @ nop
    @ nop
    @ nop
    @ nop
    @ nop
    @ nop
    return

  3. #3
    Join Date
    May 2005
    Posts
    49


    Did you find this post helpful? Yes | No

    Smile Simple but it works :)

    First this is not a pulse counter.This is only the way that i found by my self.
    Coz there re no command for 7 segment (i hope they will do)
    and u can use like a pulse counter by useing little subrutines

    all PORTB connedted to the 7 segment
    PORTA.1 enable diggit 1
    PORTA.2 enable diggit 2
    i did it without transistor if u want to see better
    u can put a transistor and decrase the pause command
    '''''''''''''''''''''''''''''''''The codes
    sayac VAR BYTE
    dij1 VAR BIT[9]
    dij2 VAR BIT[9]
    sayac=0
    gosterge1:
    IF sayac > 99 Then sayac =0
    dij1 = sayac DIG 0
    High PORTA.1
    IF dij1=0 Then TRISB=%00111111
    IF dij1=1 Then TRISB=%00000110
    IF dij1=2 Then TRISB=%01011011
    IF dij1=3 Then TRISB=%01001111
    IF dij1=4 Then TRISB=%01100110
    IF dij1=5 Then TRISB=%01101101
    IF dij1=6 Then TRISB=%01111101
    IF dij1=7 Then TRISB=%00000111
    IF dij1=8 Then TRISB=%01111111
    IF dij1=9 Then TRISB=%01100111
    Pause 90
    Low PORTA.1
    dij2 = sayac DIG 1
    High PORTA.2
    IF dij2=0 Then TRISB=%00111111
    IF dij2=1 Then TRISB=%00000110
    IF dij2=2 Then TRISB=%01011011
    IF dij2=3 Then TRISB=%01001111
    IF dij2=4 Then TRISB=%01100110
    IF dij2=5 Then TRISB=%01101101
    IF dij2=6 Then TRISB=%01111101
    IF dij2=7 Then TRISB=%00000111
    IF dij2=8 Then TRISB=%01111111
    IF dij2=9 Then TRISB=%01100111
    Pause 90
    Low PORTA.2
    sayac = sayac + 1
    Pause 300
    GoTo gosterge1
    End
    I know it's really simple but i am a newbie i can't do better now
    Last edited by SuB-ZeRo; - 17th June 2005 at 05:16.
    Asking is not a shame but not learning is a SHAME!!!

  4. #4
    Join Date
    Sep 2004
    Location
    montreal, canada
    Posts
    6,898


    Did you find this post helpful? Yes | No

    Default

    This was the audio frequency counter code... posted there
    http://www.picbasic.co.uk/forum/showthread.php?t=1044

    And like i said it's also post on the Melabs website and include the schematics wich can help to figure few things
    http://www.melabs.com/resources/samp...ed/counter.zip

    Also, what are the CON numbers doing, as I changed them and get different results based on their number?
    i always try to make it easy to read but here's a short explanation of those constants because the choice of their value are important in that.

    If you look to the schematic and comments at the top of the original code, PORTA<3:0> is attach to a transistor wich is driving the Common anode on each 7 segment display. Each transistor need to be drive with a low level signal at the base.

    Using constant make the code easier to read.
    _7Seg1 con 14 ' enable more significant 7 segment display

    and later we use...
    PORTA=_7seg1 ' enable hundreds 7 segment

    same as PORTA=14 or PORTA=%11111110
    only the 'hundreds' display is used. When i look to your own definition, you choose more than one 7 segment display at the time so you display on more than one 7 segment at the time. this is one of the reason you see some odd results. few other things now
    • on PIC16F818, PORTA is analogue, you must set it to digital.
    • PORTA.4 is open drain, you'll need to modify your hardware to fit to this pin.
    • to use PORTA.5 you must set your configuration fuse to disable MCLR pin and use it as an i/o
    • don't forget, the original code was made for a 20MHZ crystal speed and will really not do the same things with a 10 MHZ clock since the DelayBetweenEachDisplay is based on a MPLAB stopwatch simulation. you'll need to divide it by 2 to have about the same delay

    Once everything above is done... it's suppose to give better results. well as i see now before to go to sleep...
    Last edited by mister_e; - 17th June 2005 at 15:13.
    Steve

    It's not a bug, it's a random feature.
    There's no problem, only learning opportunities.

  5. #5
    Join Date
    Feb 2004
    Location
    Michigan, USA
    Posts
    305


    Did you find this post helpful? Yes | No

    Default

    Hey Steve thanks for the info. It now works perfectly. I still have to add the 6th digit, and it currently only counts up to 65000 before rolling over. I need to put the count in 2 locations and use them to get up to 999999. Im not sure how to do that. Any idea? lowbyte and hibyte?

    Here is the updated code. The display rate is set very fast to count up quickly.

    define OSC 10
    TRISA = %11100000
    ADCON1 = 0
    TRISB = 0


    data @0,192,249,164,176,153,146,130,248,128,144 ' table to convert
    ' numbers to 7 segments
    ' pattern output when
    ' drive invert


    DisplayPort var PORTB ' Port for 7 Segments
    ClockInput var PORTA.5 ' Input pin for signal
    _7Seg0 con 207 ' enable tenthousands 7 segment display
    _7Seg1 con 215 ' enable thousands 7 segment display
    _7Seg2 con 222 ' enable hundreds 7 segment display
    _7Seg3 con 221 ' enable tens 7 segment display
    _7Seg4 con 219 ' enable units 7 segment display
    Digit_0 var word ' tenthousands digit
    Digit_1 var word ' thousands digit
    Digit_2 var word ' hundreds digit
    Digit_3 var word ' tens digit
    Digit_4 var word ' Unit digit
    ToBeDisplay var word ' Result of count to be send to 7 segment display
    Display var word ' Temp variable
    DisplayLoop var word '
    Delay var word ' Variable for Delay loop
    OverFlowVar var word '
    Thousands var bit ' Flag for count >= 1000 & < 10 000
    TenThousands var bit ' Flag for count >= 10 000





    tobedisplay = 0 ' set initial value of count


    DisplayRefresh:

    ' convert digit to 7 segment output pattern
    ' -----------------------------------------
    display=ToBeDisplay dig 4 ' Read tenthousands digit
    read display,digit_0 ' Convert tenthousands
    if thousands==1 then digit_0=digit_0 & $7F ' enable decimal dot
    ' by clearing PORTB.7

    display=ToBeDisplay dig 3 ' Read thousands digit
    read display,digit_1 ' Convert thousands
    if thousands==1 then digit_1=digit_1 & $7F ' enable decimal dot
    ' by clearing PORTB.7

    display=ToBeDisplay dig 2 ' Read hundreds digit
    read display,digit_2 ' Convert hundreds
    if thousands==1 then digit_2=digit_2 & $7F ' enable decimal dot
    ' by clearing PORTB.7

    display=ToBeDisplay dig 1 ' Read tenths digit
    read display,digit_3 ' Convert tenths
    if tenthousands==1 then digit_3=digit_3 & $7F ' enable decimal dot '
    ' by clearing PORTB.7

    display=ToBeDisplay dig 0 ' Read units digit
    read display,digit_4 ' Convert units
    '
    '
    ' Send digit to 7 segments
    ' ------------------------

    for displayloop = 1 to 10 'was 53
    ' display tenthousands
    ' ----------------
    PORTA=_7seg0 ' enable tenthousands 7 segment
    displayport=digit_0 ' display
    gosub DelayBetweenEachDigit


    ' display thousands
    ' ----------------
    PORTA=_7seg1 ' enable thousands 7 segment
    displayport=digit_1 ' display
    gosub DelayBetweenEachDigit

    ' display hundreds
    ' ----------------
    PORTA=_7seg2 ' enable hundreds 7 segment
    displayport=digit_2 ' display
    gosub DelayBetweenEachDigit

    ' display tenth
    ' -------------
    PORTA=_7seg3 ' enable tenth 7 segment
    displayport=digit_3 ' display
    gosub DelayBetweenEachDigit

    ' display units
    ' -------------
    PORTA=_7seg4 ' enable unit 7 segment
    displayport=digit_4 ' display
    gosub DelayBetweenEachDigit

    next
    tobedisplay = tobedisplay + 1
    goto displayrefresh



    DelayBetweenEachDigit:

    ' DelayBetweenEachDigit
    ' ---------------------
    ' Produce delay of about 3 mSec
    '
    ' Fine tuned with MPLAB StopWatch to get MainLoop = 1 sec
    '
    for delay=1 to 5 'was 307
    @ nop
    next
    @ nop
    @ nop
    @ nop
    @ nop
    @ nop
    @ nop
    @ nop
    return

  6. #6
    Join Date
    Feb 2004
    Location
    Michigan, USA
    Posts
    305


    Did you find this post helpful? Yes | No

    Default

    Here's an update to the code. Darrel has done all the hard work, so a big thank you to him.
    It currently counts all the way up to 99999.9 hours. All thats remaining is to work the bugs out of the eeprom storage. The project has to store the number accumulated so that when power is restored, we dont start logging hours from 0 again.


    Regards,
    James.
    Attached Files Attached Files

  7. #7
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default

    Hey James,

    I thinks it's just that there is already data at locations 0-10 for the seven segment decoding.

    Try moving the EE_Hours constant to somewhere above that.

    Darrel

  8. #8
    highlander's Avatar
    highlander Guest


    Did you find this post helpful? Yes | No

    Default

    I've been reading thru the code and am currently working on my own program based on Mr_E's program for 3 digits. I'm actually modding it to work with 2 and am having a slight issue. I'm definitely a newbie on this but could use some pointers.

    My current setup is to have PortA pins 0 and 1 be inputs for sensors I'm hooking up. PortA 2 and 3 are hooked up to the transistors as described on meLabs site for the 7seg 4 display. And planning to use either a pin on PortB or PortA pin 5 to drive a motor.

    Now on my understanding this would result into what I want

    TRISA = %11110011 <--- 0011 being outputs to transistors and inputs from sensors

    TRISB = %11111110 <-- 0 being the motor servo

    Now is there anything else that may cause a issue with doing it this way where the 1st 7dig segment doens't light up and the 2nd would cycle thru erronous LED's lighting up?

    I could go into more detail but being I'm at work, I can't really go into it at the moment. But any hints would be helpful. Thanks

Similar Threads

  1. Making Program Code Space your playground...
    By Melanie in forum Code Examples
    Replies: 15
    Last Post: - 19th July 2008, 08:26
  2. pic18F code size problem???
    By dogi in forum mel PIC BASIC Pro
    Replies: 2
    Last Post: - 7th March 2005, 21:52
  3. WRITE not working
    By servo260 in forum mel PIC BASIC Pro
    Replies: 31
    Last Post: - 29th December 2004, 02:02
  4. Driver code for 14 segment LED display
    By Durward Searcy in forum mel PIC BASIC Pro
    Replies: 4
    Last Post: - 12th December 2004, 20:08
  5. Multiplex two 7 segment display
    By Fernando Santos in forum mel PIC BASIC Pro
    Replies: 0
    Last Post: - 20th July 2003, 13:26

Members who have read this thread : 1

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts