Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

A-to-D

Status
Not open for further replies.

YAN-1

New Member
Hi. I'm using the 16F876A to drive a stepper motor and I need to use 2 A-to-D channels. The first one is for monitoring the current and the second is for position feedback. I am using the first one just fine but when I attempt to add the second one, things are not working. I thought it was straight forward. After I finish the conversion on the first channel, I change the CHS0 bit to use AN1 and then I change the ADCON1 to switch to a left-justified result and then I set the GO bit and proceed. When I'm done reading from the second channel, I do the same to use the first one again and so on. Am I doing it wrong? Thanks a lot.
 
YAN-1 said:
Am I doing it wrong? Thanks a lot.

Have you waited for the required time to let the input channel correctly sample the input voltage?

Check the datasheet for detailed A/D Acquisition Requirements and the minimum time you must wait before starting another A/D conversion.
 
Check my PIC tutorials for more details, but essentially the time taken to switch between channels is VERY dependent on the source impedance feeding the analogue inputs. The MAXIMUM impedance should be no more than about 2.5kohms - if you use something like a 100K pot to feed the pin it might take half a second to settle down after the switch.
 
Well yeah. My potentiometer is 200k! But there's something that I can't explain. I'm using 2 channels. Suppose that I'm reading channel 1 and outputting it on PORTB and then I read channel 2 and output it on PORTD. What is happening with me is that the outputs are exchanged! In my case, the current sensing value is output on the LEDs as if it's the shaft position and the shaft position input controls the pulses of the stepper motor! I'm pretty sure of my channel selection. I revised it many times. And I'm not using the potentiometer now. I'm just placing the inputs at Vcc or GND. It's as if ADRESH is not affected or that it retains the old value or something. I feel like it's a timing issue. Any suggestions? Thanks.
 
YAN-1 said:
Well yeah. My potentiometer is 200k! But there's something that I can't explain. I'm using 2 channels. Suppose that I'm reading channel 1 and outputting it on PORTB and then I read channel 2 and output it on PORTD. What is happening with me is that the outputs are exchanged! In my case, the current sensing value is output on the LEDs as if it's the shaft position and the shaft position input controls the pulses of the stepper motor! I'm pretty sure of my channel selection. I revised it many times. And I'm not using the potentiometer now. I'm just placing the inputs at Vcc or GND. It's as if ADRESH is not affected or that it retains the old value or something. I feel like it's a timing issue. Any suggestions? Thanks.

Post the relevent part of the circuit so we can see what you're doing!.

And again, read my PIC analogue tutorial, and check the circuit I used for the analogue board.
 
200K is way beyond the PIC's recommeneded input impedance of 2.5k!
Not only is the acquisition time higher, the offset error will be significant and this cannot be improved by increasing acq time. You can buffer the signal to remedy the impedance problem.

With this input impedance issue, it's possible to get the readings to switch around. i.e. the ADC's internal sampling capacitance is charged to Ch1, you switch to Ch2 yet don't allow sufficient charging time. The result will reflect more Ch1's voltage than Ch2. The part then spends some time doing other things while the ADC is still mux'ed to Ch2 and thus the ADC's cap voltage approaches Ch2 finally. Switch to Ch1 and convert too soon and you'll get mostly Ch2's reading.
 
Well I understand that but the thing is I'm still getting the same thing even after I stopped using the potentiometer. I'm just connecting channel 0 to Vcc and channel 1 to the GND for example and I get the results reversed even though I am also allowing for a very large acquisition time.
 
YAN-1 said:
Well I understand that but the thing is I'm still getting the same thing even after I stopped using the potentiometer. I'm just connecting channel 0 to Vcc and channel 1 to the GND for example and I get the results reversed even though I am also allowing for a very large acquisition time.

As I said above, post the circuit you're using!.

Try using just one analogue input, and see if that works OK, then try using just the other and see if that's OK - this avoids the switching problem for testing purposes.
 
Well sorry but the reason that I didn't post it yet is that I don't have a digital camera around right now. It's just a PIC 16F876A. A0 and A1 are switched between gnd and vcc and PORTC is an output port to LEDs while PORTB outputs a certain sequence. Channel 0 should stop the sequence when it's at vcc and channel 1 is outputted on the LEDs. But it's the opposite that's happening. I tried each one on its own and it works just fine. But when together, things get weird.
 
Just insert 12 nop instructions after you write to ADCON0 and before you set the GO bit.

So to read channel 2 (AN1) you would do.
Code:
ReadADC         movlw   B'01001011'
                movwf   ADCON0
                nop
                nop
                nop
                nop
                nop
                nop
                nop
                nop
                nop
                nop
                bsf     ADCON0,GO
WaitADC         btfsc   ADCON0,GO
                goto    WaitADC
                return

If your running at 20Meg then make it 30 nops.
When it works then you can look at calculating the acquisition time properly.


HTH

Mike.
 
1. Make sure you set the registers to set them as analog inputs
2. Make sure the port direction sets them as inputs
3. Make sure you've hooked up to the right pins. AN4 is on RA5, not RA4. Got tripped up with that once.
4. Make sure your code selects an appropriate conversion clock and waits the proper acq time.
5. Make sure you've selected the proper channel and designated the desired internal/external reference.
 
Thanks a lot. I'm about to start debugging my system now. I'll review all these points. I got a 1k potentiometer instead of the 200k one.
 
Ok can someone please tell me what's wrong with this?!

//////////////////////////////////////////////////////////////////////
void main() {


TRISB = 0x00;
PORTB = 0x00;
TRISC = 0x00;
TRISA = 0b11111111;

ADCON0 = 0b10000001; //Fosc/32, CHN0, AD-ON
ADCON1 = 0x00; // left-justified result + all analogue

DelayUs (60); //Tacq (exaggerated)

ADCON0 = (ADCON0 | 0b00000100); //(start conversion)


do{

while ((ADCON0 & 0b00000100) == 1){ //wait till it's done
}

if (ADRESH > 0b00001000){
PORTB = 0x00;}

if(ADRESH <= 0b00001000){
PORTB = 0xFF;}


ADCON0 = 0b10001001; //switch to CHN1
DelayUs (60); //Tacq

ADCON0 = (ADCON0 | 0b00000100);

while ((ADCON0 & 0b00000100) == 1){
}
PORTC = ADRESH; //display CHN1 on PORTC


ADCON0 = 0b10000001; //go back to CHN0
DelayUs (60); //Tacq

ADCON0 = (ADCON0 | 0b00000100);

}while(1);
}
/////////////////////////////////////////////////////////////////////////////


The delay subroutines I'm using are not accurate (a factor of 0.6 has to be used). i.e. DelayUs(100) actually gives a delay of 60 usec.
 
Shouldn't

while ((ADCON0 & 0b00000100) == 1)

be

while ((ADCON0 & 0b00000100) == 4)

or

while ((ADCON0 & 0b00000100) != 0)

or better still, if your using PICC lite


while(ADGO)


HTH

Mike.
 
Don't be embarrassed, I've been programming more years than I care to remember and still make stupid mistakes like that.

A good tip, when something doesn't work, explain it to your cat, teddy, bottle of beer etc. It's amazing how explaining it out loud to a teddy can make you see the error of your ways.

Mike.
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top