Simple Math
KaosKidd
Posts: 296
This is one of the times I wish I had a scope. I'm working on my first timing sensitive project (The inkJet Printer project) and I need some clarification please.
At the top of my project I have :
_clkmode = xtal1 + pll16x 'Standard clock mode * crystal frequency = 80 MHz
_xinfreq = 5_000_000
There three things which I must "abide by" within my prjoect.
#1: the "shot" must last between 3.5 uS and 6.0 uS. This is how long a single element of the inkjet head must be on, and the max length it can be on.
Playing with the numbers and visually testing the outputs (via the vga term), I come up with:
#2: My stepper motor driver states it's fastest drive rate is 250 Khz. If I am understanding things correctly, to get the max speed from things without over driving them, I would do something like this:
Without a scope, it's hard for me to confirm what I'm looking at in code (and on the screen and a few leds), so if anyone has better suggestions, ideas, comments or crits, please feel free to jump right in and correct me...
Thanks for any and all comments!
Fred
At the top of my project I have :
_clkmode = xtal1 + pll16x 'Standard clock mode * crystal frequency = 80 MHz
_xinfreq = 5_000_000
There three things which I must "abide by" within my prjoect.
#1: the "shot" must last between 3.5 uS and 6.0 uS. This is how long a single element of the inkjet head must be on, and the max length it can be on.
Playing with the numbers and visually testing the outputs (via the vga term), I come up with:
WAITCNT(((CLKFREQ / 1_000_000) * 5) + CNT)which I believe to be a 5uS delay, well within my limits. Part of this is because when I go for the 3.5uS, I get close to a 15~20 second delay, which tells me the calculated wait period is less then the minimum the WAITCNT can use, which is about 384, or some place close to this. If I understand the math (And I'm just grasping this side of it), at this clock speed, 1uS = 100 clock cycles. Please, someone, correct any and every place where this paragraph may be wrong, because it's the logic I use for the next paragraph.
#2: My stepper motor driver states it's fastest drive rate is 250 Khz. If I am understanding things correctly, to get the max speed from things without over driving them, I would do something like this:
StepperWaiTime = (CLKFREQ / 230_000) / 2 'Use a lower number then max to avoid maxing out the driver REPEAT StepperCount FROM 0 to NumOfSteps 'Counting the number of steps we need for this move OUTA[StepPin] 'Turn on the pulse WAITCNT(StepperWaitTime + CNT) 'Wait the minimum time OUTA[StepPin]~ 'Turn off the pulse WAITCNT(StepperWaitTime + CNT) 'Wait the minimum time (just in case we are NOT done with the loop)
Without a scope, it's hard for me to confirm what I'm looking at in code (and on the screen and a few leds), so if anyone has better suggestions, ideas, comments or crits, please feel free to jump right in and correct me...
Thanks for any and all comments!
Fred
Comments
So 5 us is only time for 100 instructions to execute.
I suspect you can't do that in Spin which takes about that many instructions per byte code to execute. (Someone might correct me here though).
If I wanted to do this I would have started out in PASM.
By the way you do have a scope. If you have a spare cog you can use it read the pin that you are driving and measure the pulse width it sees. Again I'd do that in PASM.
It takes (as close as I can tell) nearly the same amount of time for each. As long as I don't go over 6uS, which I'm calculating to be a wait of 600 + CNT, I'm good.
I have read the propeller manual on this and it does say the minimum WAITCNT is like 386 or so due to over head. At this point, the numbers make sense, but I do NOT want to start burning out $15.00 inkjet heads because my math was off, hence the discussion.
And, is there example code of a using a prop pin to measure the frequency of a pin on the same prop? How would that get wired? (Your idea above). I can always "include" this PASM code, and wire a temp pin setup to do my measurements...
The nice thing is you don't have to do any physical wiring. All COGs have access to all pins. So your monitoring COG need only set the same pin to input and then read it.
Try JonnyMac's object in the OBEX:
http://obex.parallax.com/object/308
That's going to require PASM -- Spin is just not fast enough. One of the cool things about Spin, though, is that you can do timing tests without a 'scope -- I use this trick all the time. Let's say, for example, that you want to know how long it takes to take a pin high, then immediately back low. You can do this:
The "- 544" at the end removes instruction overhead; the result is the number of ticks to run the test code. In this case it turns out to be 1120 ticks which, at 80MHz, is 14us -- so figure ~7us for the "on" time (which exceeds your requirement). The program is attached so you can experiment.
New Avatar is nice too.
Thank you John!
I was playing with your object and the first bits of code and I was coming close to that figure... what I couldn't come up with was the overhead number, and what's funny is your code could be used to come up with exactly that overhead figure as well... Nice... slick and nice..
So now I guess I have to write a PSAM routine... so it's time for me to start playing...
Maybe something simple that will monitor a pin... and when it goes high... it waits for {delay} then make it go low...
Thank you again everyone...
However, I'm not sure of a few things here.
First off, the Spin code:
This code was made from the bits and parts scattered throughout the various objects I looked at, trying to find the best way to have an PASM routine that toggled two pins for calculated (not changing) routine. No questions here. However, I'm always open to suggestions about better ways of doing this.
The PASM code:
After doing a LOT of reading, Using Beau's code:
My goal was to precalculate and save the masks and delay, thus the loop would be fast as possible.
My first question is when I move from Temp into Mask1, does temp get emptied?
My next question is about the main loop. I used Parsko's code as a template for the timing from this post (Edited for content and space)
My Questions are about the timing loop:
Why are we adding #9 to the delay?
And how does it handle when CNT rolls?
I do plan on testing once I reclaim my desk again, and test with a longer duration, but these questions just beg the asking.
And again, as always, any comments on how to do it better, please let me know.
Fred
Jonathan
Fred
As for rollover, doesn't really matter here. You're just confined to certain bounderies, e.g. the loop has a minimum execution time so your (minimum) output period is limited by that (you can in fact remove one waitcnt/xor pair).