Stepper motor using Accelstepper lib to have one degree answer

Hello people !

I’m new on the forum and I need now your help after searching for few weeks a solution to my problem… I tried to find a solution by myself, reading some topics everywhere and espacially on the forum, nothing to answer exactly to this…

My final project is to make a weather station, I found all the dedicated code for my equipments. But I would like to display on an indicator the wind direction (like a compass) using a stepper motor (I tried already to use DC motor, unsucessfully…).

I have a wind vane which can send me a wind direction with an accuracy of one degree. The following code is working to have one degree accuracy on my stepper motor :

#include <HalfStepper.h>
#include <math.h>
#define STEPS 200 //number of steps on the motor

HalfStepper stepper(STEPS, 8, 9, 10, 11);

float memory = 0;
float order = 0;
float delta = 0;

//________________________________________________________________________
void setup() {

Serial.begin(9600);
Serial.println("Ready");
}

//________________________________________________________________________
void loop() {
  
if (Serial.available()>! 0 ) {
    float measure=Serial.parseFloat();

delta = measure - memory;

//Check the shorter distance to reach the measure + allow passing NE to NW & NW to NE
if (delta > 0){
      if ((abs(delta) >= 180)){order = delta - 360;}
      else {order = delta;}
   }   
   else {
      if (abs(delta) <= 180) {order = delta;}
        else {order = delta+360;}
   }

//Debug
Serial.print("order :"),Serial.println(order);


//Keep the measure in memory
memory = measure;

//send order to stepper motor
stepper.step(order*STEPS/180);

}
}

Now I would like a smooth motion when the needle direction on the stepper changes. For that I’m using Accelstepper library. I tried many configuration but still same issues as followed.
It’s working for big direction difference, but not for a difference less than 10° … Sometimes for big changes, some steps are skipped, I don’t know why… And when I reduce the angle difference (order), I can see the needle moving backward before to go forward and conversely… At the time moving my home position (000° - North)…

To resume :

  • angle of 1 degree : 1st order, moving; 2nd order, nothing; 3rd nothing; etc

  • angle more than 10 :

  • ok but …

  • Sometimes some steps are skipped

  • Sometimes moving backward before to go forward for positiv order // for negative, moving forward before to go backward

In both cases: North position (order 0) is changing because some steps were skipped

My config :

This is the code :

#include <AccelStepper.h>

AccelStepper stepper(AccelStepper::HALF4WIRE,8,9,10,11); 

float memory = 0;
float order = 0;
float delta = 0;

//_____________________________________________________________

void setup() {
  
Serial.begin(9600);
    stepper.setMaxSpeed(1000.0);
    stepper.setAcceleration(500.0);
    Serial.println("Ready");}

//_____________________________________________________________

void loop() {
  
if (Serial.available()>! 0 ) {
    float measure=Serial.parseFloat();

delta = measure - memory;

//Check the shorter distance to reach the measure + allow passing NE to NW & NW to NE
if (delta > 0){
      if ((abs(delta) >= 180)){order = delta - 360;}
      else {order = delta;}
   }   
   else {
      if (abs(delta) <= 180) {order = delta;}
        else {order = delta+360;}
   }

  int order2=order/0.9;
  Serial.print("order :"),Serial.println(order);
  Serial.print("order :"),Serial.println(order2);

//Send order to stepper motor
  stepper.moveTo(order2);
  stepper.runToPosition();
  stepper.setCurrentPosition(0);
  memory = measure; //Keep measure in memory
  }
}

Thank a lot for your precious help that you can give !

I would not do this...

 stepper.setCurrentPosition(0);

Drive it to the desired position. It should stay there. So why reset the position?

I think your missed steps are here:

  int order2=order/0.9;

Converting float to int will truncate by default. The decimals are just chopped off. Even if it was 0.999, that truncates to 0.

Keep counting the stepper steps in an integer. Move to the nearest (or truncated) integer for the desired position. When you have to move again, you need to know that you aren't quite exactly on the previous memory position.

You always, for a particular stepper, have to find out the maximum speed and acceleration it can handle under load by experiment - there's no easy way to calculate this, it depends on too many things.

Once you've found the limits by experiment, back off conservatively for the values to use in your sketch.

And yes calling setCurrentPostion completely resets the position, you'd normally only ever use that call in a homing sequence at startup.

Hello guys!

Thanks a lot for your answers !

So i tried to change my order into an float value, it was not working…
I tired after to incorporate directly my measure as order, and after convert my measure in steps, now it’s working !

  stepper.runToNewPosition(measure*STEPS/180);

I have directly my one degree accurancy. I think my step to permit my switch at North position is not working…

Finaly, I think it’s better to use the relative fonction for that ( Stepper.move() & Stepper.run() ) like this I can work directly by a difference instead of absolute position. (I don’t want to have a position more than 359 and less than 000).

Thanks again for your help !