×

INDI Library v2.0.6 is Released (02 Feb 2024)

Bi-monthly release with minor bug fixes and improvements

Moonlite focuser protocol

  • Posts: 11
  • Thank you received: 0
Hello all

I am implementing an Arduino-based focuser like everyone else out there. Instead of inventing my own protocol and having headaches with ASCOM and INDI, I want to implement the Moonlite protocol (also same as EasyFocus/LazyFocus). Also I'm much better at low-level programming than either VB or C++ so I would rather use someone's existing ASCOM and INDI drivers.

I don't want to implement Robofocus protocol (even though somebody has already reverse-engineered it and published Arduino source code) because the Robofocus Windows application doesn't play well with Arduino.

I could reverse-engineer the Moonlite protocol from the INDI driver (looked through it last night), but I would much prefer a protocol document so I don't need to rack my brain so hard.
9 years 11 months ago #966

Please Log in or Create an account to join the conversation.

There you go

File Attachment:

File Name: HighResSte...r107.pdf
File Size:958 KB
The following user(s) said Thank You: dolguldur
Last edit: 9 years 11 months ago by Jasem Mutlaq.
9 years 11 months ago #968
Attachments:

Please Log in or Create an account to join the conversation.

  • Posts: 11
  • Thank you received: 0
Thanks Jasem.

Can you share what is the return value of the :GV# command for a "real" Moonlite controller?
9 years 11 months ago #981

Please Log in or Create an account to join the conversation.

  • Posts: 11
  • Thank you received: 0
Folks may be amused to know that I have successfully reverse-engineered enough of the Moonlite protocol thanks to Jasem's document that both the stand-alone Moonlite program and the ASCOM driver work. I have not tested it with the INDI driver yet, however.
9 years 11 months ago #990

Please Log in or Create an account to join the conversation.

  • Posts: 21
  • Thank you received: 1

Replied by Cees on topic Moonlite focuser protocol

