Trouble with stepper motor movement combined with light tracking sensors.

Greetings!

I am having some trouble with a project of mine. The project is based on an old SEA TEL antenna pedestal(see attached).

The idea is to have three modes. Manuel (controlled by a joystick). OFF (no power to motors). and Auto ( Tracking a flashlight pointed at the dish).

So far I've managed to get the Manuel and OFF mode to work. Auto mode works partially but my knowledge about accelstepper is very limited and I can't see to make it run smoothly compared to the projects I've found on youtube etc.

I found the guide for joystick movement on this forum and addapted it to work with my setup. When I move the joystick the dish moves smoothly (albeit quite loud).

However when I try to use auto mode it moves what looks nothing like the movement on manuel. I've attached a video that shows both.

I've read that it is recommend to write your own code instead of using accelstepper but due to some problems with getting the joystick movement to work I started to use it since I could find other projects that got it to work with that library.

I suspect the problem is within these functions and is related to my wrong use of the accelstepper library. however after days of trial and error using diffrent commands (run, moveTo, move, runToPosition, etc) I still haven't found a solution.

I hope you guys can help with understanding where it goes wrong at maybe come up with a few recommendations on what to change.

Cheers! :slight_smile:
Sorry if the format is messy. First time trying to seek help on a forum.

Video of manuel(joystick) movement: https://streamable.com/3ub37

Video of the light tracking mode: https://streamable.com/l2l04

