How to get a compass to cross from 360 to 001 ???

533 views
Skip to first unread message

t...@thegauvins.com

unread,
Feb 27, 2014, 12:27:59 AM2/27/14
to accels...@googlegroups.com

I am new to Accelstepper and having a hard time wrapping my head around it.

I have a flight simulation program that outputs aircraft's compass heading as a 3 character serial string (001 to 360) that I am reading with an Arduino.  I am trying to build a simulated compass (known in aviation parlance as a Wet Compass or |Whiskey Compass) that will rotate with that heading value.

I was using the default stepper library that comes with the Arduino IDE but it wasn't smooth enough and someone suggested I look at Acellstepper.  I have some basic code written that seems to be working well with one exception and I am hoping someone can give me a suggestion or two that I can try.

My setup is an Arduino Mega, a SeeedStudio Motor Shield, and a Wantal 42BYGHM809  0.9 degree/step motor.  The motor will drive a compass disc via 9 to 1 gearing so that 3600 steps on the motor = 360 degrees of rotation on the compass disc.
 

My only problem is crossing North. Heading changes are typically gradual in the range of 1 to 3 degrees with each change.  I am converting the string to an integer and then mapping it get the correct position value for the stepper.

It all works well of course until the heading crosses North from 360 to 001 or 001 to 360 at which point the stepper does an about face and circle back around 359 degrees.

Any thoughts on how I can get it to step backwards one step (actually ten given my gearing) on the 001 to 360 transition or forward one (10) step on 360 to 001 and of course reset the current position to the correct value?

Here's my basic code:

Heading = HdgString.toInt();        
StpToPstn = map(Heading, 1,360,0,3599);
WetCmps.moveTo(StpToPstn);
 
WetCmps.run();
while(StpToPstn != CrntPstn){
             WetCmps.run();
             CrntPstn = WetCmps.currentPosition();
          }


Here was my first attempt at resetting the current position value

Heading = HdgString.toInt();        
StpToPstn = map(Heading, 1,360,0,3599);
WetCmps.moveTo(StpToPstn);

while(StpToPstn != CrntPstn){
   WetCmps.run();
   CrntPstn = WetCmps.currentPosition();
    if (CrntPstn == 3600){
                 WetCmps.setCurrentPosition(0);
   }
   if (CrntPstn == -1){
                WetCmps.setCurrentPosition(3599);
   }
}

And all my attempts at stepping back or forward one step to cross north all failed so they aren't worth posting.

Any help would be greatly appreciated!!!
Tom G.

Mike McCauley

unread,
Feb 27, 2014, 2:18:12 AM2/27/14
to accels...@googlegroups.com
Hello,


I think the solution is simpler than you think:

After initialising the motor to 0 (North) and setting the current position to
0:

loop ()
{
if (have some input heading data)
{
Heading = HdgString.toInt();
WetCmps.moveTo((Heading % 360) * 10);
}
WetCmps.run();
}

I dont think you will need to change currentPosition in the accel stepper
after initialisation

Cheers.
--
Mike McCauley VK4AMM mi...@airspayce.com
Airspayce Pty Ltd 9 Bulbul Place Currumbin Waters QLD 4223 Australia
http://www.airspayce.com
Phone +61 7 5598-7474 Fax +61 7 5598-7070

t...@thegauvins.com

unread,
Feb 27, 2014, 9:00:19 AM2/27/14
to accels...@googlegroups.com
Mike,

Thanks for the code example.  It is much cleaner than what I was doing.  I've edited my code to use "WetCmps.moveTo((Heading % 360) * 10);"

Unfortunately, it doesn't address my primary issue. It works great for heading changes that don't cross North, but when crossing North it does not act correctly.

As an example I'll use a 2 degree change that crosses North:

What I need the code to do:

When the current heading is 359 and the next heading string received is 001 I need the stepper to move Clockwise 20 steps and consider its new position to be 10 and not 3610
Or conversely
When the current heading is 001 and the next heading string received is 359 I need the stepper to move Counter Clockwise 20 steps and consider its new position to be 3590 and not -20

What it is doing:

At present with either my original code or the newly edited code a change from 359 to 001 causes the stepper to move counter clockwise 3580 steps
or if 001 to 359 it moves clockwise 3580 steps.

What command can I send to the stepper to move it a specified number of steps in a specified direction rather than sending it to a specified position?

