You got a Celestron 21024 FirstScope Telescope and…

 

…what are you going to do with it during the day light? Hack it!!!


SUMMARY

On this post I will walk through the basic steps and rational used to develop a motorised mechanism to move both axis electronically.

All the source code and 3D objects are free to use, share, and modify.

It requires a 3D Printer, soldering iron, and a DIY mindset.

Out of scope: modify or damage the scope in any way (no screw holes or glue).


BILL OF MATERIAL

  • Mechanism ($5)
    • FDM 3D Printer
    • PLA Filament
  • Electronics ($50)
    • Arduino UNO Rev3 [Link] – Microcontroller
    • Two 28BYJ-48 – Stepper Motors
    • ULN2003 Driver – Module Board
    • Small PCB
    • Four push buttons
  • Software ($0)
    • Arduino IDE [Link] – Integrated Development Environment.

MECHANIC PARTS

Body

Pan Gear

Tilt Gear

Small Gears (2X)

  • STL File [Link]
  • SCAD File – Can be found in the same SCAD files of the big gears.

Remote Control

Back Cover

Smartphone Support (optional)

  • <pending>

Power Bank (optional)

Assembly

 


MECHANIC AND ELECTRONIC ASSEMBLY

Step #1 – Print the big gears.

The larger dimensions are 208x208mm. Even though my printer is capable of printing 220x220mm it did not print properly two of the sides when the part was centralised on the bed (no idea why or if it was an issue of the printer firmware or the slicer). I had to move it closer to the origins of X and Y to get it all printed.

Step #2 – Test the mounting of both gears, then take them out.

Both gear can be attached to the telescope with no screw, bolt, glue, or tape. You may need to sand the internal of the tilt gear for perfect adjustment because the telescope counterpart is conical and a bit flexible. If needed I provisioned 6 tiny holes in the centre of the gear for pins (not needed in my case).

Step #3 – Print two small gears and press them to the motor shaft.

Note the direction of the gear before placing then on the stepper motor. It does not need any thing but just old fashion friction. So, avoid having to remove it unnecessarily. Both motors get the gear aligned to the same direction, which make them interchangeable.

Step #4 – Print and pre-assembly the electronics to the main body.

The stepper motors require quite a bit of force to lace into the jaws, and it is much easier to make changes if necessary. The pinout of the Arduino to the drivers and to the remote control is up to you. Just make notes of pinout to replace accordingly in the code.

Step #5 – Mount the body to the neck of the scope.

The body should slide smoothly through the neck with enough friction to keep it solidly steady. The stainless steel screw is an obstacle and needs to be removed.

Step #6 – Place the big gears back scope.

