Bart replied to the topic 'Celestron focus motor' in the forum. 9 hours 47 minutes ago

Hi Mohamed,

You don't need all that resolution on a Celestron. it is already 'geared' by the focuser thread inside. 200 steps/rev is plenty. 400 would also be fine.
I use 400 steps/rev on my Maksutov Newton telescope with a Crayford style focuser. This is a much more sensitive focuser, because the translation per rotation of the focus shaft is more. Diameter of shaft: 4 mm, and so: 4 * Pi / 400 = 0.0314 mm/step (full step!) This is a faster system ( f / 4.8 ) which is more critical to focusing than the Celestron ( f / 6.3 ) and even then it -just works- with no problem.

I think I used 16x microstepping with that system. What this is, is that the stepper driver interpolates the electrical current through the phases of the stepper motor, so the magnetic angle can be 'anywhere' within the normal full (native) step angle.

Don't use all that heavy gearboxes and just direct-drive that stuff :-)
The beauty of the Trinamic drivers is that they can be controlled over SPI protocol, so digital communication with the focus controller (arduino like) and can quickly change settings such as stepper current and microstepping. So you could, if you like, change the microstepping value dynamically. This is almost useless for a focuser, because it's a slow system anyway (but fast enough!).
The change in current, however, is exceptionally useful in this regard, because you don't want to heat up everything by holding the stepper at a certain angle with high current. You want the 'hold current' for that, just enough to lock the position.
When you are changing the position, the current is first increased, enabling higher torque, and next a move is initiated. Then it goes back to hold current again. Very strong but minimal use of electricity.

Jo,
I feed the stepper driver directly from the USB (Vcc pin on the Seeeduino Xiao). it is buffered by a 100 uF capacitor. I'm not routing 600 mA -yet- but 300 mA works fine. There is one downside of powering the Trinamic with only 5 V, which is the reduced speed the steppers can get to while keeping high torque.
Luckily, focusers which require a bit more rotational speed (SCT telescopes) need only low torque and vice versa, a focuser which requires more torque (Crayford/ rack & pinion), the speed can be very low.

I intend to design a few PCBs within a month. I may make a few 'kits'.

Cheers,
Bart

Read More...

Bart replied to the topic 'Celestron focus motor' in the forum. yesterday

I've uploaded it to Thingiverse, so anyone can download it:

www.thingiverse.com/thing:4670151

The controller with the code will be uploaded later on, for now it looks like the Arduino code below...
It's still 'quick and DIRTY', but everything works already, even a cheap infrared remote controller (and the position is updated to EKOS as well!)
If someone has any remarks on the code or suggestions on how to make it faster/ more interactive, please let me know!

I feed the motor + controller purely from USB now, which works OK. this is nice, since it removes -another- cable from the system!

Cheers!

// Moonlite-compatible stepper controller
//
// Uses AccelStepper (http://www.airspayce.com/mikem/arduino/AccelStepper/)

#include <TMC2130Stepper.h>
#include <AccelStepper.h>
#include <IRremote.h>

#define EnPin    0  // Nano v3
#define DirPin   1
#define StepPin  2
#define CsPin    7
#define TemperaturePin A4
#define TempAvgs 10


TMC2130Stepper driver = TMC2130Stepper(EnPin, DirPin, StepPin, CsPin);
AccelStepper stepper = AccelStepper(stepper.DRIVER, StepPin, DirPin);

const int RECV_PIN = 6;
IRrecv irrecv(RECV_PIN);
decode_results results;
unsigned long key_value = 0;

#define MaxSpeed 20000 //Maximum stepper speed in steps/s
#define MaxAcc MaxSpeed * 4 //Maximum stepper acceleration in steps/s/s
#define HoldTime 5
#define Direction false //Set the focuser direction using true or false
#define RunCurrent 500
#define HoldCurrent 15

//#define SPEEDMULT 3
#define MAXCOMMAND 8

char inChar;
char cmd[MAXCOMMAND];
char param[MAXCOMMAND];
char line[MAXCOMMAND];
long pos;
long Temperature = 100;
int isRunning = 0;
int Speed = 2000;
int eoc = 0;
int idx = 0;
int TempSum = 0;
long millisLastMove = 0;
float MeasVolt = 0;

void setup() {
  Serial.begin(38400);
  SPI.begin();

  pinMode(CsPin, OUTPUT);
  digitalWrite(CsPin, HIGH);
  driver.begin();             // Initiate pins and registeries
  driver.rms_current(RunCurrent);    // Set stepper current to 600mA. The command is the same as command TMC2130.setCurrent(600, 0.11, 0.5);
  driver.stealthChop(1);      // Enable extremely quiet stepping
  driver.stealth_autoscale(1);
  driver.microsteps(2);

  //stepper.setSpeed(Speed);
  stepper.setMaxSpeed(Speed);
  stepper.setAcceleration(MaxAcc);
  stepper.setEnablePin(EnPin);
  stepper.setPinsInverted(false, false, true);
  stepper.enableOutputs();

  irrecv.enableIRIn();
  
  memset(line, 0, MAXCOMMAND);
  millisLastMove = millis();
  analogReadResolution(12);
}



