help setting up 16F886 for ADC
I'm trying to use adcin to read two different pots to get 8 bit results and I'm having trouble. I'm using the internal oscillator (there is no external oscillator). The pots are connected to AN0 and AN1
' Define ADCIN parameters ********************************
Define ADC_BITS 8 ' Set number of bits in result
Define ADC_SAMPLEUS 50 ' Set sampling time in uS
'Define ADC_CLOCK 3 ' This define is inoperative on 16F88x
ADCON0 = %11000000 ' Set ADC_CLOCK to RC (DEFINE ACD_CLOCK inoperative on the 16F88x)
ADCON1 = %00000000 ' Left-Justify result in ADRESH:ADRESL registers
ANSEL = %00000011 ' Set AN0, AN1 to analog, others digital
ANSELH = %00000000 ' Set AN8 and higher channels to digital operation
'************************************************* *********
I just copied the code from the LAB-X1 "adcin3x" sample program for the 16F887. I figured it would work the same for the 16F886 since it's basically a 28 pin version of the 16F887, but it doesn't seem to be working. I figured the problem was that the LAB-X1 uses a 4MHz external oscillator, but I've tried different setting on ADCON0 and it doesn't seem to change anything.
Re: help setting up 16F886 for ADC
I think that the code "adcin3x" is for the old pic16F877, not a pic16f887. The adc in the newer chips have more registers. I have found the adcin command does not always work. So I use a manual set and read routine. Below is an example for 10bit, I think the 8bit result will be in the ADC_AN0.HIGHBYTE when the adc is set to left shift?
Code:
ADC_AN0 var WORD '10bit result
ADC_AN1 var WORD '10bit result
'Read AN0
'--------------------------------------------------------------------------
ADCON0 = %11000011 'Set adc channel = AN0
WHILE ADCON0.1 = 1 'WAIT FOR CONVERSION
WEND
ADC_AN0.HIGHBYTE = ADRESH
ADC_AN0.LOWBYTE = ADRESL
'Read AN1
'--------------------------------------------------------------------------
ADCON0 = %11000111 'Set adc channel = AN1
While ADCON0.1 = 1 'WAIT FOR CONVERSION
WEND
ADC_AN1.HIGHBYTE = ADRESH
ADC_AN1.LOWBYTE = ADRESL
'---------------------------------------------------------------------------
Re: help setting up 16F886 for ADC
Hi to all,
I have troubles with reading 10 bit on AN0 , too .
Can somebody give me some ideas, please ?
Code:
'****************************************************************
'* Name : UNTITLED.BAS *
'* Author : [select VIEW...EDITOR OPTIONS] *
'* Notice : Copyright (c) 2014 [select VIEW...EDITOR OPTIONS] *
'* : All Rights Reserved *
'* Date : 10/2/2018 *
'* Version : 1.0 *
'* Notes : *
'* : *
'****************************************************************
'PIC16F886
#config
__CONFIG _CONFIG1, _LVP_OFF & _FCMEN_OFF & _IESO_OFF & _BOR_OFF & _CPD_OFF & _CP_ON & _MCLRE_OFF & _PWRTE_ON & _WDT_OFF & _INTRC_OSC_NOCLKOUT
__CONFIG _CONFIG2, _WRT_OFF & _BOR21V
#endconfig
define osc 4
include "lcd886.bas"
CM1CON0 = 0 'Comparator Off
CM2CON0 = 0 'Comparator Off
Define ADC_BITS 10 'Set number of bits in result (10)
Define ADC_CLOCK 3 'Set clock source (3=rc)
Define ADC_SAMPLEUS 50 'Set sampling time in microseconds (50us)
TRISA = %00000001 'Set PORTA.0 as input
TRISB = %00000000 'Set PORTB as outputs
TRISC = %00000000 'Set PORTC as outputs
ANSEL = %00000001 'Set PORTA.0 as analog
ANSELH = %00000000 'The rest ports are digital
'ADCON0 = %11000011 'Set adc channel = AN0
'ADCON1 = %10000000 'SETUP ADC RIGHT JUSTIFY SET REFV to VDD & VSS
PORTA = 0
PORTB = 0
PORTC = 0
light var PORTA.3
tc var word
'--------light is ON and initialize the LCD ---------
pause 300
high light
gosub lcdrst
lcdout $fe, $80,"TEST"
gosub lcdrst
'---------------------PROGRAM------------------------
MAIN:
ADCON0 = %11000011
gosub read_tc
lcdout $fe, $80, #tc
pause 200
goto main
end
'---------------------Read AN0------------------------
read_tc:
WHILE ADCON0.1 = 1:WEND 'WAIT FOR CONVERSION
tc.HIGHBYTE = ADRESH
tc.LOWBYTE = ADRESL
return
'--------------------lcd reset------------------------
lcdrst:
lcdout, $fe, 1
pause 10
return
Re: help setting up 16F886 for ADC
Is it on a F886?
You MUST NOT set the GO/DONE bit at the same time you enable the ADC converter (Data Sheet page 106, Note in the box).
Also you do not setup the ADCON1. It is commented.
Try this:
Code:
'****************************************************************
'* Name : UNTITLED.BAS *
'* Author : [select VIEW...EDITOR OPTIONS] *
'* Notice : Copyright (c) 2014 [select VIEW...EDITOR OPTIONS] *
'* : All Rights Reserved *
'* Date : 10/2/2018 *
'* Version : 1.0 *
'* Notes : *
'* : *
'****************************************************************
'PIC16F886
#config
__CONFIG _CONFIG1, _LVP_OFF & _FCMEN_OFF & _IESO_OFF & _BOR_OFF & _CPD_OFF & _CP_ON & _MCLRE_OFF & _PWRTE_ON & _WDT_OFF & _INTRC_OSC_NOCLKOUT
__CONFIG _CONFIG2, _WRT_OFF & _BOR21V
#endconfig
define osc 4
include "lcd886.bas"
CM1CON0 = 0 'Comparator Off
CM2CON0 = 0 'Comparator Off
Define ADC_BITS 10 'Set number of bits in result (10)
Define ADC_CLOCK 3 'Set clock source (3=rc)
Define ADC_SAMPLEUS 50 'Set sampling time in microseconds (50us)
TRISA = %00000001 'Set PORTA.0 as input
TRISB = %00000000 'Set PORTB as outputs
TRISC = %00000000 'Set PORTC as outputs
ANSEL = %00000001 'Set PORTA.0 as analog
ANSELH = %00000000 'The rest ports are digital
ADCON0 = %11000001 'Set adc channel = AN0
ADCON1 = %10000000 'SETUP ADC RIGHT JUSTIFY SET REFV to VDD & VSS
PORTA = 0
PORTB = 0
PORTC = 0
light var PORTA.3
tc var word
'--------light is ON and initialize the LCD ---------
pause 300
high light
gosub lcdrst
lcdout $fe, $80,"TEST"
gosub lcdrst
'---------------------PROGRAM------------------------
MAIN:
ADCON0.1=1
gosub read_tc
lcdout $fe, $80, #tc," " ' I put some space here when you go from large result to 1 digit result.
pause 200
goto main
end
'---------------------Read AN0------------------------
read_tc:
WHILE ADCON0.1 = 1:WEND 'WAIT FOR CONVERSION
tc.HIGHBYTE = ADRESH
tc.LOWBYTE = ADRESL
return
'--------------------lcd reset------------------------
lcdrst:
lcdout, $fe, 1
pause 10
return
Ioannis
Re: help setting up 16F886 for ADC
Thank you for your fast reply !
I tried your version, but don't work. The readed adc values oscilating from 10x to 22x.....
Re: help setting up 16F886 for ADC
Now I readed the some value on AN2 with succes, but AN0 is the same.
Re: help setting up 16F886 for ADC
If you read on AN2 then we are getting somewhere.
Did you remember to change the channel to 0 after testing on AN2?
Does AN0 work on ADCIN 0,tc ?
Ioannis
1 Attachment(s)
Re: help setting up 16F886 for ADC
Thank you Ioannis for your effort ! .. you spend a time for me. The problem is solved, I don't understand what happened really.
So, on AN0 I had a TC1047 ( analog temperature sensor ) with a 100nF capacitor to ground. The voltage measured on AN0 was 726 mV , also I verified with a osciloscop and I had a "clean" voltage. After I removed the capacitor, AN0 work well .
Re: help setting up 16F886 for ADC
this may lead you to these two things:
1. Your cap is shorted, or
2. if you use breadboard, it is faulty.
Ioannis
1 Attachment(s)
Re: help setting 10 bit for ADC and conversion
I work on proffesional PCB, I changed the capacitor, but the same problem. So, nevermind, without 100nF capacitance the AN0 is ok. Anyway is strange whats what happen there.
On AN0 I read the voltage from a linear sensor temperature (TC1047). The temperature slope is fixed at 10 mV/°C and the output voltage at 0°C is 500 mV (according with page4 from datasheet).
My ideea to extract the °C isn't ok because the maximum reading read on the input is 1024 ((1024-500) / 10 = 52.4 degrees) and the number of read bits is read in step 5, so only 256 bits.
The problem with me is that I do not read correctly the milivolts on 10 bit. Any ideea is apreciated, thank you !
Code:
'---------------------PROGRAM------------------------
MAIN:
gosub read_tc 'read analog value
gosub calc_voltage 'calculate the mVolts
gosub conv_temp 'conversion to degrees
lcdout $fe, $80, #tc 'displat TC and mVolt only for info
lcdout $fe, $C0, #mvolt , " Temp= " , #grd
pause 100
goto main
end
'---------------------Read AN0------------------------
read_tc:
z=0
for i = 1 to 100 ' average to 100 reads
ADCON0.1=1
WHILE ADCON0.1 = 1:pause1:WEND 'WAIT FOR CONVERSION
tc.HIGHBYTE = ADRESH
tc.LOWBYTE = ADRESL
z = tc + z
next i
tc = z/100
return
'--------------------Calc Voltage----------------------
calc_voltage:
mvolt = (tc * 5//1024)
return
'-------------------Convert Temp----------------------
conv_temp:
grd = (mvolt - 500)/10 'readed mVolt value - 500 (according with TC1047 datasheet)
lcdout $fe, $C0+4, " Temp= " , #grd
return
'--------------------lcd reset------------------------
lcdrst:
lcdout, $fe, 1
pause 10
return
Attachment 8593
Re: help setting up 16F886 for ADC
Quote:
mvolt = (tc * 5//1024)
really
try
Quote:
mvolt = (tc * 5/1024)
Re: help setting up 16F886 for ADC
also 100 iterations of this has every chance of overflowing a word var
z = tc + z
ie 100*921 = 92100 , word max val 65535
every count of tc = 5000/1024 mv
40 deg = 4500 mv would be a 921 count
the most accurate calc for pbp
would be mvolt = tc */ 1249
result for 921 = 4493
ps I assume ADFM set correctly
Re: help setting up 16F886 for ADC
Thank you very much Richard !
Now I see that 100 iterations overflowing a word var, so I'll use 10 iteration or DT Average routine, but nevermind right now.
I know it's unpleasant to ask beginners an advanced but you can explain me how its made middle 16 bits of multiplication calculation, please ? ( mvolt = tc */ 1249 )
Also I'm confused about "40 deg = 4500 mv would be a 921 count" , the maximum scale what I need is 1750 mV, 40 deg = 900mv ( 40 deg = 400mV + 500mV = 900mV) .
Please do not mind that I ask so many aberrations, but for me there are things I could not understand ...I'm old man and also beginner in programming.
Re: help setting up 16F886 for ADC
Quote:
Also I'm confused about "40 deg = 4500 mv would be a 921 count" , the maximum scale what I need is 1750 mV, 40 deg = 900mv ( 40 deg = 400mV + 500mV = 900mV)
I must have up past my bedtime , managed to multiply 40 * 10 mv and got 4000
(
Code:
mvolt = tc */ 1249 )
@5v vcc each adc count is 4.88 mV
4.88*256=1249
pbp divides/multiplies have internal 32 bit results there are various commands the allow convenient
access to this result in useful ways
@40 deg tc would be about 184 counts
so our calc is (184*4.88*256)/256
since pbp can't do real numbers
we do the 4.88*256 =1249
and 184*/1249 does the rest ie 184*1249/256
Re: help setting up 16F886 for ADC
Now its clear for me.
Thank you very much for your patience and explanation !!
Re: help setting up 16F886 for ADC
Re: help setting up 16F886 for ADC
Sometimes I read this topic but when I needed it I did not find it ...I dug after him a few hours, so thousands thanks to all for help !