Shop OBEX P1 Docs P2 Docs Learn Events
math dependant program questions — Parallax Forums

math dependant program questions

krazyideaskrazyideas Posts: 119
edited 2010-02-14 18:16 in Propeller 1
Hello all,

Ok well A little while ago I made a RPM gage using the propellor, but it is not very accurate. It jumps by about 60 RPM up and down. It was a while ago that I made that program and it worked suffencently.

But now I want to build a program that I can use time to mark 1/3 degree marks for a entire rotation at 2500 RPM.
And with my past experince with the propellor (which is very limited), this is not possible, because I need a seperate cog to run (I think) floating point math to get accurate multiplication and division and that would take too long for me to get a 1/3 degree map of the motor's rotation each rotation.

I expect that I am underestimating the abilities of the propellor as I have before, but I just wanted to know if what I want to do is doable.

The program would
1)·measure the number of counts in a rotation
2)(Using Floating Point Math) divide the number of counts by 1080 (360 * 3),·calling it Mark
3)then wait for my mark to signal·the zero·mark (which only shows once a rotation)
4)from which I can·(using Floating Point Math) use Mark times whichever 1/3 of a degree I want to execute a command on.

I would have 2 cogs running the above program just off set by one rotation and therefore still being able to execute commands every rotation

More or less I'm trying to make a decoder wheel with only one mark on it.

I'm I barking up the right tree, is the idea decent?
Is Floating Point Math Fast enough?

I'd just like to know if I should give it·a whirl.

Thanks so much
·

