Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
318 changes: 318 additions & 0 deletions ARCHITECTURE.md

Large diffs are not rendered by default.

171 changes: 93 additions & 78 deletions PLAN.md

Large diffs are not rendered by default.

8 changes: 4 additions & 4 deletions src/EPROMStore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,16 @@ POP_NO_WARNINGS
#include "EPROMStore.hpp"

// The platform-independant EEPROM class

// Steps/deg are normalized to this value and stored.
const float SteppingStorageNormalized = 25600.0;
//
// The on-device layout (addresses, flags, magic markers) is defined in hal::eeprom.
using namespace hal::eeprom;

///////////////////////////////////////
// PLATFORM-SPECIFIC IMPLEMENTATIONS

#if USE_DUMMY_EEPROM == true

static uint8_t dummyEepromStorage[EEPROMStore::STORE_SIZE];
static uint8_t dummyEepromStorage[STORE_SIZE];

// Initialize the EEPROM object for ESP boards, setting aside storage
void EEPROMStore::initialize()
Expand Down
161 changes: 7 additions & 154 deletions src/EPROMStore.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include "DayTime.hpp"
#include "Latitude.hpp"
#include "Longitude.hpp"
#include "hal/EepromLayout.hpp"

// Platform independant abstraction of the EEPROM storage capability of the boards.
// This is needed because the ESP boards require two things that the Arduino boards don't:
Expand Down Expand Up @@ -75,160 +76,12 @@ class EEPROMStore
static void storeALTPosition(int32_t altPosition);

private:
/////////////////////////////////
//
// EEPROM storage location 5 ("magic marker") must be 0xCE or 0xCF for the mount to read any data.
// The lowest bit of location 5 indicates if extended flags are available in (21/22).
//
// Location 4 indicates what has been stored so far: 0000 0000
// ^^^^ ^^^^
// |||| ||||
// Roll angle offset (19/20) -----+||| ||||
// Pitch angle offset (17/18) ------+|| ||||
// Longitude (14/15) -------+| ||||
// Latitude (12/13) --------+ ||||
// Backlash steps (10/11) ----------+|||
// Speed factor (0/3) -----------+||
// DEC stepper motor steps per degree (8/9) ------------+|
// RA stepper motor steps per degree (6/7) -------------+
//
// Locations for HATime (1/2), Brightness (16)
//
// If Location 5 is 0xCF, then an extended 16-bit flag is stored in 21/22 and
// indicates the additional fields that have been stored: 0000 0000 0000 0000
// ^^^^ ^^^^ ^^^^ ^^^^
// |||| |||| ||||
// ALT Steps/deg, normalized to 256MS (70-73) -------------+||| |||| ||||
// AZ Steps/deg, normalized to 256MS (66-69) --------------+|| |||| ||||
// ALT position (62-65) ---------------+| |||| ||||
// AZ Position (58-61) ----------------+ |||| ||||
// Last flashed version (56-57) ------------------+||| ||||
// DEC Homing Offet (52-55) -------------------+|| ||||
// DEC Steps/deg, normalized to 256MS (48-51) --------------------+| ||||
// RA Steps/deg, normalized to 256MS (44-47) ---------------------+ ||||
// RA Homing Offet (40-43) -----------------------+|||
// UTC Offset (39) ------------------------+||
// DEC lower (31-34) and upper (35-38) limits -------------------------+|
// RA (23-26) and DEC (27-30) Parking offsets --------------------------+ ( ==== Obsolete V1.13.0 and beyond ==== )
//
/////////////////////////////////

enum ItemFlag
{
MAGIC_MARKER_VALUE
= 0xCE00, // Changed to 0xCxxx in V1.8.60 since we changed RA and DEC Steps to be 10x (previous settings ignored)
MAGIC_MARKER_MASK = 0xFE00, // If these bits are set to MAGIC_MARKER_VALUE, something has been written to the EEPROM

// The marker bits for the first 8 values stored in EEPROM.
RA_STEPS_FLAG = 0x0001,
DEC_STEPS_FLAG = 0x0002,
SPEED_FACTOR_FLAG = 0x0004,
BACKLASH_STEPS_FLAG = 0x0008,
LATITUDE_FLAG = 0x0010,
LONGITUDE_FLAG = 0x0020,
PITCH_OFFSET_FLAG = 0x0040,
ROLL_OFFSET_FLAG = 0x0080,
EXTENDED_FLAG = 0x0100,
FLAGS_MASK = 0x01FF // The bitwise OR of all preceding values
};