void loop(){
  // run the stepper if there's no pending command and if there are pending movements
  if(!Serial.available()){
    if(isRunning){
      driver.rms_current(RunCurrent);
      stepper.run();
      millisLastMove = millis();
    } 
    else{
      if((millis() - millisLastMove) > HoldTime){
        driver.rms_current(HoldCurrent);
        //stepper.disableOutputs();
      }
    }

    if(stepper.distanceToGo() == 0){
      stepper.run();
      isRunning = 0;
    }
  }
  else{
    // read the command until the terminating # character
    while(Serial.available() && !eoc){
      inChar = Serial.read();
      if(inChar != '#' && inChar != ':'){
        line[idx++] = inChar;
        if(idx >= MAXCOMMAND){
          idx = MAXCOMMAND - 1;
        }
      }
      else{
        if(inChar == '#'){
          eoc = 1;
        }
      }
    }
  }

  if (irrecv.decode(&results)){
        if (results.value == 0XFFFFFFFF)
          results.value = key_value;
        switch(results.value){
          case 0xFFA25D:
          Speed -= 500;
            if (Speed <= 0){
            Speed = 100;
            }
          delay(100);
          stepper.setMaxSpeed(Speed);
          break;
          
          case 0xFFE21D:
          Speed += 500;
            if (Speed > MaxSpeed){
            Speed = MaxSpeed;
            }
          delay(100);
          stepper.setMaxSpeed(Speed);
          break;

          case 0xFF22DD:
          pos -= 100;
            if (pos < 0){
            pos = 0;
            }
          delay(100);
          stepper.moveTo(pos);
          isRunning = 1;
          break;

          case 0xFFC23D:
          pos += 100;
            if (pos > 100000){
            pos = 100000;
            }
          delay(100);
          stepper.moveTo(pos);
          isRunning = 1;
          break;
        }
        key_value = results.value;
        irrecv.resume();
  }
  
  // process the command we got
  if (eoc) {
    memset(cmd, 0, MAXCOMMAND);
    memset(param, 0, MAXCOMMAND);

    int len = strlen(line);
    if(len >= 2){
      strncpy(cmd, line, 2);
    }
    if(len > 2){
      strncpy(param, line + 2, len - 2);
    }

    memset(line, 0, MAXCOMMAND);
    eoc = 0;
    idx = 0;

    // the stand-alone program sends :C# :GB# on startup
    // :C# is a temperature conversion, doesn't require any response

    // LED backlight value, always return "00"
    if (!strcasecmp(cmd, "GB")) {
      Serial.print("00#");
    }

    // home the motor, hard-coded, ignore parameters since we only have one motor
    if (!strcasecmp(cmd, "PH")) { 
      stepper.setCurrentPosition(8000);
      stepper.moveTo(0);
      isRunning = 1;
    }

    // firmware value, always return "10"
    if (!strcasecmp(cmd, "GV")) {
      Serial.print("01#");
    }

    // get the current motor position
    if (!strcasecmp(cmd, "GP")) {
      pos = stepper.currentPosition();
      char tempString[6];
      sprintf(tempString, "%04X", pos);
      Serial.print(tempString);
      Serial.print("#");
    }

    // get the new motor position (target)
    if (!strcasecmp(cmd, "GN")) {
      pos = stepper.targetPosition();
      char tempString[6];
      sprintf(tempString, "%04X", pos);
      Serial.print(tempString);
      Serial.print("#");
    }

    // get the current temperature, hard-coded
    if (!strcasecmp(cmd, "GT")) {
      if(!isRunning){
        TempSum = 0;
        for(uint8_t i=0; i < TempAvgs; i++){
          TempSum += analogRead(TemperaturePin);
          delayMicroseconds(200);
        }
        MeasVolt = 3.3*TempSum / (4095 * TempAvgs);
        Temperature = long((MeasVolt - 0.5) * 200);
        if(Temperature < 0){
          Temperature += 65536;
        }
      }
      char tempString[6];
      sprintf(tempString, "%04X", Temperature);
      Serial.print(tempString);
      Serial.print("#");
    }
    

    // get the temperature coefficient, hard-coded
    if (!strcasecmp(cmd, "GC")) {
      Serial.print("01#");
    }

    // get the current motor speed, only values of 02, 04, 08, 10, 20
    if (!strcasecmp(cmd, "GD")) {
      char tempString[4];
      sprintf(tempString, "%02X", Speed);
      Serial.print(tempString);
      Serial.print("#");
    }

    // set speed, only acceptable values are 02, 04, 08, 10, 20
    if (!strcasecmp(cmd, "SD")) {
      Speed = hexstr2long(param);

      stepper.setSpeed(Speed);
      stepper.setMaxSpeed(Speed);
    }

    // whether half-step is enabled or not, always return "00"
    if (!strcasecmp(cmd, "GH")) {
      Serial.print("00#");
    }

    // motor is moving - 01 if moving, 00 otherwise
    if (!strcasecmp(cmd, "GI")) {
      if (abs(stepper.distanceToGo()) > 0) {
        Serial.print("01#");
      } 
      else {
        Serial.print("00#");
      }
    }

    // set current motor position
    if (!strcasecmp(cmd, "SP")) {
      pos = hexstr2long(param);
      stepper.setCurrentPosition(pos);
    }

    // set new motor position
    if (!strcasecmp(cmd, "SN")) {
      pos = hexstr2long(param);
      stepper.moveTo(pos);
    }


    // initiate a move
    if (!strcasecmp(cmd, "FG")) {
      driver.rms_current(RunCurrent);
      //stepper.enableOutputs();
      isRunning = 1;
    }

    // stop a move
    if (!strcasecmp(cmd, "FQ")) {
      stepper.moveTo(stepper.currentPosition());
      stepper.run();
      isRunning = 0;
    }
  }
}