Comments

  • Mike GreenMike Green Posts: 23,101
    edited 2010-02-13 23:10
    You're asking the wrong question. It's not "is floating point math fast enough?". It should be "how do I divide a rotation into 1/3 degree 'ticks' at 2500 RPM?".

    2500 RPM is roughly 40 revolutions per second or 25ms per revolution. That's roughly 25us per 1/3 of a degree rotation. The Propeller can execute about 2000 instructions in that amount of time. If you call the floating point routines from assembly language, you could do a couple of simple operations in 25us, but it sounds like what you want to do doesn't need floating point.

    Why not calculate ahead of time how many system clock ticks are needed from the "zero mark" to when you want to execute something? You'd have an assembly routine running in a cog waiting for the "zero mark" using a WAITPNE instruction, then do a WAITCNT instruction with the number of system clock ticks to wait. When the WAITCNT is over, your "command" routine would execute. When the "command" is done, your cog program would jump back to wait for the "zero mark" again.

    If you want to run two cogs so there's time for the "command" to run, it's easy enough to compute the time just before the next "zero mark" will come up and wait for that before waiting for the "zero mark".

    Post Edited (Mike Green) : 2/13/2010 11:15:28 PM GMT
  • krazyideaskrazyideas Posts: 119
    edited 2010-02-14 00:10
    Well I can't calculate how many clock ticks I need to wait before executeing a command because the motor does not hold a perfect 2500 RPM. In fact, this program has to keep up with the motor from about 500 RPM up to 2500 RPM and then adjust for its small flucuations up and down in RPM.

    It's not so much that I need to do commands every 1/3 degree but more I need to execute a command that lasts for X number of 1/3 degrees and it needs to occur at A 1/3 degrees, B 1/3 degrees , C 1/3 degrees, etc... after the "zero mark" each rotation.

    So how I was going to have the program adjust for the RPM flucuations was to measure the time it takes for a rotation on one rotation and then execute on the following rotation, that leads to the problem of only being able to execute on every other rotation, which I hoped to remedy that was have two programs running off set like I mentioned before.

    So it sounds like this shouldn't really be all the hard to do, and that the propeller is plently able to do what I am wanting.

    Though Assembly and I don't get along very well. Knowing more of what I want to do would Spin be suffencent?
    Also just wondering how much faster is Assembly then Spin?

    Thanks a ton Mike
  • MagIO2MagIO2 Posts: 2,243
    edited 2010-02-14 00:11
    The question is how accurate should it be?! What do you want to do in 1/3 degree steps?

    80_000_000 / 2500 = 32_000 clock ticks per round
    32_000 / 1080 = ~30 clock ticks per 1/3 degree
    You can not wait for 29,629 ticks, so the prop can't be accurate with waiting for 1/3 degrees.
    Floating point arithmetic won't help with that!
    30 - 29,629 = 0,371 => deviation of ~1,25% (at this speed)

    Bigger problem might be that you need a full turn until you can correct the value.

    You should have a look at the bresnham algorithm. It's usually used for drawing lines, but it draws lines with integer arithmetic by keeping track of the deviation.

    Maybe you can tell a bit more about your project, so that we can see more clearly what's the reason behind.

    One other idea might be to use 3 marks per round and maybe run 3 COGs to create the 1/3 degree marks.
  • Mike GreenMike Green Posts: 23,101
    edited 2010-02-14 00:23
    @MagIO2 - remember the 2500 is revolutions per Minute. There's a factor of 60 in his favor.

    @crazyideas - I suspect that you and assembly language will need to get acquainted. Spin may be sufficient, but it'll be a close thing and will depend on details of what you're trying to do that you haven't shared yet.

    There hasn't be a detailed comparison of Spin speeds vs assembly speeds, but it's roughly 200:1. It depends a lot on what you're trying to do. Have a look at Bean's (Hitt Consulting's) new PropBasic. This is a subset of integer Basic that compiles into Propeller assembly language. It's still in development, but far enough along to be very useful. It'll be integrated into BST, a very good 3rd party Spin compiler / Propeller assembler, downloader, and IDE that runs under Windows, Linux, and the MacOS. There's a recent forum thread that you can download it from.
  • MagIO2MagIO2 Posts: 2,243
    edited 2010-02-14 10:45
    Oh ... ok ... that's what the M stands for in RPM ... now I remember ;o)

    But still it's true that a modification of the bresnham algorithm will be sufficient for the problem. No need to use floats.

    I think the decoder wheel can help to improve accuracy. For example you can have 3 marks instead of one. Or you can use a mark which is exactly ... say 1 degree or 5 degrees ... and use a counter to measure the actual speed. And still use the old way to measure the average speed. With some math you can find out if speed is increasing or decreasing.
  • Graham StablerGraham Stabler Posts: 2,510
    edited 2010-02-14 11:51
    I think there might be some confusion over what you are trying to do. I think you are creating a gauge that will turn one revolution if the input rpm is 2500, and the resolution of your scale it 1/3 of a degree. Hence there are 1080 steps in your scale. You hope to measure the time it takes to do a revolution and calculate in another cog what position on the scale the time measured equates to.

    At 2500rpm you are talking about updating your gauge ~42 times per second. Assuming that this is supposed to be a human readable gauge and the rate of change of rpm is not super high then you could do it much less frequently and still get smooth and accurate operation.

    You could measure the time for one rotation and then take more than a rotation to process it, just hold the gauge at the previous measurement while the calculation takes place. Even if it takes 3 or 4 rotations you will not notice it. But if you wanted to you could use multiple cogs, in assembly this would be simple for one cog, updating every revolution.

    I also think that you don't really need to use floating point math, you have 1080 divisions on your scale, if you treat these as your fundamental unit (even though they represent 1/3 of a degree) no floats are needed.

    Your calculation is this:

    T2500 = 1/(2500/60) ' Time period at 2500rpm (full scale)

    ticks@2500 = T2500*clkfreq ' Number of clock counts in a revolution at 2500rpm

    point on scale = (1080/ticks@2500)*ticks ' This will be 1080 at 2500rpm

    The important thing to notice is that (1080/ticks@2500) is a constant you can calculate either on a calculator or at compile time. You can ignore the fractional part because what does it matter if you are out by a single clock cycle (12.5ns), it will make no difference to your reading.

    Hope that helps and I didn't drop any clangers

    Graham
  • localrogerlocalroger Posts: 3,452
    edited 2010-02-14 14:29
    What Graham said. You absolutely do not need floating point to do this, and in fact Spin is quite fast enough to do it once you scale everything to use integer math. There are other approaches; I'd be tempted to normalize 1 to 65536 and use the ** function to do fractional multiplication, but I think Graham's method is simpler and would also work.
  • Graham StablerGraham Stabler Posts: 2,510
    edited 2010-02-14 15:35
    I just realised that (1080/ticks@2500) will be a fraction and would become zero when converted to an integer so better to do:

    point on scale := (ticks*1080)/(ticks@2500)
  • MagIO2MagIO2 Posts: 2,243
    edited 2010-02-14 17:16
    @graham:
    2500 RPM is the max., he talked about a min of 500 RPM. So, your multiplication will bust the 32 bit size of a long.

    500 RPM = 8.3333 RPsec => 1/8.3333 = 120ms => 80_000_000 / 8.3333 = ~9_600_000 => 9_600_000 * 1080 = 10_368_000_000
    where 4_294_967_294 is the max.

    But you can divide both values by 10 and you're back in the allowed range. (1080/10 and [url=mailto:ticks@2500/10]ticks@2500/10[/url])

    Just for the records, because I think he does not want to do a gauge again.

    Post Edited (MagIO2) : 2/14/2010 5:24:46 PM GMT
  • Graham StablerGraham Stabler Posts: 2,510
    edited 2010-02-14 18:16
    Good catch.
Sign In or Register to comment.