diff --git a/src/MeadeCommandProcessor.cpp b/src/MeadeCommandProcessor.cpp index 419f7630..dd36fcb9 100644 --- a/src/MeadeCommandProcessor.cpp +++ b/src/MeadeCommandProcessor.cpp @@ -97,13 +97,40 @@ meade::RaCoordinate raFrom(const DayTime &t) }; } +// The mount stores declination internally as "degrees from the pole" +// (0 = pole, see Declination.cpp), but the Meade protocol carries standard +// celestial declination (+90 = north celestial pole). Convert at the +// protocol boundary, using the same arithmetic as Declination::formatString +// and Declination::FromSeconds. +constexpr long polarDistanceArcSeconds = 90L * 60L * 60L; + meade::DecCoordinate decFrom(const Declination &d) { - return meade::DecCoordinate { - static_cast(d.getHours()), - static_cast(d.getMinutes()), - static_cast(d.getSeconds()), + const long internal = d.getTotalSeconds(); + const long distance = internal < 0 ? -internal : internal; + const long celestial = inNorthernHemisphere ? polarDistanceArcSeconds - distance : -polarDistanceArcSeconds + distance; + + long secs = celestial < 0 ? -celestial : celestial; + meade::DecCoordinate out { + static_cast(secs / 3600), + static_cast((secs / 60) % 60), + static_cast(secs % 60), }; + if (celestial < 0) + { + out.degrees = static_cast(-out.degrees); + } + return out; +} + +// Inverse conversion for values received from the wire (:Sd, :CM), matching +// Declination::ParseFromMeade. Note: the wire struct cannot carry the sign +// of "-00*MM:SS" values (degrees == 0), a pre-existing parser limitation. +Declination declinationFromMeade(const meade::DecCoordinate &dec) +{ + const long degrees = dec.degrees < 0 ? -static_cast(dec.degrees) : static_cast(dec.degrees); + const long magnitude = degrees * 3600L + static_cast(dec.minutes) * 60L + dec.seconds; + return Declination::FromSeconds(dec.degrees < 0 ? -magnitude : magnitude); } } // namespace @@ -248,7 +275,7 @@ void MeadeCommandProcessor::onSyncToTarget() ///////////////////////////// bool MeadeCommandProcessor::onSetTargetDec(meade::DecCoordinate dec) { - _mount->targetDEC() = Declination(static_cast(dec.degrees), static_cast(dec.minutes), static_cast(dec.seconds)); + _mount->targetDEC() = declinationFromMeade(dec); LOG(DEBUG_MEADE, "[MEADE]: SetInfo: Received Target DEC: %s", _mount->targetDEC().ToString()); return true; } @@ -282,7 +309,7 @@ bool MeadeCommandProcessor::onSetHourAngle(uint8_t hours, uint8_t minutes) bool MeadeCommandProcessor::onSyncCoordinates(meade::DecCoordinate dec, meade::RaCoordinate ra) { - Declination decValue(static_cast(dec.degrees), static_cast(dec.minutes), static_cast(dec.seconds)); + Declination decValue = declinationFromMeade(dec); DayTime raValue(static_cast(ra.hours), static_cast(ra.minutes), static_cast(ra.seconds)); _mount->syncPosition(raValue, decValue); return true; diff --git a/src/core/meade/MeadeParser.hpp b/src/core/meade/MeadeParser.hpp index 3dd9912a..71ac159d 100644 --- a/src/core/meade/MeadeParser.hpp +++ b/src/core/meade/MeadeParser.hpp @@ -39,7 +39,11 @@ namespace meade class MeadeResponse { public: - static constexpr size_t Capacity = 64; + // Must fit the longest reply: :XGM# (board + two stepper descriptors + + // the full addon list) exceeds 100 bytes on an OAE. At 64 the reply was + // silently truncated mid-token and the '#' terminator was dropped, + // breaking every client waiting for it. + static constexpr size_t Capacity = 160; MeadeResponse() : _length(0) {