I need help with micro stepping

Hi, I really need help here, so I made a rotator using an Arduino Nano Every and 2 TB6600 drivers but they were way too noisy, I tried microstepping but the angles were off, thinking it might be a problem with the drivers I bought two TMC2160 they are much more silent but the minimum stepping is 8 times.

The problem is I set the SPR to 1600 on the code, but when I set the angle, for example to 90º it only turn 22.5º and reports it as 90. I tried setting the SPR, changing the ratios, but it doesn't make a difference, it refuses to go to the set angle. I have got the driver properly set to 1600 steps per rotation, but whatever I do to the code it doesn't change it. Please help!

The code:

#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <AccelStepper.h>

#define DIR_AZ 18 //PIN for Azimuth Direction
#define STEP_AZ 10 //PIN for Azimuth Steps
#define DIR_EL 6 //PIN for Elevation Direction
#define STEP_EL 7 //PIN for Elevation Steps

#define MS1 9 //PIN for step size
#define EN 8 //PIN for Enable or Disable Stepper Motors

#define SPR 200 //Step Per Revolution
#define RATIO 60 //Gear ratio
#define T_DELAY 60000 //Time to disable the motors in millisecond

#define HOME_AZ 4 //Homing switch for Azimuth
#define HOME_EL 5 //Homing switch for Elevation
/*The MAX_ANGLE depends of ANGLE_SCANNING_MULT and maybe misbehave for large values*/
#define ANGLE_SCANNING_MULT 180 //Angle scanning multiplier
#define MAX_AZ_ANGLE 360 //Maximum Angle of Azimuth for homing scanning
#define MAX_EL_ANGLE 360 //Maximum Angle of Elevation for homing scanning

#define HOME_DELAY 6000 //Time for homing Decceleration in millisecond

/*Global Variables*/
unsigned long t_DIS = 0; //time to disable the Motors
/*Define a stepper and the pins it will use*/
AccelStepper AZstepper(1, STEP_AZ, DIR_AZ);
AccelStepper ELstepper(1, STEP_EL, DIR_EL);

void setup()
{  
  /*Change these to suit your stepper if you want*/
  AZstepper.setMaxSpeed(150);
  AZstepper.setAcceleration(50);
  
  /*Change these to suit your stepper if you want*/
  ELstepper.setMaxSpeed(150);
  ELstepper.setAcceleration(50);
  
  /*Enable Motors*/
  pinMode(EN, OUTPUT);
  digitalWrite(EN, LOW);
  /*Step size*/
  pinMode(MS1, OUTPUT);
  digitalWrite(MS1, LOW); //Full step
  /*Homing switch*/
  pinMode(HOME_AZ, INPUT);
  pinMode(HOME_EL, INPUT);
  /*Serial Communication*/
  Serial.begin(19200);
  /*Initial Homing*/
  Homing(deg2step(-ANGLE_SCANNING_MULT), deg2step(-ANGLE_SCANNING_MULT));
}

void loop()
{ 
  /*Define the steps*/
  static int AZstep = 0;
  static int ELstep = 0;
  /*Time Check*/
  if (t_DIS == 0)
    t_DIS = millis();

  /*Disable Motors*/
  if (AZstep == AZstepper.currentPosition() && ELstep == ELstepper.currentPosition() && millis()-t_DIS > T_DELAY)
  {
    digitalWrite(EN, HIGH);
  }
  /*Enable Motors*/
  else
    digitalWrite(EN, LOW);
    
  /*Read the steps from serial*/
  cmd_proc(AZstep, ELstep);
  /*Move the Azimuth & Elevation Motor*/
  stepper_move(AZstep, ELstep);
}