enum ExtendedItemFlag
{
// The marker bits for the extended values
PARKING_POS_MARKER_FLAG = 0x0001,
DEC_LIMIT_MARKER_FLAG = 0x0002,
UTC_OFFSET_MARKER_FLAG = 0x0004,
RA_HOMING_MARKER_FLAG = 0x0008,
RA_NORM_STEPS_MARKER_FLAG = 0x0010,
DEC_NORM_STEPS_MARKER_FLAG = 0x0020,
DEC_HOMING_MARKER_FLAG = 0x0040,
LAST_FLASHED_MARKER_FLAG = 0x0080,
AZ_POSITION_MARKER_FLAG = 0x0100,
ALT_POSITION_MARKER_FLAG = 0x0200,
AZ_NORM_STEPS_MARKER_FLAG = 0x0400,
ALT_NORM_STEPS_MARKER_FLAG = 0x0800,
};

// These are the offsets to each item stored in the EEPROM
enum ItemAddress
{
SPEED_FACTOR_LOW_ADDR = 0,
SPEED_FACTOR_HIGH_ADDR = 3, // Split as two discontinuous Uint8
HA_HOUR_ADDR = 1,
HA_MINUTE_ADDR = 2, // Both Uint8
FLAGS_ADDR = 4, // Uint8
MAGIC_MARKER_ADDR = 5, // Uint8
MAGIC_MARKER_AND_FLAGS_ADDR = 4, // Alias for Uint16 access
RA_STEPS_DEGREE_ADDR = 6,
_RA_STEPS_DEGREE_ADDR_1 = 7, // Int16
DEC_STEPS_DEGREE_ADDR = 8,
_DEC_STEPS_DEGREE_ADDR_1 = 9, // Int16
BACKLASH_STEPS_ADDR = 10,
_BACKLASH_STEPS_ADDR_1 = 11, // Int16
LATITUDE_ADDR = 12,
_LATITUDE_ADDR_1 = 13, // Int16
LONGITUDE_ADDR = 14,
_LONGITUDE_ADDR_1 = 15, // Int16
LCD_BRIGHTNESS_ADDR = 16, // Uint8
PITCH_OFFSET_ADDR = 17,
_PITCH_OFFSET_ADDR_1 = 18, // Uint16
ROLL_OFFSET_ADDR = 19,
_ROLL_OFFSET_ADDR_1 = 20, // Uint16
EXTENDED_FLAGS_ADDR = 21,
_EXTENDED_FLAGS_ADDR_1 = 22, // Uint16
RA_PARKING_POS_ADDR = 23,
_RA_PARKING_POS_ADDR_1,
_RA_PARKING_POS_ADDR_2,
_RA_PARKING_POS_ADDR_3, // Int32
DEC_PARKING_POS_ADDR = 27,
_DEC_PARKING_POS_ADDR_1,
_DEC_PARKING_POS_ADDR_2,
_DEC_PARKING_POS_ADDR_3, // Int32
DEC_LOWER_LIMIT_ADDR = 31,
_DEC_LOWER_LIMIT_ADDR_1,
_DEC_LOWER_LIMIT_ADDR_2,
_DEC_LOWER_LIMIT_ADDR_3, // Int32
DEC_UPPER_LIMIT_ADDR = 35,
_DEC_UPPER_LIMIT_ADDR_1,
_DEC_UPPER_LIMIT_ADDR_2,
_DEC_UPPER_LIMIT_ADDR_3, // Int32
UTC_OFFSET_ADDR = 39, // Int8
RA_HOMING_OFFSET_ADDR = 40,
_RA_HOMING_OFFSET_ADDR_1,
_RA_HOMING_OFFSET_ADDR_2,
_RA_HOMING_OFFSET_ADDR_3, // Int32
RA_NORM_STEPS_DEGREE_ADDR = 44,
_RA_NORM_STEPS_DEGREE_ADDR_1,
_RA_NORM_STEPS_DEGREE_ADDR_2,
_RA_NORM_STEPS_DEGREE_ADDR_3, // Int32
DEC_NORM_STEPS_DEGREE_ADDR = 48,
_DEC_NORM_STEPS_DEGREE_ADDR_1,
_DEC_NORM_STEPS_DEGREE_ADDR_2,
_DEC_NORM_STEPS_DEGREE_ADDR_3, // Int32
DEC_HOMING_OFFSET_ADDR = 52,
_DEC_HOMING_OFFSET_ADDR_1,
_DEC_HOMING_OFFSET_ADDR_2,
_DEC_HOMING_OFFSET_ADDR_3, // Int32
LAST_FLASHED_VERSION = 56,
_LAST_FLASHED_VERSION_1,
AZ_POSITION_ADDR = 58,
_AZ_POSITION_ADDR_1,
_AZ_POSITION_ADDR_2,
_AZ_POSITION_ADDR_3,
ALT_POSITION_ADDR = 62,
_ALT_POSITION_ADDR_1,
_ALT_POSITION_ADDR_2,
_ALT_POSITION_ADDR_3,
AZ_NORM_STEPS_DEGREE_ADDR = 66,
_AZ_NORM_STEPS_DEGREE_ADDR_1,
_AZ_NORM_STEPS_DEGREE_ADDR_2,
_AZ_NORM_STEPS_DEGREE_ADDR_3, // Int32
ALT_NORM_STEPS_DEGREE_ADDR = 70,
_ALT_NORM_STEPS_DEGREE_ADDR_1,
_ALT_NORM_STEPS_DEGREE_ADDR_2,
_ALT_NORM_STEPS_DEGREE_ADDR_3, // Int32
STORE_SIZE = 74
};
// The storage format itself (magic markers, flags, addresses) lives in
// hal::eeprom (src/hal/EepromLayout.hpp) so it can be tested without any
// Arduino dependencies.
using ItemFlag = hal::eeprom::ItemFlag;
using ExtendedItemFlag = hal::eeprom::ExtendedItemFlag;
using ItemAddress = hal::eeprom::ItemAddress;