long hexstr2long(char *line) {
  long ret = 0;
  ret = strtol(line, NULL, 16);
  return (ret);
}


Read More...

Bart replied to the topic 'Celestron focus motor' in the forum. yesterday

I will when I'm done debugging this new, tiny setup...



It is a seeeduino xiao with a TMC2130 driver, as a temperature probe the TMP36 from Analog Devices (can go sub-zero) and a IR remote controller that also works standalone.
Seems to work great so far! :-)

Read More...

With elevation is meant the altitude of the object (as if using an alt-az mount), this -does- change during a session.

Also, if you take refraction into account, will you then -not- take it into account when using narrow band filters? There the effect isn't measurable.

Now a question, would you consider to focus during imaging or quickly adjust the focus in between lights?
Personally, I don't use very long exposure lights, especially with Starlink up and screwing up our images.

Read More...

Bart replied to the topic 'Celestron focus motor' in the forum. 6 days ago

Indeed Jo,
I used one of those slim line.
Nema 14 could also be ok, but I had the 17 lying around and a bit of headroom in the torque is nice to have.
I prefer the Trinamic fdrivers, for they are just absolutely smooth, which just 'feels' good.

Yes Mohamed, the code to control the stepper motor driver (microstepping, speed, acceleration etc) is in the Arduino code.
I'm busy now, but will upload files later this week.

Cheers!

Read More...

Bart replied to the topic 'Celestron focus motor' in the forum. 6 days ago

Hi mate,
I have 3D printed a focus motor attachment & coupler for my C8.
I've shared a photo of my setup before here, I guess you can find it there.
What I like is that it still has a (big!) handwheel.

Would you like to have the design?
It uses a direct drive very flat Nema 17 stepper motor and the SilentStepper drivers (TMC2130) on a breadboard still.

Works flawlessly and runs absolutely smooth. I have attached a temp sensor and configured it to play well with the Moonlite protocol.

Cheers!
Bart

Read More...

Bart replied to the topic 'StellarMate in Cold Weather?' in the forum. 2 weeks ago

The condensation of bringing equipment back in a warm room again concerns me as well...

Maybe it's better to leave it outside until the morning, under a cover or under a roof or so?
Put a few desiccant bags under the cover as well? ;) haha

Read More...

Bart replied to the topic 'Light leak' in the forum. 2 weeks ago

When light still generates signal on the imaging chip, but the maximum value that can be recorded is already reached.
Then some information about the shape of the star is lost, because it will be truncated.

Read More...

Bart replied to the topic 'M 31 - Andomeda Galaxy' in the forum. 2 weeks ago

Ah ok! :)

I mean to thermally isolate the tube, in order to reduce 'seeing', but seeing that's generated within the OTA itself.

I don't know of a topic on an international forum. On the Dutch forum there are some topics about it, describing excellent results!
So I recently did mine, but hadn't had a clear night yet.

Thought you might like to know that with negligable investment, you can get much better quality images ;)



Read More...

Bart replied to the topic 'StellarMate in Cold Weather?' in the forum. 2 weeks ago

Not from experience, but a few things I would consider:
- cables are less flexible, maybe even brittle.
- mechanical adjustment of for example worm gear play could get too little.
- grease between the worm and worm gear gets a bit thicker.

And just try it, it will probably be fine ;)

Read More...

Bart replied to the topic 'M 31 - Andomeda Galaxy' in the forum. 2 weeks ago

Have you considered using a reducer/ flattener? They're not expensive and reduce the effective focal length to 1280 mm with an aperture ratio of 6.3.
With your 2.4 micron pixel dimensions, you're very over-sampled, especially considering the mount and seeing.

Another piece of advice: isolate your SCT tube. Only the tube. This reduces tube currents dramatically!

Read More...