Placing the big gears after the body makes the process much easier. Also, having it already adjusted (from step #2) is fundamental because the gears engagement (gearing) does not allow any adjustment at this point because of its gear type (herringbone). A M10 lock nut replacing the original plastic suits much better too.

Step #7 – Print and assemble the remote control.

I did print a 0.5 mm light guide for seeing the red LED through without any open hole. The buttons are only hold by the mounting order (up side down) then the move smoothly but not much free play. Except for the Ground and +5V pins, all the others sequence it irrelevant, just need to be numbered accordingly in the code to match.

Step #8 – Optionally, print a cover and assemble a power bank.

Of course just any power bank would work. I printed one because I had the parts in my shelf. I also printed a 0.5 mm light guide in white to allow the LED indicators to be seeing as it charges and discharges.

Step #9 – Final gear adjustments.

By turning the stepper motors in its axis tightens and loosens the force between the gears. I used a small pin to lock them to the pressure that I wanted (very tight). A simulation software that makes many many spins in both directions of both axis will reveal any issue and remove a few rough edges that make squeaky noises.

Step #10 – Print and close the back cover.

The back cover slides down embracing the wood neck with no clip or screw, just friction. It is good enough but here is the caveat. Glue a neodymium magnet on the body and a piece of metal on the cover and the feeling of a smooth grip will bring it to a higher level of craftsmanship.


SOFTWARE

Basic Actuation – Single Speed

//Includes the Arduino Stepper Library
#include 

// Steps per Revolution
const int stepsPerRevolution = 2048;
const int nSteps = 1;

// Pins Sequence IN1-IN3-IN2-IN4
Stepper myStepperTilt = Stepper(stepsPerRevolution, 10, 12, 11, 13);
Stepper myStepperPan = Stepper(stepsPerRevolution, 2, 4, 3, 5);

// Button Pins
int pinButtonTiltUp = 9;
int pinButtonTiltDown = 8;
int pinButtonPanCW = 7;
int pinButtonPanCCW = 6;

void setup() {
    // Button Pins Mode
    pinMode(pinButtonTiltUp, INPUT_PULLUP);
    pinMode(pinButtonTiltDown, INPUT_PULLUP);
    pinMode(pinButtonPanCW, INPUT_PULLUP);
    pinMode(pinButtonPanCCW, INPUT_PULLUP);
    myStepperTilt.setSpeed(10);
    myStepperPan.setSpeed(10);
}

void loop() {
  // Button Status
  int statusButtonTiltUp = digitalRead(pinButtonTiltUp);
  int statusButtonTiltDown = digitalRead(pinButtonTiltDown);
  int statusButtonPanCW = digitalRead(pinButtonPanCW);
  int statusButtonPanCCW = digitalRead(pinButtonPanCCW);
  
  // TILT UP
  if (!statusButtonTiltUp && statusButtonTiltDown && statusButtonPanCW && statusButtonPanCCW) myStepperTilt.step(-nSteps);
  // TILT DOWN
  if (statusButtonTiltUp && !statusButtonTiltDown && statusButtonPanCW && statusButtonPanCCW) myStepperTilt.step(nSteps);
  // PAN CW
  if (statusButtonTiltUp && statusButtonTiltDown && !statusButtonPanCW && statusButtonPanCCW) myStepperPan.step(nSteps);
  // PAN CCW
  if (statusButtonTiltUp && statusButtonTiltDown && statusButtonPanCW && !statusButtonPanCCW) myStepperPan.step(-nSteps);

  // TILT UP + CW
  if (!statusButtonTiltUp && statusButtonTiltDown && !statusButtonPanCW && statusButtonPanCCW) {
    myStepperTilt.step(-nSteps);
    myStepperPan.step(nSteps);
  }  
  // TILT DOWN + CW
  if (statusButtonTiltUp && !statusButtonTiltDown && !statusButtonPanCW && statusButtonPanCCW) {
    myStepperTilt.step(nSteps);
    myStepperPan.step(nSteps);
  }
  // PAN UP + CCW
  if (!statusButtonTiltUp && statusButtonTiltDown && statusButtonPanCW && !statusButtonPanCCW) {
    myStepperTilt.step(-nSteps);
    myStepperPan.step(-nSteps);
  }
  // PAN DOWN + CCW
  if (statusButtonTiltUp && !statusButtonTiltDown && statusButtonPanCW && !statusButtonPanCCW) {
    myStepperTilt.step(nSteps);
    myStepperPan.step(-nSteps);
  }
}

Advanced Actuation – Accelerated Speed

//Includes the Arduino Stepper Library
#include 

// Steps per Revolution
const int stepsPerRevolution = 2048;
const int nSteps = 1;

// Pins Sequence IN1-IN3-IN2-IN4
Stepper myStepperTilt = Stepper(stepsPerRevolution, 10, 12, 11, 13);
Stepper myStepperPan = Stepper(stepsPerRevolution, 2, 4, 3, 5);

// Button Pins
int pinButtonTiltUp = 9;
int pinButtonTiltDown = 8;
int pinButtonPanCW = 7;
int pinButtonPanCCW = 6;
int speed = 1;
float speedAccellerated = 1.0;
float speedAccelleration = 0.02;

void setup() {
    // Button Pins Mode
    pinMode(pinButtonTiltUp, INPUT_PULLUP);
    pinMode(pinButtonTiltDown, INPUT_PULLUP);
    pinMode(pinButtonPanCW, INPUT_PULLUP);
    pinMode(pinButtonPanCCW, INPUT_PULLUP);
}

void loop() {
  // Button Status
  int statusButtonTiltUp = digitalRead(pinButtonTiltUp);
  int statusButtonTiltDown = digitalRead(pinButtonTiltDown);
  int statusButtonPanCW = digitalRead(pinButtonPanCW);
  int statusButtonPanCCW = digitalRead(pinButtonPanCCW);
  
  // TILT UP
  if (!statusButtonTiltUp && statusButtonTiltDown && statusButtonPanCW && statusButtonPanCCW) {
    myStepperTilt.step(-nSteps);
    speedAccellerated = speedAccellerated + speedAccelleration;
  }
  // TILT DOWN
  else if (statusButtonTiltUp && !statusButtonTiltDown && statusButtonPanCW && statusButtonPanCCW) {
    myStepperTilt.step(nSteps);
    speedAccellerated = speedAccellerated + speedAccelleration;
  }
  // PAN CW
  else if (statusButtonTiltUp && statusButtonTiltDown && !statusButtonPanCW && statusButtonPanCCW) {
    myStepperPan.step(nSteps);
    speedAccellerated = speedAccellerated + speedAccelleration;
  }
  // PAN CCW
  else if (statusButtonTiltUp && statusButtonTiltDown && statusButtonPanCW && !statusButtonPanCCW) {
    myStepperPan.step(-nSteps);
    speedAccellerated = speedAccellerated + speedAccelleration;
  }
  // TILT UP + CW
  else if (!statusButtonTiltUp && statusButtonTiltDown && !statusButtonPanCW && statusButtonPanCCW) {
    myStepperTilt.step(-nSteps);
    myStepperPan.step(nSteps);
    speedAccellerated = speedAccellerated + speedAccelleration;
  }
  // TILT DOWN + CW
  else if (statusButtonTiltUp && !statusButtonTiltDown && !statusButtonPanCW && statusButtonPanCCW) {
    myStepperTilt.step(nSteps);
    myStepperPan.step(nSteps);
    speedAccellerated = speedAccellerated + speedAccelleration;
  }
  // PAN UP + CCW
  else if (!statusButtonTiltUp && statusButtonTiltDown && statusButtonPanCW && !statusButtonPanCCW) {
    myStepperTilt.step(-nSteps);
    myStepperPan.step(-nSteps);
    speedAccellerated = speedAccellerated + speedAccelleration;
  }
  // PAN DOWN + CCW
  else if (statusButtonTiltUp && !statusButtonTiltDown && statusButtonPanCW && !statusButtonPanCCW) {
    myStepperTilt.step(nSteps);
    myStepperPan.step(-nSteps);
    speedAccellerated = speedAccellerated + speedAccelleration;
  }
  else {
    speedAccellerated = 1;
  }

  if (speedAccellerated <= 10) speed = speedAccellerated;
  myStepperTilt.setSpeed(speed);
  myStepperPan.setSpeed(speed);
}

DEMO


LINKS

Thingiverse [Link]

GitHub [Link]