// Using a stepper to move an equilateral barn-door tracker at sidereal rate.
// Written by John Wasser, on May 23rd, 2020
// Copied from https://forum.arduino.cc/t/jjrobots-startracker/948662/3
//
// Wokwi Simulation: https://wokwi.com/projects/390541131703748609
// Modified to use this simulated hardware setup and add a speed adjustment potentiometer
// Second stepper is unused in this case
const uint16_t StepsPerRevolution = 200;
const float MillimetersPerRevolution = 1.0; // 1mm pitch threaded rod
const uint16_t RotationRadiusMM = 400; // Distance from hinge to threaded rod.
// connection Constants
// As in StepperDemo for Motor 1 on AVR
constexpr byte dirPinStepper = 8;
constexpr byte enablePinStepper = 12;
constexpr byte stepPinStepper = 9; // OC1A in case of AVR
constexpr byte dirPinStepper2 = 7;
constexpr byte enablePinStepper2 = 12;
constexpr byte stepPinStepper2 = 10; // OC1B in case of AVR
constexpr byte PotPin = A0;
// Some sidereal rate constants:
// Seconds per Sidereal Day: 86164.0905 (Astronomical constant from Wikipedia)
// Radians per Second 7.2921158579e-5 (2 Pi radians divided by Siderail Day in Seconds)
const unsigned long MillisecondsPerRadian = 13713441;
uint32_t TimeAtLastStep = 0;
uint32_t IntervalToNextStep = 0;
uint32_t CurrentSteps = 0; // Barn Door Tracker starts closed.
float CurrentAngle = 0;
void setup()
{
Serial.begin(115200);
TimeAtLastStep = millis();
pinMode(stepPinStepper, OUTPUT);
pinMode(dirPinStepper, OUTPUT);
}
void loop()
{
uint32_t currentTime = millis();
if (currentTime - TimeAtLastStep >= IntervalToNextStep)
{
TimeAtLastStep += IntervalToNextStep;
// Code Here to Step Once
digitalWrite(stepPinStepper, HIGH);
//delay(1);
digitalWrite(stepPinStepper, LOW);
CurrentSteps++;
uint32_t nextStep = CurrentSteps + 1;
float nextRodLengthMM = (nextStep * MillimetersPerRevolution) / (float)StepsPerRevolution;
float nextAngle = asin(nextRodLengthMM / (2 * RotationRadiusMM)) * 2.0;
float deltaAngle = nextAngle - CurrentAngle;
IntervalToNextStep = MillisecondsPerRadian * deltaAngle + speedAdjustment();
CurrentAngle = nextAngle;
Serial.print("ms:");
Serial.print(currentTime);
Serial.print("\tsteps:");
Serial.print(CurrentSteps);
Serial.print("\tIntervalMs:");
Serial.println(IntervalToNextStep);
}
}
int speedAdjustment(void) {
// calculate a speed adjustment using a pot and a deadband
const int DeadbandTop = 700;
const int DeadbandBottom = 300;
const int AdjustMax = 100;
int potVal = analogRead(PotPin);
int adjustment = 0;
if (potVal >= DeadbandTop) {
adjustment = map(potVal, DeadbandTop, 1023, 0, AdjustMax);
}
if (potVal <= DeadbandBottom) {
adjustment = map(potVal, 0, DeadbandBottom, -AdjustMax, 0);
}
return (-adjustment); // change sign to flip sense of pot.
}