Shop OBEX P1 Docs P2 Docs Learn Events
C: Four Axes Driver Problem — Parallax Forums

C: Four Axes Driver Problem

idbruceidbruce Posts: 6,197
edited 2015-04-15 16:17 in Propeller 1
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:
				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?

Comments

  • JasonDorieJasonDorie Posts: 1,930
    edited 2015-04-15 10:15
    Is it possible that some other cog is messing with your direction pins? I had a recent issue with my SideWay where the LED wouldn't light with the proper color, and I tracked it down to the Servo32 object updating the DIR value constantly.

    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)
  • kuronekokuroneko Posts: 3,623
    edited 2015-04-15 11:03
    JasonDorie wrote: »
    I had a recent issue with my SideWay where the LED wouldn't light with the proper color, and I tracked it down to the Servo32 object updating the DIR value constantly.
    I knew this would bite someone sooner or later. Unfortunately the [post=1183083]requested change[/post] was never applied.
  • JasonDorieJasonDorie Posts: 1,930
    edited 2015-04-15 12:18
    It was a very simple change to make once I actually knew what to change - I moved a label down a single line, so it was below the MOV DIRA, blah command. Finding that one line among thousands though, . . .
  • idbruceidbruce Posts: 6,197
    edited 2015-04-15 13:04
    Jason
    Is it possible that some other cog is messing with your direction pins?

    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.
    Does it HAVE to be a second?

    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.
    Try disabling other concurrent modules (if possible) and see if the problem goes away.

    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.


    attachment.php?attachmentid=113897&d=1429128193
    571 x 426 - 66K
  • abecedarianabecedarian Posts: 312
    edited 2015-04-15 13:27
    Casual observation....
    For clarity, your code:
    while(x_move_complete == false && y_move_complete == false && z_move_complete == false && e_move_complete == false)
    
    ... could be written
    while((x_move_complete == false) && (y_move_complete == false) && (z_move_complete == false) && (e_move_complete == false))
    
    ... 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(!x_move_complete && !y_move_complete && !z_move_complete && !e_move_complete)
    



    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.
  • JasonDorieJasonDorie Posts: 1,930
    edited 2015-04-15 13:29
    One thing I notice immediately that *could* be a problem is your "app_move_now" variable. You set it to true to tell the axis drivers to start going, but then EACH axis driver sets it to false. It's quite possible that the first axis driver to see it could clear the variable before all the others get a chance. (Do you have motors connected to this? IE, can you actually see all four motors running together with the code as it is now?)

    I would do something like this instead:
    bool app_move_now_x = false;
    bool app_move_now_y = false;
    bool app_move_now_z = false;
    bool app_move_now_e = false;
    

    ...and then:
       // Trigger all four axis drivers
       app_move_now_x = app_move_now_y = app_move_now_z = app_move_now_e = true;
    

    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.
  • idbruceidbruce Posts: 6,197
    edited 2015-04-15 13:37
    abe
    while((x_move_complete == false) && (y_move_complete == false) && (z_move_complete == false) && (e_move_complete == false))
    

    I would have to agree that is more appropriate, so it has been changed. Thanks.
  • JasonDorieJasonDorie Posts: 1,930
    edited 2015-04-15 13:43
    ...and it's faster & smaller to bitwise-and the values together and test all at once, like this:
      while(  (x_move_complete & y_move_complete & z_move_complete & e_move_complete) == false )
    

    Using the logical tests in your original version turns into something like this in asm:
    LoopStart:
    
      test x_move_complete, 1
      jz LoopStart
    
      test y_move_complete, 1
      jz LoopStart
    
      test z_move_complete, 1
      jz LoopStart
    
      test e_move_complete, 1
      jz LoopStart
    
    LoopEnd:
    

    ...whereas the bitwise-or + test will compile to something more like this:
    LoopStart:
    
      mov  tempReg, x_test_complete
      and  tempReg, y_test_complete
      and  tempReg, z_test_complete
      and  tempReg, e_test_complete
    
      test tempReg, 1
      jz    LoopStart
    
    LoopEnd:
    

    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)
  • idbruceidbruce Posts: 6,197
    edited 2015-04-15 13:51
    Jason
    Do you have motors connected to this? IE, can you actually see all four motors running together with the code as it is now?

    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 do something like this instead:


    Code:
    bool app_move_now_x = false;
    bool app_move_now_y = false;
    bool app_move_now_z = false;
    bool app_move_now_e = false;...and then:
    

    Code:
       // Trigger all four axis drivers
       app_move_now_x = app_move_now_y = app_move_now_z = app_move_now_e = true;In each driver, have it set its own flag back to false.
    

    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.
  • abecedarianabecedarian Posts: 312
    edited 2015-04-15 13:54
    Never mind, Jason got there before me.
  • idbruceidbruce Posts: 6,197
    edited 2015-04-15 14:12
    Jason

    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.
  • JasonDorieJasonDorie Posts: 1,930
    edited 2015-04-15 14:51
    This is where most of my C/C++ work is: ;-) (and you're welcome - happy I could help)
  • idbruceidbruce Posts: 6,197
    edited 2015-04-15 15:04
    Jason
    This is where most of my C/C++ work is: ;-)

    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.
  • idbruceidbruce Posts: 6,197
    edited 2015-04-15 15:09
    Well now.....

    THAT WORKS PRETTY FREAKING GOOD :):):)
  • JasonDorieJasonDorie Posts: 1,930
    edited 2015-04-15 15:23
    idbruce wrote: »
    I don't understand... Video and media?

    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)
  • idbruceidbruce Posts: 6,197
    edited 2015-04-15 15:35
    Jason
    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.

    Sounds very cool.... What is that... all like DirectX kind of stuff? Anyhow, I wish you all the success in the world.
    As for your "pretty freaking good" comment - which code? The fixed version of yours, or the other stuff I suggested? (Just curious)

    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.
  • idbruceidbruce Posts: 6,197
    edited 2015-04-15 16:17
    For those that may be interested, the resulting fix as discussed here, can be found at this location: http://forums.parallax.com/showthread.php/160739-New-Attempt-3D-Printer-Controller-And-Firmware?p=1326443&viewfull=1#post1326443
Sign In or Register to comment.