News:

Let's find out together what makes a PIC Tick!

Main Menu

Simple adc values on 4 digit seven segment display

Started by Amod, Jun 17, 2021, 06:06 PM

Previous topic - Next topic

Amod

Hello,

Is there any simple way to read 10 bit adc and display it over four digit seven segment display with decimal point selectable.

trastikata

Hello,

can you elaborate a bit more on your question. It is too broad and vague - what do you mean by "simple", are you asking for the hardware or software part etc ... ?

Regards

Amod

It's a software part. I have done this but my way is very lenthy.

trastikata

Right now, I don't mean to be rude, it sounds a bit like you are asking for somebody else to write the entire program.  Maybe you can post the code part that troubles you and then we can advise on it and give examples. Also sharing the hardware diagram with the 7-LED connections is advisable to have better idea what you do.

Amod

This code is working very well but its too lenthy.



 Device 16F886
Xtal 20


All_Digital On
Include "MODEDEFS.BAS"


 Dim DG1 As Byte       
 Dim DG2 As Byte   
 Dim dg3 As Byte
 Dim DG4 As Byte
 Dim DIGIT As Byte
 Dim DG As Byte
 Dim COUNTT As Byte
 Dim result1 As Float
 Dim NUMB As Dword
 Dim N As Dword
 Dim adval As Dword
 Dim temP As Dword
 Dim TEMPP As Dword
 Dim Last_Result1 As Float
 Dim O As Byte
 
 
 ADCON1=%10000000
 ADCON0=%01000011
 TRISA=%00111101           
 TRISB=0   
 TRISC=%11110000           
 ANSELH=%00000001
 ANSEL=%00000001
 CM1CON0=0
 CM2CON0=0
 VRCON=0
 
 Declare Adin_Res 10 ' 10-bit result required
 Declare Adin_Tad FRC ' RC OSC chosen
 Declare Adin_Stime 50 ' Allow 50us sample time
 
 Symbol Input1 = PORTA.0
 GoSub DIGITCALC
 N=NUMB
 DelayMS 1000
     
   
'-------------------------------------------------------------------------
 
                        ADCON0=%01000011

                       MAIN:
                        result1 = ADCON0
                       
                        N=result1
                        GoSub DISPLAY
                        GoSub DIGITCALC
                       
                        GoTo MAIN
                       
                       
                                               
 DISPLAY:
       
       
        For COUNTT=0 To 99

        PORTB=DG1
        PORTC.3=0
        DelayUS 100
        PORTC.3=1

        PORTB=DG2
        PORTC.2=0
        DelayUS 100
        PORTC.2=1

        PORTB=dg3
        PORTC.1=0
        DelayUS 100
        PORTC.1=1
       
        PORTB=DG4
        PORTC.0=0
        DelayUS 100
        PORTC.0=1

        Next COUNTT

        Return

     
DIGITCALC:

DIGIT=0
LP1:
If N<1000 Then DS1
N=N-1000
DIGIT=DIGIT+1
GoTo LP1
        DS1:
        GoSub FND
        DG1=DG
       

DIGIT=0
LP2:
If N<100 Then DS2
N=N-100
DIGIT=DIGIT+1
GoTo LP2

        DS2:
        GoSub FND
        DG2=DG
       
       
DIGIT=0
LP3:
If N<10 Then DS3
N=N-10
DIGIT=DIGIT+1
GoTo LP3

        DS3:
        GoSub FND
        dg3=DG

DIGIT=N
GoSub FND
DG4=DG
 
Return




FND:

FND0:
If DIGIT>0 Then FND1
DG=%00000011                       '%0111 1110     
GoTo FNDEND

FND1:
If DIGIT>1 Then FND2
DG=%10011111                       '%0100 1000     
GoTo FNDEND

FND2:
If DIGIT>2 Then FND3
DG=%00100101                       '%0011 1101     
GoTo FNDEND

FND3:
If DIGIT>3 Then FND4
DG=%00001101                       '%0110 1101     
GoTo FNDEND