Code with auto movement(note the run command is in the full code in the LOOP function:

void track() {

  /*if (digitalRead(limitoverst) == LOW) {
    Y.moveTo(300);
    }
    if (digitalRead(limitnederst) == LOW) {
    Y.moveTo(-300);

    }
  */
  if (X.distanceToGo() == 0) {
    if (abs((HojreLys - VenstreLys)) > 4 ) {
      ; // Change position only if light difference is bigger then 4 %
      if (HojreLys < VenstreLys) {

        Serial.println("venstre");
        X.move(1);
      }

      else  {     //(HojreLys > VenstreLys)
        Serial.println("højre");
        X.move(-1);
      }

    }
  }
  if (Y.distanceToGo() == 0) {
    if (abs((OverstLys - NederstLys)) > 4 ) {
      //Change position only if light difference is bigger then 4%
      if (OverstLys < NederstLys) {
        Serial.println("ned");
        Y.move(1);
      }

      else  {             //(OverstLys > NederstLys)
        Serial.println("op");
        Y.move(-1);
      }
    }
  }
}

Full code:

#include <AccelStepper.h>
#include <MultiStepper.h>

AccelStepper X(1, 3, 2); // fortæller drivertype, Step ben(3) og Dir ben (2) (azimuth)
AccelStepper Y(1, 5, 4); // fortæller drivertype, Step ben(5) og Dir ben (4) (elevation)
MultiStepper StepperControl; // MultiStepper funktion (styrer flere stepper på én gang)

//joystick set up
#define JoyX A0 //Joystick x axe til analog 0 (azimuth)
#define JoyY A1 //Joystick y axe til analog 1 (elevation)
// Auto / OFF / Manuel
#define SwAuto 8
#define SwMan  9
#define aziEN  52
#define eleEN  53

#define limitoverst 22 //limit switch overst
#define limitnederst 23 // limit switch nederst

long joystep_x = 0; // variable til ændre hvor mange steps der er tilbage i en bevægelse på azimuth
long joystep_y = 0; // variable til ændre hvor mange steps der er tilbage i en bevægelse på elevation

long track_x = 0;
long track_y = 0;

//lyssensor
int OverstVenstreLys = 0;
int OverstHojreLys = 0;
int NederstVenstreLys = 0;
int NederstHojreLys = 0;
int VenstreLys = 0;
int HojreLys = 0;
int OverstLys = 0;
int NederstLys = 0;

void setup() {
  Serial.begin(9600);
  pinMode(SwAuto, INPUT); // Auto
  pinMode(SwMan, INPUT); // manuel
  pinMode(aziEN, OUTPUT);
  pinMode(eleEN, OUTPUT);


  //X.setEnablePin(52); //enable pin til azimuth
  X.setMaxSpeed(100); //max fart for motor
  X.setAcceleration(4000); //acceleration steps pr. sekund. pr sekund
  //X.enableOutputs(); //sætter alle til outputs

  //Y.setEnablePin(53); //enable pin til elevation
  Y.setMaxSpeed(100);
  Y.setAcceleration(4000);
  //Y.enableOutputs(); // sætter alle til outputs


  StepperControl.addStepper(X); //laver et array til akser så multistepper virker
  StepperControl.addStepper(Y); // 

  pinMode(A8, INPUT);   //Lys  overst - hojre (brun)
  pinMode(A9, INPUT);   //Lys overst - venstre (gul)
  pinMode(A10, INPUT);   //Lys nederst - Hojre ( hvid)
  pinMode(A11, INPUT);   //Lys nederst - venstre (grå)


}

void manuel() {
  X.stop();
  Y.stop();
  /* Serial.print("Overste switch:    ");
    Serial.print(digitalRead(limitoverst));
    Serial.print("     Nederste switch:    ");
    Serial.println(digitalRead(limitnederst));
    if (digitalRead(limitoverst) == LOW) {
    Y.setCurrentPosition(0);
    Y.moveTo(300);
    }
    if (digitalRead(limitnederst) == LOW) {
    Y.setCurrentPosition(0);
    Y.moveTo(-300);
    }*/

  if (X.distanceToGo() == 0) { //Hvis distance mellem nuværende postion og joystick position er 0
    if (analogRead(JoyX) < 450) { //Joystick til venstre)
      joystep_x = X.currentPosition(); //Joystick x (azimuth) position bliver sat til x nuværende postion
      joystep_x = joystep_x - 10; //Joystick flytter sig -50 steps fra nuværende postion
    }
    if (analogRead(JoyX) > 574) { //Joystick til hojre
      joystep_x = X.currentPosition(); //Joystick x (azimuth) position bliver sat til x nuværende posti
      joystep_x = joystep_x + 10; //Joystick flytter sig +50 steps fra nuværende postion
    }
    X.moveTo(joystep_x); //flytter motor til den nye stepposition
  }

  if (Y.distanceToGo() == 0) { //Hvis distance mellem nuværende postion og joystick position er 0
    if (analogRead(JoyY) < 450) { //Joystick op
      joystep_y = Y.currentPosition(); //Joystick y (elevation) position bliver sat til y nuværende postion
      joystep_y = joystep_y + 10; //Joystick flytter sig +50 steps fra nuværende postion
    }
    if (analogRead(JoyY) > 574) { //Joystick ned
      joystep_y = Y.currentPosition(); //Joystick y (elevation) position bliver sat til y nuværende postion
      joystep_y = joystep_y - 10; //Joystick flytter sig +50 steps fra nuværende postion
    }
    Y.moveTo(joystep_y); //flytter motor til den nye stepposition

  }
  X.run(); // korer x motor
  Y.run(); // korer y motor
}


void sensor() {
  OverstHojreLys = map(analogRead(A8), 11, 1020, 0, 100);
  OverstVenstreLys = map(analogRead(A9), 0, 1020, 0, 100);
  NederstHojreLys = map(analogRead(A10), 0, 1021, 0, 100);
  NederstVenstreLys = map(analogRead(A11), 0, 1021, 0, 100);
  Serial.print("overst hojre (brun):    ");
  Serial.print(OverstHojreLys);
  Serial.print(",  overst venstre(gul):    ");
  Serial.print(OverstVenstreLys);
  Serial.print(",  nederst hojre(hvid):    ");
  Serial.print(NederstHojreLys);
  Serial.print(",  nederst venstre(grå):    ");
  Serial.println(NederstVenstreLys);
}

void diffrence() {

  OverstLys = ((OverstVenstreLys + OverstHojreLys) / 2);
  NederstLys = ((NederstVenstreLys + NederstHojreLys) / 2);
  HojreLys = ((OverstHojreLys + NederstHojreLys) / 2);
  VenstreLys = ((OverstVenstreLys + NederstVenstreLys) / 2);

}

void track() {

  /*if (digitalRead(limitoverst) == LOW) {
    Y.moveTo(300);
    }
    if (digitalRead(limitnederst) == LOW) {
    Y.moveTo(-300);

    }
  */
  if (X.distanceToGo() == 0) {
    if (abs((HojreLys - VenstreLys)) > 4 ) {
      ; // Change position only if light difference is bigger then 4 %
      if (HojreLys < VenstreLys) {

        Serial.println("venstre");
        X.move(1);
      }

      else  {     //(HojreLys > VenstreLys)
        Serial.println("højre");
        X.move(-1);
      }

    }
  }
  if (Y.distanceToGo() == 0) {
    if (abs((OverstLys - NederstLys)) > 4 ) {
      //Change position only if light difference is bigger then 4%
      if (OverstLys < NederstLys) {
        Serial.println("ned");
        Y.move(1);
      }

      else  {             //(OverstLys > NederstLys)
        Serial.println("op");
        Y.move(-1);
      }
    }
  }
}

void loop() {
  if (digitalRead(SwMan) == LOW && digitalRead(SwAuto) == LOW) { // turn off drivers
    digitalWrite(52, HIGH);
    digitalWrite(53, HIGH);
  }

  if (digitalRead(SwAuto) == HIGH && digitalRead(SwMan) == LOW) { //auto mode
    digitalWrite(52, LOW);
    digitalWrite(53, LOW);
    sensor();
    diffrence();
    track();
    X.run();
    Y.run();
  }
  if (digitalRead(SwMan) == HIGH && digitalRead(SwAuto) == LOW) { // manuel Mode
    digitalWrite(52, LOW);
    digitalWrite(53, LOW);
    manuel();

  }
}

Satelitmodtager_bb.pdf (1.6 MB)

dish front.jpg

dish front.jpg

I looked at your two video links but they show a photograph with no movement.

I suspect all your Serial.print() statements in your sensor() function are slowing the Arduino down. There is no value in printing data for every iteration of loop() - humans can't read that fast.

...R

Thank you very much that helped indeed.
Another issue I have is how to implement my azimuth limit switches. I have one in each end. I know that you can HOME the stepper and then implement a software limit. However since the switches are already there I was thinking of just using both of them instead of calculating maximum steps. I've only been able to make it stop once it hits the switch but whenever I try to make it bounce it just goes right back down on the switch the second it has released. I'm guessing it has something to do with the currentposition and moveto commands?.
Is there a way to do it for all the modes (auto and manuel) or is that the point of running a HOME function in setup?
again thank you for the advice

    if (digitalRead(limitoverst) == LOW) {
    Y.setCurrentPosition(0);
    Y.moveTo(300);
    }
    if (digitalRead(limitnederst) == LOW) {
    Y.setCurrentPosition(0);
    Y.moveTo(-300);
    }

  if (X.distanceToGo() == 0) { //Hvis distance mellem nuværende postion og joystick position er 0
    if (analogRead(JoyX) < 450) { //Joystick til venstre)
      joystep_x = X.currentPosition(); //Joystick x (azimuth) position bliver sat til x nuværende postion
      joystep_x = joystep_x - 10; //Joystick flytter sig -50 steps fra nuværende postion
    }
    if (analogRead(JoyX) > 574) { //Joystick til hojre
      joystep_x = X.currentPosition(); //Joystick x (azimuth) position bliver sat til x nuværende posti
      joystep_x = joystep_x + 10; //Joystick flytter sig +50 steps fra nuværende postion
    }
    X.moveTo(joystep_x); //flytter motor til den nye stepposition
  }

  if (Y.distanceToGo() == 0) { //Hvis distance mellem nuværende postion og joystick position er 0
    if (analogRead(JoyY) < 450) { //Joystick op
      joystep_y = Y.currentPosition(); //Joystick y (elevation) position bliver sat til y nuværende postion
      joystep_y = joystep_y + 10; //Joystick flytter sig +50 steps fra nuværende postion
    }
    if (analogRead(JoyY) > 574) { //Joystick ned
      joystep_y = Y.currentPosition(); //Joystick y (elevation) position bliver sat til y nuværende postion
      joystep_y = joystep_y - 10; //Joystick flytter sig +50 steps fra nuværende postion
    }
    Y.moveTo(joystep_y); //flytter motor til den nye stepposition

  }
  X.run(); // korer x motor
  Y.run(); // korer y motor
}