/*Homing Function*/
void Homing(int AZsteps, int ELsteps)
{
  int value_Home_AZ = HIGH;
  int value_Home_EL = HIGH;
  int n_AZ = 1; //Times that AZ angle has changed
  int n_EL = 1; //Times that EL angle has changed
  boolean isHome_AZ = false;
  boolean isHome_EL = false;
  
  AZstepper.moveTo(AZsteps);
  ELstepper.moveTo(ELsteps);
  
  while(isHome_AZ == false || isHome_EL == false)
  {
    value_Home_AZ = digitalRead(HOME_AZ);
    value_Home_EL = digitalRead(HOME_EL);
    /* Change to LOW according to Home sensor */
    if (value_Home_AZ == HIGH)
    {
      AZstepper.moveTo(AZstepper.currentPosition());
      isHome_AZ = true;
    }   
    /* Change to LOW according to Home sensor */
    if (value_Home_EL == HIGH)
    {
      ELstepper.moveTo(ELstepper.currentPosition());
      isHome_EL = true;
    }
    if (AZstepper.distanceToGo() == 0 && !isHome_AZ)
    {
      n_AZ++;
      AZsteps = deg2step(pow(-1,n_AZ)*n_AZ*ANGLE_SCANNING_MULT);
      if (abs(n_AZ*ANGLE_SCANNING_MULT) > MAX_AZ_ANGLE)
      {
        error(0);
        break;
      }
      AZstepper.moveTo(AZsteps);
    } 
    if (ELstepper.distanceToGo() == 0 && !isHome_EL)
    { 
      n_EL++;
      ELsteps = deg2step(pow(-1,n_EL)*n_EL*ANGLE_SCANNING_MULT);
      if (abs(n_EL*ANGLE_SCANNING_MULT) > MAX_EL_ANGLE)
      {
        error(1);
        break;
      }
      ELstepper.moveTo(ELsteps);
    }
    
    AZstepper.run();
    ELstepper.run();
  }
  /*Delay to Deccelerate*/
  long time = millis();  
  while(millis() - time < HOME_DELAY)
  {  
    AZstepper.run();
    ELstepper.run();
  }
  /*Reset the steps*/
  AZstepper.setCurrentPosition(0);
  ELstepper.setCurrentPosition(0); 
}
 
/*EasyComm 2 Protocol & Calculate the steps*/
void cmd_proc(int &stepAz, int &stepEl)
{
  /*Serial*/
  char buffer[256];
  char incomingByte;
  char *p=buffer;
  char *str;
  static int counter=0;
  char data[100];
  
  double angleAz,angleEl;
  
  /*Read from serial*/
  while (Serial.available() > 0)
  {
    incomingByte = Serial.read();
    /* XXX: Get position using custom and test code */
    if (incomingByte == '!')
    {
      /* Get position */
      Serial.print("TM");
      Serial.print(1);
      Serial.print(" ");
      Serial.print("AZ");
      Serial.print(10*step2deg(AZstepper.currentPosition()), 1);
      Serial.print(" ");
      Serial.print("EL");
      Serial.println(10*step2deg(ELstepper.currentPosition()), 1);
    }
    /*new data*/
    else if (incomingByte == '\n')
    {
      p = buffer;
      buffer[counter] = 0;
      if (buffer[0] == 'A' && buffer[1] == 'Z')
      {
        if (buffer[2] == ' ' && buffer[3] == 'E' && buffer[4] == 'L')
        {
          /* Get position */
          Serial.print("AZ");
          Serial.print(step2deg(AZstepper.currentPosition()), 1);
          Serial.print(" ");
          Serial.print("EL");
          Serial.print(step2deg(ELstepper.currentPosition()), 1);
          Serial.println(" ");
        }
        else
        {
          /*Get the absolute value of angle*/
          str = strtok_r(p, " " , &p);
          strncpy(data, str+2, 10);
          angleAz = atof(data);
          /*Calculate the steps*/
          stepAz = deg2step(angleAz);

          /*Get the absolute value of angle*/
          str = strtok_r(p, " " , &p);
          if (str[0] == 'E' && str[1] == 'L')
          {
            strncpy(data, str+2, 10);
            angleEl = atof(data);
            /*Calculate the steps*/
            stepEl = deg2step(angleEl);
          }
        }
      }
      /* Stop Moving */
      else if (buffer[0] == 'S' && buffer[1] == 'A' && buffer[2] == ' ' && buffer[3] == 'S' && buffer[4] == 'E')
      {
        /* Get position */
        Serial.print("AZ");
        Serial.print(step2deg(AZstepper.currentPosition()), 1);
        Serial.print(" ");
        Serial.print("EL");
        Serial.println(step2deg(ELstepper.currentPosition()), 1);
        stepAz = AZstepper.currentPosition();
        stepEl = ELstepper.currentPosition();
      }
      /* Reset the rotator */
      else if (buffer[0] == 'R' && buffer[1] == 'E' && buffer[2] == 'S' && buffer[3] == 'E' && buffer[4] == 'T')
      {
        /* Get position */
        Serial.print("AZ");
        Serial.print(step2deg(AZstepper.currentPosition()), 1);
        Serial.print(" ");
        Serial.print("EL");
        Serial.println(step2deg(ELstepper.currentPosition()), 1);
        /*Move the steppers to initial position*/
        Homing(0,0);
        /*Zero the steps*/
        stepAz = 0;
        stepEl = 0;
      }      
      counter = 0;
      /*Reset the disable motor time*/
      t_DIS = 0;
    }
    /*Fill the buffer with incoming data*/
    else {
      buffer[counter] = incomingByte;
      counter++;
    }
  }
}

