diff --git a/Changelog.md b/Changelog.md index d8e923b5..9b2288e2 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,3 +1,16 @@ +**V1.12.6 - Updates** +- Fixed all known issues related to running in the southern hemisphere. +- Added support for DIR inversion to interrupt stepper library. +- Hemisphere no longer needs to be defined in config, firmware determines it automatically from the given Latitude, switching at the equator. +- Fixed the logic in Sync call to account for both hemispheres. +- Fixed some logic that stopped tracking when setting home position. +- Fixed a bug that caused the firmware to fail to recognize the end of very short slews. +- Added Meade Extension command to query remaining tracking time +- Added Meade Extension command to query the hemisphere that is set. + +**V1.12.5 - Updates** +- Bound interrupt stepper library to version 0.0.1. + **V1.12.4 - Updates** - Fixed a bug that incorrectly stopped the RA motor after issuing a DEC move. diff --git a/Configuration.hpp b/Configuration.hpp index 8032b202..9f975d2a 100644 --- a/Configuration.hpp +++ b/Configuration.hpp @@ -47,7 +47,7 @@ #error You have to specify the board #endif -// Set to 1 for the northern hemisphere, 0 otherwise +// Default to northern hemisphere #ifndef NORTHERN_HEMISPHERE #define NORTHERN_HEMISPHERE 1 #endif diff --git a/Version.h b/Version.h index a3989c17..608d9088 100644 --- a/Version.h +++ b/Version.h @@ -3,4 +3,4 @@ // Also, numbers are interpreted as simple numbers. _ __ _ // So 1.8 is actually 1.08, meaning that 1.12 is a later version than 1.8. \_(..)_/ -#define VERSION "V1.12.4" +#define VERSION "V1.12.6" diff --git a/platformio.ini b/platformio.ini index 6d5e5e45..79d0bce9 100644 --- a/platformio.ini +++ b/platformio.ini @@ -92,7 +92,7 @@ debug_build_flags = lib_deps = ${common.lib_deps} jdolinay/avr-debugger @ 1.2 - https://github.com/andre-stefanov/avr-interrupt-stepper + https://github.com/andre-stefanov/avr-interrupt-stepper@0.0.2 [env:mksgenlv21] extends = env:ramps diff --git a/src/Declination.cpp b/src/Declination.cpp index 9f8eef2b..072caeda 100644 --- a/src/Declination.cpp +++ b/src/Declination.cpp @@ -1,4 +1,5 @@ -#include "../Configuration.hpp" // For NORTHERN_HEMISPHERE only +#include "./inc/Globals.hpp" +#include "../Configuration.hpp" #include "Utility.hpp" #include "Declination.hpp" @@ -11,13 +12,13 @@ // Parses the RA or DEC from a string that has an optional sign, a two digit degree, a seperator, a two digit minute, a seperator and a two digit second. // For example: -45*32:11 or 23:44:22 -// In the northern hemisphere, 0 is north pole, 180 and -180 is south pole +// In the NORTHERN hemisphere, 0 is north pole, 180 and -180 is south pole //------------------ S---------------------------------------- N ---------------------------------- S // Celestial -90 -60 -30 0 30 60 90 60 30 0 -30 -60 -90 // Celestial = 90 - abs(Declination) // Declination -180 -150 -120 -90 -60 -30 0 30 60 90 120 150 180 -// In the southern hemisphere, 0 is south pole, 180 and -180 is north pole +// In the SOUTHERN hemisphere, 0 is south pole, 180 and -180 is north pole //------------------ N---------------------------------------- S ---------------------------------- N // Celestial 90 60 30 0 -30 -60 -90 -60 -30 0 30 60 90 // Celestial = -90 + abs(Declination) @@ -87,7 +88,9 @@ const char *Declination::ToString() const *p++ = ' '; *p++ = '('; - strcpy(p, String(NORTHERN_HEMISPHERE ? 90 - fabsf(getTotalHours()) : -90 + fabsf(getTotalHours()), 4).c_str()); + strcpy(p, String(inNorthernHemisphere ? 90 - fabsf(getTotalHours()) : -90 + fabsf(getTotalHours()), 4).c_str()); + strcat(p, ", "); + strcat(p, String(getTotalHours(), 4).c_str()); strcat(p, ")"); return achBufDeg; @@ -96,15 +99,16 @@ const char *Declination::ToString() const Declination Declination::ParseFromMeade(String const &s) { Declination result; - LOG(DEBUG_GENERAL, "[DECLINATION]: Declination.Parse(%s)", s.c_str()); + LOG(DEBUG_MEADE, "[DECLINATION]: Declination.Parse(%s) for %s Hemi", s.c_str(), inNorthernHemisphere ? "N" : "S"); // Use the DayTime code to parse it... DayTime dt = DayTime::ParseFromMeade(s); + LOG(DEBUG_MEADE, "[DECLINATION]: Declination DayTime is %l secs", dt.getTotalSeconds()); // ...and then correct for hemisphere - result.totalSeconds = NORTHERN_HEMISPHERE ? (arcSecondsPerHemisphere / 2) - dt.getTotalSeconds() - : -(arcSecondsPerHemisphere / 2) + dt.getTotalSeconds(); - LOG(DEBUG_GENERAL, "[DECLINATION]: Declination.Parse(%s) -> %s (%l)", s.c_str(), result.ToString(), result.totalSeconds); + result.totalSeconds = inNorthernHemisphere ? (arcSecondsPerHemisphere / 2) - labs(dt.getTotalSeconds()) + : -(arcSecondsPerHemisphere / 2) + labs(dt.getTotalSeconds()); + LOG(DEBUG_MEADE, "[DECLINATION]: Adjust for hemisphere. %s -> %s (%l secs)", s.c_str(), result.ToString(), result.totalSeconds); return result; } @@ -112,16 +116,16 @@ Declination Declination::FromSeconds(long seconds) { const auto secondsFloat = static_cast(seconds); const auto arcSecondsPerHemisphereFloat = static_cast(arcSecondsPerHemisphere); -#if NORTHERN_HEMISPHERE == 1 - return Declination(((arcSecondsPerHemisphereFloat / 2.0f) - secondsFloat) / 3600.0f); -#else - return Declination(((-arcSecondsPerHemisphereFloat / 2.0f) + secondsFloat) / 3600.0f); -#endif + if (inNorthernHemisphere) + { + return Declination(((arcSecondsPerHemisphereFloat / 2.0f) - secondsFloat) / 3600.0f); + } + return Declination(((arcSecondsPerHemisphereFloat / 2.0f) + secondsFloat) / 3600.0f); } const char *Declination::formatString(char *targetBuffer, const char *format, long *) const { long secs - = NORTHERN_HEMISPHERE ? (arcSecondsPerHemisphere / 2) - labs(totalSeconds) : -(arcSecondsPerHemisphere / 2) + labs(totalSeconds); + = inNorthernHemisphere ? (arcSecondsPerHemisphere / 2) - labs(totalSeconds) : -(arcSecondsPerHemisphere / 2) + labs(totalSeconds); return DayTime::formatString(targetBuffer, format, &secs); } diff --git a/src/InterruptAccelStepper.h b/src/InterruptAccelStepper.h index 40d83fe1..31d93f73 100644 --- a/src/InterruptAccelStepper.h +++ b/src/InterruptAccelStepper.h @@ -136,7 +136,7 @@ template class InterruptAccelStepper void setPinsInverted(bool directionInvert = false, bool stepInvert = false, bool enableInvert = false) { - // STUB + STEPPER::setInverted(directionInvert); } bool isRunning() diff --git a/src/Latitude.cpp b/src/Latitude.cpp index f0e99107..b90db767 100644 --- a/src/Latitude.cpp +++ b/src/Latitude.cpp @@ -35,11 +35,11 @@ Latitude Latitude::ParseFromMeade(String const &s) { Latitude result(0.0); - LOG(DEBUG_GENERAL, "[LATITUDE]: Latitude.Parse(%s)", s.c_str()); + LOG(DEBUG_MEADE, "[LATITUDE]: Latitude.Parse(%s)", s.c_str()); // Use the DayTime code to parse it. DayTime dt = DayTime::ParseFromMeade(s); result.totalSeconds = dt.getTotalSeconds(); result.checkHours(); - LOG(DEBUG_GENERAL, "[LATITUDE]: Latitude.Parse(%s) -> %s", s.c_str(), result.ToString()); + LOG(DEBUG_MEADE, "[LATITUDE]: Latitude.Parse(%s) -> %s", s.c_str(), result.ToString()); return result; } diff --git a/src/Longitude.cpp b/src/Longitude.cpp index 9da5dba3..de019770 100644 --- a/src/Longitude.cpp +++ b/src/Longitude.cpp @@ -35,7 +35,7 @@ void Longitude::checkHours() Longitude Longitude::ParseFromMeade(String const &s) { Longitude result(0.0); - LOG(DEBUG_GENERAL, "[LONGITUDE]: Parse(%s)", s.c_str()); + LOG(DEBUG_MEADE, "[LONGITUDE]: Parse(%s)", s.c_str()); // Use the DayTime code to parse it. DayTime dt = DayTime::ParseFromMeade(s); @@ -52,7 +52,7 @@ Longitude Longitude::ParseFromMeade(String const &s) } result.checkHours(); - LOG(DEBUG_GENERAL, "[LONGITUDE]: Parse(%s) -> %s = %ls", s.c_str(), result.ToString(), result.getTotalSeconds()); + LOG(DEBUG_MEADE, "[LONGITUDE]: Parse(%s) -> %s = %ls", s.c_str(), result.ToString(), result.getTotalSeconds()); return result; } diff --git a/src/MeadeCommandProcessor.cpp b/src/MeadeCommandProcessor.cpp index 59c11dab..eb1b23a7 100644 --- a/src/MeadeCommandProcessor.cpp +++ b/src/MeadeCommandProcessor.cpp @@ -772,6 +772,14 @@ bool gpsAqcuisitionComplete(int &indicator); // defined in c72_menuHA_GPS.hpp // Returns: // "float#" // +// :XGST# +// Description: +// Get Remaining Safe Time +// Information: +// Get the number of hours before the RA ring reaches its end. +// Returns: +// "float#" +// // :XGT# // Description: // Get Tracking speed @@ -796,6 +804,15 @@ bool gpsAqcuisitionComplete(int &indicator); // defined in c72_menuHA_GPS.hpp // Returns: // "n#" - the number of steps from the center of the hall sensor trigger range to the home position. // +// :XGHS# +// Description: +// Get Hemisphere +// Information: +// Get the hemisphere that the OAT currently assumes it is operating in. This is set via setting Latitude (see ":St" command) +// Returns: +// "N#" - for northern hemisphere +// "S#" - for southern hemisphere +// // :XGM# // Description: // Get Mount configuration settings @@ -1346,7 +1363,7 @@ String MeadeCommandProcessor::handleMeadeSetInfo(String inCmd) } else if (inCmd[1] == 'P') { - // Set home point + // Set home point :SHP# _mount->setHome(false); } else @@ -1685,9 +1702,16 @@ String MeadeCommandProcessor::handleMeadeExtraCommands(String inCmd) return String(_mount->getStepsPerDegree(DEC_STEPS), 1) + "#"; } } - else if (inCmd[1] == 'S') // :XGS# + else if (inCmd[1] == 'S') { - return String(_mount->getSpeedCalibration(), 5) + "#"; + if (inCmd.length() == 2) // :XGS# + { + return String(_mount->getSpeedCalibration(), 5) + "#"; + } + else if ((inCmd.length() == 3) && (inCmd[2] == 'T')) // :XGST# + { + return String(_mount->checkRALimit(), 7) + "#"; + } } else if (inCmd[1] == 'T') // :XGT# { @@ -1726,9 +1750,16 @@ String MeadeCommandProcessor::handleMeadeExtraCommands(String inCmd) } else if (inCmd[1] == 'H') // :XGH# { - if (inCmd.length() > 2 && inCmd[2] == 'R') // :XGHR# + if (inCmd.length() > 2) { - return String(_mount->getHomingOffset(StepperAxis::RA_STEPS)) + "#"; + if (inCmd[2] == 'R') // :XGHR# + { + return String(_mount->getHomingOffset(StepperAxis::RA_STEPS)) + "#"; + } + else if (inCmd[2] == 'S') // :XGHS# + { + return String(inNorthernHemisphere ? "N#" : "S#"); + } } else if (inCmd.length() > 2 && inCmd[2] == 'D') // :XGHD# { @@ -1840,12 +1871,14 @@ String MeadeCommandProcessor::handleMeadeExtraCommands(String inCmd) { _mount->setBacklashCorrection(inCmd.substring(2).toInt()); } - else if (inCmd[1] == 'H') // :XSH { - if (inCmd.length() > 2 && inCmd[2] == 'R') // :XSHR + if (inCmd.length() > 2) { - _mount->setHomingOffset(StepperAxis::RA_STEPS, inCmd.substring(3).toInt()); + if (inCmd[2] == 'R') // :XSHR + { + _mount->setHomingOffset(StepperAxis::RA_STEPS, inCmd.substring(3).toInt()); + } } else if (inCmd.length() > 2 && inCmd[2] == 'D') // :XSHD { diff --git a/src/Mount.cpp b/src/Mount.cpp index fbacc3ef..eefd8326 100644 --- a/src/Mount.cpp +++ b/src/Mount.cpp @@ -86,13 +86,17 @@ Mount::Mount(LcdMenu *lcdMenu) void Mount::initializeVariables() { + // We are now defaulting to northern hemisphere at 45deg. Switching is now supported + // at runtime when the Latitude is received via Meade command. + inNorthernHemisphere = NORTHERN_HEMISPHERE == 1; + _stepsPerRADegree = RA_STEPS_PER_DEGREE; // u-steps per degree when slewing _stepsPerDECDegree = DEC_STEPS_PER_DEGREE; // u-steps per degree when slewing _mountStatus = 0; _lastDisplayUpdate = 0; _stepperWasRunning = false; - _latitude = Latitude(45.0); + _latitude = Latitude(inNorthernHemisphere ? 45.0f : -45.0f); _longitude = Longitude(100.0); _zeroPosDEC = 0.0f; @@ -206,6 +210,41 @@ void Mount::readPersistentData() LOG(DEBUG_INFO, "[MOUNT]: EEPROM: DEC limits read as %l -> %l", _decLowerLimit, _decUpperLimit); } +///////////////////////////////// +// +// configureHemisphere +// +///////////////////////////////// +void Mount::configureHemisphere(bool inNorthern, bool force) +{ + if ((inNorthernHemisphere != inNorthern) || force) + { + bool wasTracking = isSlewingTRK(); + LOG(DEBUG_ANY, "[SYSTEM]: Hemisphere changed (or forced update) to %s.", inNorthern ? "northern" : "southern"); + LOG(DEBUG_ANY, "[SYSTEM]: Stopping all steppers."); + stopSlewing(ALL_DIRECTIONS | TRACKING); + waitUntilStopped(ALL_DIRECTIONS); + inNorthernHemisphere = inNorthern; + bool invertDir = inNorthernHemisphere ? (RA_INVERT_DIR == 1) : (RA_INVERT_DIR != 1); + LOG(DEBUG_ANY, "[SYSTEM]: Configured RA steppers, DIR Invert is %d", invertDir); + _stepperRA->setPinsInverted(invertDir, false, false); + _stepperTRK->setPinsInverted(invertDir, false, false); + + LOG(DEBUG_ANY, "[SYSTEM]: Reset RA and TRK positions to 0"); + _stepperTRK->setCurrentPosition(0); + _stepperRA->setCurrentPosition(0); + if (wasTracking) + { + LOG(DEBUG_ANY, "[SYSTEM]: Restarting TRK since it was on."); + startSlewing(TRACKING); + } + } + else + { + LOG(DEBUG_ANY, "[SYSTEM]: Already in %s hemisphere, no action taken.", inNorthernHemisphere ? "northern" : "southern"); + } +} + ///////////////////////////////// // // configureRAStepper @@ -225,8 +264,7 @@ void Mount::configureRAStepper(byte pin1, byte pin2, uint32_t maxSpeed, uint32_t _stepperTRK->setMaxSpeed(2000); _stepperTRK->setAcceleration(15000); - _stepperRA->setPinsInverted(NORTHERN_HEMISPHERE == RA_INVERT_DIR, false, false); - _stepperTRK->setPinsInverted(NORTHERN_HEMISPHERE == RA_INVERT_DIR, false, false); + configureHemisphere(inNorthernHemisphere, true); } ///////////////////////////////// @@ -1118,6 +1156,7 @@ void Mount::setLST(const DayTime &lst) void Mount::setLatitude(Latitude latitude) { _latitude = latitude; + configureHemisphere(_latitude.getTotalHours() > 0); EEPROMStore::storeLatitude(_latitude); } @@ -1190,7 +1229,7 @@ const DayTime Mount::currentRA() const hourPos += _zeroPosRA.getTotalHours(); const float degreePos = (_stepperDEC->currentPosition() / _stepsPerDECDegree) + _zeroPosDEC; - if (NORTHERN_HEMISPHERE ? degreePos < 0 : degreePos > 0) + if (degreePos < 0) { hourPos += 12; if (hourPos > 24) @@ -1233,7 +1272,15 @@ void Mount::syncPosition(DayTime ra, Declination dec) long solutions[6]; _targetDEC = dec; _targetRA = ra; - LOG(DEBUG_COORD_CALC, "[MOUNT]: syncPosition( RA: %s and DEC: %s )", _targetRA.ToString(), _targetDEC.ToString()); + LOG(DEBUG_COORD_CALC, + "[MOUNT]: syncPosition: Target Sync is RA: %f and DEC: %f", + _targetRA.getTotalHours(), + _targetDEC.getTotalDegrees()); + LOG(DEBUG_COORD_CALC, + "[MOUNT]: syncPosition: Current Pos is RA: %f and DEC: %f )", + currentRA().getTotalHours(), + currentDEC().getTotalDegrees()); + LOG(DEBUG_COORD_CALC, "[MOUNT]: syncPosition: ZeroPos values RA: %f and DEC: %f)", _zeroPosRA.getTotalHours(), _zeroPosDEC); // Adjust the home RA position by the delta sync position. float raAdjust = ra.getTotalHours() - currentRA().getTotalHours(); @@ -1252,14 +1299,25 @@ void Mount::syncPosition(DayTime ra, Declination dec) // Adjust the home DEC position by the delta between the sync'd target and current position. const float degreePos = (_stepperDEC->currentPosition() / _stepsPerDECDegree) + _zeroPosDEC; // u-steps / u-steps/deg = deg - float decAdjust = dec.getTotalDegrees() - fabsf(currentDEC().getTotalDegrees()); + LOG(DEBUG_COORD_CALC, "[MOUNT]: syncPosition: DEC degreePos is: %f", degreePos); + + // Dec totalhours can be plus or minus the distance from the pole (because it keeps track of whether we are upwards or downwards from the pole) + // So we use the abs of both values to find their difference + float decAdjust = fabsf(dec.getTotalDegrees()) - fabsf(currentDEC().getTotalDegrees()); + LOG(DEBUG_COORD_CALC, + "[MOUNT]: syncPosition: DecAdjust is: %f ( |%f| - |%f| )", + decAdjust, + dec.getTotalDegrees(), + currentDEC().getTotalDegrees()); if (degreePos < 0) { + LOG(DEBUG_COORD_CALC, "[MOUNT]: syncPosition: Inverted DecAdjust to: %f (below home pos)", decAdjust); decAdjust = -decAdjust; } + _zeroPosDEC += decAdjust; - LOG(DEBUG_COORD_CALC, "[MOUNT]: syncPosition: _zerPosDEC adjusted by: %f", decAdjust); - LOG(DEBUG_COORD_CALC, "[MOUNT]: syncPosition: _zerPosDEC: %f", _zeroPosDEC); + LOG(DEBUG_COORD_CALC, "[MOUNT]: syncPosition: _zeroPosDEC adjusted by: %f", decAdjust); + LOG(DEBUG_COORD_CALC, "[MOUNT]: syncPosition: _zeroPosDEC: %f", _zeroPosDEC); long targetRAPosition, targetDECPosition; calculateRAandDECSteppers(targetRAPosition, targetDECPosition, solutions); @@ -1317,16 +1375,16 @@ void Mount::startSlewingToTarget() } _mountStatus |= STATUS_SLEWING | STATUS_SLEWING_TO_TARGET; - moveSteppersTo(targetRAPosition, targetDECPosition, RA_AND_DEC_STEPS); // u-steps (in slew mode) - _totalDECMove = 1.0f * _stepperDEC->distanceToGo(); - _totalRAMove = 1.0f * _stepperRA->distanceToGo(); - LOG(DEBUG_MOUNT, "[MOUNT]: RA Dist: %l, DEC Dist: %l", _stepperRA->distanceToGo(), _stepperDEC->distanceToGo()); - #if DEC_DRIVER_TYPE == DRIVER_TYPE_TMC2209_UART // Since normal state for DEC is guide microstepping, switch to slew microstepping here. LOG(DEBUG_STEPPERS, "[STEPPERS]: startSlewingToTarget: Switching DEC driver to microsteps(%d)", DEC_SLEW_MICROSTEPPING); _driverDEC->microsteps(DEC_SLEW_MICROSTEPPING == 1 ? 0 : DEC_SLEW_MICROSTEPPING); #endif + _stepperWasRunning = true; + moveSteppersTo(targetRAPosition, targetDECPosition, RA_AND_DEC_STEPS); // u-steps (in slew mode) + _totalDECMove = static_cast(_stepperDEC->distanceToGo()); + _totalRAMove = static_cast(_stepperRA->distanceToGo()); + LOG(DEBUG_MOUNT, "[MOUNT]: RA Dist: %l, DEC Dist: %l", _stepperRA->distanceToGo(), _stepperDEC->distanceToGo()); } ///////////////////////////////// @@ -1383,16 +1441,16 @@ void Mount::startSlewingToHome() } _mountStatus |= STATUS_SLEWING | STATUS_SLEWING_TO_TARGET; - moveSteppersTo(targetRAPosition, targetDECPosition, RA_AND_DEC_STEPS); // u-steps (in slew mode) - _totalDECMove = static_cast(_stepperDEC->distanceToGo()); - _totalRAMove = static_cast(_stepperRA->distanceToGo()); - LOG(DEBUG_MOUNT, "[MOUNT]: RA Dist: %l, DEC Dist: %l", _stepperRA->distanceToGo(), _stepperDEC->distanceToGo()); - #if DEC_DRIVER_TYPE == DRIVER_TYPE_TMC2209_UART // Since normal state for DEC is guide microstepping, switch to slew microstepping here. LOG(DEBUG_STEPPERS, "[STEPPERS]: startSlewingToHome: Switching DEC driver to microsteps(%d)", DEC_SLEW_MICROSTEPPING); _driverDEC->microsteps(DEC_SLEW_MICROSTEPPING == 1 ? 0 : DEC_SLEW_MICROSTEPPING); #endif + _stepperWasRunning = true; + moveSteppersTo(targetRAPosition, targetDECPosition, RA_AND_DEC_STEPS); // u-steps (in slew mode) + _totalDECMove = static_cast(_stepperDEC->distanceToGo()); + _totalRAMove = static_cast(_stepperRA->distanceToGo()); + LOG(DEBUG_MOUNT, "[MOUNT]: RA Dist: %l, DEC Dist: %l", _stepperRA->distanceToGo(), _stepperDEC->distanceToGo()); } ///////////////////////////////// @@ -2167,7 +2225,7 @@ void Mount::startSlewing(int direction) else { // Start slewing - int sign = NORTHERN_HEMISPHERE ? 1 : -1; + int sign = inNorthernHemisphere ? 1 : -1; // Set move rate to last commanded slew rate setSlewRate(_moveRate); @@ -2699,8 +2757,11 @@ void Mount::loop() } else { - // Check whether we should stop tracking now - checkRALimit(); + // Check whether we should stop tracking every 5 seconds + if (now - _lastTRKCheck > 5000) + { + checkRALimit(); + } if (_mountStatus & STATUS_SLEWING_MANUAL) { @@ -3015,7 +3076,16 @@ void Mount::getDecLimitPositions(float &lowerLimit, float &upperLimit) ///////////////////////////////// void Mount::setHome(bool clearZeroPos) { - LOG(DEBUG_MOUNT, "[MOUNT]: setHome() called"); + LOG(DEBUG_MOUNT, "[MOUNT]: setHome() called. Stopping steppers"); + bool wasTracking = isSlewingTRK(); + stopSlewing(ALL_DIRECTIONS); + waitUntilStopped(ALL_DIRECTIONS); + if (wasTracking) + { + LOG(DEBUG_MOUNT, "[MOUNT]: setHome: Tracking was on, so start it again."); + startSlewing(TRACKING); + } + //LOG(DEBUG_MOUNT_VERBOSE, "[MOUNT]: setHomePre: currentRA is %s", currentRA().ToString()); //LOG(DEBUG_MOUNT_VERBOSE, "[MOUNT]: setHomePre: targetRA is %s", targetRA().ToString()); //LOG(DEBUG_MOUNT_VERBOSE, "[MOUNT]: setHomePre: zeroPos is %s", _zeroPosRA.ToString()); @@ -3028,9 +3098,11 @@ void Mount::setHome(bool clearZeroPos) _stepperRA->setCurrentPosition(0); _stepperDEC->setCurrentPosition(0); _stepperTRK->setCurrentPosition(0); - // TODO: Set New Guide Stepper to 0 + _stepperGUIDE->setCurrentPosition(0); - _targetRA = currentRA(); + _targetRA = currentRA(); + _slewingToHome = false; + _slewingToPark = false; //LOG(DEBUG_MOUNT_VERBOSE, "[MOUNT]: setHomePost: currentRA is %s", currentRA().ToString()); //LOG(DEBUG_MOUNT_VERBOSE, "[MOUNT]: setHomePost: zeroPos is %s", _zeroPosRA.ToString()); @@ -3097,6 +3169,7 @@ void Mount::calculateRAandDECSteppers(long &targetRASteps, long &targetDECSteps, DayTime raTarget = _targetRA; Declination decTarget = _targetDEC; + // Calculate how far from the home position this new target is. raTarget.subtractTime(_zeroPosRA); LOG(DEBUG_COORD_CALC, "[MOUNT]: CalcSteppersIn: Adjust RA by ZeroPosRA. New Target RA: %s, DEC: %s", @@ -3105,10 +3178,7 @@ void Mount::calculateRAandDECSteppers(long &targetRASteps, long &targetDECSteps, // Where do we want to move RA to? float moveRA = raTarget.getTotalHours(); - if (!NORTHERN_HEMISPHERE) - { - moveRA += 12; - } + LOG(DEBUG_COORD_CALC, "[MOUNT]: CalcSteppersIn: moveRA (target) is %f", moveRA); // Total hours of tracking-to-date float trackedHours = (_stepperTRK->currentPosition() / _trackingSpeed) / 3600.0F; // steps / steps/s / 3600 = hours @@ -3116,9 +3186,14 @@ void Mount::calculateRAandDECSteppers(long &targetRASteps, long &targetDECSteps, // The current RA of the home position, taking tracking-to-date into account float homeRA = _zeroPosRA.getTotalHours() + trackedHours; + LOG(DEBUG_COORD_CALC, "[MOUNT]: CalcSteppersIn: homeRA adjusted by elasped tracking actually represents %f h", homeRA); // Delta between target RA and home position with a normalized range of -12 hr to 12 hr float homeTargetDeltaRA = _targetRA.getTotalHours() - homeRA; + LOG(DEBUG_COORD_CALC, + "[MOUNT]: CalcSteppersIn: Delta of home to targetRA (%f) is %f (will use to check limits) ", + _targetRA.getTotalHours(), + homeTargetDeltaRA); while (homeTargetDeltaRA > 12) { homeTargetDeltaRA = homeTargetDeltaRA - 24; @@ -3143,10 +3218,20 @@ void Mount::calculateRAandDECSteppers(long &targetRASteps, long &targetDECSteps, // Where do we want to move DEC to? float moveDEC = decTarget.getTotalDegrees(); + if (!inNorthernHemisphere) + { + LOG(DEBUG_COORD_CALC, "[MOUNT]: CalcSteppersIn: moveDEC inverted for southern Hemisphere => %f", moveDEC); + moveDEC = -moveDEC; + } - LOG(DEBUG_COORD_CALC, "[MOUNT]: CalcSteppersIn: Target hrs pos RA: %f (regRA: %f), DEC: %f", homeTargetDeltaRA, moveRA, moveDEC); + LOG(DEBUG_COORD_CALC, + "[MOUNT]: CalcSteppersIn: Target hrs pos RA: Delta:%f (moveRA: %f), DEC: %s (moveDEC: %f)", + homeTargetDeltaRA, + moveRA, + decTarget.ToString(), + moveDEC); -/* + /* * Current RA wheel has a rotation limit of around 7 hours in each direction from home position. * Since tracking does not trigger the meridian flip, we try to extend the possible tracking time * without reaching the RA ring end by executing the meridian flip before slewing to the target. @@ -3155,13 +3240,8 @@ void Mount::calculateRAandDECSteppers(long &targetRASteps, long &targetDECSteps, * sections around the home position of RA. The tracking time will still be limited to around 2h in * worst case if the target is located right before the 5h mark during slewing. */ -#if NORTHERN_HEMISPHERE == 1 - float const RALimitL = -RA_LIMIT_LEFT; - float const RALimitR = RA_LIMIT_RIGHT; -#else - float const RALimitL = -RA_LIMIT_RIGHT; - float const RALimitR = RA_LIMIT_LEFT; -#endif + float const RALimitL = inNorthernHemisphere ? -RA_LIMIT_LEFT : -RA_LIMIT_RIGHT; + float const RALimitR = inNorthernHemisphere ? RA_LIMIT_RIGHT : RA_LIMIT_LEFT; LOG(DEBUG_COORD_CALC, "[MOUNT]: CalcSteppersIn: Limits are : %f to %f", RALimitL, RALimitR); if (pSolutions != nullptr) @@ -3182,7 +3262,7 @@ void Mount::calculateRAandDECSteppers(long &targetRASteps, long &targetDECSteps, if (homeTargetDeltaRA > RALimitR) { LOG(DEBUG_COORD_CALC, - "[MOUNT]: CalcSteppersIn: targetRA %f (RA:%f) is past max limit %f (solution 2)", + "[MOUNT]: CalcSteppersIn: Using Solution 2, since hometargetDeltaRA %f (RA:%f) is past max limit %f, inverting both axes", homeTargetDeltaRA, moveRA, RALimitR); @@ -3196,7 +3276,7 @@ void Mount::calculateRAandDECSteppers(long &targetRASteps, long &targetDECSteps, else if (homeTargetDeltaRA < RALimitL) { LOG(DEBUG_COORD_CALC, - "[MOUNT]: CalcSteppersIn: targetRA %f (RA:%f) is past min limit: %f, (solution 3)", + "[MOUNT]: CalcSteppersIn: Using solution 3 since homeTargetDeltaRA %f (RA:%f) is past min limit: %f, inverting both axes", homeTargetDeltaRA, moveRA, RALimitL); @@ -3209,19 +3289,20 @@ void Mount::calculateRAandDECSteppers(long &targetRASteps, long &targetDECSteps, else { LOG(DEBUG_COORD_CALC, - "[MOUNT]: CalcSteppersIn: targetRA %f is in range. RA: %f, DEC: %f (solution 1)", + "[MOUNT]: CalcSteppersIn: Using solution 1 since targetRA %f is in range. RA: %f, DEC: %f", homeTargetDeltaRA, moveRA, moveDEC); } - moveDEC -= _zeroPosDEC; // deg - LOG(DEBUG_COORD_CALC, "[MOUNT]: CalcSteppersIn: _zeroPosDEC: %f", _zeroPosDEC); - LOG(DEBUG_COORD_CALC, "[MOUNT]: CalcSteppersIn: Adjusted moveDEC: %f", moveDEC); + // zeroPosDEC will be zero unless one or more Sync commands have moved it, in which case it is the + // accumulated offset from zero (home) in degrees. + moveDEC -= _zeroPosDEC; + LOG(DEBUG_COORD_CALC, "[MOUNT]: CalcSteppersIn: adjusted DEC by _zeroPosDEC: %f => DEC: %f", _zeroPosDEC, moveDEC); targetRASteps = -moveRA * stepsPerSiderealHour; targetDECSteps = moveDEC * _stepsPerDECDegree; - LOG(DEBUG_COORD_CALC, "[MOUNT]: CalcSteppersPost: Target Steps RA: %l, DEC: %l", targetRASteps, targetDECSteps); + LOG(DEBUG_COORD_CALC, "[MOUNT]: CalcSteppersPost: ResultTarget Steps RA: %l, DEC: %l", targetRASteps, targetDECSteps); } ///////////////////////////////// @@ -3309,22 +3390,23 @@ void Mount::moveStepperBy(StepperAxis direction, long steps) LOG(DEBUG_STEPPERS, "[STEPPERS]: moveStepperBy: Switching RA driver to microsteps(%d)", RA_SLEW_MICROSTEPPING); _driverRA->microsteps(RA_SLEW_MICROSTEPPING == 1 ? 0 : RA_SLEW_MICROSTEPPING); #endif - moveSteppersTo(_stepperRA->currentPosition() + steps, 0, direction); _mountStatus |= STATUS_SLEWING | STATUS_SLEWING_TO_TARGET; + _stepperWasRunning = true; + moveSteppersTo(_stepperRA->currentPosition() + steps, 0, direction); _totalRAMove = 1.0f * _stepperRA->distanceToGo(); break; case DEC_STEPS: { - moveSteppersTo(0, _stepperDEC->currentPosition() + steps, direction); _mountStatus |= STATUS_SLEWING | STATUS_SLEWING_TO_TARGET; - _totalDECMove = 1.0f * _stepperDEC->distanceToGo(); - #if DEC_DRIVER_TYPE == DRIVER_TYPE_TMC2209_UART // Since normal state for DEC is guide microstepping, switch to slew microstepping here. LOG(DEBUG_STEPPERS, "[STEPPERS]: moveStepperBy: Switching DEC driver to microsteps(%d)", DEC_SLEW_MICROSTEPPING); _driverDEC->microsteps(DEC_SLEW_MICROSTEPPING == 1 ? 0 : DEC_SLEW_MICROSTEPPING); #endif + _stepperWasRunning = true; + moveSteppersTo(0, _stepperDEC->currentPosition() + steps, direction); + _totalDECMove = 1.0f * _stepperDEC->distanceToGo(); } break; @@ -3477,21 +3559,15 @@ String Mount::DECString(byte type, byte active) Declination dec; if ((type & TARGET_STRING) == TARGET_STRING) { - //LOG(DEBUG_MOUNT_VERBOSE, "[MOUNT]: DECString: TARGET!"); dec = _targetDEC; } else { - //LOG(DEBUG_MOUNT_VERBOSE, "[MOUNT]: DECString: CURRENT!"); dec = currentDEC(); } - //LOG(DEBUG_INFO, "[MOUNT]: DECString: Precheck : %s %s %dm %ds", dec.ToString(), dec.getDegreesDisplay().c_str(), dec.getMinutes(), dec.getSeconds()); - // dec.checkHours(); - // LOG(DEBUG_MOUNT_VERBOSE, "[MOUNT]: DECString: Postcheck : %s", dec.ToString()); dec.formatString(scratchBuffer, formatStringsDEC[type & FORMAT_STRING_MASK]); - // sprintf(scratchBuffer, formatStringsDEC[type & FORMAT_STRING_MASK], dec.getDegreesDisplay().c_str(), dec.getMinutes(), dec.getSeconds()); if ((type & FORMAT_STRING_MASK) == LCDMENU_STRING) { scratchBuffer[active * 4 + (active > 0 ? 1 : 0)] = '>'; @@ -3674,6 +3750,14 @@ DayTime Mount::calculateLst() DayTime timeUTC = getUtcTime(); LocalDate localDate = getLocalDate(); DayTime lst = Sidereal::calculateByDateAndTime(longitude().getTotalHours(), localDate.year, localDate.month, localDate.day, &timeUTC); + LOG(DEBUG_INFO, + "[MOUNT]: Calculating LST. UTC time: %s. Date: %d-%d-%d. Longitude: %s", + timeUTC.ToString(), + localDate.year, + localDate.month, + localDate.day, + longitude().ToString()); + LOG(DEBUG_INFO, "[MOUNT]: LST is: %s", lst.ToString()); return lst; } @@ -3685,7 +3769,10 @@ DayTime Mount::calculateLst() DayTime Mount::calculateHa() { DayTime lst = calculateLst(); - return Sidereal::calculateHa(lst.getTotalHours()); + LOG(DEBUG_INFO, "[MOUNT]: Calculating HA from LST: %s", lst.ToString()); + DayTime ha = Sidereal::calculateHa(lst.getTotalHours()); + LOG(DEBUG_INFO, "[MOUNT]: HA is: %s", ha.ToString()); + return ha; } ///////////////////////////////// @@ -3752,31 +3839,34 @@ void Mount::testUART_vactual(TMC2209Stepper *driver, int _speed, int _duration) // checkRALimit // ///////////////////////////////// -void Mount::checkRALimit() +float Mount::checkRALimit() { - // Check tracking limits every 5 seconds - if (millis() - _lastTRKCheck < 5000) - return; const float trackedHours = (_stepperTRK->currentPosition() / _trackingSpeed) / 3600.0F; // steps / steps/s / 3600 = hours const float homeRA = _zeroPosRA.getTotalHours() + trackedHours; const float RALimit = RA_TRACKING_LIMIT; - const float degreePos = (_stepperDEC->currentPosition() / _stepsPerDECDegree) + _zeroPosDEC; - float hourPos = currentRA().getTotalHours(); - if (NORTHERN_HEMISPHERE ? degreePos < 0 : degreePos > 0) + LOG(DEBUG_MOUNT_VERBOSE, + "[MOUNT]: checkRALimit: homeRA: %f (ZeroPos: %f + TrkHrs: %f)", + homeRA, + _zeroPosRA.getTotalHours(), + trackedHours); + const float degreePos = (_stepperDEC->currentPosition() / _stepsPerDECDegree) + _zeroPosDEC; + float hourPos = currentRA().getTotalHours(); + LOG(DEBUG_MOUNT_VERBOSE, "[MOUNT]: checkRALimit: degreePosDec: %f , RA hourpos : %f)", degreePos, hourPos); + if (inNorthernHemisphere ? degreePos < 0 : degreePos > 0) { hourPos -= 12; if (hourPos < 0) hourPos += 24; + LOG(DEBUG_MOUNT_VERBOSE, "[MOUNT]: checkRALimit: switching RA hourPos to: %f", hourPos); } - LOG(DEBUG_MOUNT_VERBOSE, "[MOUNT]: checkRALimit: homeRA: %f", homeRA); - LOG(DEBUG_MOUNT_VERBOSE, "[MOUNT]: checkRALimit: currentRA: %f", currentRA().getTotalHours()); - LOG(DEBUG_MOUNT_VERBOSE, "[MOUNT]: checkRALimit: currentRA (adjusted): %f", hourPos); + LOG(DEBUG_MOUNT_VERBOSE, "[MOUNT]: checkRALimit: RA hourPos (adjusted): %f", hourPos); float homeCurrentDeltaRA = homeRA - hourPos; + LOG(DEBUG_MOUNT_VERBOSE, "[MOUNT]: checkRALimit: DeltaRA: %f (home:%f - hour:%f)", homeCurrentDeltaRA, homeRA, hourPos); while (homeCurrentDeltaRA > 12) homeCurrentDeltaRA -= 24; while (homeCurrentDeltaRA < -12) homeCurrentDeltaRA += 24; - LOG(DEBUG_MOUNT_VERBOSE, "[MOUNT]: checkRALimit: homeRAdelta: %f", homeCurrentDeltaRA); + LOG(DEBUG_MOUNT_VERBOSE, "[MOUNT]: checkRALimit: deltaRA: %f => Check against %f", homeCurrentDeltaRA, RALimit); if (homeCurrentDeltaRA > RALimit) { @@ -3784,4 +3874,6 @@ void Mount::checkRALimit() stopSlewing(TRACKING); } _lastTRKCheck = millis(); + + return RALimit - homeCurrentDeltaRA; } diff --git a/src/Mount.hpp b/src/Mount.hpp index e2a27254..d719470a 100644 --- a/src/Mount.hpp +++ b/src/Mount.hpp @@ -129,6 +129,8 @@ class Mount // Configure the RA stepper motor. This also sets up the TRK stepper on the same pins. void configureRAStepper(byte pin1, byte pin2, uint32_t maxSpeed, uint32_t maxAcceleration); + void configureHemisphere(bool isNorthern, bool force = false); + // Configure the DEC stepper motor. void configureDECStepper(byte pin1, byte pin2, uint32_t maxSpeed, uint32_t maxAcceleration); @@ -451,6 +453,9 @@ class Mount byte slewStatus() const; byte mountStatus() const; + // Returns the remaining tracking time available and stops tracking if it reaches zero. + float checkRALimit(); + #if UART_CONNECTION_TEST_TX == 1 #if RA_DRIVER_TYPE == DRIVER_TYPE_TMC2209_UART void testRA_UART_TX(); @@ -466,8 +471,6 @@ class Mount #endif #endif - void checkRALimit(); - // Reads values from EEPROM that configure the mount (if previously stored) void readPersistentData(); diff --git a/src/StepperConfiguration.hpp b/src/StepperConfiguration.hpp index 6e16bc1f..105c119e 100644 --- a/src/StepperConfiguration.hpp +++ b/src/StepperConfiguration.hpp @@ -32,7 +32,7 @@ struct Ra { using pin_dir = Pin; using interrupt = IntervalInterrupt; - using driver = Driver; + using driver = Driver; using ramp_slew = AccelerationRamp<256, interrupt::FREQ, UINT32(SPEED_SLEW), UINT32(ACCEL_SLEW)>; using ramp_trk = ConstantRamp; @@ -64,7 +64,7 @@ struct Dec { using pin_dir = Pin; using interrupt = IntervalInterrupt; - using driver = Driver; + using driver = Driver; using ramp_slew = AccelerationRamp<256, interrupt::FREQ, UINT32(SPEED_SLEW), UINT32(ACCEL_SLEW)>; using ramp_trk = ConstantRamp; @@ -84,7 +84,7 @@ struct Az { using pin_dir = Pin; using interrupt = IntervalInterrupt; - using driver = Driver; + using driver = Driver; using ramp_slew = AccelerationRamp<64, interrupt::FREQ, UINT32(SPEED_SLEW), UINT32(ACCEL_SLEW)>; @@ -103,7 +103,7 @@ struct Alt { using pin_dir = Pin; using interrupt = IntervalInterrupt; - using driver = Driver; + using driver = Driver; using ramp_slew = AccelerationRamp<64, interrupt::FREQ, UINT32(SPEED_SLEW), UINT32(ACCEL_SLEW)>; diff --git a/src/c76_menuCAL.hpp b/src/c76_menuCAL.hpp index 6d5c8e8b..9936670a 100644 --- a/src/c76_menuCAL.hpp +++ b/src/c76_menuCAL.hpp @@ -697,7 +697,7 @@ bool processCalibrationKeys() // Set DEC to move the same distance past Polaris as // it is from the Celestial Pole. That equates to 88deg 42' 11.2". - mount.targetDEC() = Declination(88 - (NORTHERN_HEMISPHERE ? 90 : -90), 42, 11); + mount.targetDEC() = Declination(88 - (inNorthernHemisphere ? 90 : -90), 42, 11); mount.startSlewingToTarget(); okToUpdateMenu = false; } @@ -717,7 +717,7 @@ bool processCalibrationKeys() mount.delay(750); // Sync the mount to Polaris, since that's where it's pointing - mount.syncPosition(mount.currentRA(), Declination(89 - (NORTHERN_HEMISPHERE ? 90 : -90), 21, 6)); + mount.syncPosition(mount.currentRA(), Declination(89 - (inNorthernHemisphere ? 90 : -90), 21, 6)); // Go home from here mount.startSlewingToHome(); diff --git a/src/inc/Globals.cpp b/src/inc/Globals.cpp index 54a3d63a..ec803da0 100644 --- a/src/inc/Globals.cpp +++ b/src/inc/Globals.cpp @@ -1,4 +1,5 @@ #include "Globals.hpp" // TODO: Should move this somewhere else... -bool inSerialControl = false; // True when the serial port is in control +bool inSerialControl = false; // True when the serial port is in control +bool inNorthernHemisphere = true; // Default to northern hemisphere diff --git a/src/inc/Globals.hpp b/src/inc/Globals.hpp index 54713563..dac7ef4f 100644 --- a/src/inc/Globals.hpp +++ b/src/inc/Globals.hpp @@ -17,3 +17,4 @@ PUSH_NO_WARNINGS POP_NO_WARNINGS extern bool inSerialControl; // True when the serial port is in control +extern bool inNorthernHemisphere;