By George I think he has it![]()
Dave
Always wear safety glasses while programming.
Mack,
Thank you for your help today. I can't believe I had so much trouble with that. I wrote a program in mumps a few years ago that converted a number to base 36 for this wacky interface checksum I had to write and I don't think I struggled that hard.
I was able to use my knew found logic and incoporate that same philosphy into my 10 bit program I originally started to work on but stepped back from to get the 8bit to work and understand this a little better. I know you pointed out a couple things about the high and low bits. I won't try to kid you I am not sure what you were trying to tell me there. I put this program together from bits and pieces by looking at others and their examples.
I can run this side by side with the 8 bit program and I get the same results. Is there any advatage of reading the analog value using ADCIN vs. Bruces example? Any disadvatages?
Thanks again today.
David
INCLUDE "modedefs.bas"
' Hardware specific settings
@ DEVICE pic16F877, XT_OSC ' System Clock Options
@ DEVICE pic16F877, WDT_ON ' Watchdog Timer
@ DEVICE pic16F877, PWRT_ON ' Power-On Timer
@ DEVICE pic16F877, BOD_ON ' Brown-Out Detect
@ DEVICE pic16F877, LVP_ON ' Low-Voltage Programming
@ DEVICE pic16F877, CPD_OFF ' Data Memory Code Protect
@ DEVICE pic16F877, WRT_ON ' Flash Memory Word Enable
' ADC definitions 16F877 - (8) 10bit channels
'*****************************
DEFINE ADC_BITS 10 ' (8) 10 Bit channels
DEFINE ADC_CLOCK 3 ' tell the us per osc clock tick?
DEFINE ADC_SAMPLEUS 50 ' how long to sample the pin
DEFINE OSC 10
DEFINE LOADER_USED 1
'INIT ADC
ADCON1 = %10001110 ' Just one analog input needed see page 112 of 16f877 spec
ADCON0 = %11000001 ' Analog converter Fosc/32, ADC module is ON
ADCON0.7 = 1 'I DID THAT ABOVE RIGHT DO I NEED TO RESET THIS OR
'DID MISS SOMETHING ABOUT SETTING VALUES THIS WAY?
'Varibles
SO VAR PORTC.6
ADval VAR word ' Storage for A/D result
PRESSURE VAR word
PRESS VAR word
ADavg VAR WORD[2]
READING var byte
Value VAR WORD
RES var word
'CONSTANTS
AvgCount CON 64 ' = Number of samples to average
FAspread CON 25 ' = Fast Average threshold +/-
BAUD CON 32
'**************************************
'****START OF PROGRAM*****
'**************************************
BEGIN:
SerOut2 SO,baud,[12,"Hello World 10 bit AD Test",10,13]
pause 2000
Serout2 so,baud,[27,"[2;1H","Pressure: "]
MAINLOOP:
ADCIN 0,adval ' Read A/D channel 0 to adval variable
adval = adval - 96
res = adval * 1953
adval = div32 1000
'average out press first before calcuating true pressure
READING = 1
value = adval
gosub average
press = value
Serout2 so,baud,[27,"[2;11H",DEC5 PRESS]
'PRESSURE = ( 58 * PRESS - 58 ) / 100
'pressure = ( 1464 * press - 1464 ) / 10
'value = pressure
'READING = 2
'GOSUB AVERAGE
'PRESSURE = VALUE
'Serout2 so,baud,[27,"[1;11H",DEC5 PRESSURE]
Pause 200 ' Wait period between updates
GOTO MAINLOOP
END
' -=-=-=-=-=-= Average Analog values -=-=-=-=-=-=-=-=-=-=
' compliments of Darryl Taylor
AVERAGE:
IF Value = ADavg[READING] Then NoChange
IF ABS (Value - ADavg[reading]) > FAspread OR Value < AvgCount Then FastAvg
IF ABS (Value - ADavg[reading]) < AvgCount Then RealClose
ADavg[reading] = ADavg[reading] - (ADavg[reading]/AvgCount)
ADavg[reading] = ADavg[reading] + (Value/AvgCount)
GoTo AVGok
FastAvg:
ADavg[reading] = Value
GoTo AVGok
RealClose:
ADavg[reading] = ADavg[reading] - (ADavg[reading]/(AvgCount/4))
ADavg[reading] = ADavg[reading] + (Value/(AvgCount/4))
AVGok:
Value = ADavg[reading] ' Put Average back into Value
NoChange:
Return
I like Bruce's example because I feel it allows more control.Is there any advatage of reading the analog value using ADCIN vs. Bruces example? Any disadvatages?
Example:
I can when reading multiple channels, or one channel for that matter, switch from 8 or 10 bit with
ADCON1.7 = 1
or
ADCON1.7 = 0
I have not checked to see if one way is faster or uses less code space.
Dave
Always wear safety glasses while programming.
Mack,
Gotcha that would make sense. If you don't mind can we discuss the 8 bit vs. 10bit and let me rant a little about some observations. With regards to the ADC isn't just the obvious difference between reading 8 bit vs. 10 bit just precision? There is nothing else to consider is there? I can either get a return value from 0 -> 255 or 0 -> 1024. One thing I noticed given the 8 bit response it tends to not bounce around as much as the 10 bit. The 10 bit response raw data when I am at 0psi bounces all over the place from 92 to 100. I have to run that through Darryl's average routine to get that stablized. That helps but doesn't stop it completely which brings me to a question is there any way to get that to settle down? The other question is whats the proper term for a signle interval on the ADC read? Is it tick or interval, increment?
My other observation/question based on your statment about switching back and fourth between 10 bit and 8 bit. From my observations and looking at many examples of code there is always more then one way to accomplish something in the coding. I didn't miss anything here right I mean:
ADCON1 = %10000000
'ADCON1.7 = 1 'I DID THAT ABOVE RIGHT?
Setting ADCON1.7 = 1 is essentially the same thing as my example correct? You're just setting the individual bit right?
After this experience and reviewing what you taught me and looking at Bruce's example more closely that you could accomplish the 8 bit using the ADCIN by just setting ADC_BITS=8 in the beginning and the read on ADCIN basically puts both the ADRESH and ADRESL together for you in your variable. If you choose to use Bruce's method and wanted to do the 10 bit you've got to put those two result registers together right? Setting ADC_BITS is a one time thing at the beginning?
It's tough even with the datasheet until someone get's you pointed in the right direction. I think I am intellegent and I should be able to figure this stuff out but thats not always so. Now that you've given me direction it's much clearer I appreciate the help I get from this forum.
Good morning
David
Just a precision thing. With more precision you can can expect more "bouncing" sometimes noise will cause this or the sensor it's self. A lot of sensors a pretty sensitiveSometimes a capacitor from the ADC pin to zero will help smooth thing out, This may even be needed with some 8 bit applications.
Yep there is always more than one way do do anything. I coding we call this a style.My other observation/question based on your statment about switching back and fourth between 10 bit and 8 bit. From my observations and looking at many examples of code there is always more then one way to accomplish something in the coding. I didn't miss anything here right I mean:
For your chipADCON1 = %10000000
'ADCON1.7 = 1 'I DID THAT ABOVE RIGHT?
Setting ADCON1.7 = 1 is essentially the same thing as my example correct? You're just setting the individual bit right?
ADCON1 = %10000000
makes all of th ADC pins analog, left justified, VREF+ at VDD and VREF- at VSS.
If you want some of the ADC pins digital or change the VREFs then you will run into a problem.
ADCON1.7 = 1 or 0 is just changing that particular bit.
Not quite... In the data sheet I have for this chip take a look at section 11.4.1.After this experience and reviewing what you taught me and looking at Bruce's example more closely that you could accomplish the 8 bit using the ADCIN by just setting ADC_BITS=8 in the beginning and the read on ADCIN basically puts both the ADRESH and ADRESL together for you in your variable. If you choose to use Bruce's method and wanted to do the 10 bit you've got to put those two result registers together right? Setting ADC_BITS is a one time thing at the beginning?
The register containing ADRESH and ADRESL is really 16 bits wide. ADRESH and ADRESL are 8 bits each.
This all can be quite confusing, if this forum was not here I would not have a clue either.It's tough even with the datasheet until someone get's you pointed in the right direction. I think I am intellegent and I should be able to figure this stuff out but thats not always so. Now that you've given me direction it's much clearer I appreciate the help I get from this forum.
Dave
Always wear safety glasses while programming.
I have a similar problem, I got everything to work, except translating the math.
My lowest ADVAL is 0 and it's also the HIGHEST pressure.
I saw how the math worked out for him, but I am lost.
************************************************** ***********************
Why insist on using 32 Bits when you're not even able to deal with the first 8 ones ??? ehhhhhh ...
************************************************** ***********************
IF there is the word "Problem" in your question ...
certainly the answer is " RTFM " or " RTFDataSheet " !!!
*****************************************
What if I switched the VRef+ and Vref- to
Vref+ = 0v
Vref- = 5v
Would that work?
Bookmarks