/*Error Handling*/
void error(int num_error)
{
  switch (num_error)
  {
    /*Azimuth error*/
    case (0):
      while(1)
      {
        Serial.println("AL001");
        delay(100);
      }
    /*Elevation error*/
    case (1):
      while(1)
      {
        Serial.println("AL002");
        delay(100);
      }
    default:
      while(1)
      {
        Serial.println("AL000");
        delay(100);
      }
  }
}

/*Send pulses to stepper motor drivers*/
void stepper_move(int stepAz, int stepEl)
{
  AZstepper.moveTo(stepAz);
  ELstepper.moveTo(stepEl);
    
  AZstepper.run();
  ELstepper.run();
}

/*Convert degrees to steps*/
int deg2step(double deg)
{
  return(RATIO*SPR*deg/360);
}

/*Convert steps to degrees*/
double step2deg(int Step)
{
  return(360.00*Step/(SPR*RATIO));
}

What does that mean "stepping is 8 times" ?????

Without posting the complete sketch that really has SPR set to 1600 no analysis is possible

Post a much smaller code that does nothing more than:

rotating a full rotation
rotating 90°

Print the values of each variable that is used to calculate the steps
each variable on its own and then build up the calculation in steps with printing inbetween results.

best regards Stefan

I meant 1/8 stepping, that is the complete code.

This is the complete sketch set to 1600 SPR, no matter what value I put here the behaviour is the same, the only thing that almost made it work was by changing this, but when azimuth got past 160º it started reversing.

/*Convert degrees to steps*/
int deg2step(double deg)
{
  return(RATIO*SPR*deg/360);
}

/*Convert steps to degrees*/
double step2deg(int Step)
{
  return(360.00*Step/(SPR*RATIO));
}

to this:

/*Convert degrees to steps*/
int deg2step(double deg)
{
  return(RATIO*SPR*deg/67.5);
}

/*Convert steps to degrees*/
double step2deg(int Step)
{
  return(67.50*Step/(SPR*RATIO));
}

Complete sketch:

#include <stdlib.h>
#include <math.h>
#include <AccelStepper.h>

#define DIR_AZ 9 //PIN for Azimuth Direction
#define STEP_AZ 10 //PIN for Azimuth Steps
#define DIR_EL 6 //PIN for Elevation Direction
#define STEP_EL 7 //PIN for Elevation Steps

#define MS1 18 //PIN for step size
#define EN 8 //PIN for Enable or Disable Stepper Motors

#define SPR 1600 //Step Per Revolution
#define RATIO 50 //Gear ratio
#define T_DELAY 60000 //Time to disable the motors in millisecond

#define HOME_AZ 4 //Homing switch for Azimuth
#define HOME_EL 5 //Homing switch for Elevation
/*The MAX_ANGLE depends of ANGLE_SCANNING_MULT and maybe misbehave for large values*/
#define ANGLE_SCANNING_MULT 180 //Angle scanning multiplier
#define MAX_AZ_ANGLE 360 //Maximum Angle of Azimuth for homing scanning
#define MAX_EL_ANGLE 360 //Maximum Angle of Elevation for homing scanning

#define HOME_DELAY 6000 //Time for homing Decceleration in millisecond

/*Global Variables*/
unsigned long t_DIS = 0; //time to disable the Motors
/*Define a stepper and the pins it will use*/
AccelStepper AZstepper(1, STEP_AZ, DIR_AZ);
AccelStepper ELstepper(1, STEP_EL, DIR_EL);

void setup()
{  
  /*Change these to suit your stepper if you want*/
  AZstepper.setMaxSpeed(600);
  AZstepper.setAcceleration(200);
  
  /*Change these to suit your stepper if you want*/
  ELstepper.setMaxSpeed(600);
  ELstepper.setAcceleration(200);
  
  /*Enable Motors*/
  pinMode(EN, OUTPUT);
  digitalWrite(EN, LOW);
  /*Step size*/
  pinMode(MS1, OUTPUT);
  digitalWrite(MS1, HIGH); //Full step
  /*Homing switch*/
  pinMode(HOME_AZ, INPUT);
  pinMode(HOME_EL, INPUT);
  /*Serial1 Communication*/
  Serial1.begin(19200); // Use Serial1 for RX/TX on Nano Every
  /*Initial Homing*/
  Homing(deg2step(-ANGLE_SCANNING_MULT), deg2step(-ANGLE_SCANNING_MULT));
}

