Pulsing a pin
Newzed
Posts: 2,503
I hve hopes of using the Propeller to run my little SuperMill which is presently controlled by a BS2E.
I modified my frequency generator program as follows:
cycle:= 500
travel = 100
· DirA[noparse][[/noparse]OutPin] := Out
· Repeat travel
·· repeat 104
··· !OutA[noparse][[/noparse]OutPin]·········· 'Toggles at cycle rate
··· WaitCNT(cycle + CNT)
I·ran it four times and got answers of 5107, 5236, 5209 and 5198 pulses.· My mill must receive a pulse train of 5156 pulses, plus or minus 2 pulses, to travel 100 mils, which makes the Propeller output I am getting unacceptable.· Is there any way to get a very precise and consistent number of pulses for what ever travel I enter?
Thanks
Sid
I modified my frequency generator program as follows:
cycle:= 500
travel = 100
· DirA[noparse][[/noparse]OutPin] := Out
· Repeat travel
·· repeat 104
··· !OutA[noparse][[/noparse]OutPin]·········· 'Toggles at cycle rate
··· WaitCNT(cycle + CNT)
I·ran it four times and got answers of 5107, 5236, 5209 and 5198 pulses.· My mill must receive a pulse train of 5156 pulses, plus or minus 2 pulses, to travel 100 mils, which makes the Propeller output I am getting unacceptable.· Is there any way to get a very precise and consistent number of pulses for what ever travel I enter?
Thanks
Sid
Comments
What are you using to measure the pulses, and is there a specific timeframe in which the pulses are to be delivered?
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Who says you have to have knowledge to use it?
I've killed a fly with my bare mind.
term.out(13)·························
· DirA[noparse][[/noparse]InPin] := In·················
· CTRA := 0································ 'Clear CTRA settings···········································
· CTRA := (%01010 << 26 ) | (%001 << 23) | (0 << 9) | (InPin) 'Trigger to count
··························································· 'rising edge on InPin······································· ' edge on pin
· FRQA := 1000····························· 'Count 1000 each trigger
·
··· term.Str(string("Travel of "))················ 'Display string on LCD
··· PHSA := 0································ 'Clear accumulated value
··· WaitCNT( clkfreq + CNT )·············· 'Wait for 1 second
··· Frequency := PHSA / 1000················· 'Calculate···frequency·
··· term.Dec(travel)······························ 'based on duration
··· term.str(string(" = "))
··· term.dec(frequency)
··· term.Str(string(" pulses"))··················· 'Display string on LCD
··· term.out(13)
The time frame is determined in part by the number of pulses I want to generate.· On the BS2E I wrote:
pulsout pin, 10
which is 20us for each pulse.··With code overhead it takes about 3 seconds to travel 100 mils.· Time frame is also dependent on the rotational speed of my stepper.
Sid
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Who says you have to have knowledge to use it?
I've killed a fly with my bare mind.
Sid
Post Edited (Newzed) : 6/25/2006 10:10:25 PM GMT
A cycle of 500 = clkfreq/160_000.· This tells me I should be able to get a max of 160_000 toggles per second which is equivalent to a max pulse count of 80_000 Hz.· The max number of pulses I can get if the program counts for "waitcnt(clkfreq + cnt)" is about 22455, which is equivalent to about 44910 toggles per second.· Is this correct or am I missing something?
Sid
I think the angle of attack needed for this problem is getting the right formula for calculating the correct number of pulses total rather than a given freq
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Who says you have to have knowledge to use it?
I've killed a fly with my bare mind.
edit: have not actually tested the code, as I don't yet have a keyboard attached
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Who says you have to have knowledge to use it?
I've killed a fly with my bare mind.
Post Edited (CJ) : 6/26/2006 12:57:02 AM GMT
I'm not positive of this as I don't profess to be an expert in the Spin language, but I suspect that interfacing reasonably fast real life signals is somewhat incompatible with the relatively slow and unpredictable timing of executing Spin code.
What I am positive of is that an assembly routine, while more complicated to write, is able to perform the required functions accurately and repeatedly.
If you could run one Cog in assembler to measure the pulses, and one assembler Cog to generate the pulses, all can be perfect. The other Cogs could be used to do non-realtime things like your display etc.
Let us know if you need some help creating the assembly routines.
Cheers,
Peter (pjv)
CJ, I ran the program you attached and it seems to work.· A couple of things - when I ran the program the screen displayed:
Travel of 1120403456 = 5156 pulses
The pulse count is OK but I have no idea where that big number came from.· So.......i changed the program as follows:
·'floatmath to use the per mil value of 51.56
· y := travel····· 'inserted this line
· travel := fp.ffloat(travel)
· 'term.out(13)
and
PHSA := 0································ 'Clear accumulated value
··· WaitCNT( clkfreq*4 + CNT )·············· 'Wait for·4 seconds
··· Frequency := PHSA / 1000·················
··· term.str(string("Y travel of· "))
··· term.Dec(y)························· ·'y was travel
··· term.str(string(" mils = "))········ 'added mils
··· term.dec(frequency)
··· term.Str(string(" pulses"))
Now the TV displays:
Y travel of· 100 mils = 5156 pulses
Also please note that I had to increase the count time to 4 seconds to display the pulses for a travel of 1000 mils.
Peter, if you could·change whatever is necessary to assembly, that would be fantastic.· I do not understand assembly so·any sequence where I choose an option or where I have to control the keyboard or TV would have to be in Spin.· I have attached the program and all the objects it uses for your convenience and·to make sure we are working with the same code.
Sid
I have changed the program as follows:
DirA[noparse][[/noparse]OutPin] := Out
·· repeat pulsetrain
··· !OutA[noparse][[/noparse]OutPin]·········· 'Toggles at cycle rate
··· WaitCNT(cycle + CNT)
··· !OutA[noparse][[/noparse]OutPin]······
··· WaitCNT(cycle + CNT)
· if kb.getkey······················· 'added this line
··· waitcnt(clkfreq/100 + cnt)· 'changed waitcnt
Now the TV displays until I press any key, then it clears the screen and goes back to the first repeat after start and displays the starting menu again.
Sid
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Who says you have to have knowledge to use it?
I've killed a fly with my bare mind.
will generate a number of pulses equal to pulsetrain. All you need to do is find a value for cycle that generates a frequency that's acceptable to your mill. I think the errors you are seeing are related to the measurement, not the generation. The measurement routine you're using was created to measure frequency, not count, so it's not the appropriate tool to use in your situation.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
OS-X: because making Unix user-friendly was easier than debugging Windows
links:
My band's website
Our album on the iTunes Music Store
This morning I hooked up my Optascope and took a screen shot of the Stamp output and the Prop output.· The pictures are attached.· Settings on the scope were the same for both.· The width of the pulse on the Stamp output as about 29us and the delay between pulses was about 1330us.· I do not know what generates the delay - maybe that is code overhead.· Obviously, I could not measure the Prop output
The Stamp output is what actually runs the mill steppers, so I have to get the Prop output looking the same as the Stamp.· This means that instead of toggling the Prop output I will have to take it high for about 25us, then low for about 1300us.· Also, I no longer need to count the output - I have counted it enough to know that the output is correct for the amount of travel entered.· So I will see if I can disable the counting function without interfering with the rest of the program.
Sid
DirA[noparse][[/noparse]OutPin] := Out
·· repeat pulsetrain
··· !OutA[noparse][[/noparse]OutPin]·········· 'Toggles at cycle rate
··· WaitCNT(cycle + CNT)
··· !OutA[noparse][[/noparse]OutPin]······
··· WaitCNT(cycle + CNT)
and modified it to read:
DirA[noparse][[/noparse]OutPin] := Out
·· repeat pulsetrain
··· OutA[noparse][[/noparse]OutPin] := 1·········· 'Toggles at cycle rate
··· WaitCNT(cycle + CNT)
··· OutA[noparse][[/noparse]OutPin] := 0······
··· WaitCNT(cycle*178 + CNT)
A picture of the resultant Prop output is attached.· Pulse width is about 30us and the delay between pulses is about 1330us.
Sid
Do you have the PBASIC code that's currently working with the mill? If so, that would also eliminate a lot of guesswork.
Just remove the lines that start and stop the MeasureFrequency cog. You can also remove or comment out the MeasureFrequency method.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
OS-X: because making Unix user-friendly was easier than debugging Windows
links:
My band's website
Our album on the iTunes Music Store
Sid
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
OS-X: because making Unix user-friendly was easier than debugging Windows
links:
My band's website
Our album on the iTunes Music Store
Sid
The entire program is now menu-driven, and we added a new cog for the Z axis.· We also added a sequence to drill a hole.· Assuming the drill is positioned where you want it and that the height of the drill above the PC board is set at about .060, if you press "d", the drill goes down 185 mils, pauses for 500ms, then goes up 185 mils and returns to the start menu.· Next effort will be to add a sequence to drill holes for a SIP or DIP, with a varying number of holes and a varying width.· I still have about 9900 bytes of memory left.
I have attached a copy of pulsout_F in case you would like to take a look at it.· You will need a keyboard and a TV connected if you want to run it.
Sid