fwiw, I've got this working with the indi_moonlite_focus driver after a few minor changes.
I'm not an expert on coding for the arduino and just started with libindi so bear with me.
Turns out the indi_moonlite driver requires leading zeros (or numbers in a XXXX# or XX# format and your arduino script doesn't provide these. For example a position 1 should be reported as 0001# whereas your script returns 1#

A simple modification that I used to make it work is as follows.
 // get the current motor position
    if (!strcasecmp(cmd, "GP")) {
      pos = stepper.currentPosition();
      char tempString[6];
      sprintf(tempString, "%04X", pos);
      Serial.print(tempString);
      Serial.print("#");
    }

etc, etc

I'm sure there are more elegant ways to do this.

Thanks for your hard work. It did get me started on this project and am happy man now. My homemade focuser works beautiful on a raspberry pi
9 years 11 months ago #1021

Please Log in or Create an account to join the conversation.

  • Posts: 11
  • Thank you received: 0
Thanks for the update!

I know I wasn't using leading zero'es in the return, but the Windows dedicated client and ASCOM driver both work.

I noticed that at my speed of 160 pps, I was losing steps on my Microtouch motor (e.g. one night the focus position is 2965, the next night it's 3100..) so you may want to reduce the MAXSPEED and acceleration.
9 years 11 months ago #1040

Please Log in or Create an account to join the conversation.

  • Posts: 21
  • Thank you received: 1

Replied by Cees on topic Moonlite focuser protocol

Speed does not seem to be a problem. I scavenged a stepper motor from an old epson r230 printer and am using a easydriver stepper board with 12V supply to the motor. Seems to work nicely. I've also connected arduino pin 4 to the easydriver sleep pin and switch it low when isRunnig is low and back on when receiving the FQ command to start moving. Keeps the board cool.
Of course rain has come and I haven't been able to test it outside yet. Maybe next weekend.
9 years 11 months ago #1041

Please Log in or Create an account to join the conversation.

  • Posts: 85
  • Thank you received: 3

Hi.
I also want to run a homemade focuser with an arduino+easy stepper with indi running on a raspberry pi.

I've looked into running the INDIDUINOStepper firmware (indiduino.wordpress.com/2012/12/03/focusser/)
but I don't understand fully how it will work without a driver, or am I missing something?

Running with the moonlite driver sounds like a good option and I was wondering if it was possible to use your arduino sketch modified for indi?

Regards
Daniel
9 years 10 months ago #1060

Please Log in or Create an account to join the conversation.

  • Posts: 21
  • Thank you received: 1

Replied by Cees on topic Moonlite focuser protocol

Sure.
The original script is by orly_andico orlygoingthirty.blogspot.co.nz/2014/04/a...user-controller.html.

I have attached a file with my modifications. The instructions for printing the leading zeros I found somewhere on the net but can't remember where.

I am using an arduino pro-mini 3.3V and cp2102 based USB to TTL converter (all ebay). I do not use a capacitor between GND and RESET (the converter doesn't have a proper reset pin). It seems to work. All that is connected is RXD TXD 5V and GND on the converter to TXD RXD VCC and GND on the arduino.
pin 2,3,4 are connected to step, dir and sleep on the easydriver. The easy driver is powered with a seperate 12V supply.

It runs on a leonardo as well through usb. Only tried it in simulation mode without the easydriver connected but it connects and does respond to commands from the moonlite driver.

Hope this helps
9 years 10 months ago #1066

Please Log in or Create an account to join the conversation.

  • Posts: 21
  • Thank you received: 1

Replied by Cees on topic Moonlite focuser protocol

Whoops. Didn't insert the file. Try again

nope. file attach doesn't work. try code
// Moonlite-compatible stepper controller
//
// Uses AccelStepper (http://www.airspayce.com/mikem/arduino/AccelStepper/)
//
// Requires a 10uf - 100uf capacitor between RESET and GND on the motor shield; this prevents the
// Arduino from resetting on connect (via DTR going low).  Without the capacitor, this sketch works
// with the stand-alone Moonlite control program (non-ASCOM) but the ASCOM driver does not detect it.
// Adding the capacitor allows the Arduino to respond quickly enough to the ASCOM driver probe
//
// orly.andico@gmail.com, 13 April 2014
//
// adapted for libindi and easydriver Cees Lensink
 
#include <AccelStepper.h>
 
int stepperPin = 2;
int dirPin = 3;
int powerPin = 4;
 
// maximum speed is 160pps which should be OK for most
// tin can steppers
#define MAXSPEED 160
#define SPEEDMULT 3
 
AccelStepper stepper(AccelStepper::DRIVER, stepperPin, dirPin);
 
#define MAXCOMMAND 8
 
char inChar;
char cmd[MAXCOMMAND];
char param[MAXCOMMAND];
char line[MAXCOMMAND];
long pos;
int isRunning = 0;
int speed = 32;
int eoc = 0;
int idx = 0;
 
char tempString[8]; 
 
void setup()
{  
  Serial.begin(9600);
 
  // we ignore the Moonlite speed setting because Accelstepper implements
  // ramping, making variable speeds un-necessary
  stepper.setSpeed(MAXSPEED);
  stepper.setMaxSpeed(MAXSPEED);
  stepper.setAcceleration(50);
  stepper.enableOutputs();
  memset(line, 0, MAXCOMMAND);
  // Easydriver Sleep mode or power off
  pinMode(powerPin,OUTPUT);
  // Easydriver Power off (Low = powered down)
  digitalWrite(powerPin, LOW);
 
}
 
 
 
void loop(){
  // run the stepper if there's no pending command and if there are pending movements
  if (!Serial.available())
  {
    if (isRunning) {
      stepper.run();
    } 
    else {
      stepper.disableOutputs();
      digitalWrite(powerPin, LOW); 
    }
    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;
        }
      }
    }
  } // end if (!Serial.available())
 
  // 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;
    // initiate a move
    if (!strcasecmp(cmd, "FG")) {
      isRunning = 1;
      digitalWrite(powerPin, HIGH);
      stepper.enableOutputs();
    }
    // stop a move
    if (!strcasecmp(cmd, "FQ")) {
      isRunning = 0;
      stepper.moveTo(stepper.currentPosition());
      stepper.run();
    }
    // get the temperature coefficient, hard-coded
    if (!strcasecmp(cmd, "GC")) {
      Serial.print("02#");
    }
    // get the current motor speed, only values of 02, 04, 08, 10, 20
    if (!strcasecmp(cmd, "GD")) {
      sprintf(tempString, "%02X", speed);
      Serial.print(tempString);
 
      Serial.print("#");
    }
    // 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 (stepper.distanceToGo() > 0) {
        Serial.print("01#");
      } 
      else {
        Serial.print("00#");
      }
    }
    // get the new motor position (target)
    if (!strcasecmp(cmd, "GN")) {
      pos = stepper.targetPosition();
      sprintf(tempString, "%04X", pos);
      Serial.print(tempString);
      Serial.print("#");
    }
    // get the current motor position
    if (!strcasecmp(cmd, "GP")) {
      pos = stepper.currentPosition();
      sprintf(tempString, "%04X", pos);
      Serial.print(tempString);
      Serial.print("#");
    }
    // get the current temperature, hard-coded
    if (!strcasecmp(cmd, "GT")) {
      Serial.print("0020#");
    }
    // firmware value, always return "10"
    if (!strcasecmp(cmd, "GV")) {
      Serial.print("10#");
    }
    // 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;
    }
    // set speed, only acceptable values are 02, 04, 08, 10, 20
    if (!strcasecmp(cmd, "SD")) {
      speed = hexstr2long(param);
 
      // we ignore the Moonlite speed setting because Accelstepper implements
      // ramping, making variable speeds un-necessary
 
      // stepper.setSpeed(speed * SPEEDMULT);
      // stepper.setMaxSpeed(speed * SPEEDMULT);
      stepper.setSpeed(MAXSPEED);
      stepper.setMaxSpeed(MAXSPEED);
    }
    // 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);
    }
 
  }
} // end loop
 
long hexstr2long(char *line) {
  long ret = 0;
 
  ret = strtol(line, NULL, 16);
  return (ret);
}
 
 
The following user(s) said Thank You: Daniel Franzén
Last edit: 9 years 10 months ago by Cees.
9 years 10 months ago #1067

Please Log in or Create an account to join the conversation.

  • Posts: 85
  • Thank you received: 3
Thank you very much. I got my stepper motor to run using the moonlite focuser driver. Now I only have to assemble the focuser on my telescope :)

/Daniel
9 years 10 months ago #1076

Please Log in or Create an account to join the conversation.

  • Posts: 21
  • Thank you received: 1

Replied by Cees on topic Moonlite focuser protocol

Glad it works for you.
I'm going to have another look at this script and learn some arduino programming in the process.
I still haven't been able to try this out under clear skies but I'm finding that the auto focus routine (canon eos camera) the focuser driver reports the focuser reached the required position before it is actually there. Almost likes like it reports this before it has even started moving. It will than take the next frame to early. I suspect it has something to do with timing and running AccelStepper. Perhaps the Serial communication is to slow or blocking the stepper from starting . I don't know. We'll see.

Anyway, big thank you to orly_andico for getting this started.
9 years 10 months ago #1077

Please Log in or Create an account to join the conversation.

Time to create page: 1.167 seconds