void loop()
{ 
  /*Define the steps*/
  static int AZstep = 0;
  static int ELstep = 0;
  /*Time Check*/
  if (t_DIS == 0)
    t_DIS = millis();

  /*Disable Motors*/
  if (AZstep == AZstepper.currentPosition() && ELstep == ELstepper.currentPosition() && millis()-t_DIS > T_DELAY)
  {
    digitalWrite(EN, HIGH);
  }
  /*Enable Motors*/
  else
    digitalWrite(EN, LOW);
    
  /*Read the steps from Serial1*/
  cmd_proc(AZstep, ELstep);
  /*Move the Azimuth & Elevation Motor*/
  stepper_move(AZstep, ELstep);
}

/*Homing Function*/
void Homing(int AZsteps, int ELsteps)
{
  int value_Home_AZ = HIGH;
  int value_Home_EL = HIGH;
  int n_AZ = 1; //Times that AZ angle has changed
  int n_EL = 1; //Times that EL angle has changed
  boolean isHome_AZ = false;
  boolean isHome_EL = false;
  
  AZstepper.moveTo(AZsteps);
  ELstepper.moveTo(ELsteps);
  
  while(isHome_AZ == false || isHome_EL == false)
  {
    value_Home_AZ = digitalRead(HOME_AZ);
    value_Home_EL = digitalRead(HOME_EL);
    /* Change to LOW according to Home sensor */
    if (value_Home_AZ == HIGH)
    {
      AZstepper.moveTo(AZstepper.currentPosition());
      isHome_AZ = true;
    }   
    /* Change to LOW according to Home sensor */
    if (value_Home_EL == HIGH)
    {
      ELstepper.moveTo(ELstepper.currentPosition());
      isHome_EL = true;
    }
    if (AZstepper.distanceToGo() == 0 && !isHome_AZ)
    {
      n_AZ++;
      AZsteps = deg2step(pow(-1,n_AZ)*n_AZ*ANGLE_SCANNING_MULT);
      if (abs(n_AZ*ANGLE_SCANNING_MULT) > MAX_AZ_ANGLE)
      {
        error(0);
        break;
      }
      AZstepper.moveTo(AZsteps);
    } 
    if (ELstepper.distanceToGo() == 0 && !isHome_EL)
    { 
      n_EL++;
      ELsteps = deg2step(pow(-1,n_EL)*n_EL*ANGLE_SCANNING_MULT);
      if (abs(n_EL*ANGLE_SCANNING_MULT) > MAX_EL_ANGLE)
      {
        error(1);
        break;
      }
      ELstepper.moveTo(ELsteps);
    }
    
    AZstepper.run();
    ELstepper.run();
  }
  /*Delay to Deccelerate*/
  long time = millis();  
  while(millis() - time < HOME_DELAY)
  {  
    AZstepper.run();
    ELstepper.run();
  }
  /*Reset the steps*/
  AZstepper.setCurrentPosition(0);
  ELstepper.setCurrentPosition(0); 
}
 