FND4:
If DIGIT>4 Then FND5
DG=%10011001                       '%0100 0011     
GoTo FNDEND

FND5:
If DIGIT>5 Then FND6
DG=%01001001                       '%0110 0111     
GoTo FNDEND

FND6:
If DIGIT>6 Then FND7
DG=%01000001                       '%0111 0111     
GoTo FNDEND

FND7:
If DIGIT>7 Then FND8
DG=%00011111                       '%0100 1100     
GoTo FNDEND

FND8:
If DIGIT>8 Then FND9
DG=%00000001                       '%0111 1111     
GoTo FNDEND

FND9:
DG=%00011001                       '%0110 1111     

FNDEND:
Return
'______________________________


trastikata

Quote from: Amod on Jun 18, 2021, 08:29 AMThis code is working very well but its too lenthy.

Do you mean it takes too much processing time or the code generated takes a lot of programming memory?

By the way I noticed in your program "result1 = ADCON0" and then you display result1?

Amod

result1 = ADCON0" and then you display result1?

Yes.

trastikata

Quote from: Amod on Jun 18, 2021, 09:10 AMresult1 = ADCON0" and then you display result1?

Yes.

There is a lot of inconsistency in your code and I seriously doubt it works "very well".

1. ADCON0 is the A/D Control Register - so you are displaying the Control Register - so not really clear what are you trying to do!
2. You Declare All_Digital and TAD = FRC and then you change it with the ADCON registers in your code.
3. A lot of unnecessary code and declarations which make no sense
4. You have no conversion from ADC bits to another meaningful value - so why do you insist on "decimal point selectable" if you don't have a floating point variable?
5. It is still not clear what do you need help with - if the code works "very well" what do you need to happen - speed optimization, size optimization etc?

Amod

 Sorry if I am rude.
I think you don't want to help.

trastikata

Quote from: Amod on Jun 18, 2021, 09:55 AMSorry if I am rude.
I think you don't want to help.

On the contrary I want to help - if I didn't want, I wouldn't take the time to look at your code, it is just not clear what exactly do you need help with?

Stephen Moss

You say the code is working very well but I cannot see how when...
As trastikata said you appear to be loading the result of the ADC conversion with the value of the ADCON0 (ADC Control 0) register when the result is stored in the ADRES registers.

You have Declared result1 as Float but in your Main code are loading it with the ADC result which is an integer, I can see nothing in your code that would convert it into a float, i.e. result = result * 1.3 so why not declare it as Word. 

You are mixing methods of doing things, you are writing to the ADCON registers to configure the ADC and then doing the same thing again using the ADC declares, it would be better to stick to one method or the other. Generally, I would say write to registers if you are writing your own ADC read code or use the Declares when using the compilers ADin command to perform the conversion which will also take care of the next item.

In you Main loop you have left no time for the ADC conversion to complete, you start the conversion by writing to ADCON0 immediately before your main loop and the first thing in your main loop it to read the result.
If you had read section 9.2.6 of the datasheet you would know that if not using the compilers ADin command you need to either put in a long enough delay for the conversion to finish, do a loop that polls the GO/Done Bit until it goes to 0 indicating the conversion has finished or use the ADC Interrupt and read the result within the interrupt handler.

There is nothing in your main loop to trigger any subsequent ADC reads, surely you would want to take more than one reading.

Unless you are using a rather old copy of the compiler there is no point using the All_Digital command, it has been obsolete for some time and does nothing. The compiler automatically sets all inputs as Digital so you do not need to do it yourself unless you have changed a pin to Analogue and then want to change it back to digital.

Try looking at the "Dig" and "Decimal Digit Extract" sections of the manual they may provide you with a better solution to get the digit you want to display.

In your main loop you have...
result1 = ADCON0
N = result1
Ignoring the already addresses ADCON0 issue here, why load the ADC result into result1 and then copy it to N instead of loading it into N directly?
Additionally, you have dimensioned N as Dword, so even if result1 held a float value I think it would be converted back to an integer for N as N is not dimensioned as a float which may not be what you wanted.

