Log in

View Full Version : 12F1840 ADCIN troubles, help needed :(



CuriousOne
- 11th August 2015, 12:15
Hello.

I'm trying to use ADCIN on 12F1840, here's the code:



;----[12F1840 Hardware Configuration]-------------------------------------------
#IF __PROCESSOR__ = "12F1840"
#DEFINE MCU_FOUND 1
#CONFIG
cfg1 = _FOSC_INTOSC ; INTOSC oscillator: I/O function on CLKIN pin
cfg1&= _WDTE_OFF ; WDT disabled
cfg1&= _PWRTE_OFF ; PWRT disabled
cfg1&= _MCLRE_OFF ; MCLR/VPP pin function is digital input
cfg1&= _CP_OFF ; Program memory code protection is disabled
cfg1&= _CPD_OFF ; Data memory code protection is disabled
cfg1&= _BOREN_ON ; Brown-out Reset enabled
cfg1&= _CLKOUTEN_OFF ; CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin
cfg1&= _IESO_ON ; Internal/External Switchover mode is enabled
cfg1&= _FCMEN_ON ; Fail-Safe Clock Monitor is enabled
__CONFIG _CONFIG1, cfg1

cfg2 = _WRT_OFF ; Write protection off
cfg2&= _PLLEN_OFF ; 4x PLL disabled
cfg2&= _STVREN_ON ; Stack Overflow or Underflow will cause a Reset
cfg2&= _BORV_19 ; Brown-out Reset Voltage (Vbor), low trip point selected.
cfg2&= _LVP_OFF ; High-voltage on MCLR/VPP must be used for programming
__CONFIG _CONFIG2, cfg2

#ENDCONFIG

#ENDIF

;----[Verify Configs have been specified for Selected Processor]----------------
; Note: Only include this routine once, after all #CONFIG blocks
#IFNDEF MCU_FOUND
#ERROR "No CONFIGs found for [" + __PROCESSOR__ +"]"
#ENDIF


OSCCON = %11110000 'SET INTOSC TO 32MHZ

TRISA=%00110000 'set LATAA.4 as input
ANSELA=%00010000 'set LATAA.4 as analog
ADCON0=%00001101 'ENABLE AND CONFIGURE ADC
ADCON1=%11100011 'JUSTIFY
CM1CON0=%00000000 'DISABLE COMPARATORS

DEFINE OSC 32
DEFINE ADC_BITS 10
DEFINE ADC_SAMPLEUS 50
DEFINE ADC_CLOCK 3
VOLTAGE VAR WORD
SHEMAVALI VAR LATA.4
LED VAR LATA.2


'PACUKA:
'HIGH LED
'PAUSE 200
'LOW LED
'PAUSE 200
'GOTO PACUKA

CIKLURI:
ADCIN 3,VOLTAGE
IF VOLTAGE=>1023 THEN
HIGH LED
else
low led
endif
pause 5
GOTO CIKLURI




The problem is that VOLTAGE variable always reads 1024, if input is not connected to ground.

Any ideas?

grahamg
- 11th August 2015, 16:13
Firstly ADCON1=%11100011 'JUSTIFY statement is conflicting with DEFINE ADC_CLOCK 3.
Secondly IF VOLTAGE=>1023 THEN statement can never be greater than 1023. DEFINE ADC_BITS 10 means maximum value of voltage =1023.

CuriousOne
- 11th August 2015, 20:36
well that IF is just experiment
In real life, ADCIN returns 0 if input is grounded, if any other voltage is applied, it returns 1023.

CuriousOne
- 12th August 2015, 14:58
Found the problem!

I was using Fixed internal voltage reference, but was not enabling it at all.

added

FVRCON=%11011111

and now it works OK!

CuriousOne
- 4th December 2015, 16:18
Well, troubles continue.

I've built a following circuitry. 10K resistor goes to LATA.2 pin and goes then to gnd.
100k variable pot is connected one end to VCC, another to LATA.2
LED is connected to GND via 1k resistor from LATA.1

Wiring is 100% checked and corrected for shorts, misswire, etc.

The code is as follows:



OSCCON = %11110000 'SET INTOSC TO 32MHZ
TRISA=%00110000 'set PORt as input
'ANSELA=%00010101 'set PORTA.4 as analog
ADCON0=%00001111 'ENABLE AND CONFIGURE ADC
ADCON1=%11000011 'JUSTIFY
FVRCON=%11011111 'VREF ENABLE & set at 4.096v
WPUA=%00000000 'pull up disable
'CM1CON0=%00000000 'DISABLE COMPARATORS

DEFINE OSC 32
DEFINE ADC_BITS 10
DEFINE ADC_SAMPLEUS 50
DEFINE ADC_CLOCK 3
VOLT VAR WORD
LED VAR LATA.1

greater:
adcin 2,volt
high led
pause 1
low led
pause volt/10
goto greater


This code should do a simple thing - vary LED brightness according to pot setting. And sure it does, but the problem is that it works in very narrow range, because port sinks huge amount of current - up to 25mA via that pin. So say to achieve 2.5v on the pin, the pot resistance should be set somewhere to 40 ohms. I think this is not correct, right?

Also I found a strange thing - if I set TRISA=%00110010, which means to set LATA.2 as input, the code does not works at all, but it also stops consuming current on that pin. What can be the reason?

mark_s
- 4th December 2015, 16:49
Well, troubles continue.

Also I found a strange thing - if I set TRISA=%00110010, which means to set LATA.2 as input, the code does not works at all, but it also stops consuming current on that pin. What can be the reason?

I think you have set porta.1 to input and not porta.2

This sets PORTA.2 as input


%00110100

Not sure about your other problems

HenrikOlsson
- 4th December 2015, 18:36
Hi,
The input (basically) only sinks current when it's configured as an output and set low. When being used as an input for the ADC it obviously needs to be set to input - just as Mark has pointed out. Then it "sinks" current only when the input is connected to the S/H circuit which leads us to the next issue: Your 100k pot viloates the maximum recommended input impedance by an order of magnitude.

/Henrik.

CuriousOne
- 4th December 2015, 20:07
I have created a voltage divider, 100k and 10k resistors, ADC input connected in their middle point. The problem is that PIC shorts the input to GND, but still works as ADC. This has no relation to input impedance, it feels like same pin is both digital out and analog in at same time. Is this possible?

HenrikOlsson
- 4th December 2015, 21:17
Hi,
In your original code ( TRISA=%00110000 ) leaves PortA.2 as an output which is wrong.
In your post you contiune to say TRISA=%00110010, to set LATA.2 as input which again, as mark_s points out, is wrong, the above will STILL leave PortA.2 as an OUTPUT.

Your setting of ANSELA in the code is commented out which doesn't really have any effect on the ADC input since it defaults to analog but it WILL have an effect on the pins you want to use as digital.

The ADC DOES put a load on the node when it samples the input that's where the max input impedance comes from. Too high impedance and too short sampling time makes the voltage at the node droop when it's sampled.

/Henrik.

pedja089
- 4th December 2015, 22:32
HenrikOlsson,
If you use 10K and 100K for divider, impedance that PIC input see is 9,09K.

CuriousOne
- 5th December 2015, 04:54
Yes I have commented ANSELA because it had no effect anyways.

CuriousOne
- 5th December 2015, 04:54
And I know that ADC needs some current, but not 25mA! On the RA3 or LATA.3 how you call it, which is input only, ADC works just fine and does not hog current.

richard
- 5th December 2015, 05:14
RA3 or LATA.3 how you call it, which is input only, ADC works just fine and does not hog current.

? really
RA3 is not an analogue input

the only way a pic I/O pin will sink 25ma is :- if its an output, damaged or fed more volts than vdd

CuriousOne
- 5th December 2015, 05:32
So, if I understood correctly, I need to set TRISA correctly and that is the issue?

richard
- 5th December 2015, 05:38
any pin that is set to analogue needs to have its corresponding tris bit set

from the data sheet

The TRISA register (Register 12-3) controls the
PORTA pin output drivers, even when they are being
used as analog inputs. The user should ensure the bits
in the TRISA register are maintained set when using
them as analog inputs. I/O pins configured as analog
input always read ‘0’.

CuriousOne
- 5th December 2015, 13:14
Yes, thanks, now that clear, changed TRISA to TRISA=%00111101 and it now works just fine!
Just it is a bit silly, why it can be possible to have same pin both as ADC IN and LOGIC OUT at same time (circuitry-wise)

richard
- 6th December 2015, 01:35
Just it is a bit silly, why it can be possible to have same pin both as ADC IN and LOGIC OUT at same time (circuitry-wise)


why is that you can drive a car for hundreds of miles in low gear , and with the handbrake on ?

is that any different ?

just because you're in the drivers seat with the motor running does not mean you are proficient

CuriousOne
- 6th December 2015, 11:02
That's not fair comparison, the situations is like when you can have zipper closed on your pants, but your junk still hanging from zipper :)

A side question, I'm going to monitor 9VDC battery voltage via ADCIN. To reduce current consumption, I'll have to increase resistance of both resistors, but this will also make circuit less noise proof. How do you think, what will be the gold cut in that case?

pedja089
- 6th December 2015, 19:56
Maybe this will help you.
http://electronics.stackexchange.com/questions/64490/low-current-battery-monitoring

CuriousOne
- 7th December 2015, 05:15
Thanks, but that is a bit complicated - no need to save that much power. The battery voltage to be monitored is around 11V (3S LiPo), so divider with 470k/100k resistors should work just fine?

pedja089
- 7th December 2015, 08:18
Look at last post.

CuriousOne
- 7th December 2015, 14:18
Tried that already. Too small values and I have too large ripple going on (current consumption is 20-25A). So I settled with 750k/150k+1nf combo, works just fine.