/*EasyComm 2 Protocol & Calculate the steps*/
void cmd_proc(int &stepAz, int &stepEl)
{
  /*Serial1*/
  char buffer[256];
  char incomingByte;
  char *p=buffer;
  char *str;
  static int counter=0;
  char data[100];
  
  double angleAz,angleEl;
  
  /*Read from Serial1*/
  while (Serial1.available() > 0)
  {
    incomingByte = Serial1.read();
    /* XXX: Get position using custom and test code */
    if (incomingByte == '!')
    {
      /* Get position */
      Serial1.print("TM");
      Serial1.print(1);
      Serial1.print(" ");
      Serial1.print("AZ");
      Serial1.print(10*step2deg(AZstepper.currentPosition()), 1);
      Serial1.print(" ");
      Serial1.print("EL");
      Serial1.println(10*step2deg(ELstepper.currentPosition()), 1);
    }
    /*new data*/
    else if (incomingByte == '\n')
    {
      p = buffer;
      buffer[counter] = 0;
      if (buffer[0] == 'A' && buffer[1] == 'Z')
      {
        if (buffer[2] == ' ' && buffer[3] == 'E' && buffer[4] == 'L')
        {
          /* Get position */
          Serial1.print("AZ");
          Serial1.print(step2deg(AZstepper.currentPosition()), 1);
          Serial1.print(" ");
          Serial1.print("EL");
          Serial1.print(step2deg(ELstepper.currentPosition()), 1);
          Serial1.println(" ");
        }
        else
        {
          /*Get the absolute value of angle*/
          str = strtok_r(p, " " , &p);
          strncpy(data, str+2, 10);
          angleAz = atof(data);
          /*Calculate the steps*/
          stepAz = deg2step(angleAz);
      
      //----------------------------------------------------------
      // detect any 360-0 or 0-360 crossing to avoid Meridian Flip
      //----------------------------------------------------------
          double eps;     // differenza in gradi tra posiz. voluta e attuale
      double az_val = angleAz;    // posizione voluta in gradi
      double az_att = step2deg(AZstepper.currentPosition());  // posizione attuale in gradi
      
      // da qui si presuppone che le posizioni siano sempre tra 0 e 360, quindi per sicurezza le riporta nel range 0-360
      int n_giri=( int ) (az_att / 360.0);   // esempio con az_att=357 -> ngiri = 0
        az_att = az_att - ((double) n_giri)*360.;  // azimuth attuale, riportato tra 0 e 360 gradi
      
      n_giri=( int ) (az_val / 360.0);
      az_val = az_val - ((double) n_giri)*360.;  // azimuth voluto, riportato tra 0 e 360 gradi
      
          eps = az_val - az_att;     // calcola errore di posizione
  
          if (fabs(eps) > 180.)      // deve fare piu' di mezzo giro (quindi deve attraversare il nord)
          {
             if (az_att < 180)       // lo attraversa girando in senso antiorario
             {
               // esempio: deve andare da +10 a +350, eps diventa (350 - 360) -10 = -20 e gira al contrario 
               eps = (az_val - 360) - az_att; 
             }
             else    // az_att > 180
             {
               // ha passato il nord girando in senso orario (esempio az_att = 350 e az_val = 10)
               eps = az_val -(az_att - 360);   // 10 - (350 - 360) = +20 e continua in senso orario
             }      // end if az_att > 180
          }   // end if fabs(eps) > 180

          // ridefinisce la posizione voluta in step
          stepAz = AZstepper.currentPosition() + deg2step(eps);   
      //------------------------------------------------------
      // end of meridian flip detection code
      //------------------------------------------------------

          /*Get the absolute value of angle*/
          str = strtok_r(p, " " , &p);
          if (str[0] == 'E' && str[1] == 'L')
          {
            strncpy(data, str+2, 10);
            angleEl = atof(data);
            /*Calculate the steps*/
            stepEl = deg2step(angleEl);
          }
        }
      }
      /* Stop Moving */
      else if (buffer[0] == 'S' && buffer[1] == 'A' && buffer[2] == ' ' && buffer[3] == 'S' && buffer[4] == 'E')
      {
        /* Get position */
        Serial1.print("AZ");
        Serial1.print(step2deg(AZstepper.currentPosition()), 1);
        Serial1.print(" ");
        Serial1.print("EL");
        Serial1.println(step2deg(ELstepper.currentPosition()), 1);
        stepAz = AZstepper.currentPosition();
        stepEl = ELstepper.currentPosition();
      }
      /* Reset the rotator */
      else if (buffer[0] == 'R' && buffer[1] == 'E' && buffer[2] == 'S' && buffer[3] == 'E' && buffer[4] == 'T')
      {
        /* Get position */
        Serial1.print("AZ");
        Serial1.print(step2deg(AZstepper.currentPosition()), 1);
        Serial1.print(" ");
        Serial1.print("EL");
        Serial1.println(step2deg(ELstepper.currentPosition()), 1);
        /*Move the steppers to initial position*/
        Homing(0,0);
        /*Zero the steps*/
        stepAz = 0;
        stepEl = 0;
      }      
      counter = 0;
      /*Reset the disable motor time*/
      t_DIS = 0;
    }
    /*Fill the buffer with incoming data*/
    else {
      buffer[counter] = incomingByte;
      counter++;
    }
  }
}

/*Error Handling*/
void error(int num_error)
{
  switch (num_error)
  {
    /*Azimuth error*/
    case (0):
      while(1)
      {
        Serial1.println("AL001");
        delay(100);
      }
    /*Elevation error*/
    case (1):
      while(1)
      {
        Serial1.println("AL002");
        delay(100);
      }
    default:
      while(1)
      {
        Serial1.println("AL000");
        delay(100);
      }
  }
}

/*Send pulses to stepper motor drivers*/
void stepper_move(int stepAz, int stepEl)
{
  AZstepper.moveTo(stepAz);
  ELstepper.moveTo(stepEl);
    
  AZstepper.run();
  ELstepper.run();
}

/*Convert degrees to steps*/
int deg2step(double deg)
{
  return(RATIO*SPR*deg/360);
}

/*Convert steps to degrees*/
double step2deg(int Step)
{
  return(360.00*Step/(SPR*RATIO));
}

what results were printed to the serial monitor if you print

#include <stdlib.h>
#include <math.h>
#include <AccelStepper.h>

