PDA

View Full Version : Again ADC with 12F675 ...



fratello
- 27th March 2015, 07:06
Hi !
I wote this code for 12F675:

@ __config _XT_OSC & _WDT_OFF & _PWRTE_ON & _MCLRE_ON & _BODEN_OFF & _CP_ON

DEFINE OSC 4
DEFINE ADC_BITS 10
DEFINE ADC_CLOCK 3
DEFINE ADC_SAMPLEUS 50

CMCON = 7
OPTION_REG = %10000110
TRISIO = %00001100
GPIO = %00000001
ANSEL = %00010100
ADCON0 = %10001001
In ISIS I have multiple errors ... what did I do wrong ?

HenrikOlsson
- 27th March 2015, 08:49
Hi,
Is that really ALL of the code?

When you select an analog input which you want to convert the sample and hold circuit for the ADC needs to charge the S/H capacitor. It takes a certain amount of time (called acquisition time) for this capacitor to charge up. When the the A to D conversion starts the capacitor is disconnected from the input. If the A to D conversion is started before the acquisition time has expired the conversion result will not be correct.

I'm not sure if perhaps ISIS can, based on the simulation, figure out that the acquisition time isn't long enough. I've never used ISIS (haven't been able to justify the cost) so I don't know.... From the time stamp it looks like you're doing a A to D conversion in a quite tight loop, I don't know if that's a possible problem. It think you're going to have to post more of the code.

Finally, it's not an error, it's message telling you that it has happend. It doesn't prevent the code form compiling or from running but the behaviour of the code, as written, might not be what you actually wanted.

/Henrik.

fratello
- 27th March 2015, 11:24
Thank You so much for reply !
The rest of code is :

main:
pause 200
ADCON0.1 = 1
WHILE ADCON0.1 = 1 : WEND
adval.HighByte = ADRESH
adval.LowByte = ADRESL
if k=0 and adval > 10 and adval < 750 then
k=1
pause 250
endif

while k=1
gosub start
wend
goto main


start:

ADCON0.1 = 1
WHILE ADCON0.1 = 1 : WEND
adval.HighByte = ADRESH
adval.LowByte = ADRESL
if adval > 10 AND adval < 103 then gosub VolDn

return

HenrikOlsson
- 27th March 2015, 12:02
Hi,

>The rest of code is :

Is it? You're calling VolDn but I don't see that in the code but I guess there's nothing to do with the ADC there?

Anyway, have you tried using ADCIN just to see if the message from ISIS goes away then?
I'm asking beacuse the DEFINE ADC_SAMPLUS 50 is for use with the ADCIN command I don't think it does anything for you when you run the ADC "manually". Alternativaly, whenever you're doing a converstion try:


ADCON0 = %10001001 ' Right justify, VRef=Vdd, select AN2, enable ADC.
PAUSEUS 100
ADCON0.1 = 1 ' Start conversion
WHILE ADCON0.1 = 1 : WEND
adval.HighByte = ADRESH
adval.LowByte = ADRESL


In this case I don't think anything of it really matters since you're always sampling the same channel but it might be worth a try just to see if ISIS stops generating the message.

Finally, you're doing DEFINE ADC_CLOCK 3 but then you're overriding that by manually setting ANSEL to %00010100 which will set the ADC Clock to FOsc/8 instead of FRC. I don't think that's a problem in this case though.

/Henrik.

fratello
- 27th March 2015, 20:36
Thank you verry much !
Indeed, my mistake was the overriding of defines ...I didn't know until today the things You've posted. Hm ... so much to learn ! I'm glad I met people like You and other kindly members of this forum !
Best regards !

fratello
- 3rd April 2015, 06:38
Me, again ...with something strange (at least for me) !
I try to use ADC for reading a couple of buttons. I have two situations :
- three buttons, with 82 ohms, 164 ohms, 1448 ohms resistors ; ADC reading = 1023 nothing pressed ; 78 with button 1 pressed ; 144 with button 2 ; 605 with button 3 ;
- three buttons, with 300 ohms, 1300 ohms, 3110 ohms AND 100 Kohms in parallel ; ADC reading = 1013 nothing pressed ; 236 with button 1 pressed; 575 with button 2 ; 768 with button 3.

I tried with 2 version of code (for both situations):

ADCON0.1 = 1
WHILE ADCON0.1 = 1 : WEND
adval.HighByte = ADRESH
adval.LowByte = ADRESL
if adval > 10 and adval < 300 then gosub LED1
...etc....

and


ADCIN 3, adval
if adval > 10 and adval < 300 then gosub LED1
...etc...