Rather than set the value when the switch IS low you need to set it when it changes from HIGH to LOW.

Something like this

if (limitSwitchState == LOW and previousLimitSwitchState == HIGH) {
   // switch has just been pressed
}

...R

So I got the limit and homing to work. Thank you :slight_smile: Is there a way to mark the question as solved?

HOME:

long initial_homing = -1;
Y.setMaxSpeed(100);
  Y.setAcceleration(100);

  while (digitalRead(limitoverst)) {
    Y.moveTo(initial_homing);
    initial_homing--;
    Y.run();
  }

  Y.setCurrentPosition(0);
  initial_homing = 1;

  while (!digitalRead(limitoverst)) {
    Y.moveTo(initial_homing);
    Y.run();
    initial_homing++;
  }
  Y.setCurrentPosition(0);

  while (Y.currentPosition() != 20)
  {
    Y.setSpeed(10);
    Y.runSpeed();

  }

Software limit on tracker:

void track() {
  if (X.distanceToGo() == 0) {
    if (abs((HojreLys - VenstreLys)) > 10 ) {
      // Change position only if light difference is bigger then 4 %
      if (HojreLys < VenstreLys) {
        X.move(1);
      }
      else  {     //(HojreLys > VenstreLys)
        X.move(-1);
      }
    }
  }
  if (Y.currentPosition() > 15
  && Y.currentPosition() < 325) {
    if (Y.distanceToGo() == 0) {
      if (abs((OverstLys - NederstLys)) > 10 ) {
        //Change position only if light difference is bigger then 4%
        if (OverstLys < NederstLys)  {
          Y.move(1);
        }
        else  {             //(OverstLys > NederstLys)
          Y.move(-1);
        }
      }
    }
  }
  else if (Y.currentPosition() < 20) {
    Y.move(10);
  }
  else if (Y.currentPosition() > 320) {
    Y.move(-10);
  }
}

Gnomi:
So I got the limit and homing to work. Thank you :slight_smile: Is there a way to mark the question as solved

Good to hear you have it working.

If you edit your Original Post you can add the word "[Solved]" to the Title

...R