#define DIR_AZ 9 //PIN for Azimuth Direction
#define STEP_AZ 10 //PIN for Azimuth Steps
#define DIR_EL 6 //PIN for Elevation Direction
#define STEP_EL 7 //PIN for Elevation Steps

#define MS1 18 //PIN for step size
#define EN 8 //PIN for Enable or Disable Stepper Motors

#define SPR 1600 //Step Per Revolution
#define RATIO 50 //Gear ratio
#define T_DELAY 60000 //Time to disable the motors in millisecond

#define HOME_AZ 4 //Homing switch for Azimuth
#define HOME_EL 5 //Homing switch for Elevation
/*The MAX_ANGLE depends of ANGLE_SCANNING_MULT and maybe misbehave for large values*/
#define ANGLE_SCANNING_MULT 180 //Angle scanning multiplier
#define MAX_AZ_ANGLE 360 //Maximum Angle of Azimuth for homing scanning
#define MAX_EL_ANGLE 360 //Maximum Angle of Elevation for homing scanning

#define HOME_DELAY 6000 //Time for homing Decceleration in millisecond

/*Global Variables*/
unsigned long t_DIS = 0; //time to disable the Motors
/*Define a stepper and the pins it will use*/
AccelStepper AZstepper(1, STEP_AZ, DIR_AZ);
AccelStepper ELstepper(1, STEP_EL, DIR_EL);

void setup()
{  
  /*Change these to suit your stepper if you want*/
  AZstepper.setMaxSpeed(600);
  AZstepper.setAcceleration(200);
  
  /*Change these to suit your stepper if you want*/
  ELstepper.setMaxSpeed(600);
  ELstepper.setAcceleration(200);
  
  /*Enable Motors*/
  pinMode(EN, OUTPUT);
  digitalWrite(EN, LOW);
  /*Step size*/
  pinMode(MS1, OUTPUT);
  digitalWrite(MS1, HIGH); //Full step
  /*Homing switch*/
  pinMode(HOME_AZ, INPUT);
  pinMode(HOME_EL, INPUT);
  /*Serial1 Communication*/
  Serial1.begin(19200); // Use Serial1 for RX/TX on Nano Every
  /*Initial Homing*/
  Homing(deg2step(-ANGLE_SCANNING_MULT), deg2step(-ANGLE_SCANNING_MULT));
}

void loop()
{ 
  /*Define the steps*/
  static int AZstep = 0;
  static int ELstep = 0;
  /*Time Check*/
  if (t_DIS == 0)
    t_DIS = millis();

  /*Disable Motors*/
  if (AZstep == AZstepper.currentPosition() && ELstep == ELstepper.currentPosition() && millis()-t_DIS > T_DELAY)
  {
    digitalWrite(EN, HIGH);
  }
  /*Enable Motors*/
  else
    digitalWrite(EN, LOW);
    
  /*Read the steps from Serial1*/
  cmd_proc(AZstep, ELstep);
  /*Move the Azimuth & Elevation Motor*/
  stepper_move(AZstep, ELstep);
}

/*Homing Function*/
void Homing(int AZsteps, int ELsteps)
{
  int value_Home_AZ = HIGH;
  int value_Home_EL = HIGH;
  int n_AZ = 1; //Times that AZ angle has changed
  int n_EL = 1; //Times that EL angle has changed
  boolean isHome_AZ = false;
  boolean isHome_EL = false;
  
  AZstepper.moveTo(AZsteps);
  ELstepper.moveTo(ELsteps);
  
  while(isHome_AZ == false || isHome_EL == false)
  {
    value_Home_AZ = digitalRead(HOME_AZ);
    value_Home_EL = digitalRead(HOME_EL);
    /* Change to LOW according to Home sensor */
    if (value_Home_AZ == HIGH)
    {
      AZstepper.moveTo(AZstepper.currentPosition());
      isHome_AZ = true;
    }   
    /* Change to LOW according to Home sensor */
    if (value_Home_EL == HIGH)
    {
      ELstepper.moveTo(ELstepper.currentPosition());
      isHome_EL = true;
    }
    if (AZstepper.distanceToGo() == 0 && !isHome_AZ)
    {
      n_AZ++;
      AZsteps = deg2step(pow(-1,n_AZ)*n_AZ*ANGLE_SCANNING_MULT);
      if (abs(n_AZ*ANGLE_SCANNING_MULT) > MAX_AZ_ANGLE)
      {
        error(0);
        break;
      }
      AZstepper.moveTo(AZsteps);
    } 
    if (ELstepper.distanceToGo() == 0 && !isHome_EL)
    { 
      n_EL++;
      ELsteps = deg2step(pow(-1,n_EL)*n_EL*ANGLE_SCANNING_MULT);
      if (abs(n_EL*ANGLE_SCANNING_MULT) > MAX_EL_ANGLE)
      {
        error(1);
        break;
      }
      ELstepper.moveTo(ELsteps);
    }
    
    AZstepper.run();
    ELstepper.run();
  }
  /*Delay to Deccelerate*/
  long time = millis();  
  while(millis() - time < HOME_DELAY)
  {  
    AZstepper.run();
    ELstepper.run();
  }
  /*Reset the steps*/
  AZstepper.setCurrentPosition(0);
  ELstepper.setCurrentPosition(0); 
}
 