For first situation everything works fine, with both version of reading ADC !
BUT ... for second situation, NOTHING HAPPENS !!! I really not understand what I do wrong ... Can me point to the right direction ? Thanks in advance !

7758 7759

fratello
- 3rd April 2015, 07:52
Note : In Proteus both schematic work, so I made it on PCB. First variant works just fine, second none :( ...

HenrikOlsson
- 3rd April 2015, 08:18
For the code using ADCIN, is the left/right justification set correctly? I can never remember which way around it wants it so whatever you have it set to, try changing it. And, do you have DEFINE ADCBITS 10 in there?

/Henrik.

fratello
- 3rd April 2015, 08:28
Thanks for reply !

CMCON = 7
OPTION_REG = %10000110
TRISIO = %00001100
GPIO = %00000001
ANSEL = %00010100
ADCON0 = %10001001

I don't change anything in code (except values for actions) ... just the resistors from "chain" command.
With first chain work ; with second not. It's because of 100 kOhms ?!?

Acetronics2
- 3rd April 2015, 09:29
may be we could suspect the debounce time for your switches ... 50 µs is rather a short time !

did you try to use a little pause for settling ???

Alain

fratello
- 3rd April 2015, 09:55
Thank you !
That means to add something like "Pause 50" before or after ADCIN command ?

Acetronics2
- 3rd April 2015, 11:12
Here you can find an example ( in assembler ... YES ! ) that shows how it is done.
http://www.piclist.com/techref/microchip/4x4key1ad7r.htm

did you also read that one ???
http://www.picbasic.co.uk/forum/showthread.php?t=17956

Alain

fratello
- 3rd April 2015, 11:15
Thanks ! But still no have answers on my problem ...

Gusse
- 3rd April 2015, 19:52
Hi Fratello,

1) Do you have two PCB with different resistor values?
or
2) Have you changed resistors to same board and tested with two SW settings?

In case
1) there must be some other differences on PCB
2) resistors are not with correct values

fratello
- 3rd April 2015, 20:16
Thanks, Mr. Gusse, for support !
I have only one PCB, without the resistors from chain (just R2=1k is soldered on PCB, between +5V and ADC_IN).
I put the resistors from chain 1 from R2/ADC_IN to ground ; in first case works perfect.
Then I soldered the R9=100k from R2/ADC_IN to ground ; I put resistors from chain 2 into circuit (in parallel with R9). In this case nothing happens.
All the resistors are measured, look to be OK (this was my first concern too ...).

Tomorrow I'm going to try to set some debounce ...

fratello
- 4th April 2015, 06:25
Update picture...
7763

fratello
- 4th April 2015, 19:18
SOLVED !!!
In first case the code is :
"If adval > 419 and adval < 536 then gosub LED" = working fine.
In second case :
"If adval > 450 and adval < 600 then gosub LED" = NOT working.

So I tried this :
"If adval < 600 and adval > 450 then gosub LED"
And VOILA, IT'S WORKING !!!

Thanks for support ! Regards !

Demon
- 6th April 2015, 18:12
I don't get it. That looks identical to me.

Robert

fratello
- 6th April 2015, 18:42
For me too ... But I can prove it (by video) !
Maybe because when no button is pressed, ADC reading is NOT 1023 ?!

Tabsoft
- 6th April 2015, 20:28
I do not know what version of PICBasic you are using or what version of MPASM either.

I compiled and ran the following code in the MPASM Simulator and it works fine for all (3) IF/THEN statements in main.