What I think I need is something like this (again using my 2 degree change crossing North example) but I don't yet understand Accelstepper well enough to know how to make it happen:

if (Heading == 001 && HeadingLast == 359){
   <send command to stepper to move clockwise 20 steps>
   CrntPstn = WetCmps.currentPosition(10);
}

OR

if (Heading == 359 && HeadingLast == 001){
   <send command to stepper to move counter clockwise 20 steps>
   CrntPstn = WetCmps.currentPosition(3590);
}
// Keeping in mind that the biggest single heading change I might receive is 5 to 10 degrees
// I would, of course, modify the above to look at a range of 355 to 010, maybe a bit wider,
// and calculate the needed steps to cross North properly 

It's the <send command to stepper to move x direction, x steps> line that I don't know how to do.  And, I need to be sure that my use of currentPosition "CrntPstn = WetCmps.currentPosition(3590);" will do what I think it does.

If you have any advice on how I can do that, or a simpler way to do it, that would be greatly appreciated!

Thanks!!!
Tom G.

Mike McCauley

unread,
Feb 27, 2014, 5:24:27 PM2/27/14
to accels...@googlegroups.com
Hello,

you ask:

> What command can I send to the stepper to move it a specified number of
> steps in a specified direction rather than sending it to a specified
> position?

the move() function moves a relative number of steps.

Suggest you carefully read the AccelStepper documentation at:

http://www.airspayce.com/mikem/arduino/AccelStepper/classAccelStepper.html

Cheers.

On Thursday, February 27, 2014 06:00:19 AM t...@thegauvins.com wrote:
> Mike,
>
> Thanks for the code example. It is much cleaner than what I was doing.
> I've edited my code to use "WetCmps.moveTo((Heading % 360) * 10);"
>
> Unfortunately, it doesn't address my primary issue. It works great for
> heading changes that don't cross North, but when crossing North it does not
> act correctly.
>
> As an example I'll use a 2 degree change that crosses North:
>
> *What I need the code to do:*
>
> When the current heading is 359 and the next heading string received is 001
> I need the stepper to move Clockwise 20 steps and consider its new position
> to be 10 and not 3610
> Or conversely
> When the current heading is 001 and the next heading string received is 359
> I need the stepper to move Counter Clockwise 20 steps and consider its new
> position to be 3590 and not -20
>
> *What it is doing:*
>
> At present with either my original code or the newly edited code a change
> from 359 to 001 causes the stepper to move counter clockwise 3580 steps
> or if 001 to 359 it moves clockwise 3580 steps.
>
> What command can I send to the stepper to move it a specified number of
> steps in a specified direction rather than sending it to a specified
> position?
>
> What I think I need is something like this (again using my 2 degree change
> crossing North example) but I don't yet understand Accelstepper well enough
> to know how to make it happen:
>
> if (Heading == 001 && HeadingLast == 359){
>
> <send command to stepper to move clockwise 20 steps>
>
> CrntPstn = WetCmps.currentPosition(10);
>
> }
>
>
> OR
>
> if (Heading == 359 && HeadingLast == 001){
>
> <send command to stepper to move counter clockwise 20 steps>
>
> CrntPstn = WetCmps.currentPosition(3590);
>
> }
>
> *// Keeping in mind that the biggest single heading change I might receive
> is 5 to 10 degrees*
>
> *// I would, of course, modify the above to look at a range of 355 to 010,
> maybe a bit wider,*
>
> *// and calculate the needed steps to cross North properly *
>
>
> It's the <send command to stepper to move x direction, x steps> line that I
> don't know how to do. And, I need to be sure that my use of
> currentPosition "CrntPstn = WetCmps.currentPosition(3590);" will do what I
> think it does.
>
> If you have any advice on how I can do that, or a simpler way to do it,
> that would be greatly appreciated!
>
> Thanks!!!
> Tom G.

t...@thegauvins.com

unread,
Feb 27, 2014, 10:14:50 PM2/27/14
to accels...@googlegroups.com

Mike,

Thanks!!  That did the trick!

I have read through the documentation, but managed to look right past that.   I am finding though that there are a couple items in the documentation that aren't real clear to me.  So I hope I don't try yours or anyone else's patients as I try to get this all straight in my head.

Again, Thanks!

Tom G.
Reply all
Reply to author
Forward
0 new messages