For the FND subroutine you might want to take at look at the Compilers Select-Case function, It may not increase speed much as it does essentially the same thing but the resulting code looks neater, i.e.
 Select Digit
   Case = 0
   DG=%00000011                       '%0111 1110

   Case = 1
   DG=%10011111                       '%0100 1000   


Amod

this is temperature controller program.






;-------------------------------------------------------------------------------
;**** Added by Fuse Configurator ****
; Use the Fuse Configurator plug-in to change these settings

Device = 16F886

Config1 FOSC_INTRC_NOCLKOUT, WDTE_OFF, PWRTE_OFF, MCLRE_OFF, CP_OFF, CPD_OFF, BOREN_OFF, IESO_OFF, FCMEN_OFF, LVP_OFF, DEBUG_OFF
Config2 BOR4V_BOR40V, WRT_OFF

;**** End of Fuse Configurator Settings ****
;-------------------------------------------------------------------------------





 Xtal 4
 OSCCON=%01110001
 All_Digital On


 Dim DG1 As Byte       
 Dim DG2 As Byte   
 Dim DG3 As Byte
 Dim DG4 As Byte
 Dim DIGIT As Byte
 Dim DG As Byte
 Dim COUNTT As Byte
 Dim i As Byte
 Dim J As Byte
 Dim NUMB As Word
 Dim N As Float
 Dim ADVAL As Float
 Dim temp As Word
 Dim TEMPP As Word
 Dim RESULT1 As Float
 Symbol avgcount=20
 Dim value As Float
 Dim AD As Word
 Dim II As Byte
 Dim cntn As Byte
 Dim avrg As Word
 
 
 ADCON1=%10000000
 ADCON0=%01000011
 TRISA=%00111101           
 TRISB=%00000000   
 TRISC=%11110000           
 ANSELH=0
 ANSEL=0
 CM1CON0=0
 CM2CON0=0
 VRCON=0
 
 
 
 
 
;display UER1 for 5 seconds
 For i=0 To 999
 '
 DG=$C7
 
 PORTB=DG
 PORTC.3=0
 DelayUS 5000
 PORTC.3=1
 
 DG=$61
 
PORTB=DG
PORTC.2=0
DelayUS 5000
PORTC.2=1
 
 DG=$F4

 PORTB=DG
 PORTC.1=0
 DelayUS 5000
 PORTC.1=1
 
 DG=$9F
 
 PORTB=DG
 PORTC.0=0
 DelayUS 5000
 PORTC.0=1
 

 Next i
 
 
 
 
 
 GoSub MREAD
 GoSub DIGITCALC
 
 
 

 N=NUMB
 
 
     
   
