C: Four Axes Driver Problem
idbruce
Posts: 6,197
Let me begin this discussion, by saying that the attached test driver works perfectly fine and just the way I want it to work. Although I am currently testing just X and Y axes, the other axes, Z and E are simply simulated in code. This code takes four motors and rotates them simultaneously in one direction, for one revolution, then it immediately changes the direction of all four motors and rotates them simultaneously in the opposite direction. However, in the firmware that I am attempting to write, this same code, is not playing so nicely.
In the actual firmware code, to enable a direction change, a one second delay is required and I cannot understand this. And this one second delay seems to work best at a location that seems unreasonable. To be able to understand the context, you would of course have to examine the attached project.
In the actual firmware code, the steppers will not change directions, unless I place a one second delay, in a similar location to the one shown below:
The only thing that I can think of is that I am stressing the available resources in the actual firmware. The attached test uses five cogs and has plenty of memory left over, while the actual firmware is probably running six or seven cogs, and the total build size is a little over 28,000.
Any ideas?
In the actual firmware code, to enable a direction change, a one second delay is required and I cannot understand this. And this one second delay seems to work best at a location that seems unreasonable. To be able to understand the context, you would of course have to examine the attached project.
In the actual firmware code, the steppers will not change directions, unless I place a one second delay, in a similar location to the one shown below:
while(x_move_complete == false && y_move_complete == false && z_move_complete == false && e_move_complete == false){} waitcnt(CNT + CLKFREQ);
The only thing that I can think of is that I am stressing the available resources in the actual firmware. The attached test uses five cogs and has plenty of memory left over, while the actual firmware is probably running six or seven cogs, and the total build size is a little over 28,000.
Any ideas?
zip
837K
Comments
The only reason you would need a delay is to allow some other code / cog to get into a different state - it seems unlikely to be a resource issue. Does it HAVE to be a second? Have you tried semi-random other delays? If it is a second, is there other code running that may take that amount of time to complete? Try disabling other concurrent modules (if possible) and see if the problem goes away. (That's how I solved my LED problem)
I have been over it again and again, and I cannot find anything that would be messing with the pin state. Motor directions are calculated in the perform_gcode_struct_calcs() function, then the calulations are checked by the driver for that specific axis, and then the direction is set by the driver. However, it may be a case of code blindness and staring right at me.
From the testing I have done, yes it has to be a second or above, 1/4, 1/2, 3/4 of a sec, just don't cut it. By the time it reaches that portion of code, all processing should have been completed. The main should be in a loop and only the four drivers should be executing code, all based upon precalculated data. And if you look at attached image, you will see where I indicate that all processing should theorhetically be at a standstill.
If I am not mistaken, I narrowed it down to just X and Y, and then it worked without any delay.
Additionally, I am attaching the whole project, just in case someone can see something that I am not seeing.
For clarity, your code: ... could be written ... so that all your equalities are guaranteed to be evaluated before things are logically "AND" ed.
... or, assuming you're only using 0 = false and 1 = true for your flags, the following use of the NOT operator does the same:
While the evaluation you used shouldn't produce any issues, since the logical comparison should have higher precedence than the logical AND, seeing this suggests you've done similar elsewhere and those may be introducing unexpected errors resulting from precedence orders which may not immediately manifest themselves. Or at least that's what I've been told by others.
Edit- on closer examination, == is of higher precedence than && but things also progress left to right, so the compiler might do the first comparison, then the AND, then the next ==, and so on down the line. So using parentheses to group things explicitly as you want them processed might be a good idea regardless, and it also displays what your intent is.
I would do something like this instead:
...and then:
In each driver, have it set its own flag back to false. That way if the cogs are not running in perfect lock-step, it won't be an issue. For what it's worth, having all four drivers in the same cog would eliminate the need to have the 4 independent variables.
I would have to agree that is more appropriate, so it has been changed. Thanks.
Using the logical tests in your original version turns into something like this in asm:
...whereas the bitwise-or + test will compile to something more like this:
It's a relatively minor thing, but depending on how the compiler produces the test/branch code, it might end up saving you a bit more.
On a PC with branch prediction, doing this "congealed testing" can help make branches much more predictable and avoid instruction cache flushes. (granted, not an issue on the Prop)
I currently only have two hooked up, X and Y. It would not be to hard to hook up Z, but I really don't want to hook up E at the moment. However, I believe if I find the problem, then it should change directions on X and Y without the delay.
I would most likely disagree on this point, because I would say, what does this have to do with direction? However considering that they are moving equal distance in both directions, it could be a deception, to make me think it is a direction issue. Perhaps you may have found it.
I will give that a try.
You are a smart guy That did the trick Thank you very much!!!!
You are pretty darn good at this C stuff. I am surprised that I haven't seen any of your C work.... Although I am sure it exists.
Thanks again Jason, now I can move forward with testing the other code you suggested.
I don't understand... Video and media?
By the way, getting ready to test multiple moves on X and Y.... I will let you know how it goes.
THAT WORKS PRETTY FREAKING GOOD
No, I work for 2K Sports in the tools and technology group. I wrote a bunch of the core tech for that game, including the character rig compiler / deformation engine, the pipeline tools that extract 3D model / material / texture data from Maya, the video codec and video streaming, the tool we use to author the UI, etc, etc.
As for your "pretty freaking good" comment - which code? The fixed version of yours, or the other stuff I suggested? (Just curious)
Sounds very cool.... What is that... all like DirectX kind of stuff? Anyhow, I wish you all the success in the world.
When I wrote that comment, I was just referring to the fixed version. And then I tested with the other stuff that you suggested and it works just as well. I cannot see any difference in performance, from the other changes, but I intend to keep them because they are more succinct, and I am sure there is other advantages, that I just can't see.
I will be uploading the lastest build to the other thread in just a moment and I will add a link to it, for those folks who find this thread.