/*EasyComm 2 Protocol & Calculate the steps*/
void cmd_proc(int &stepAz, int &stepEl)
{
  /*Serial1*/
  char buffer[256];
  char incomingByte;
  char *p=buffer;
  char *str;
  static int counter=0;
  char data[100];
  
  double angleAz,angleEl;
  
  /*Read from Serial1*/
  while (Serial1.available() > 0)
  {
    incomingByte = Serial1.read();
    /* XXX: Get position using custom and test code */
    if (incomingByte == '!')
    {
      /* Get position */
      Serial1.print("TM");
      Serial1.print(1);
      Serial1.print(" ");
      Serial1.print("AZ");
      Serial1.print(10*step2deg(AZstepper.currentPosition()), 1);
      Serial1.print(" ");
      Serial1.print("EL");
      Serial1.println(10*step2deg(ELstepper.currentPosition()), 1);
    }
    /*new data*/
    else if (incomingByte == '\n')
    {
      p = buffer;
      buffer[counter] = 0;
      if (buffer[0] == 'A' && buffer[1] == 'Z')
      {
        if (buffer[2] == ' ' && buffer[3] == 'E' && buffer[4] == 'L')
        {
          /* Get position */
          Serial1.print("AZ");
          Serial1.print(step2deg(AZstepper.currentPosition()), 1);
          Serial1.print(" ");
          Serial1.print("EL");
          Serial1.print(step2deg(ELstepper.currentPosition()), 1);
          Serial1.println(" ");
        }
        else
        {
          /*Get the absolute value of angle*/
          str = strtok_r(p, " " , &p);
          strncpy(data, str+2, 10);
          angleAz = atof(data);
          /*Calculate the steps*/
          stepAz = deg2step(angleAz);
      
      //----------------------------------------------------------
      // detect any 360-0 or 0-360 crossing to avoid Meridian Flip
      //----------------------------------------------------------
          double eps;     // differenza in gradi tra posiz. voluta e attuale
      double az_val = angleAz;    // posizione voluta in gradi
      double az_att = step2deg(AZstepper.currentPosition());  // posizione attuale in gradi
      
      // da qui si presuppone che le posizioni siano sempre tra 0 e 360, quindi per sicurezza le riporta nel range 0-360
      int n_giri=( int ) (az_att / 360.0);   // esempio con az_att=357 -> ngiri = 0
        az_att = az_att - ((double) n_giri)*360.;  // azimuth attuale, riportato tra 0 e 360 gradi
      
      n_giri=( int ) (az_val / 360.0);
      az_val = az_val - ((double) n_giri)*360.;  // azimuth voluto, riportato tra 0 e 360 gradi
      
          eps = az_val - az_att;     // calcola errore di posizione
  
          if (fabs(eps) > 180.)      // deve fare piu' di mezzo giro (quindi deve attraversare il nord)
          {
             if (az_att < 180)       // lo attraversa girando in senso antiorario
             {
               // esempio: deve andare da +10 a +350, eps diventa (350 - 360) -10 = -20 e gira al contrario 
               eps = (az_val - 360) - az_att; 
             }
             else    // az_att > 180
             {
               // ha passato il nord girando in senso orario (esempio az_att = 350 e az_val = 10)
               eps = az_val -(az_att - 360);   // 10 - (350 - 360) = +20 e continua in senso orario
             }      // end if az_att > 180
          }   // end if fabs(eps) > 180

          // ridefinisce la posizione voluta in step
          stepAz = AZstepper.currentPosition() + deg2step(eps);   
      //------------------------------------------------------
      // end of meridian flip detection code
      //------------------------------------------------------

          /*Get the absolute value of angle*/
          str = strtok_r(p, " " , &p);
          if (str[0] == 'E' && str[1] == 'L')
          {
            strncpy(data, str+2, 10);
            angleEl = atof(data);
            /*Calculate the steps*/
            stepEl = deg2step(angleEl);
          }
        }
      }
      /* Stop Moving */
      else if (buffer[0] == 'S' && buffer[1] == 'A' && buffer[2] == ' ' && buffer[3] == 'S' && buffer[4] == 'E')
      {
        /* Get position */
        Serial1.print("AZ");
        Serial1.print(step2deg(AZstepper.currentPosition()), 1);
        Serial1.print(" ");
        Serial1.print("EL");
        Serial1.println(step2deg(ELstepper.currentPosition()), 1);
        stepAz = AZstepper.currentPosition();
        stepEl = ELstepper.currentPosition();
      }
      /* Reset the rotator */
      else if (buffer[0] == 'R' && buffer[1] == 'E' && buffer[2] == 'S' && buffer[3] == 'E' && buffer[4] == 'T')
      {
        /* Get position */
        Serial1.print("AZ");
        Serial1.print(step2deg(AZstepper.currentPosition()), 1);
        Serial1.print(" ");
        Serial1.print("EL");
        Serial1.println(step2deg(ELstepper.currentPosition()), 1);
        /*Move the steppers to initial position*/
        Homing(0,0);
        /*Zero the steps*/
        stepAz = 0;
        stepEl = 0;
      }      
      counter = 0;
      /*Reset the disable motor time*/
      t_DIS = 0;
    }
    /*Fill the buffer with incoming data*/
    else {
      buffer[counter] = incomingByte;
      counter++;
    }
  }
}