// Helper functions
static void displayContents();
Expand Down
143 changes: 56 additions & 87 deletions src/Mount.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
#include "Mount.hpp"
#include "Sidereal.hpp"
#include "core/CalendarMath.hpp"
#include "core/CoordinateFormatter.hpp"
#include "core/CoordinateMath.hpp"
#include "libs/MappedDict/MappedDict.hpp"

PUSH_NO_WARNINGS
Expand Down Expand Up @@ -3709,64 +3711,64 @@ void Mount::calculateRAandDECSteppers(long &targetRASteps, long &targetDECSteps,
float const RALimitR = inNorthernHemisphere ? RA_LIMIT_RIGHT : RA_LIMIT_LEFT;
LOG(DEBUG_COORD_CALC, "[MOUNT]: CalcSteppersIn: Limits are : %f to %f", RALimitL, RALimitR);

core::SlewGeometry geometry;
geometry.moveRA = moveRA;
geometry.moveDEC = moveDEC;
geometry.homeTargetDeltaRA = homeTargetDeltaRA;
geometry.stepsPerSiderealHour = stepsPerSiderealHour;
geometry.stepsPerDECDegree = _stepsPerDECDegree;
geometry.zeroPosDEC = _zeroPosDEC;
geometry.raLimitL = RALimitL;
geometry.raLimitR = RALimitR;

const core::SlewResult result = core::calculateStepperPositions(geometry);

if (pSolutions != nullptr)
{
pSolutions[0] = long(-moveRA) * stepsPerSiderealHour;
pSolutions[1] = long(moveDEC) * _stepsPerDECDegree;
pSolutions[2] = long(-(moveRA - 12.0f)) * stepsPerSiderealHour;
pSolutions[3] = long(-moveDEC) * _stepsPerDECDegree;
pSolutions[4] = long(-(moveRA + 12.0f)) * stepsPerSiderealHour;
pSolutions[5] = long(-moveDEC) * _stepsPerDECDegree;
for (int i = 0; i < 6; i++)
{
pSolutions[i] = result.solutions[i];
}
}

LOG(DEBUG_COORD_CALC, "[MOUNT]: CalcSteppersIn: Solution 1: %f, %f", -moveRA, moveDEC);
LOG(DEBUG_COORD_CALC, "[MOUNT]: CalcSteppersIn: Solution 2: %f, %f", -(moveRA - 12.0f), -moveDEC);
LOG(DEBUG_COORD_CALC, "[MOUNT]: CalcSteppersIn: Solution 3: %f, %f", -(moveRA + 12.0f), -moveDEC);

// If we reach the limit in the positive direction ...
if (homeTargetDeltaRA > RALimitR)
{
LOG(DEBUG_COORD_CALC,
"[MOUNT]: CalcSteppersIn: Using Solution 2, since hometargetDeltaRA %f (RA:%f) is past max limit %f, inverting both axes",
homeTargetDeltaRA,
moveRA,
RALimitR);

// ... turn both RA and DEC axis around
moveRA -= 12.0f;
moveDEC = -moveDEC;
LOG(DEBUG_COORD_CALC, "[MOUNT]: CalcSteppersIn: Adjusted Target. RA: %f, DEC: %f", moveRA, moveDEC);
}
// If we reach the limit in the negative direction...
else if (homeTargetDeltaRA < RALimitL)
switch (result.selected)
{
LOG(DEBUG_COORD_CALC,
"[MOUNT]: CalcSteppersIn: Using solution 3 since homeTargetDeltaRA %f (RA:%f) is past min limit: %f, inverting both axes",
homeTargetDeltaRA,
moveRA,
RALimitL);
// ... turn both RA and DEC axis around

moveRA += 12.0f;
moveDEC = -moveDEC;
LOG(DEBUG_COORD_CALC, "[MOUNT]: CalcSteppersIn: Adjusted Target. RA: %f, DEC: %f", moveRA, moveDEC);
}
else
{
LOG(DEBUG_COORD_CALC,
"[MOUNT]: CalcSteppersIn: Using solution 1 since targetRA %f is in range. RA: %f, DEC: %f",
homeTargetDeltaRA,
moveRA,
moveDEC);
case core::SlewSolution::FlipUpper:
LOG(DEBUG_COORD_CALC,
"[MOUNT]: CalcSteppersIn: Using Solution 2, since hometargetDeltaRA %f (RA:%f) is past max limit %f, inverting both axes",
homeTargetDeltaRA,
moveRA,
RALimitR);
break;
case core::SlewSolution::FlipLower:
LOG(DEBUG_COORD_CALC,
"[MOUNT]: CalcSteppersIn: Using solution 3 since homeTargetDeltaRA %f (RA:%f) is past min limit: %f, inverting both axes",
homeTargetDeltaRA,
moveRA,
RALimitL);
break;
case core::SlewSolution::Direct:
LOG(DEBUG_COORD_CALC,
"[MOUNT]: CalcSteppersIn: Using solution 1 since targetRA %f is in range. RA: %f, DEC: %f",
homeTargetDeltaRA,
moveRA,
moveDEC);
break;
}

// 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);
// zeroPosDEC is the accumulated offset from zero (home) in degrees that one or more Sync commands have applied.
LOG(DEBUG_COORD_CALC, "[MOUNT]: CalcSteppersIn: Adjusted Target. RA: %f, DEC: %f", result.adjustedRA, result.adjustedDEC);
LOG(DEBUG_COORD_CALC,
"[MOUNT]: CalcSteppersIn: adjusted DEC by _zeroPosDEC: %f => DEC: %f",
_zeroPosDEC,
result.adjustedDEC - _zeroPosDEC);

targetRASteps = -moveRA * stepsPerSiderealHour;
targetDECSteps = moveDEC * _stepsPerDECDegree;
targetRASteps = result.targetRASteps;
targetDECSteps = result.targetDECSteps;
LOG(DEBUG_COORD_CALC, "[MOUNT]: CalcSteppersPost: ResultTarget Steps RA: %l, DEC: %l", targetRASteps, targetDECSteps);
}