If adval <= 419 then myLED does not increment.
If adval > 419 and <= 450 then myLED only increments 1 time for each loop (IF/THEN #1 : Not #2 and #3)
if adval > 450 and < 536, then myLED increments 3 times for each loop (IF/THEN #1, #2 and #3)
if adval => 536 and < 600 then myLED increments 2 times for each loop (IF/THEN #2 and #3 : Not #1)
if adval => 600 then myLED does not increment.



'MCU = 12F675
'PBP v3.0.7.4
'MPASM v8.90


DEFINE OSC 4
DEFINE ADC_BITS 10
DEFINE ADC_CLOCK 3
DEFINE ADC_SAMPLEUS 50

CMCON = 7
OPTION_REG = %10000110
TRISIO = %00001100
GPIO = %00000001
ANSEL = %00010100
ADCON0 = %10001001

adval var word
myLED var word

adval = 0
myLed = 0

goto main

LED:
myLED = myLEd + 1

return

main:
for adval = 0 to 700
If adval > 419 and adval < 536 then gosub LED 'Works
If adval > 450 and adval < 600 then gosub LED 'Works
If adval < 600 and adval > 450 then gosub LED 'Works
next
myLed = 0

goto main

fratello
- 6th April 2015, 21:09
Thanks !
In Proteus my code work fine too ... But not work in "real life".
Tomorrow I will come with another issue ...

fratello
- 7th April 2015, 18:08
...so I'm back !
After solving first problem, I meet another one ... I can not reading two channel ADC.
I try two version of code :
-first variant

@ __config _XT_OSC & _WDT_OFF & _PWRTE_ON & _MCLRE_ON & _BODEN_ON & _CP_ON
DEFINE OSC 4


CMCON = 7
OPTION_REG.7= 1
TRISIO = %00001110
GPIO = %00000001
ANSEL = %00110110
ADCON0.7 = 1

adval var word
advalb var word

PAUSE 200

main:

ADCON0.2 = 1
ADCON0.3 = 0
ADCON0.1 = 1
WHILE ADCON0.1 = 1 : WEND
adval.HighByte = ADRESH
adval.LowByte = ADRESL
PAUSE 50

if adval < 950 then
if adval < 940 AND adval > 650 THEN gosub Led1
IF adval < 600 AND adval > 450 THEN gosub Led2
IF adval < 400 AND adval > 150 THEN gosub Led3
IF adval < 100 THEN gosub Led4
endif

ADCON0.2 = 0
ADCON0.3 = 1
ADCON0.1 = 1
WHILE ADCON0.1 = 1 : WEND
adval.HighByte = ADRESH
adval.LowByte = ADRESL
PAUSE 50

if advalb < 950 then
if advalb < 940 AND advalb > 650 THEN gosub Led1
IF advalb < 600 AND advalb > 450 THEN gosub Led2
IF advalb < 400 AND advalb > 150 THEN gosub Led3
IF advalb < 100 THEN gosub Led4
endif

goto main

-second variant

@ __config _XT_OSC & _WDT_OFF & _PWRTE_ON & _MCLRE_ON & _BODEN_ON & _CP_ON

DEFINE OSC 4

DEFINE ADC_BITS 10
DEFINE ADC_CLOCK 3
DEFINE ADC_SAMPLEUS 200

CMCON = 7
OPTION_REG = %10000110
TRISIO = %00000110
GPIO = %00000110
ANSEL = %00000110
ADCON0.7 = 1



ADVALA VAR WORD
ADVALB VAR WORD

pAUSE 100

main:

adcin 1, advalA
pause 5
if advalA < 950 then
if advaLA < 940 AND advalA > 650 THEN gosub LED1
IF advalA < 600 AND advalA > 450 THEN gosub LED2
IF advalA < 400 AND advalA > 150 THEN gosub LED3
IF advalA < 100 THEN gosub LED4
endif

adcin 2, advalB
pause 5
if advalB < 950 then
if advalB < 940 AND advalB > 655 THEN gosub LED1
IF advalB < 600 AND advalB > 450 THEN gosub LED2
IF advalB < 400 AND advalB > 150 THEN gosub LED3
IF advalB < 100 THEN gosub LED4
endif


goto main

ONLY "advalA < 100" is sensing and LED4 command is executed ...
Can somebody pointing to the right direction ? Thanks in advance !
Schematic added.
7766

Tabsoft
- 8th April 2015, 05:42
A couple of suggestions second variant.
Remove "GPIO = %00000110" you are trying to set a high on the input pins.
Change "ANSEL = %00000110" to "%01110110", this will set the PIC ADC clock to RC mode and will match the
"DEFINE ADC_CLOCK 3" directive.

Then give Variant 2 a try.

fratello
- 8th April 2015, 06:13
I will try this, thanks !

peterdeco1
- 9th April 2015, 16:26
Hi Fratello. A while back I did the same basic thing you're doing. On an ADC pin I attached a 47K pullup resistor. Then a 22K resistor with pushbutton to ground, 10K with button to ground, 2.2K with button to ground and a 1K with button to ground. Here is the code. It works perfect for me.

ANSEL = 0 'all inputs digital
CMCON = 7 'comparators off
DEFINE OSCCAL_1K 1 ' Set OSCCAL for 1K device to accurize osc
TRISIO = %11111111 'SET I/O'S to all inputs for now
@ device pic12F675, INTRC_OSC_NOCLKOUT, wdt_on, BOD_ON,pwrt_on, mclr_off, protect_on
BUT VAR BYTE 'BUTTON VARIABLE
BUT2 VAR BYTE 'VARIABLE TO COMPARE READINGS TO PREVENT WRONG ADC READINGS
Pause 500 'SETTLE DOWN

STAYHERE:
ADCIN 3,BUT 'ADCIN COMMAND AUTOMATICALLY CONVERTS I/O TO ADC PORT
IF BUT < 100 Then STAYHERE 'IF BUTTON STUCK on power up WAIT HERE

BEGIN:
NAP 0 'REDUCE BATTERY DRAIN
ADCIN 3,BUT
IF BUT > 100 Then begin 'BUTTON not PUSHED

table:
ADCIN 3,BUT
Pause 100
ADCIN 3,BUT2
IF BUT <> BUT2 Then TABLE 'RE-READ ADC should both be same

IF BUT < 91 AND BUT > 71 Then (DO FUNCTION 1)
IF BUT < 50 AND BUT > 40 Then (DO FUNCTION 2)
IF BUT < 15 AND BUT > 8 Then (DO FUNCTION 3)
IF BUT < 8 AND BUT > 4 Then (DO FUNCTION 4)
IF BUT < 5 AND BUT > 2 Then (DO FUNCTION 5) '1K & 2.2K BUTTON PUSHED @ SAME TIME
GOTO BEGIN

fratello
- 9th April 2015, 16:47
Thank you !
As I say, with just one resistors chain , everything works PERFECT !
My troubles appears when I try to use TWO resistors chains (and TWO ADC channel).
I wrote another version :

@ __config _XT_OSC & _WDT_OFF & _PWRTE_ON & _MCLRE_ON & _BODEN_ON & _CP_ON

DEFINE OSC 4

DEFINE ADC_BITS 10
DEFINE ADC_CLOCK 3
DEFINE ADC_SAMPLEUS 100



CMCON = 7
OPTION_REG.7= 1
TRISIO = %00000110
GPIO = %00000001
ANSEL = %00110110
ADCON0.7 = 1

adval var word
valb var word
vala var word

PAUSE 200

goto mainloop

getadv:
PAUSEuS 50 ' Wait for A/D channel acquisition time
ADCON0.1 = 1
WHILE ADCON0.1 = 1 : WEND
adval.HighByte = ADRESH
adval.LowByte = ADRESL
Return

getadvala:
ADCON0 = %10000101
Gosub getadv
vala=adval
Return

getadvalb:
ADCON0 = %10001001
Gosub getadv
valb=adval
Return

mainloop:
gosub getadvala
gosub getadvalb


if vala < 950 then
if vala < 940 AND vala > 650 THEN gosub LED1
IF vala < 600 AND vala > 450 THEN gosub LED2
IF vala < 400 AND vala > 150 THEN gosub LED3
IF vala < 100 THEN gosub LED4
endif

if valb < 950 then
if valb < 940 AND valb > 650 THEN gosub LED1
IF valb < 600 AND valb > 450 THEN gosub LED2
IF valb < 400 AND valb > 150 THEN gosub LED3
IF valb < 100 THEN gosub LED4
endif

goto mainloop

But still no have proper results :( ...

fratello
- 10th April 2015, 13:10
My schematic/code are from here : http://www.imdb.com/title/tt0052520/ !!!
I did it work ... by re-reversing all those commands :
" If VALA > 650 and VALA < 940 Then Gosub LED1"" ...
instead of :
" If VALA < 940 and VALA > 650 Then Gosub LED1"

Nothing else ! And now everything works just fine !
Thank you all for support !
Have a Nice and Happy Easter !

grahamg
- 10th April 2015, 14:31
I think you may wat to try the following: if (vala >650) and (vala <920) then go sub xx

flotulopex
- 17th April 2015, 22:24
In your very first post, I couldn't find any clear description of your problem or goal.... ;)


Post#6
7758 7759


Post #22
7766

Resistor coupling is apparently not the same in those two posts - is this okay?



Try this:
7802
Button 1 = 0 Volt => ADC 8 bits = +/-0 , ADC 10 bits = +/-0
Button 2 = 1,25 Volts => ADC 8 bits = +/-64 , ADC 10 bits = +/-320
Button 3 = 2,5 Volts => ADC 8 bits = +/-128 , ADC 10 bits = +/-640
Button 4 = 3,75 Volts => ADC 8 bits = +/-192 , ADC 10 bits = +/-960

I didn't built the circuit above; if ADC values are not stable, try with all R values ( :10) => 10k becomes 1k, 3k3 becomes 300Ohms and so on.



As an alternative, you may want to have a look here "Compiled Tips ‘N Tricks Guide" (http://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&sqi=2&ved=0CCQQFjAA&url=http%3A%2F%2Fww1.microchip.com%2Fdownloads%2Fe n%2FDeviceDoc%2F01146B.pdf&ei=nXExVY2dO8XfatuSgMgC&usg=AFQjCNHEVnQdIwht7UbjQ-Md7m96FKuYtg&bvm=bv.91071109,d.bGg&cad=rja).7801

fratello
- 18th April 2015, 07:11
Thanks for info !