|
|
View previous topic :: View next topic |
Author |
Message |
Sam_63
Joined: 21 Oct 2011 Posts: 17
|
32Khz Ext XTAL and delay_us() problem? |
Posted: Fri Oct 21, 2011 9:20 pm |
|
|
The snippet of code below is designed to vary the duty cycle servo motor along with some hysteresis based in an ADC reading (error) on an PIC16F616.
It works fine using #fuse INTRC and #use delay(clock = 8000000). I do however need to lower the overall power consumption of INTRC and use the #fuse LP and #use delay (clock=32768, xtal) and of course, I'm using a tuning fork xtal and 22pf caps on OSC1 and OSC2 as per the data sheet.
The problem appears only when using the 32768Hz xtal and in the delay_us() directives. However, the "delay_ms(xxx)" appear properly timing but, when program enters into "delay_us(xxx)", the controller/program basically stops.
I'm using PCM compiler and a http://cfm.citizen.co.jp/english/product/pdf/CFS-CFV.pdf xtal.
The xtal appears to be running properly (amplitude maybe a little low but my scope does load it down slightly, freq is right on) and again, the program seems to run fine until it runs the "delay_us()" section/s.
Any idea's?
Code: |
#include <16F616.h>
#device adc=10;
#fuses LP, NOWDT, NOPROTECT, BROWNOUT, PUT
#use delay(clock=32768, xtal)
if((error >= 1) && (error <= 1024))
{
if(error >= error_previous_high)
{
output_high(PIN_C2);//red light on, enable servo FET, wait 2 secs
delay_ms(2000);
for(y = (error_previous_high - 10) ; y <= error; y++)
{
output_high(PIN_C0); //start pulse
delay_us(y + 1360); //delay on
output_low(PIN_C0); //end pulse
delay_us(20000-(y + 1360));//delay off
}
error_previous_high = (error + 10);
error_previous_low = (error - 10);
output_low(PIN_C2);//red off, FET off
}
else if(error <= error_previous_low)
{
output_high(PIN_C2);//red light on, enable servo FET, wait 2 secs
delay_ms(2000);
for(y = (error_previous_low + 10); y >= error; y--)
{
output_high(PIN_C0);
delay_us(y + 1360);
output_low(PIN_C0);
delay_us(20000-(y + 1360));
}
error_previous_high = (error + 10);
error_previous_low = (error - 10);
output_low(PIN_C2);//red off, FET off
}
}
|
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19524
|
|
Posted: Sat Oct 22, 2011 3:57 am |
|
|
There are a number of things to realise.
First, the simple addition maths in your delay_us call, is going to take nearly 2mSec to run at 32KHz.....
Second the delay_us loop, takes a _minimum_ of several instructions to execute. and more if using an int16 loop variable (which you will be doing, though you don't show us the declaration of y). Say perhaps 12 instructions, giving a loop resolution of 400uSec, at your clock. 90% of loop values will simply be impossible at this loop frequency....
The internal count, is probably just going 'underscale' and failing.
It is a bit like asking a cricketer to catch a bullet. Just not possible.
Best Wishes |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9230 Location: Greensville,Ontario
|
|
Posted: Sat Oct 22, 2011 5:08 am |
|
|
It looks like you're trying to control an RC hobby type servo.If this is true, changing the type of oscillator to reduce power is NOT worth the effort.You are either powering the project from either a 'pluged into the wall' PSU or batteries.In either case the PIC uses very,very little power compared to the servo.
Also your code snippet also shows power hungry LED,again it'll take more energy to light than the PIC needs to run !
So I'm confused as to WHY you want to reduce PIC power when the 'perpipherals'(LEDs, servo) consume 100s of times the energy ? |
|
|
Sam_63
Joined: 21 Oct 2011 Posts: 17
|
|
Posted: Sat Oct 22, 2011 8:37 am |
|
|
Thanks temt and Ttel,
Ttel, you nailed it...thank you. I Just wasn't thinking, although after I posted 1/32khz = 32us, it occurred to me....doh.
temt, Yes you're correct but.....the led is just a diagnostic used that is removed and replaced by a FET. The servo doesn't run all the time.......the micro servo only comes on when needed...ie., short bursts when needed to correct errors in positions. The duty cycle is about 2% at a freq of around .001hz with off/idle currents around 1.6ma. The PIC is using about 90% of this 1.6ma while just spinning on data collections.
The AA are lasting about 30-60 some days at an overall idle current of around 1.6ma, I'd like the idle current down in the 10's-50's ua. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19524
|
|
Posted: Sun Oct 23, 2011 2:39 am |
|
|
The first obvious thing is to 'not go so far'. Take the CPU frequency down to perhaps 1MHz, and though timing resolution will go down, things will still be possible. Your consumption is a little high at 8MHz. This will obviously depend on what lines you are changing/driving though. Typical consumption at 1MHz, is 345uA.
If you can change PICs, one possibility would be to go for one that support oscillator switching. Then on the delays between pulses, switch the oscillator down, and perform these at a low clock rate. Devices like the 16F1503, support an internal clock, that might be accurate enough for your application (servos are not that accurate), and offer switching between the rates from this 'on the fly'. It's baseline consumption is already about 50% lower than the chip you are using....
Best Wishes |
|
|
Sam_63
Joined: 21 Oct 2011 Posts: 17
|
|
Posted: Sun Oct 23, 2011 9:29 am |
|
|
Yes totally agreed Ttel, that was is what i was just considering.
As slow as the data collection is, I could switch on the fly between the LP 32Khz ext. clk. mode for data acquisition and over to 8/4/1Mhz int. clk. for servo commands.
You say the 16F616 doesn't support that INT/EXT clock switch over? Bummer
If not, yes, I'll have to switch PIC's then. |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|