Expand Down Expand Up @@ -4066,7 +4068,7 @@ String Mount::DECString(byte type, byte active)
dec = currentDEC();
}

dec.formatString(scratchBuffer, formatStringsDEC[type & FORMAT_STRING_MASK]);
core::formatDEC(scratchBuffer, dec, formatStringsDEC[type & FORMAT_STRING_MASK]);

if ((type & FORMAT_STRING_MASK) == LCDMENU_STRING)
{
Expand Down Expand Up @@ -4094,7 +4096,7 @@ String Mount::RAString(byte type, byte active)
ra = currentRA();
}

sprintf(scratchBuffer, formatStringsRA[type & FORMAT_STRING_MASK], ra.getHours(), ra.getMinutes(), ra.getSeconds());
core::formatRA(scratchBuffer, sizeof(scratchBuffer), ra, formatStringsRA[type & FORMAT_STRING_MASK]);
if ((type & FORMAT_STRING_MASK) == LCDMENU_STRING)
{
scratchBuffer[active * 4] = '>';
Expand Down Expand Up @@ -4136,46 +4138,13 @@ LocalDate Mount::getLocalDate()
LocalDate localDate = _localStartDate;
long secondsSinceSetDayEnd = ((millis() - _localStartTimeSetMillis) / 1000) - (86400 - _localStartTime.getTotalSeconds());

while (secondsSinceSetDayEnd >= 0)
{
localDate.day++;
secondsSinceSetDayEnd -= 86400;

int maxDays = 31;
switch (localDate.month)
{
case 2:
if (((localDate.year % 4 == 0) && (localDate.year % 100 != 0)) || (localDate.year % 400 == 0))
{
maxDays = 29;
}
else
{
maxDays = 28;
}
break;

case 4:
case 6:
case 9:
case 11:
maxDays = 30;
break;
}
// Number of day ends passed since the date was set; a partial day still counts as one.
const long daysElapsed = secondsSinceSetDayEnd >= 0 ? (secondsSinceSetDayEnd / 86400) + 1 : 0;

//calculate day overflow
if (localDate.day > maxDays)
{
localDate.day = 1;
localDate.month++;
}
//calculate year overflow
if (localDate.month > 12)
{
localDate.month = 1;
localDate.year++;
}
}
const core::CalendarDate rolled = core::addDays({localDate.year, localDate.month, localDate.day}, daysElapsed);
localDate.year = rolled.year;
localDate.month = rolled.month;
localDate.day = rolled.day;

return localDate;
}
Expand Down
Loading
Loading