'-------------------------------------------------------------------------
 
 MAIN1:
 
 GoSub DISPLAY
 
 If PORTA.2=0 Then MREAD
 
 If PORTA.2=1 Then MAIN
 
 
 
                         
                       ;adc routine
                       MAIN:
                        RESULT1 = ADIn 0
                        ADVAL=RESULT1
                        N = ADVAL
                       
                       
                        GoSub DISPLAY
                        GoSub DIGITCALC
                       
                        If ADVAL >= NUMB Then PORTA.6=0
                        If ADVAL <= NUMB-10 Then PORTA.6=1
 
                       
                        GoTo MAIN1

                       
                       
                    ;set point routine

                     UP:
                     If NUMB=999 Then MAIN
                     NUMB=NUMB+1
                     N=NUMB
                     GoSub DISPLAY
                     GoSub DIGITCALC
                     If PORTA.3=0 Then memory
                     GoTo MAIN1
                     
                     
                     memory:
                     EWrite 00,[NUMB]     
                     
                     GoTo MAIN1

                    '_____________________________________

                     DOWN:
                     If NUMB=0 Then MAIN      'MIN LIMIT
                     NUMB=NUMB-1
                     N=NUMB
                     GoSub DISPLAY
                     GoSub DIGITCALC
                     If PORTA.4=0 Then memory
                     GoTo MAIN1
                     
                     
                    '_____________________________________
                    MREAD:
                    NUMB = ERead 00
                   
                    N=NUMB
                    GoSub DISPLAY
                    GoSub DIGITCALC
                    If PORTA.3=0 Then UP
                   
                    If PORTA.4=0 Then DOWN
                   
                    GoTo MAIN1
                   
                   
                   
 'Thermocouple break TCB:           
 'for O=1 to 999 
                   
 'DG=$E1
 'PORTB=DG
 'PORTC.3=0
 'PAUSEus 3000
 'PORTC.3=1
 
 'DG=$E5
 'PORTB=DG
 'PORTC.2=0
 'PAUSEus 3000
 'PORTC.2=1
 
 'DG=$C1
 'PORTB=DG
 'PORTC.1=0
 'PAUSEus 3000
 'PORTC.1=1
 
 'DG=$F5
 'PORTB=DG
 'PORTC.0=0
 'PAUSEus 3000
 'PORTC.0=1
 

 'NEXT O             
                 
                     
                     
                     
     
        DISPLAY:
       
       
        For COUNTT=0 To 99

        PORTB=DG1
        PORTC.3=0
        DelayUS 100
        PORTC.3=1

        PORTB=DG2
        PORTC.2=0
        DelayUS 100
        PORTC.2=1

        PORTB=DG3
        PORTC.1=0
        DelayUS 100
        PORTC.1=1
       
        PORTB=DG4
        PORTC.0=0
        DelayUS 100
        PORTC.0=1

        Next COUNTT

        Return

       '________________________________________________________________



'__________________________________________________________________________
DIGITCALC:

DIGIT=0
LP1:
If N<1000 Then DS1
N=N-1000
DIGIT=DIGIT+1
GoTo LP1
        DS1:
        GoSub FND
        DG1=DG
       

DIGIT=0
LP2:
If N<100 Then DS2
N=N-100
DIGIT=DIGIT+1
GoTo LP2

        DS2:
        GoSub FND
        DG2=DG
       
       
DIGIT=0
LP3:
If N<10 Then DS3
N=N-10
DIGIT=DIGIT+1
GoTo LP3

        DS3:
        GoSub FND
        DG3=DG - 1   'decimal point

DIGIT=N
GoSub FND
DG4=DG
 
Return



'__________________________________________________________________________


'__________________________________________________________________________
FND:

FND0:
If DIGIT>0 Then FND1
DG=%00000011                       '%0111 1110     
GoTo FNDEND

FND1:
If DIGIT>1 Then FND2
DG=%10011111                       '%0100 1000     
GoTo FNDEND

FND2:
If DIGIT>2 Then FND3
DG=%00100101                       '%0011 1101     
GoTo FNDEND

FND3:
If DIGIT>3 Then FND4
DG=%00001101                       '%0110 1101     
GoTo FNDEND

FND4:
If DIGIT>4 Then FND5
DG=%10011001                       '%0100 0011     
GoTo FNDEND

FND5:
If DIGIT>5 Then FND6
DG=%01001001                       '%0110 0111     
GoTo FNDEND

FND6:
If DIGIT>6 Then FND7
DG=%01000001                       '%0111 0111     
GoTo FNDEND

FND7:
If DIGIT>7 Then FND8
DG=%00011111                       '%0100 1100     
GoTo FNDEND

FND8:
If DIGIT>8 Then FND9
DG=%00000001                       '%0111 1111     
GoTo FNDEND

FND9:
DG=%00011001                       '%0110 1111     

FNDEND:
Return
'______________________________

RGV250

Hi,
There are people trying to help and I applaud them, in my case I find the total lack of comments in your code off putting.
I have found from previous experience that although you may understand your code now, in 6 months time it will seem unintelligible so it is worth commenting even the most basic things.
It also does not help when you are asking others to assist, just my observation.

Regards,
Bob