|
|
View previous topic :: View next topic |
Author |
Message |
hobby_85
Joined: 17 Aug 2009 Posts: 50
|
PWM for ultrasonic |
Posted: Mon Aug 17, 2009 9:24 am |
|
|
Hey all,
I'm new to PICs and am currently going through tutorials on how to program them. I find it extremely interesting. However, the tutorials I am currently going through don't mention anything about the PWM function.
My ultimate aim is to create a 40 KHz wave in my 16f690 and send it through a voltage multiplier (hardware) and then onto my ultrasonic transducer.
Before I posted this, I check this forum and, yes, there's heeeeaps on the topic....but its all over the place and there doesn't seem to be like a guide/tutorial as such. Is there a good place I can start?
Thanks. |
|
|
bungee-
Joined: 27 Jun 2007 Posts: 206
|
|
Posted: Mon Aug 17, 2009 2:36 pm |
|
|
I didn't use PWM for my Ultrasonic ranger project. I simply coded that part in asm to get the timing right.
You do not need to send very long pulse, in my project I used 8 cycles that was "long" enough to catch it on receiving end.
Now try to write the code and I'll help you with suggestions. |
|
|
Ttelmah Guest
|
|
Posted: Mon Aug 17, 2009 3:00 pm |
|
|
You can use either direct loop code, or a PWM.
The ultrasonic rangefinder used with the Lego Mindstorms system, was coded in CCS C, using a PIC, that doesn't even have a PWM.
Like bungee, the pulse length was only a few cycles.
At the end of the day, for the PWM, all you do, is chose a timer divider to give 40KHz, and set the duty cycle to 50%. Wait for a _short_ time (no more than 1mSec typically), and then set the duty cycle to 0%, or 100%, according to whether your drive circuit is 'off' with a ve input, or a -ve input.
Your _minimum_useable distance, is controlled by how fast the detector settles after picking up the outgoing pulse, and how short the pulse train is. Longer pulse trains though give better detection at greater ranges.
A really great 'test' target, is a tennis ball. It's soft surface, and shape make it a very difficult target to detect at reasonable ranges.
Best Wishes |
|
|
hobby_85
Joined: 17 Aug 2009 Posts: 50
|
|
Posted: Mon Aug 17, 2009 5:30 pm |
|
|
bungee- wrote: | I didn't use PWM for my Ultrasonic ranger project. I simply coded that part in asm to get the timing right.
You do not need to send very long pulse, in my project I used 8 cycles that was "long" enough to catch it on receiving end.
Now try to write the code and I'll help you with suggestions. |
Oh excellent. sure. I'll write up something and put it up by end of today. Thanks alot.
However, I'm hellbent on using pwm because I'm trying to make something alot more complicated, and this is just part of it. I need the pic to be able to control the length of the burst (125 ms), when it bursts the signal and so on. So I'm going for something like....Wait for something to happen -> when the something happens, burst ultrasonic signal for 125ms-> stop bursting.
But yeah, for the time being, I'll work on non-stop bursting.
Anyway, thanks heaps fellas. I'll put something up soon. |
|
|
asmboy
Joined: 20 Nov 2007 Posts: 2128 Location: albany ny
|
|
Posted: Mon Aug 17, 2009 6:09 pm |
|
|
In every project I take on - I strive to make it as uncomplicated as possible -
Basically only as complicated as required, to do the job reliably with the precision ++needed - but no more complicated than that
I've listened to TTelmah's wisdom on that score before , as many the complicated approach can frustrate the creator as well as fail , where simple && elegant gets the job done && leaves more time at the pub.
|
|
|
Guest
|
|
Posted: Mon Aug 17, 2009 10:46 pm |
|
|
Ttelmah wrote: | You can use either direct loop code, or a PWM.
The ultrasonic rangefinder used with the Lego Mindstorms system, was coded in CCS C, using a PIC, that doesn't even have a PWM.
Like bungee, the pulse length was only a few cycles.
At the end of the day, for the PWM, all you do, is chose a timer divider to give 40KHz, and set the duty cycle to 50%. Wait for a _short_ time (no more than 1mSec typically), and then set the duty cycle to 0%, or 100%, according to whether your drive circuit is 'off' with a ve input, or a -ve input.
Your _minimum_useable distance, is controlled by how fast the detector settles after picking up the outgoing pulse, and how short the pulse train is. Longer pulse trains though give better detection at greater ranges.
A really great 'test' target, is a tennis ball. It's soft surface, and shape make it a very difficult target to detect at reasonable ranges.
Best Wishes |
yeah, that makes sense. still working on something. i dont have an oscislloscope at home so ill let you know how it turns out |
|
|
Guest
|
|
Posted: Mon Aug 17, 2009 10:49 pm |
|
|
Ttelmah wrote: | You can use either direct loop code, or a PWM.
|
Just a quick question with using a loop code. I'm guessing you're talking about a loop where you define the pins to turn off and on at different times. Doesn't this use a lot more pins of the chip...unlike a PWM version, which uses the CCP one?
Sorry about the questions. I'm still new to this. I've read about the direct loop method and saw the circuit for it, but it looked like a lot of pins were being wasted.
Thanks |
|
|
bungee-
Joined: 27 Jun 2007 Posts: 206
|
|
Posted: Tue Aug 18, 2009 12:00 am |
|
|
Loop needs like PWM only one pin if you write your code like that.
Pseudo code for loop would look like that:
Code: |
while (pulses<8)
{
turn_pin_on;
wait;
turn_pin_off;
wait;
pulses++;
}
|
|
|
|
languer
Joined: 09 Jan 2004 Posts: 144 Location: USA
|
|
Posted: Tue Aug 18, 2009 12:23 am |
|
|
As a start, the following snippet produced a 40kHz output on the 16F88 (8MHz INTOSC).
Code: | setup_timer_2(T2_DIV_BY_1, 49, 1); // Configure timer2 for 40kHz PWM frequency
setup_ccp1(CCP_PWM); // Configure CCP1 as a PWM, the cycle time will be (1/clock)*4*t2div*(period+1)
set_pwm1_duty(100L); |
Values were obtained using a little utility called PicMultiCalc (see http://www.picbasic.co.uk/forum/showpost.php?p=65639&postcount=38).
I've used both HW PWM and software routines to produce 40kHz (to drive both ultrasonic and IR). If I have a device with two pins to spare (one of them being HW PWM), I like to drive both outputs to a NAND (or AND) gate. I then use the non-PWM output as an enable signal. Alternatively, as Ttelmah suggested, drive the PWM to 0% or 100%. |
|
|
hobby_85
Joined: 17 Aug 2009 Posts: 50
|
|
Posted: Tue Aug 18, 2009 3:45 am |
|
|
Hey, this is my first attempt at creating the PWM signal of 40 Khz through the internal osc of my 16f690.
Very sorry if I've done some stupid stuff, I'm still learning. I got the code from various discussions in this forum and modified it for me. As a reminder, I'm trying to drive my ultrasonic transmitter.
Code: |
//creating a PWM signal from the CCP pin of the 16f690
#include <htc.h>
#fuses XT, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP
#use delay(clock = 4000000)
main()
{
TRISC = 0b00011111; // set the CCP pin (rc5) to out
setup_ccp1(CCP_PWM); // Configure CCP1 as a PWM
setup_timer_2(T2_DIV_BY_1,24,1); // 40000 Hz
set_pwm1_duty(62); // 50% duty cycle on pin C2
while(1); // forever
}
|
Of course, when I compiled it, I got lots of errors. These are:
Warning [107] C:\Users\admin\Desktop\Pic training\pwm_signal.c; 6.6 illegal # directive "fuses"
Warning [107] C:\Users\admin\Desktop\Pic training\pwm_signal.c; 7.4 illegal # directive "use"
Warning [361] C:\Users\admin\Desktop\Pic training\pwm_signal.c; 14.1 function declared implicit int
Error [192] C:\Users\admin\Desktop\Pic training\pwm_signal.c; 14.12 undefined identifier "CCP_PWM"
Warning [361] C:\Users\admin\Desktop\Pic training\pwm_signal.c; 16.1 function declared implicit int
Error [192] C:\Users\admin\Desktop\Pic training\pwm_signal.c; 16.15 undefined identifier "T2_DIV_BY_1"
Warning [361] C:\Users\admin\Desktop\Pic training\pwm_signal.c; 17.1 function declared implicit int
edit: After looking around, i realized that my ccs compiler version doesnt correspond to the 16f688 pic that im using. Ill sort that out. However, I was just wondering if the above code to generate the 40khz PWM wave is correct. Thanks ! |
|
|
mkuang
Joined: 14 Dec 2007 Posts: 257
|
|
Posted: Tue Aug 18, 2009 8:23 am |
|
|
The 40Khz is about right. This is wrong:
Quote: |
set_pwm1_duty(62);
|
The number should be 12 or 13 depending on whether you want t a little more or less than 50%. Or you can adjust your code slight and do this:
Code: |
setup_timer_2(T2_DIV_BY_1,25,1); // 40000 Hz
set_pwm1_duty(13); // 50% duty cycle on pin C2
|
And get rid of the TRISC line of code, not necessary as the direction of the pins are set by the compiler. |
|
|
hobby_85
Joined: 17 Aug 2009 Posts: 50
|
|
Posted: Tue Aug 18, 2009 8:55 am |
|
|
your god send!!
thanks mate. feeling a little more confident using ccs now. Was using hi-tech earlier.
i got one compiling error though.
It says unknown keyword in fuses, "NOLVP"
thanks man...cant wait to hit get the oscilloscpe to check if it works. |
|
|
mkuang
Joined: 14 Dec 2007 Posts: 257
|
|
Posted: Tue Aug 18, 2009 9:10 am |
|
|
hobby_85 wrote: | your god send!!
thanks mate. feeling a little more confident using ccs now. Was using hi-tech earlier.
i got one compiling error though.
It says unknown keyword in fuses, "NOLVP"
thanks man...cant wait to hit get the oscilloscpe to check if it works. |
Check the header file for your pic in the devices folder for your compiler and see whether you see NOLVP as a valid fuse. I do not have your compiler so I cannot check that for you.
I also have the HITECH compiler and have an example of doing the same PWM. It is copyrighted material so I am hesistant to post it. If you are interested to see how HITECH does it send me a PM with your email address and I will share it with you. It is not all that different actually. |
|
|
mkuang
Joined: 14 Dec 2007 Posts: 257
|
|
Posted: Tue Aug 18, 2009 9:34 am |
|
|
What's in this file?
#include <htc.h>
That does not look like a valid CCS device header file. Is that for HITECH? If it is no wonder it doesn't work. |
|
|
hobby_85
Joined: 17 Aug 2009 Posts: 50
|
|
Posted: Tue Aug 18, 2009 9:59 am |
|
|
mkuang wrote: | What's in this file?
#include <htc.h>
That does not look like a valid CCS device header file. Is that for HITECH? If it is no wonder it doesn't work. |
Sorry, that was changed to #include <16F690>. The code compiles properly. I'll check it in the lab tomorrow to see if the pwm emits. If it does, I'll post a copy of the code for others. Thanks for the help.
Also, I sent you an email regarding the hi-tech version.
thanks heaps mate. |
|
|
|
|
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
|