/*Error Handling*/
void error(int num_error)
{
  switch (num_error)
  {
    /*Azimuth error*/
    case (0):
      while(1)
      {
        Serial1.println("AL001");
        delay(100);
      }
    /*Elevation error*/
    case (1):
      while(1)
      {
        Serial1.println("AL002");
        delay(100);
      }
    default:
      while(1)
      {
        Serial1.println("AL000");
        delay(100);
      }
  }
}

/*Send pulses to stepper motor drivers*/
void stepper_move(int stepAz, int stepEl)
{
  AZstepper.moveTo(stepAz);
  ELstepper.moveTo(stepEl);
    
  AZstepper.run();
  ELstepper.run();
}

// Convert degrees to steps
/* original code out-commented
int deg2step(double deg)
{
  return(RATIO*SPR*deg/360);
}
*/

// modified Convert degrees to steps
int deg2step(double deg)
{
  int myLocalInt;
  Serial.println(RATIO);
  Serial.println(SPR);
  Serial.println(RATIO * SPR);
  Serial.println(RATIO * SPR * deg);
  Serial.println(RATIO * SPR * deg/360);
  myLocalInt = RATIO*SPR*deg/360;
  Serial.println(myLocalInt);
  return(RATIO*SPR*deg/360);
}


/*Convert steps to degrees*/
double step2deg(int Step)
{
  return(360.00*Step/(SPR*RATIO));
}

modified part of the code

// Convert degrees to steps
/* original code out-commented
int deg2step(double deg)
{
  return(RATIO*SPR*deg/360);
}
*/

// modified Convert degrees to steps
int deg2step(double deg)
{
  int myLocalInt;
  Serial.println(RATIO);
  Serial.println(SPR);
  Serial.println(RATIO * SPR);
  Serial.println(RATIO * SPR * deg);
  Serial.println(RATIO * SPR * deg/360);
  myLocalInt = RATIO*SPR*deg/360;
  Serial.println(myLocalInt);
  return(RATIO*SPR*deg/360);
}

first is INT(2 bytes) second is floating point with double precise(8 bytes)
when you make long deg2step(double deg) it solve the problem

Please explain in layman's terms I'm really a noob. I got this code from satnogs :sweat_smile:

upload the modificated version of your code and watch what gets printed to the serial monitor

probably not this code, you have adopt it without to calculate how big are numbers now and they will not pass anymore, the variable type must be adopted too.

How do I monitor the serial? Damn I'm such a noob...

зображення

Thanks :+1:


This is what I got

These are the last values when I sent a command for 90° elevation

instead of 80000 you get 14464, savvy?

OMG, that's right but WHY??? That's so weird :hushed:

overflow

Any fix? That makes sense because I tried other values and they all behaved the same

change any int to long
or use another sketch

2 Likes
1 Like

I tried the long instead of int but it behaved the same, I tried manually putting 80000 instead and the elevation work ok now it's only reporting back the correct angle until 147.4° if I set it any higher it suddenly thinks it's at 200+ degrees and starts hunting back and forth. :person_facepalming:

Edit, ok, so changing all the int to long didn't fix the angle discrepancy but fixed the 147° bug. But putting manually 80000 instead of (spr*ratio) seems to have fix it! I think it's good now! Thank you so much the both of you!