Any one have a sample of how to oversample the adc
Thanks Burt
oversampling adc
Moderators: David Barker, Jerry Messina
-
- Swordfish Developer
- Posts: 1469
- Joined: Fri Jan 30, 2009 6:27 pm
- Location: US
Re: oversampling adc
Here's a module that should do it.
To use it, set the '#option ADC_BITS' to match the ADC of your device (ie 10, 12, etc)
and set '#option OVERSAMPLE_BITS' to the number of bits you want to increase it by.
example test code:
To use it, set the '#option ADC_BITS' to match the ADC of your device (ie 10, 12, etc)
and set '#option OVERSAMPLE_BITS' to the number of bits you want to increase it by.
Code: Select all
module adc_oversample
// note: you need to setup the ADC before calling oversample()
// make sure it's set to "right-justify"
include "adc.bas"
include "math.bas"
// current number of ADC bits (device-dependent)
#option ADC_BITS = 10
const _adc_bits = ADC_BITS
// number of bits to increase resolution by
#option OVERSAMPLE_BITS = 4
const _num_bits = OVERSAMPLE_BITS
// set a type for the sample count based on how many oversample bits (saves some code)
#if (OVERSAMPLE_BITS < 4)
type sample_count_t = byte
#elseif (OVERSAMPLE_BITS < 8)
type sample_count_t = word
#else
type sample_count_t = longword
#endif
// number of sample averages
dim num_samples as sample_count_t
// this returns the "max ADC reading" accounting for the number of increased bits
// you can use this to scale the oversample() result
public function max_oversample() as longword
result = pow(2, _adc_bits + _num_bits) - pow(2, _num_bits)
end function
// this function returns a single adc reading
function read_adc(chan as byte) as word
result = ADC.Read(chan)
'result = pow(2, _adc_bits)-1 // just return max adc reading (useful for debugging)
end function
// read adc with oversampling
public function oversample(chan as byte) as longword
dim acc as longword,
i as sample_count_t
// first time through we need to compute the number of samples
// to average, which is 4^OVERSAMPLE_BITS
if (num_samples = 1) then
num_samples = pow(4, _num_bits)
endif
// accumulate samples
acc = 0
for i = 1 to num_samples
acc = acc + read_adc(chan)
next
// divide the sum by 2^OVERSAMPLE_BITS (by shifting right)
acc = acc >> _num_bits
result = acc
end function
// init
num_samples = 1
end module
Code: Select all
#option ADC_BITS = 10 // set exisiting ADC resolution (check your device)
#option OVERSAMPLE_BITS = 2 // desired number of bits to increase resolution by
include "oversample.bas"
include "adc.bas"
dim adc_max as longword,
adc_result as longword
//setup adc as appropriate (make sure it's set to right-justify)
adc.setconvtime(FOSC_16)
adc.setacqtime(10)
// get new "ADC max reading" so we can scale result
adc_max = max_oversample()
// read ADC chan 1 with oversampling
adc_result = oversample(1)
Re: oversampling adc
I got a problem I think windows 10 changed something when I complie it doesn't use any of the library's
Got to maybe reinstall swordfish. The asm doesn't have the adc code set at all in it. I tried the sample from swordfish it gives no LCD output
Got to maybe reinstall swordfish. The asm doesn't have the adc code set at all in it. I tried the sample from swordfish it gives no LCD output
-
- Swordfish Developer
- Posts: 1469
- Joined: Fri Jan 30, 2009 6:27 pm
- Location: US
Re: oversampling adc
Can't help you there, Burt.
I'll be installing Windows 10 Real Soon Now. Honest. Really...
I'll be installing Windows 10 Real Soon Now. Honest. Really...
Re: oversampling adc
I've tried a sample like this
Theres No ADC ouput at all.
But If I just send text the LCD works fine as long as I leave the ADC stuff out.
I don't understand what's happening there I looked at ths ASM code and it's like it's never running it.
I simulated it and the ADC pins never change to read ADC on pin AN0
Code: Select all
Device = 18F2550
Clock = 20
#option LCD_DATA = PORTB.4
#option LCD_RS = PORTB.1
#option LCD_EN = PORTB.2
// uses LCD and AD libraries...
Include "LCD.bas"
Include "ADC.bas"
Include "convert.bas"
// read the AD port and scale for 0 - 5 volts...
Function ADInAsVolt() As Word
result = (ADC.Read(0) + 1) * 500 / 1024
End Function
// sampled AD value...
Dim ADVal As Word
// initialise and clear LCD...
ADCON1 = $07 // PORTE as digital (LCD)
TRISA.0 = 1 // configure AN0 as an input
ADCON1.7 = 1 // set analogue input on PORTA.0
DelayMS (500)
LCD.Cls
// main program loop...
While true
ADVal = ADInAsVolt
LCD.MoveCursor (1,1)
LCD.Write("DC Volts = ", DecToStr(ADVal / 100), ".", DecToStr(ADVal, 2), " ")
DelayMS(250)
Wend
But If I just send text the LCD works fine as long as I leave the ADC stuff out.
I don't understand what's happening there I looked at ths ASM code and it's like it's never running it.
I simulated it and the ADC pins never change to read ADC on pin AN0