57const std::map<int, std::string> SkywatcherAPI::errorCodes
59 {0,
"Unknown command"},
60 {1,
"Command length error"},
61 {2,
"Motor not stopped"},
62 {3,
"Invalid character"},
63 {4,
"Not initialized"},
64 {5,
"Driver sleeping"}
86 return "Star Adventurer";
137 unsigned long value = 0;
139#define HEX(c) (((c) < 'A') ? ((c) - '0') : ((c) - 'A') + 10)
164 unsigned long res = 0;
166#define HEX(c) (((c) < 'A') ? ((c) - '0') : ((c) - 'A') + 10)
187 rc =
tty_read(MyPortFD, input, 20, 1, &nbytes);
197 rc =
tty_read(MyPortFD, input, 1, 1, &nbytes);
199 if ((
TTY_OK == rc) && (1 == nbytes) && (
':' == input[0]))
233 std::string Parameters, Response;
247 std::string Parameters, Response;
254 if (highSpeedRatio == 0)
268 std::string Parameters, Response;
273 long tmpMicrostepsPerRevolution =
BCDstr2long(Response);
275 if (tmpMicrostepsPerRevolution == 0)
282 tmpMicrostepsPerRevolution = 0x205318;
295 (
double)tmpMicrostepsPerRevolution / 360.0, (
double)tmpMicrostepsPerRevolution / 360.0 / 60 / 60);
303 std::string Parameters, Response;
320 std::string Parameters, Response;
325 unsigned long tmpMCVersion =
BCDstr2long(Response);
327 MCVersion = ((tmpMCVersion & 0xFF) << 16) | ((tmpMCVersion & 0xFF00)) | ((tmpMCVersion & 0xFF0000) >> 16);
346 std::string Parameters, Response;
356 "Invalid Stepper Clock Frequency value from mount. Cycle power and reconnect again.");
368 std::string Parameters, Response;
373 if ((Response[1] & 0x01) != 0)
377 if ((Response[0] & 0x01) != 0)
408 if ((Response[0] & 0x02) == 0)
413 if ((Response[0] & 0x04) != 0)
418 if ((Response[2] & 1) == 0)
430 std::string Parameters, Response;
441 std::string Parameters, Response;
442 uint32_t rafeatures = 0, defeatures = 0;
456 if ((rafeatures & 0x000000F0) != (defeatures & 0x000000F0))
459 rafeatures, defeatures);
461 if (rafeatures & 0x00000010)
465 if (defeatures & 0x00000010)
590 std::string Parameters, Response;
599 std::stringstream Temp;
600 Temp << std::hex << std::setfill(
'0') << std::uppercase << std::setw(2) << (Number & 0xff) << std::setw(2)
601 << ((Number & 0xff00) >> 8) << std::setw(2) << ((Number & 0xff0000) >> 16);
645 std::this_thread::sleep_for(std::chrono::milliseconds(100));
679 std::string Parameters, Response;
689 std::string Parameters, Response;
703 std::string Parameters, Response;
705 Parameters.push_back(Func);
714 std::string Parameters, Response;
724 std::string Parameters, Response;
734 std::string Parameters, Response;
743 std::string Response;
744 std::string Parameters = enabled ?
"1" :
"0";
754 else if (SpeedInRadiansPerSecond < -
MAX_SPEED)
757 double InternalSpeed = SpeedInRadiansPerSecond;
769 if (InternalSpeed > 0.0)
773 InternalSpeed = -InternalSpeed;
777 bool HighSpeed =
false;
800 if (0 == OffsetInMicrosteps)
814 if (OffsetInMicrosteps < 0)
818 OffsetInMicrosteps = -OffsetInMicrosteps;
846 std::this_thread::sleep_for(std::chrono::milliseconds(100));
871 std::string Parameters, Response;
878 std::string Parameters, Response;
885 int bytesWritten = 0;
888 char command[SKYWATCHER_MAX_CMD] = {0};
889 char response[SKYWATCHER_MAX_CMD] = {0};
891 snprintf(command, SKYWATCHER_MAX_CMD,
":%c%c%s", Command,
Axis ==
AXIS1 ?
'1' :
'2', cmdDataStr.c_str());
896 command[strlen(command)] = 0xD;
898 for (
int retries = 0; retries < SKYWATCHER_MAX_RETRTY; retries++)
900 tcflush(MyPortFD, TCIOFLUSH);
903 if (retries == SKYWATCHER_MAX_RETRTY - 1)
905 char errorMessage[
MAXRBUF] = {0};
912 std::this_thread::sleep_for(std::chrono::milliseconds(100));
917 bool isResponseReceived =
false;
920 memset(response,
'\0', SKYWATCHER_MAX_CMD);
925 if (retries == SKYWATCHER_MAX_RETRTY - 1)
927 char errorMessage[
MAXRBUF] = {0};
937 std::this_thread::sleep_for(std::chrono::milliseconds(100));
944 response[bytesRead - 1] =
'\0';
945 if(response[0] ==
'=' || response[0] ==
'!')
947 isResponseReceived =
true;
956 if(isResponseReceived)
break;
960 if (response[1] != 0)
963 responseStr = response + 1;
965 if (response[0] ==
'!')
968 uint8_t code = response[1] - 0x30;
969 if (errorCodes.count(code) > 0)
1038 std::string
cmd, response;
The Axis class Implements a generic Axis which can be used for equatorial or AltAz mounts for both ax...
bool SetGotoTargetOffset(AXISID Axis, long OffsetInMicrosteps)
Set the goto target offset per the specified axis.
double MicrostepsToRadians(AXISID Axis, long Microsteps)
Convert microsteps to angle in radians.
bool GetHighSpeedRatio(AXISID Axis)
Set the HighSpeedRatio status variable to the ratio between high and low speed stepping modes.
unsigned long BCDstr2long(std::string &String)
SkyWatcherFeatures AxisFeatures[2]
void TurnRAEncoder(bool on)
unsigned long Highstr2long(std::string &String)
long LowSpeedGotoMargin[2]
bool SetSlewModeDeccelerationRampLength(AXISID Axis, long Microsteps)
Set the length of the deccelaration ramp for Slew mode.
PositiveRotationSense_t GetPositiveRotationDirection(AXISID Axis)
Returns the rotation direction for a positive step on the designated axis.
static constexpr double SIDEREALRATE
bool GetMotorBoardVersion(AXISID Axis)
static constexpr double LOW_SPEED_MARGIN
double MicrostepsToDegrees(AXISID Axis, long Microsteps)
Convert microsteps to angle in degrees.
bool GetStepperClockFrequency(AXISID Axis)
Set the StepperClockFrequency status variable to fixed PIC timer interrupt frequency (ticks per secon...
void TurnEncoder(AXISID axis, bool on)
void SlewTo(AXISID Axis, long OffsetInMicrosteps, bool verbose=true)
Slew to the given offset and stop.
void SetFeature(AXISID axis, uint32_t command)
long ZeroPositionEncoders[2]
Zero position encoder values (microsteps).
double MicrostepsPerRadian[2]
long CurrentEncoders[2]
Current encoder values (microsteps).
bool GetStatus(AXISID Axis)
bool GetMicrostepsPerRevolution(AXISID Axis)
Set the MicrostepsPerRevolution status variable to the number of microsteps for a 360 degree revoluti...
long RadiansToMicrosteps(AXISID Axis, double AngleInRadians)
Convert angle in radians to microsteps.
bool GetMicrostepsPerWormRevolution(AXISID Axis)
Set the MicrostepsPermWormRevolution status variable to the number of microsteps for a 360 degree rev...
double RadiansPerMicrostep[2]
bool SetEncoder(AXISID Axis, long Microsteps)
Set axis encoder to the specified value.
void PrepareForSlewing(AXISID Axis, double Speed)
long DegreesPerSecondToClocksTicksPerMicrostep(AXISID Axis, double DegreesPerSecond)
Check if the current mount is a Virtuoso (AltAz)
bool InstantStop(AXISID Axis)
Bring the axis to an immediate halt. N.B. This command could cause damage to the mount or telescope a...
void TurnDEEncoder(bool on)
long PolarisPositionEncoders[2]
Polaris position (initial) encoder values (microsteps).
bool GetEncoder(AXISID Axis)
Set the CurrentEncoders status variable to the current encoder value in microsteps for the specified ...
long MicrostepsPerWormRevolution[2]
double MicrostepsPerDegree[2]
long DegreesToMicrosteps(AXISID Axis, double AngleInDegrees)
Convert angle in degrees to microsteps.
@ InquireTimerInterruptFreq
@ InquireGridPerRevolution
@ InquireMotorBoardVersion
double DegreesPerMicrostep[2]
bool SlowStop(AXISID Axis)
Bring the axis to slow stop in the distance specified by SetSlewModeDeccelerationRampLength.
bool StartAxisMotion(AXISID Axis)
Start the axis slewing in the previously selected mode.
bool InitMount()
Initialize the communication to the mount.
bool SetSlewToModeDeccelerationRampLength(AXISID Axis, long Microsteps)
Set the length of the deccelaration ramp for SlewTo mode.
long RadiansPerSecondToClocksTicksPerMicrostep(AXISID Axis, double RadiansPerSecond)
Convert a slewing rate in radians per second into the required clock ticks per microstep setting.
void Slew(AXISID Axis, double SpeedInRadiansPerSecond, bool IgnoreSilentMode=true)
Start the axis slewing at the given rate.
bool TalkWithAxis(AXISID Axis, SkywatcherCommand Command, std::string &cmdDataStr, std::string &responseStr)
static constexpr double MAX_SPEED
bool SetAxisMotionMode(AXISID Axis, char Func, char Direction)
Set the motion mode per the specified axis.
long MicrostepsPerRevolution[2]
bool IsInMotion(AXISID Axis)
Check if an axis is moving.
long StepperClockFrequency[2]
bool toggleSnapPort(bool enabled)
Toggle the snap port on or off.
bool SetClockTicksPerMicrostep(AXISID Axis, long ClockTicksPerMicrostep)
Set the PIC internal divider variable which determines how many clock interrupts have to occur betwee...
static const char * mountTypeToString(uint8_t type)
void Long2BCDstr(long Number, std::string &String)
int tty_write(int fd, const char *buf, int nbytes, int *nbytes_written)
Writes a buffer to fd.
int tty_read(int fd, char *buf, int nbytes, int timeout, int *nbytes_read)
read buffer from terminal
int tty_read_section_expanded(int fd, char *buf, char stop_char, long timeout_seconds, long timeout_microseconds, int *nbytes_read)
read buffer from terminal with a delimiter
int tty_write_string(int fd, const char *buf, int *nbytes_written)
Writes a null terminated string to fd.
void tty_error_msg(int err_code, char *err_msg, int err_msg_len)
Retrieve the tty error message.
Implementations for common driver routines.
#define MYDEBUG(priority, msg)
#define MYDEBUGF(priority, msg,...)
void SetSlewingTo(bool forward, bool highspeed)
void SetSlewing(bool forward, bool highspeed)
static Logger & getInstance()
Method to get a reference to the object (i.e., Singleton) It is a static method.
int addDebugLevel(const char *debugLevelName, const char *LoggingLevelName)
Adds a new debugging level to the driver.
bool hasHalfCurrentTracking