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.

Strange ADC behavior(18F452)

Status
Not open for further replies.

ombrastein

New Member
Im experincing very strange(to me at least) behavior from the ADC on my PIC18F452. Im trying to measure a very small voltage over a 0.1 ohm resistor. the resistor sits between GND and gnd on a servo. What i need to know is how much current is passed thru the servo, so i can tell how much load there is on said servo...


I know that with a 0.1 ohm resistor the ground conections resistanse will also play a part but its not all that important the actual numbers here... I only need to know the relative change in servo load, not to somehow calculate exatcly what that load is... thus it doesnt realy matter if the resistanse im measuring over is 0.1 or 0.3 ohm(at least this is the way ive imagined things .. could be wrong, wouldnt be the first time ;) ).

The voltage drop measured between GND on the micro controler and the servo (measured over the 0.1 ohm resistor pluss the ground conection wires) is about 50 mV, wich should give a reading of 10 from the adc (using Vcc as ref and 10 bit => 5v/1024 = aprox 5mV per step). When i use my ICD debug to check what the ADC reads strange things happen...


Of course i have to make sure the servo is actualy loaded while the adc is measuring so heres what i do in code. I let the servo hold its position for 1 sec, then i take an adc reading (while servo is still beeing held with constant load, wich i know prdouces 50mV on the resistor).

Now to the odd thing. This works kind of randomly. i do get some readings for maybe 2 or 3 second (one reading per second from the adc) and then i suddenly get all 0's for a few seconds, before i again get some reasonable values again. It alternates continuasly between reasonable values and 0's. There is no pattern or periode to this. The value i read is not exactly 10, it varies between 10 and 15, but i gues that with Vcc as Vref i cant expect better acuracy then that, and of course the voltage im measuring is genereted by a motor pushing current thru a resistor so it wont be that acurate to begin with.


Ive tried to read thru the datasheet about 10 times but i cant find anything wrong with my setup. Is there a minimum resistance that the pic needs to see towards GND from the adc? in my circut it sees basicly 0.1 ohm...


Any bright ideas would be much apritiated ... im kind of lost right now as to what could be causing this ...
 
Been doing some more investigating, still not sure but it could be simply that the servo load isnt as constant as i thought ... id still like to hear some ideas on this tho?

BTW: would there be anything teribly stupid about using a potmeter voltage devider as the Vref? as mentioned im not to conerned with acuracy here ...

Is there any minimum Vref that is recomended?
 
Things to check. Not using that chip.

I would look at your power input to the chip. Does the ADC require a delay or multiple reads like a debounce? Decoupling cap maybe?

And it is a PIC, check the config over and over.
 
Servo load constant? <laughs> Sorry =) Servo's pulse their motors somewhere around a rate of 50 times per second regardless of load, the motor on time is regulated by an error signal generated by the POT and internal electronics, so the further away from center the servo is the greater the on period of the individual servo pulse is.. It's no surprise you're getting somewhat random readings. 1 reading from the ADC per second is drastically insufficiant for measuring the power consumption on a servo, you're going to need to measure at least 100-200 or more times per second and average that over time. I would recomment an ADC update rate of as fast as you can possibly manage.
 
Last edited:
servo load

Im using a 30 us delay before reading the ADC result (thats because i change ad channels often).

Ad for servo load not beeing constant... im very well aware of how servo motors work. Im measuring the current drawn thru the servo, wich cannot change momentarly (its a spool). I gues tho that it is very possible that the current still changes to fast so that it sometimes will read a 0 (becaus there is actualy no movment of the servo)... supose i could put a capacitor on the analog input line?
 
You could use a capacitor as an integrator but the signal frequency is only 50hz so you need a big capacitor to smooth it, mind you this might actually load the servo motor or cause undesired operation. And the current through the servo does change momentarily. Even if you get an apparent constant motion the servo's are still being pulsed, they never receive a constant stream of power, excepting perhaps when the error signal is maxed.
 
current thru servos

Thx for the replies :)

Ive looked closley at the signal with a scope. As you said the current is pullsed thru at 50 Hz and the duty cycle is rather low. Im thinking the best aproch is to simply sample the signal at about a kilo hertz. problem is i have 12 servos that i need to measure, but it should be possible to figure some way to do that using a timer and the adc interupt. Ill figure out some code for that. When looking at the data from my test app the results look promising.

I will measure the signal evry 1 ms over a period of 20 ms and then integrate it. That would give a good idea of how heavly loaded the servo actualy is.

Another way i supose is to somehow figure out the length of the pulse and the avrg amplitude and use that info to figure out the load.

Ill run some test and see what works best...

Thx again for the help tho
 
The pulse length going to the motor can be read directly from the servo electronics by tapping into the error signal. Which is the difference between the POT setting and the applied servo signal. It's going to be available on at least one pin somewhere inside the servo. Instead of using the ADC you could use a digital input capture method that just times the on and off pulses. It's interupt intensive but servo signals are very rarely generated concurantly so you can do quiet a few channels. How are are you generating 12 channels? This can't be done with typical RC setups (aside from some slightly exotic pulse compressed methods that multiplex uses on it's 12 channel radios)
 
Controlling 12 servoes is easy enough. Each servo channel has a pulselength that differs with maximaly 1600 us (800 + 0 to 1600us). Now 12 times 1600 us is 19200 us wich means about 52 Hz.

The trick is that you just have to set the pulse high 800 us before starting the counter that sets it low. Meaning pulse n+1 has to go high while pulse n is beeing timed to go low (could be before or after it goes low).

Not sure if that mayde much sense. The basic is that with some clever coding and a 18F452 its realy no problem to generate 12 channels of 50 HZ PWM with 800+0to1600 us high time.
 
Got the current measurments working now. Reading the adc of all 12 channels evry 1 ms for 20 ms (one periode of signal). Then integrating (summing values). Then i added a simple avrg filter. Works like a charm.

Only trouble now is that the current the servoes pull can be just as high while servo is moving freely as it can when experinceing high load (high beeing relative to my system of course)

Ill figure a software way around that tho. Its a common problem it seems to trying to read force of a servo. Ive read a few articles by Brooks, including the one about his hexapod Ghengis. He describes there pretty much the same problem. Should be easy enough to figure some code for it.
 
In order to determine the true torque you'd need a rotational sensor on the motor. It gets very complicated because the gears and drive train have mass and frictional losses need to be taken into acount. So you'd need to know the current being used, the rotational speed and the acceleration/deceleration rate, which is easily determined by the difference between the last two (or more) rotational speed readings.
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top