PWM on a single pin for 1 second @20 khz without starting a cog?
eagletalontim
Posts: 1,399
in Propeller 1
As the title says, how would I be able to pulse a pin at 20khz with a 50% duty cycle for 1 second when needed without starting a new cog? I already have all cogs used in my current program. Any help is appreciated!
Comments
5 BLINK 20 KHZ 1 second MUTE
Sometime you are just evil, Peter, but you are always correct.
I really need a vacation down under to get the gist out of RPN and FORTH.
Maybe I start with mounting my globe upside down. Just to get a feeling for it.
Thanks,
Mike
My globe has Australia on top and you guys down under (it's all the same to Sol) so that means RPN is actually AFN ( Australian Forward Notation) so that is probably why it's all back to front for you guys
each cog has two timers, they run in parallel to normal execution. You can set modes and frequencies and pins and tons of other things I do not really understand by myself, but they are there. The nice thing is the timer are very fast, even when used out of spin, not assembly.
@Evanh posted the link for a detailed description. You basically need to set pin, frequency and mode, start it, wait a second and stop it.
@Peter, looks like I need to add AFN to my known Acronyms 'Australian Forward Notation'. Very nice. It looks like I am on the right trail there with the Globus south side up, since you did that too. Will try, wait some weeks to adjust, and test Tachyon again.
A friend of mine told me he has "CDO". I ask what "CDO" is. He said: It is like "OCD" but in alphabetical order...
Enjoy!
Mike
BTW, here is a scope shot of Tachyon executing the command:
22 BLINK 5 KHZ 8 ms MUTE
The solenoid needs around 20khz from what I read a long time ago. I can't find the spec sheet on it anymore
I don't know what Tachyon is and I am sure it would be a PAIN converting my entire program (over 1000 lines of code) to another language I know nothing about It does seem quite simple if it takes 1 line of code to do what 3 or 4 lines of spin can do.
This is what I have figured out so far..... which is not much at all....
ctra := %00100_000 << 26 + Controller_Pin
frqa := $A000_0000 ' ????????? lost.....
The other thing to remember is that Tachyon is interactive to you can just try an idea with instant results (and feedback) much as I did the one liner.
You could probably cherry pick 20-ish very specific settings for frequency and duty to give you 20khz with the timings you need, and have one of your cogs push those settings through the counter registers for you over your 1 second period. Would it need to be really fine granularity for it to work?
I think you can do exactly that, using two counters in NCO mode, and you can push that 1 second out to longer (or shorter).
What you do is pgm one NCO to 20.000kHz and the other to 20.0005kHz, and then externally XOR with a SingleGate Logic device.
(1G57/58/97/98 etc)
Over a time of 1 second the phase of those walks half a period, which swings XOR from 0% to 100%
If you want a movement of 0 to 50% or 50% to 0, then you need a quarter period in 1 second, or 20.00025kHz
Once you hit the target, you need to reconfig the counters, otherwise the phase movement continues and you will get a triangle wave modulation of Duty Cycle : Up-Down-up-Down
Maybe it's a smarter solenoid, and the PWM is converted to a DAC value ?
In which unlikely you would be able to use duty cycle mode effectively.
What Tim did make clear at the outset was the Cogs were all busy ... so having the hardware maintain the set level is important.
Assuming its a DC coil, 20KHz probably is a good starting point for duty mode. Worst case will be a noisy valve down near 0%. Just don't use that part of the range.
I am not that keen on counters, but it sounds to me that you could get what you want by altering my stepper driver code. This code alters the duration of the pulse, for a specific number of pulses, however, I suppose it would be easy enough to alter it to being time based (1 second), instead of being pulse based. Of course most of this code is useless to you, but the important thing is the math that alters the frequency. Here is an example:
Frequency is about 17 kHz but you can adjust time, frequency and width by changing the numbers.
The first 3 lines are only once needed to initalize, the last 5 lines do one shot of PWM for a second.
Andy
This runs at 20khz. I tested it with an LED on pin 9. It contains a cognew so I could test it. You can simply initialize it in a child object that has an available counter and call it from a parent.
edit: I didn't configure the cog to run @ 80Mhz.
http://obex.parallax.com/object/839
It is like the one in the previous post but with counter initialization added for the inverted waveform on a second pin, and a square wave synchronized at the beat frequency on a third pin. It is bare bones so that the essentials don't get lost in apps overhead.
The cog counters are great for picking up little tasks. They're limited, of course, but when appropriate, they are a great but I think underused feature of the Prop 1.