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.

PIC 16F877A - Problem with A/D conversion

Status
Not open for further replies.

disco_dave

New Member
Hi there

I am using a PIC 16F877A as an A/D converter to allow me to get two analog voltages in from a sensor into a PC. The sensor I am using measures the angle of tilt on two axis's. The sensor has been tested and is working correctly. The voltage received out from the sensor is as follows: (There are two output voltages one for each axis)

If the sensor is flat then 2.5v is outputted.
If the sensor moves towards 90 degrees in one direction a max of 3.5v is measured at 90 degrees.
If the sensor moves in the other direction by 90 degrees a minimum of 1.5v is measured at 90 degrees.

It outputs 2.5v when flat and then changes around this value to indicate what angle it is measuring.


I have set the PIC up to convert one of these voltages and output the data then hand shake out this data. Then to measure the other voltage on another of the A/D inputs and convert this to and handshake this out to the PC. The program then loops around continuously. The data is hand shake out of the PIC and into the PC.

The A/D conversion process works fine when the range is between 2.5v and 3.5v. (This is a "negative angle" once translated in my software on the PC)
However when the sensor tilts in the opposite direction (range = 1.5v to 2.5v) the values received from the PIC's A/D conversion jump in large steps. The values of the angles after the PC has computed the angles are as follows - 0 degrees, 7 degrees, 14 degrees, 28 degrees and about 56 degrees. The values listed do occur roughly when the angle occurs, in between these values the previous angle is held on the outputs. ie the ouput is step like. Because the sensor gives a linear response it would mean that the A/D value also increases in these large values which I have checked to be true.

The PIC does no work on the values it receives from the A/D process this is done in the PC. I am sure that this is something to do with the PIC as the raw data received into the PC changes is these large steps. ie before any work is done on the data to get the angle from the digital value received in. I have tried using another 16F877A PIC but still got this problem. I checked the sensor and tried changing it for another of the same type. I therefore am sure that the problem lies with the code in the PIC. I have read and reread many times the datasheet and cannot see where the problem is. As you can tell the values received in error double in value each time. I am using the full 10 bits of A/D in my design. I have also attached the code I am using. The sensor I am using is ADXL203 from Analog Devices.

I guess that the A/D is perhaps loosing one of the bits somewhere which could be why the value is doubling each time.
 

Attachments

  • code_148.txt
    5.1 KB · Views: 856
I suspect that your conversion time is too short. Try setting ADCON0 to 0x81 instead of 0x01. The wait2x is also not required, just testing the GO bit should work fine.

HTH

Mike.
 
Check my tutorials for more details, but basically you need a low impedance source to feed the PIC A2D, as specified in the datasheet. If you try and use a high impedance source you will get massive crosstalk between the two channels - unless you wait for the sample and hold to charge or discharge.
 
Nigel Goodwin said:
Check my tutorials for more details, but basically you need a low impedance source to feed the PIC A2D, as specified in the datasheet. If you try and use a high impedance source you will get massive crosstalk between the two channels - unless you wait for the sample and hold to charge or discharge.

If you look at the problem that he described and the code that he posted it is obvious that the problem is not impedance source or acquisition time.

Mike.
 
Pommie said:
Nigel Goodwin said:
Check my tutorials for more details, but basically you need a low impedance source to feed the PIC A2D, as specified in the datasheet. If you try and use a high impedance source you will get massive crosstalk between the two channels - unless you wait for the sample and hold to charge or discharge.

If you look at the problem that he described and the code that he posted it is obvious that the problem is not impedance source or acquisition time.

The problem could be related to source impedance and aquisition time?, in that it works OK if the two inputs are close together in the middle of the range. I haven't studied the code, but I'd like to know about the hardware first! - hence suggesting my tutorial, which takes you through setting the A2D up, in simpler steps than the datasheet.
 
Nigel Goodwin said:
Pommie said:
Nigel Goodwin said:
Check my tutorials for more details, but basically you need a low impedance source to feed the PIC A2D, as specified in the datasheet. If you try and use a high impedance source you will get massive crosstalk between the two channels - unless you wait for the sample and hold to charge or discharge.

If you look at the problem that he described and the code that he posted it is obvious that the problem is not impedance source or acquisition time.

The problem could be related to source impedance and aquisition time?, in that it works OK if the two inputs are close together in the middle of the range. I haven't studied the code, but I'd like to know about the hardware first! - hence suggesting my tutorial, which takes you through setting the A2D up, in simpler steps than the datasheet.


If you look at the code then you will see that the OP has adequate delays to cover acquisition times. He describes lack of resolution in the lower bits. The obvious answer is that he is trying to convert too fast and therefore reading the result before the lower bits have been resolved. Not only have you not studied the code, but you didn't read the description of the problem or consider my reply.

Mike.
 
Pommie,

You have correctly pointed out both the problem and the solution.

In OP's init routine, he has done to ADCON1:
Code:
		bcf	STATUS,RP1			;clears bank 2/3 bit		SETS UP SOME OF THE A/D MODULE
		bsf	STATUS,RP0			;Set bank 1 bit
		movlw	b'10000000'			;all analogue input code
		movwf	ADCON1				;Load it into ADCON1

So bit 6 of ADCON1, which is ADCS[2] is set to "0".

Now in his accquire routine, he set ADCON0 to b'00000001':
Code:
adcgetx		bcf		PORTD,5
		bcf 		STATUS,C			;Clear carry flag
		movlw		b'00000001'			;set clock Fosc/32 with A/D on
		movwf		ADCON0				;move new value into ADCON0

So bit7 and bit6 of ADCON0 which is ADCS[1..0] are both zero.

Note his comment saying "set clock Fosc/32 with A/D on" but in actual fact ADCS[2..0] which determines the conversion clock is "000", resulted in 2Tosc clock being used. Datasheet said the maximum OSC crystal freq.(which the OP has not mentioned) can only be 1.25MHz or less.
 

Attachments

  • adc_clock.gif
    adc_clock.gif
    9.3 KB · Views: 1,063
IT WORKS! :lol: :lol: :lol: :lol:

Hi there


Thankyou very much for your suggestions. Sorry I havnt replied sooner but this is the first chance that I have had.

I have just tried what eblc1388 suggested about the A/D Conversion Clock settings. I have just tried it set up in my room and it seems to work spot on now!!!!!!!!!!!

I know its a pritty stupid mistake but this is my first time doing a PIC project but I will certainly learn from this mistake!

Thanks again for everyones help!!!!!


Dave
 
Re: IT WORKS! :lol: :lol: :lol: :lol:

disco_dave said:
I have just tried what eblc1388 suggested about the A/D Conversion Clock settings.....

Glad it helps. Making programming mistakes is not the privilege of beginners but also experienced programmers alike.

All credits to Pommie who have spotted the problem and offered the solution in the first place. I just explained it a little more.
 
There is some 877 source code attached to the first post in this thread.

Mike.
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top