a couple of friends and i are working on a double axis solar tracker with a Adafruit Motor-shield V2 and 2x Adafruit bipolar stepper motors (200/rev). We got the following code so far but are stuck with getting the steppers to stop at a certain angle (90° for vertical and 180° for horizontal) so that we dont tangle up the wires and avoid unnecessary movement. Any help and sugestions would be much appreciated.


#include <Wire.h>
#include <Adafruit_MotorShield.h>
#include "utility/Adafruit_PWMServoDriver.h"

Adafruit_MotorShield AFMS = Adafruit_MotorShield(); 
Adafruit_StepperMotor *stepperh = AFMS.getStepper(200, 1);  // declaring horizontal stepper
Adafruit_StepperMotor *stepperv = AFMS.getStepper(200, 2);  // declaring vertical stepper

int ldr1 = A0;  // right ldr        
int ldr2 = A1;  // centre ldr
int ldr3 = A2;  // left ldr
int ldr4 = A3;  // top ldr
int ldr5 = A4;  // bottom ldr

const int threshold = 550;  // limit to stop tracker from moving at night

const int tol = 50;  // tolerance for ldrs // maybe vertical AND horizontal depending on difference?

//int = countv
//int = counth

//const int maxh = ?    // to prevent overturning horizontal (50 steps = 90°) 
//const int minh = ?    // combine with count int's // i.e. if counth > 90 - stop
//const int maxv = ?    // to prevent overturning vertical
//const int minv = ?

void setup()

void loop()
  int right = analogRead(ldr1);  
  int centre = analogRead(ldr2);
  int left = analogRead(ldr3);
  int up = analogRead(ldr4);
  int down = analogRead(ldr5);

  if ((left < threshold) && (right < threshold) && (up < threshold) && (down < threshold)) {}  // stop any movement if sensor values below threshold 
                                                                                               // at begining to check after every sensor reading

  if((right > centre + tol) && (left + tol < centre))   // && (right - ? > tol)     
    stepperh->onestep(BACKWARD,DOUBLE);  // add +1 to int counth // if (minh < counth < maxh) - move // else - stop // counth=counth++ , counth=counth--                            
  else if((left > centre + tol) && (right + tol < centre))  // && (left - ? > tol)  
  else {}  // do nothing

  if((up > centre + tol) && (down + tol < centre))  // && (up - ? > tol)  
  else if((down + tol > centre) && (up + tol < centre))  // && (down - ? > tol)  
  else{}  // do nothing
  • Well first you'll probably need to define your limits. I see you have maxh minh and so on.. how do you know when you've reached the max/min?
    – sachleen
    May 10 '14 at 18:12
  • Thanks for all the replies. Could i maybe use a magnetic switch or an accelerometer - something like this: Accelerometer? How accurate are these things?
    – Darellon
    May 12 '14 at 9:31
  • "how do you know when you've reached the max/min?"... You can create a routine of track angles. Check the maximun ammount of energy that the solar pan is getting. At this point, this is the best angle. At the end, this is the final goal. Do you have your project concluded?
    – zwitterion
    Apr 8 '16 at 15:35

The only sure way is to use one or more position or limit switches. Steps can be lost (motor didn't move as commanded due to, f/ex, overload), the motor could be back-driven while powered down or if over-powered by the mechanical system, or your step counting could be faulty due to a bug or a power glitch.

At power-up or at any time your software thinks it might have got out of sync with the mechanicals, back into the limit switch at low speed (so you don't hard-crash), and reset your software counters, and reposition from there.


When working with steppers you have to realise that you are not dealing with absolute coordinates. Unlike with, for example servos, which you command to go to particular angle, you command steppers to rotate a particular amount of steps in a particular direction. This creates in your case the problem that you cannot actively check the positions of the steppers without some sensing element.

As a solution I would suggest that you would store the steps the steppers take in some variables, and then with the code limiting, that these variables don't go over a surtain number. With this method, you need to have a way of setting the zero point of the steppers, meaning from where to start the counting. This could for example be done by driving the system against some switch, and then setting the step variable to zero here. This is usually done once in the bootup, meaning that it is excecuted in the setup function.


Stepper motors are nice and all but they actually make less than adequate servos for this purpose. the best way that I can see is with linear actuators that have position sensors in them and feed the Voltage divider outputs from those sensors to the Atmega chip. If you write the code to compare the signals from the light detectors with the voltage from the pos sensors it should be a lot better. Also, limit switches should be used in this arrangement too. They would be as a fail safe. The other benefit is that linear actuators usually hold a lot better without loosing their position due to outside stresses. Steppers can be used for prototyping, but it would still be better to start with small servos with sensors and get the system working first. I myself am trying to get a working system and I am having troubles with the coding also, but I am not good at coding. One other thing, I have looked at a lot of different codes to find something that might help me with my project and I have seen this. Stepper motor systems are written with minimal code which as I see it leaves room for much error. Atmega has plenty of room for code storage and plenty of ports for sensors in this use. Everyone knows that old phrase keep it simple but some times that is not always the best advice. You are working with something that needs to be somewhat complicated, to be less likely to fail. The more engineering you put into something the more likely something is to go wrong but less engineering gives you the same results. So consider all the posibilities and address them. Adding components and sub systems will in the end make your work better.

  • Although this is useful information, it doesn't really answer the question. Can you add a little bit more (maybe a paragraph) to better answer the question? Thanks! Dec 5 '14 at 22:39
  • It's kind of hard to read as a big block of text.
    – TheDoctor
    Dec 10 '14 at 15:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.