diff --git a/.gitignore b/.gitignore index 552d3173..c32dd46c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,8 @@ .pio .vscode venv +.venv +__pycache__ .idea cmake-* CMakeLists.txt diff --git a/Changelog.md b/Changelog.md index 3fd484bc..9b1edde0 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,8 +1,17 @@ +**V1.13.18 - Updates** +- Final changes for OAE + +**V1.13.17 - Updates** +- Store AZ/ALT steps per degree and allow them to be set from Meade +- Added more output to the InfoDisplay during boot and fixed a bug in console mode. +- Fixed a bug that was causing the firmware to hang after a slew, if a :Q# command was issued (thanks to user c3n for tracking it down, pun intended). + **V1.13.16 - Updates** - Throttled InfoDisplay updates. Turned off on two axis slew, limited to 5Hz on one-axis slew. - Guide pulses are now ignored for DEC as well when at the limits. **V1.13.15 - Updates** +- Changes necessary for OAE, add OAE board - Check `INFO_DISPLAY_TYPE` builds in CI - Fix `INFO_DISPLAY_TYPE_I2C_SSD1306_128x64` for esp32 builds diff --git a/Configuration.hpp b/Configuration.hpp index 95585a71..a62e5c50 100644 --- a/Configuration.hpp +++ b/Configuration.hpp @@ -260,6 +260,8 @@ #include "boards/RAMPS/pins_RAMPS.hpp" #elif (BOARD == BOARD_ESP32_ESP32DEV) #include "boards/ESP32_ESP32DEV/pins_ESP32DEV.hpp" +#elif (BOARD == BOARD_OAE_V1) + #include "boards/ESP32_ESP32DEV/pins_OAE_V1.hpp" #elif (BOARD == BOARD_AVR_MKS_GEN_L_V1) #include "boards/AVR_MKS_GEN_L_V1/pins_MKS_GEN_L_V1.h" #elif (BOARD == BOARD_AVR_MKS_GEN_L_V2) diff --git a/ConfigurationValidation.hpp b/ConfigurationValidation.hpp index 292f5b9e..eb31aedb 100644 --- a/ConfigurationValidation.hpp +++ b/ConfigurationValidation.hpp @@ -89,7 +89,8 @@ #error AZ driver address for DRIVER_TYPE_TMC2209_UART not specified. #endif #endif - +#elif defined(OAE) +// Valid OAE configuration #else #error Configuration does not support AZ. Use at own risk. #endif @@ -110,6 +111,9 @@ #endif #endif +#elif defined(OAE) +// Valid + #else #warning Configuration does not support ALT. Use at own risk. #endif @@ -193,7 +197,7 @@ #warning Missing pin assignments for MS pins #endif #elif (DEC_DRIVER_TYPE == DRIVER_TYPE_TMC2209_UART) - #if !defined(DEC_STEP_PIN) || !defined(DEC_DIR_PIN) || !defined(DEC_EN_PIN) || !defined(DEC_DIAG_PIN) + #if !defined(DEC_STEP_PIN) || !defined(DEC_DIR_PIN) || !defined(DEC_EN_PIN) // Required pin assignments missing #error Missing pin assignments for configured DEC DRIVER_TYPE_TMC2209_UART driver #endif @@ -213,7 +217,7 @@ #warning Missing pin assignments for MS pins #endif #elif (RA_DRIVER_TYPE == DRIVER_TYPE_TMC2209_UART) - #if !defined(RA_STEP_PIN) || !defined(RA_DIR_PIN) || !defined(RA_EN_PIN) || !defined(RA_DIAG_PIN) + #if !defined(RA_STEP_PIN) || !defined(RA_DIR_PIN) || !defined(RA_EN_PIN) // Required pin assignments missing #error Missing pin assignments for configured RA DRIVER_TYPE_TMC2209_UART driver #endif @@ -225,12 +229,12 @@ #if (AZ_STEPPER_TYPE != STEPPER_TYPE_NONE) #if (AZ_DRIVER_TYPE == DRIVER_TYPE_A4988_GENERIC) || (AZ_DRIVER_TYPE == DRIVER_TYPE_TMC2209_STANDALONE) - #if !defined(AZ_STEP_PIN) || !defined(AZ_DIR_PIN) || !defined(AZ_EN_PIN) || !defined(AZ_DIAG_PIN) + #if !defined(AZ_STEP_PIN) || !defined(AZ_DIR_PIN) || !defined(AZ_EN_PIN) // Required pin assignments missing #error Missing pin assignments for configured AZ DRIVER_TYPE_A4988_GENERIC or DRIVER_TYPE_TMC2209_STANDALONE driver #endif #elif (AZ_DRIVER_TYPE == DRIVER_TYPE_TMC2209_UART) - #if !defined(AZ_STEP_PIN) || !defined(AZ_DIR_PIN) || !defined(AZ_EN_PIN) || !defined(AZ_DIAG_PIN) + #if !defined(AZ_STEP_PIN) || !defined(AZ_DIR_PIN) || !defined(AZ_EN_PIN) // Required pin assignments missing (ATmega uses SoftwareSerial for this driver) #error Missing pin assignments for configured AZ DRIVER_TYPE_TMC2209_UART driver #endif @@ -243,12 +247,12 @@ #if (ALT_STEPPER_TYPE != STEPPER_TYPE_NONE) #if (ALT_DRIVER_TYPE == DRIVER_TYPE_A4988_GENERIC) || (ALT_DRIVER_TYPE == DRIVER_TYPE_TMC2209_STANDALONE) - #if !defined(ALT_STEP_PIN) || !defined(ALT_DIR_PIN) || !defined(ALT_EN_PIN) || !defined(ALT_DIAG_PIN) + #if !defined(ALT_STEP_PIN) || !defined(ALT_DIR_PIN) || !defined(ALT_EN_PIN) // Required pin assignments missing #error Missing pin assignments for configured AZ DRIVER_TYPE_A4988_GENERIC or DRIVER_TYPE_TMC2209_STANDALONE driver #endif #elif (ALT_DRIVER_TYPE == DRIVER_TYPE_TMC2209_UART) - #if !defined(ALT_STEP_PIN) || !defined(ALT_DIR_PIN) || !defined(ALT_EN_PIN) || !defined(ALT_DIAG_PIN) + #if !defined(ALT_STEP_PIN) || !defined(ALT_DIR_PIN) || !defined(ALT_EN_PIN) // Required pin assignments missing (ATmega uses SoftwareSerial for this driver) #error Missing pin assignments for configured ALT DRIVER_TYPE_TMC2209_UART driver #endif diff --git a/Configuration_adv.hpp b/Configuration_adv.hpp index 3359a6b4..bec77a73 100644 --- a/Configuration_adv.hpp +++ b/Configuration_adv.hpp @@ -22,6 +22,15 @@ #define BUFFER_LOGS false #endif +#ifndef OAM + #ifndef OAE + #define OAT "OAT" + #endif +#endif +#if defined(OAE) && defined(OAM) + #error "OAE and OAM cannot be defined at the same time" +#endif + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // //////// // MOTOR & DRIVER SETTINGS //////// @@ -232,14 +241,14 @@ #endif #ifndef DEC_LIMIT_UP - #ifdef OAM + #if defined(OAM) || defined(OAE) #define DEC_LIMIT_UP 135.0f #else #define DEC_LIMIT_UP 0.0f #endif #endif #ifndef DEC_LIMIT_DOWN - #ifdef OAM + #if defined(OAM) || defined(OAE) #define DEC_LIMIT_DOWN 135.0f #else #define DEC_LIMIT_DOWN 0.0f @@ -332,16 +341,34 @@ #define AZ_STEPPER_ACCELERATION (100 * AZ_MICROSTEPPING) #endif - // the Circumference of the AZ rotation. 808mm dia. + // the Circumference of the AZ rotation. 808mm dia (OAT) #ifndef AZ_CIRCUMFERENCE - #define AZ_CIRCUMFERENCE 2538.4f + #ifdef OAE + // Roughly from the joint to the rod placement is 70mm + #define AZ_CIRCUMFERENCE 56.0f * 2 * PI + #ifndef AZ_ROD_PITCH + #define AZ_ROD_PITCH 0.5 + #endif + #define AZIMUTH_STEPS_PER_REV \ + +(AZ_CORRECTION_FACTOR * (AZ_CIRCUMFERENCE / AZ_ROD_PITCH) * AZ_STEPPER_SPR * AZ_MICROSTEPPING) // Actually u-steps/rev + #else + #define AZ_CIRCUMFERENCE 2538.4f + #endif #endif + + #ifndef OAE + #define AZ_WORMGEAR_RATIO 1.0f + #endif + #ifndef AZIMUTH_STEPS_PER_REV #define AZIMUTH_STEPS_PER_REV \ (AZ_CORRECTION_FACTOR * (AZ_CIRCUMFERENCE / (AZ_PULLEY_TEETH * GT2_BELT_PITCH)) * AZ_STEPPER_SPR \ * AZ_MICROSTEPPING) // Actually u-steps/rev #endif - #define AZIMUTH_STEPS_PER_ARC_MINUTE (AZIMUTH_STEPS_PER_REV / (360 * 60.0f)) // Used to determine move distance in steps + + #ifndef AZIMUTH_STEPS_PER_ARC_MINUTE + #define AZIMUTH_STEPS_PER_ARC_MINUTE (AZIMUTH_STEPS_PER_REV / (360 * 60.0f)) // Used to determine move distance in steps + #endif // AZ TMC2209 UART settings // These settings work only with TMC2209 in UART connection (single wire to TX) @@ -373,7 +400,7 @@ #define ALT_MICROSTEPPING 4 #endif #ifndef ALT_STEPPER_SPR - #define ALT_STEPPER_SPR 400 // NEMA 0.9° = 400 | NEMA 1.8° = 200 + #define ALT_STEPPER_SPR (400.0) // NEMA 0.9° = 400 | NEMA 1.8° = 200 #endif #ifndef ALT_STEPPER_SPEED #define ALT_STEPPER_SPEED 2000 @@ -398,19 +425,30 @@ (ALT_CORRECTION_FACTOR * (ALT_CIRCUMFERENCE / ALT_ROD_PITCH) * ALT_STEPPER_SPR * ALT_MICROSTEPPING) // Actually u-steps/rev #else - // the Circumference of the AZ rotation. 770mm dia. - #define ALT_CIRCUMFERENCE 2419.0f - #if AUTOPA_VERSION == 1 - // the ratio of the ALT gearbox for AutoPA V1 (40:3) - #define ALT_WORMGEAR_RATIO (40.0f / 3.0f) - #else - // the ratio of the ALT gearbox for AutoPA V2 (40:1) - #define ALT_WORMGEAR_RATIO (40.0f) - #endif - #ifndef ALTITUDE_STEPS_PER_REV + #ifdef OAE + #ifndef ALT_ROD_PITCH + #define ALT_ROD_PITCH 1.25 // mm/rev + #endif + // the Circumference of the ALT rotation. Roughly 146mm radius. + #define ALT_CIRCUMFERENCE 130.0f * 2 * PI #define ALTITUDE_STEPS_PER_REV \ - (ALT_CORRECTION_FACTOR * (ALT_CIRCUMFERENCE / (ALT_PULLEY_TEETH * GT2_BELT_PITCH)) * ALT_STEPPER_SPR * ALT_MICROSTEPPING \ - * ALT_WORMGEAR_RATIO) // Actually u-steps/rev + +(ALT_CORRECTION_FACTOR * (ALT_CIRCUMFERENCE / ALT_ROD_PITCH) * ALT_STEPPER_SPR \ + * ALT_MICROSTEPPING) // Actually u-steps/rev + #else + // the Circumference of the AZ rotation. 770mm dia. + #define ALT_CIRCUMFERENCE 2419.0f + #if AUTOPA_VERSION == 1 + // the ratio of the ALT gearbox for AutoPA V1 (40:3) + #define ALT_WORMGEAR_RATIO (40.0f / 3.0f) + #else + // the ratio of the ALT gearbox for AutoPA V2 (40:1) + #define ALT_WORMGEAR_RATIO (40.0f) + #endif + #ifndef ALTITUDE_STEPS_PER_REV + #define ALTITUDE_STEPS_PER_REV \ + (ALT_CORRECTION_FACTOR * (ALT_CIRCUMFERENCE / (ALT_PULLEY_TEETH * GT2_BELT_PITCH)) * ALT_STEPPER_SPR \ + * ALT_MICROSTEPPING * ALT_WORMGEAR_RATIO) // Actually u-steps/rev + #endif #endif #endif @@ -620,23 +658,6 @@ // //////// //////////////////////////////////////////// -// Stepper drivers -#if (RA_DRIVER_TYPE == DRIVER_TYPE_TMC2209_UART) - #if defined(ESP32) - #define RA_SERIAL_PORT Serial2 // Can be shared with DEC_SERIAL_PORT - #elif defined(__AVR_ATmega2560__) - // Uses SoftwareSerial - #endif -#endif - -#if (DEC_DRIVER_TYPE == DRIVER_TYPE_TMC2209_UART) - #if defined(ESP32) - #define DEC_SERIAL_PORT Serial2 // Can be shared with RA_SERIAL_PORT - #elif defined(__AVR_ATmega2560__) - // Uses SoftwareSerial - #endif -#endif - // Focuser #if (FOCUS_DRIVER_TYPE == DRIVER_TYPE_TMC2209_UART) #if defined(ESP32) diff --git a/Constants.hpp b/Constants.hpp index 30dc104c..f4a9ddd0 100644 --- a/Constants.hpp +++ b/Constants.hpp @@ -18,6 +18,7 @@ // ESP32 based boards #define BOARD_ESP32_ESP32DEV 1001 +#define BOARD_OAE_V1 1002 /** * Supported keypad/display types. Use one of these values for DISPLAY_TYPE configuration matching your used display and keypad. diff --git a/LocalConfiguration.hpp b/LocalConfiguration.hpp index 0c816418..14a00510 100644 --- a/LocalConfiguration.hpp +++ b/LocalConfiguration.hpp @@ -16,6 +16,8 @@ #include "Configuration_local_mksgenlv1.hpp" #elif BOARD == BOARD_ESP32_ESP32DEV && __has_include("Configuration_local_esp32dev.hpp") #include "Configuration_local_esp32dev.hpp" +#elif BOARD == BOARD_OAE_V1 && __has_include("Configuration_local_oae.hpp") + #include "Configuration_local_oae.hpp" #elif __has_include("Configuration_local.hpp") #include "Configuration_local.hpp" #endif \ No newline at end of file diff --git a/Version.h b/Version.h index e069b894..3fa9e59d 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.13.16" +#define VERSION "V1.13.18" diff --git a/boards/ESP32_ESP32DEV/pins_OAE_V1.hpp b/boards/ESP32_ESP32DEV/pins_OAE_V1.hpp new file mode 100644 index 00000000..c27116b3 --- /dev/null +++ b/boards/ESP32_ESP32DEV/pins_OAE_V1.hpp @@ -0,0 +1,128 @@ +/** + * @brief a pins configuration file for an OAE board v1.0 + */ + +#pragma once + +// DRIVER_TYPE_TMC2209_UART requires 4 digital pins in Arduino pin numbering +#ifndef RA_STEP_PIN + #define RA_STEP_PIN 14 // STEP +#endif +#ifndef RA_DIR_PIN + #define RA_DIR_PIN 26 // DIR +#endif +#ifndef RA_EN_PIN + #define RA_EN_PIN 27 // Enable +#endif + +// DRIVER_TYPE_TMC2209_UART HardwareSerial port, can be shared across all drivers +#ifndef RA_SERIAL_PORT + #define RA_SERIAL_PORT Serial1 +#endif +#ifndef RA_TX_PIN + #define RA_TX_PIN 17 +#endif +#ifndef RA_RX_PIN + #define RA_RX_PIN 16 +#endif +#ifndef RA_DRIVER_ADDRESS + #define RA_DRIVER_ADDRESS 0b00 // Set by MS1/MS2. LOW/LOW in this case +#endif +// DRIVER_TYPE_TMC2209_UART requires 4 digital pins in Arduino pin numbering +#ifndef DEC_STEP_PIN + #define DEC_STEP_PIN 25 // STEP +#endif +#ifndef DEC_DIR_PIN + #define DEC_DIR_PIN 5 // DIR +#endif +#ifndef DEC_EN_PIN + #define DEC_EN_PIN 33 // Enable +#endif + +// DRIVER_TYPE_TMC2209_UART HardwareSerial port, can be shared across all drivers +#ifndef DEC_SERIAL_PORT + #define DEC_SERIAL_PORT Serial1 // SoftwareSerial TX port +#endif +#ifndef DEC_TX_PIN + #define DEC_TX_PIN 17 +#endif +#ifndef DEC_RX_PIN + #define DEC_RX_PIN 16 +#endif +#ifndef DEC_DRIVER_ADDRESS + #define DEC_DRIVER_ADDRESS 0b01 // Set by MS1/MS2 (MS1 HIGH, MS2 LOW) +#endif + +#define SW_SERIAL_UART 0 + +#ifndef ALT_STEP_PIN + #define ALT_STEP_PIN 13 // STEP +#endif +#ifndef ALT_DIR_PIN + #define ALT_DIR_PIN 23 // DIR +#endif +#ifndef ALT_EN_PIN + #define ALT_EN_PIN 4 // Enable +#endif + +#ifndef AZ_STEP_PIN + #define AZ_STEP_PIN 18 // STEP +#endif +#ifndef AZ_DIR_PIN + #define AZ_DIR_PIN 19 // DIR +#endif +#ifndef AZ_EN_PIN + #define AZ_EN_PIN 32 // Enable +#endif + +// DISPLAY_TYPE_LCD_JOY_I2C_SSD1306 requires 3 analog inputs in Arduino pin numbering +#ifndef LCD_KEY_SENSE_X_PIN +//#define LCD_KEY_SENSE_X_PIN 34 +#endif +#ifndef LCD_KEY_SENSE_Y_PIN +//#define LCD_KEY_SENSE_Y_PIN 39 +#endif +#ifndef LCD_KEY_SENSE_PUSH_PIN +//#define LCD_KEY_SENSE_PUSH_PIN 36 +#endif + +//Serial port for external debugging +#if DEBUG_SEPARATE_SERIAL == 1 + #ifndef DEBUG_SERIAL_PORT + #error "There is no default separate serial port for ESP32, please define DEBUG_SERIAL_PORT" + #endif +#else + #ifndef DEBUG_SERIAL_PORT + #define DEBUG_SERIAL_PORT Serial2 + #endif +#endif + +// Defines for OAE /////////////////////// + +#ifndef RA_WHEEL_CIRCUMFERENCE + #define RA_WHEEL_CIRCUMFERENCE 704.97f +#endif +#ifndef DEC_TRANSMISSION + #define DEC_TRANSMISSION (DEC_WHEEL_CIRCUMFERENCE / (DEC_PULLEY_TEETH * 1.0)) +#endif +#ifndef RA_LIMIT_LEFT + #define RA_LIMIT_LEFT 5.0f +#endif +#ifndef RA_LIMIT_RIGHT + #define RA_LIMIT_RIGHT 7.0f +#endif +#ifndef RA_TRACKING_LIMIT + #define RA_TRACKING_LIMIT 6.75f +#endif +#ifndef DEC_WHEEL_CIRCUMFERENCE + #define DEC_WHEEL_CIRCUMFERENCE 1.0f +#endif +#ifndef RA_STEPPER_SPR + #define RA_STEPPER_SPR (400 * 9) // change to (200 * 9) for 1.8° stepper +#endif +#ifndef DEC_STEPPER_SPR + #define DEC_STEPPER_SPR (200 * 50 * 4.5f) // change to (200 * 9) for 1.8° stepper +#endif +#ifndef DEC_PULLEY_TEETH + #define DEC_PULLEY_TEETH 1 +#endif diff --git a/platformio.ini b/platformio.ini index 9f81e979..32102b8c 100644 --- a/platformio.ini +++ b/platformio.ini @@ -52,7 +52,6 @@ src_build_flags = -Wno-unused-parameter ; -Wold-style-cast -Wlogical-op - -Wuseless-cast ; Wdouble-promotion can't be enabled until GCC bug 55578 is fixed, since floats are ; implicitly converted to doubles when passed to a variadic function (i.e. a printf-like). ; Else we could disable Wdouble-promotion only for our logv function inside of the LOG macro @@ -83,6 +82,9 @@ upload_protocol = wiring build_flags = ${env.build_flags} -D BOARD=BOARD_AVR_RAMPS +src_build_flags = + ${env.src_build_flags} + -Wuseless-cast debug_tool = avr-stub debug_build_flags = ${env.debug_build_flags} @@ -128,6 +130,12 @@ lib_deps = ${common.lib_deps} WiFi +[env:oaeboardv1] +extends = env:esp32 +build_flags = + ${env.build_flags} + -D BOARD=BOARD_OAE_V1 -D ESP32BOARD + [env:native] platform = native test_ignore = test_embedded diff --git a/src/EPROMStore.cpp b/src/EPROMStore.cpp index 97b92e90..5784c177 100644 --- a/src/EPROMStore.cpp +++ b/src/EPROMStore.cpp @@ -141,6 +141,8 @@ void EEPROMStore::displayContents() LOG(DEBUG_INFO, "[EEPROM]: Stored RA Homing Offset: %l", getRAHomingOffset()); LOG(DEBUG_INFO, "[EEPROM]: Stored AZ Position: %l", getAZPosition()); LOG(DEBUG_INFO, "[EEPROM]: Stored ALT Position: %l", getALTPosition()); + LOG(DEBUG_INFO, "[EEPROM]: Stored AZ Steps per Degree: %f", getAZStepsPerDegree()); + LOG(DEBUG_INFO, "[EEPROM]: Stored ALT Steps per Degree: %f", getALTStepsPerDegree()); LOG(DEBUG_INFO, "[EEPROM]: Stored DEC Homing Offset : %l", getDECHomingOffset()); LOG(DEBUG_INFO, "[EEPROM]: Stored DEC Lower Limit: %l", getDECLowerLimit()); LOG(DEBUG_INFO, "[EEPROM]: Stored DEC Upper Limit: %l", getDECUpperLimit()); @@ -463,6 +465,100 @@ void EEPROMStore::storeDECStepsPerDegree(float decStepsPerDegree) commit(); // Complete the transaction } +// Return the AZ steps per degree (actually microsteps per degree). +// If it is not present then the default uncalibrated AZ_STEPS_PER_DEGREE value is returned. +float EEPROMStore::getAZStepsPerDegree() +{ +#if AZ_STEPPER_TYPE != STEPPER_TYPE_NONE + float azStepsPerDegree(AZIMUTH_STEPS_PER_REV / 360); // Default value +#else + float azStepsPerDegree(1); // Default value +#endif + + if (isPresentExtended(AZ_NORM_STEPS_MARKER_FLAG)) + { +#if (AZ_STEPPER_TYPE != STEPPER_TYPE_NONE) + // Latest version stores 100x steps/deg for 256 MS + const float factor = SteppingStorageNormalized / AZ_MICROSTEPPING; + azStepsPerDegree = readInt32(AZ_NORM_STEPS_DEGREE_ADDR) / factor; + LOG(DEBUG_EEPROM, "[EEPROM]: AZ Normed Marker Present! AZ steps/deg is %f", azStepsPerDegree); +#else + LOG(DEBUG_EEPROM, "[EEPROM]: AZ marker present but AZ axis disabled; ignoring stored value"); +#endif + } + else + { + LOG(DEBUG_EEPROM, "[EEPROM]: No stored value for AZ steps"); + } + + return azStepsPerDegree; // microsteps per degree +} + +// Store the AZ steps per degree (actually microsteps per degree). +void EEPROMStore::storeAZStepsPerDegree(float azStepsPerDegree) +{ + // Store steps as 100x steps/deg at 256 MS. +#if (AZ_STEPPER_TYPE != STEPPER_TYPE_NONE) + const float factor = SteppingStorageNormalized / AZ_MICROSTEPPING; + int32_t val = azStepsPerDegree * factor; + LOG(DEBUG_EEPROM, "[EEPROM]: Storing AZ steps to %l (%f)", val, azStepsPerDegree); + + updateInt32(AZ_NORM_STEPS_DEGREE_ADDR, val); + updateFlagsExtended(AZ_NORM_STEPS_MARKER_FLAG); + commit(); // Complete the transaction +#else + LOG(DEBUG_EEPROM, "[EEPROM]: Skipping AZ steps store; AZ axis disabled"); + (void) azStepsPerDegree; +#endif +} + +// Return the ALT steps per degree (actually microsteps per degree). +// If it is not present then the default uncalibrated ALT_STEPS_PER_DEGREE value is returned. +float EEPROMStore::getALTStepsPerDegree() +{ +#if (ALT_STEPPER_TYPE != STEPPER_TYPE_NONE) + float azStepsPerDegree(ALTITUDE_STEPS_PER_REV / 360); // Default value +#else + float azStepsPerDegree(1); // Default value +#endif + + if (isPresentExtended(ALT_NORM_STEPS_MARKER_FLAG)) + { +#if (ALT_STEPPER_TYPE != STEPPER_TYPE_NONE) + // Latest version stores 100x steps/deg for 256 MS + const float factor = SteppingStorageNormalized / ALT_MICROSTEPPING; + azStepsPerDegree = readInt32(ALT_NORM_STEPS_DEGREE_ADDR) / factor; + LOG(DEBUG_EEPROM, "[EEPROM]: ALT Normed Marker Present! ALT steps/deg is %f", azStepsPerDegree); +#else + LOG(DEBUG_EEPROM, "[EEPROM]: ALT marker present but ALT axis disabled; ignoring stored value"); +#endif + } + else + { + LOG(DEBUG_EEPROM, "[EEPROM]: No stored value for ALT steps"); + } + + return azStepsPerDegree; // microsteps per degree +} + +// Store the ALT steps per degree (actually microsteps per degree). +void EEPROMStore::storeALTStepsPerDegree(float azStepsPerDegree) +{ + // Store steps as 100x steps/deg at 256 MS. +#if (ALT_STEPPER_TYPE != STEPPER_TYPE_NONE) + const float factor = SteppingStorageNormalized / ALT_MICROSTEPPING; + int32_t val = azStepsPerDegree * factor; + LOG(DEBUG_EEPROM, "[EEPROM]: Storing ALT steps to %l (%f)", val, azStepsPerDegree); + + updateInt32(ALT_NORM_STEPS_DEGREE_ADDR, val); + updateFlagsExtended(ALT_NORM_STEPS_MARKER_FLAG); + commit(); // Complete the transaction +#else + LOG(DEBUG_EEPROM, "[EEPROM]: Skipping ALT steps store; ALT axis disabled"); + (void) azStepsPerDegree; +#endif +} + int16_t EEPROMStore::getLastFlashedVersion() { if (isPresentExtended(LAST_FLASHED_MARKER_FLAG)) diff --git a/src/EPROMStore.hpp b/src/EPROMStore.hpp index dd943350..506e987c 100644 --- a/src/EPROMStore.hpp +++ b/src/EPROMStore.hpp @@ -29,6 +29,12 @@ class EEPROMStore static float getDECStepsPerDegree(); static void storeDECStepsPerDegree(float decStepsPerDegree); + static float getAZStepsPerDegree(); + static void storeAZStepsPerDegree(float azStepsPerDegree); + + static float getALTStepsPerDegree(); + static void storeALTStepsPerDegree(float altStepsPerDegree); + static float getSpeedFactor(); static void storeSpeedFactor(float speed); @@ -91,13 +97,15 @@ class EEPROMStore // 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) --------------------+ |||| + // 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 -------------------------+| @@ -137,6 +145,8 @@ class EEPROMStore 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 @@ -209,7 +219,15 @@ class EEPROMStore _ALT_POSITION_ADDR_1, _ALT_POSITION_ADDR_2, _ALT_POSITION_ADDR_3, - STORE_SIZE = 66 + 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 }; // Helper functions diff --git a/src/InfoDisplayRender.hpp b/src/InfoDisplayRender.hpp index ed8cf2a5..f691222e 100644 --- a/src/InfoDisplayRender.hpp +++ b/src/InfoDisplayRender.hpp @@ -1,17 +1,115 @@ #pragma once #include - -class Mount; +#include "OLEDDisplay.h" +#include "fonts128x64.h" +#include "../Configuration.hpp" // Base class to implement a class InfoDisplayRender { + const static int MAX_CONSOLE_LINES = 16; // Maximum number of lines of text to buffer in console mode + const static int DISPLAY_CONSOLE_LINES = 6; // Number of lines to display in console mode + + protected: + OLEDDisplay *_display; + long _lastNumCmds; + bool _consoleMode; + String _textList[MAX_CONSOLE_LINES]; + int _curLine; + public: - InfoDisplayRender() {}; + InfoDisplayRender() + { + _consoleMode = true; + _curLine = 0; + for (int i = 0; i < MAX_CONSOLE_LINES; i++) + { + _textList[i] = ""; + } + }; + + virtual void init() + { + _display->init(); + _display->clear(); + _display->displayOn(); + }; + + OLEDDisplay *getDisplayDevice() + { + return _display; + }; + + virtual void renderScreen(void *context) = 0; + + // Build the display from the mount + virtual void render(void (*drawContentFunction)(void *)) + { + _display->clear(); + if (drawContentFunction) + { + drawContentFunction(this); + } + + if (_consoleMode) + { + // Console lines + int y = 21; + _display->setFont(Bitmap3x5); + // Start 6 lines back from current line and display next 6 lines + int indexStart = max(0, _curLine - DISPLAY_CONSOLE_LINES); + int indexEnd = min(indexStart + DISPLAY_CONSOLE_LINES, MAX_CONSOLE_LINES); + for (int i = indexStart; i < indexEnd; i++) + { + if (_textList[i].length() != 0) + { + String text = _textList[i]; + text.toUpperCase(); + _display->drawString(0, y, text); + } + y += 7; + } + } + else + { + } + + _display->display(); + }; + + virtual void setConsoleMode(bool active) + { + _consoleMode = active; + }; + + virtual int addConsoleText(const String &text, bool tinyFont = true) + { + int returnIndex = 0; + if (_curLine > MAX_CONSOLE_LINES - 1) + { + for (int i = 0; i < MAX_CONSOLE_LINES - 1; i++) + { + _textList[i] = _textList[i + 1]; + } + _curLine = MAX_CONSOLE_LINES - 1; + _textList[_curLine] = text; + returnIndex = _curLine; + } + else + { + returnIndex = _curLine; + _textList[_curLine++] = text; + } + render(nullptr); + return returnIndex; + }; - virtual void init() {}; - virtual void render(Mount *mount) {}; - virtual void setConsoleMode(bool active) {}; - virtual int addConsoleText(String text, bool tinyFont = true); - virtual void updateConsoleText(int line, String newText); + virtual void updateConsoleText(int line, String text) + { + if (line >= 0 && line < MAX_CONSOLE_LINES) + { + _textList[line] = text; + } + render(nullptr); + }; }; diff --git a/src/MeadeCommandProcessor.cpp b/src/MeadeCommandProcessor.cpp index e06b984e..de66f0f3 100644 --- a/src/MeadeCommandProcessor.cpp +++ b/src/MeadeCommandProcessor.cpp @@ -501,7 +501,7 @@ bool gpsAqcuisitionComplete(int &indicator); // defined in c72_menuHA_GPS.hpp // Information: // This starts moving one of the steppers by the given amount of steps and returns immediately. Steps can be positive or negative. // Parameters: -// "x" is the stepper to move (r for RA, d for DEC, f for FOC, z for AZ, t for ALT) +// "x" is the stepper to move (r for RA, d for DEC, f for FOC, z for AZ, l for ALT) // "nnnn" is the number of steps // Returns: // "1" if successfully scheduled, else "0" @@ -805,6 +805,24 @@ bool gpsAqcuisitionComplete(int &indicator); // defined in c72_menuHA_GPS.hpp // Returns: // "float#" // +// :XGZ# +// Description: +// Get AZ steps +// Information: +// Get the number of steps the AZ stepper motor needs to take to rotate AZ by one degree +// Returns: +// "float#" if AZ motor is present +// "0#" if AZ is not configured +// +// :XGA# +// Description: +// Get ALT steps +// Information: +// Get the number of steps the ALT stepper motor needs to take to rotate ALT by one degree +// Returns: +// "float#" if ALT motor is present +// "0#" if ALT is not configured +// // :XGDLx# // Description: // Get DEC limits @@ -991,6 +1009,26 @@ bool gpsAqcuisitionComplete(int &indicator); // defined in c72_menuHA_GPS.hpp // Returns: // nothing // +// :XSAn.n# +// Description: +// Set AZ steps +// Information: +// Set the number of steps the AZ stepper motor needs to take to rotate by one degree. +// Parameters: +// "n.n" is the number of steps (only one decimal point is supported, must be positive) +// Returns: +// nothing +// +// :XSLn.n# +// Description: +// Set ALT steps +// Information: +// Set the number of steps the ALT stepper motor needs to take to rotate by one degree. +// Parameters: +// "n.n" is the number of steps (only one decimal point is supported, must be positive) +// Returns: +// nothing +// // :XSDLUnnnnn# // Description: // Set DEC upper limit @@ -1235,6 +1273,8 @@ String MeadeCommandProcessor::handleMeadeGetInfo(String inCmd) { #ifdef OAM return "OpenAstroMount#"; +#elif defined(OAE) + return "OpenAstroExplorer#"; #else return "OpenAstroTracker#"; #endif @@ -1818,6 +1858,14 @@ String MeadeCommandProcessor::handleMeadeExtraCommands(String inCmd) { return String(_mount->getBacklashCorrection()) + "#"; } + else if ((inCmd[1] == 'A') && (inCmd.length() == 2)) // :XGA# + { + return String(_mount->getStepsPerDegree(ALTITUDE_STEPS), 1) + "#"; + } + else if ((inCmd[1] == 'Z') && (inCmd.length() == 2)) // :XGZ# + { + return String(_mount->getStepsPerDegree(AZIMUTH_STEPS), 1) + "#"; + } else if ((inCmd[1] == 'A') && (inCmd.length() > 2) && (inCmd[2] == 'H')) // :XGAH# { return _mount->getAutoHomingStates() + "#"; @@ -1911,6 +1959,14 @@ String MeadeCommandProcessor::handleMeadeExtraCommands(String inCmd) { _mount->setStepsPerDegree(RA_STEPS, inCmd.substring(2).toFloat()); } + else if (inCmd[1] == 'A') // :XSA# + { + _mount->setStepsPerDegree(AZIMUTH_STEPS, inCmd.substring(2).toFloat()); + } + else if (inCmd[1] == 'L') // :XSL# + { + _mount->setStepsPerDegree(ALTITUDE_STEPS, inCmd.substring(2).toFloat()); + } else if (inCmd[1] == 'D') // :XSD { if ((inCmd.length() > 2) && (inCmd[2] == 'L')) // :XSDL @@ -2069,7 +2125,10 @@ String MeadeCommandProcessor::handleMeadeQuit(String inCmd) if (inCmd.length() == 0) { _mount->stopSlewing(ALL_DIRECTIONS | TRACKING); - _mount->waitUntilStopped(ALL_DIRECTIONS); + _mount->stopSlewing(AZIMUTH_STEPS); + _mount->stopSlewing(ALTITUDE_STEPS); + _mount->stopSlewing(FOCUS_STEPS); + _mount->waitUntilAllStopped(); return ""; } diff --git a/src/Mount.cpp b/src/Mount.cpp index 2e4180b5..e41eb05a 100644 --- a/src/Mount.cpp +++ b/src/Mount.cpp @@ -78,6 +78,7 @@ Mount::Mount(LcdMenu *lcdMenu) { _commandReceived = 0; + #if (INFO_DISPLAY_TYPE != INFO_DISPLAY_TYPE_NONE) _lastInfoUpdate = millis(); #endif @@ -193,6 +194,15 @@ void Mount::readPersistentData() _stepsPerDECDegree = EEPROMStore::getDECStepsPerDegree(); LOG(DEBUG_INFO, "[MOUNT]: EEPROM: DEC steps/deg is %f", _stepsPerDECDegree); +#if (AZ_STEPPER_TYPE != STEPPER_TYPE_NONE) + _stepsPerAZDegree = EEPROMStore::getAZStepsPerDegree(); + LOG(DEBUG_INFO, "[MOUNT]: EEPROM: AZ steps/deg is %f", _stepsPerAZDegree); +#endif + +#if (ALT_STEPPER_TYPE != STEPPER_TYPE_NONE) + _stepsPerALTDegree = EEPROMStore::getALTStepsPerDegree(); + LOG(DEBUG_INFO, "[MOUNT]: EEPROM: ALT steps/deg is %f", _stepsPerALTDegree); +#endif float speed = EEPROMStore::getSpeedFactor(); LOG(DEBUG_INFO, "[MOUNT]: EEPROM: Speed factor is %f", speed); setSpeedCalibration(speed, false); @@ -486,6 +496,8 @@ void Mount::configureRAdriver(Stream *serial, float rsense, byte driveraddress, #endif LOG(DEBUG_STEPPERS, "[MOUNT]: Requested RA motor rms_current: %d mA", rmscurrent); _driverRA->rms_current(rmscurrent, 1.0f); //holdMultiplier = 1 to set ihold = irun + _driverRA->pdn_disable(1); + _driverRA->ihold(31); _driverRA->toff(1); _driverRA->en_spreadCycle(RA_UART_STEALTH_MODE == 0); _driverRA->blank_time(24); @@ -569,6 +581,10 @@ void Mount::configureDECdriver(Stream *serial, float rsense, byte driveraddress, #endif LOG(DEBUG_STEPPERS, "[MOUNT]: Requested DEC motor rms_current: %d mA", rmscurrent); _driverDEC->rms_current(rmscurrent, 1.0f); //holdMultiplier = 1 to set ihold = irun + _driverDEC->pdn_disable(1); + _driverDEC->ihold(31); + _driverDEC->iholddelay(15); + _driverDEC->TPOWERDOWN(255); _driverDEC->toff(1); _driverDEC->en_spreadCycle(DEC_UART_STEALTH_MODE == 0); _driverDEC->blank_time(24); @@ -989,6 +1005,22 @@ float Mount::getStepsPerDegree(StepperAxis which) { return _stepsPerDECDegree; // u-steps/degree } + if (which == AZIMUTH_STEPS) + { +#if (AZ_STEPPER_TYPE != STEPPER_TYPE_NONE) + return _stepsPerAZDegree; // u-steps/degree +#else + return 1; +#endif + } + if (which == ALTITUDE_STEPS) + { +#if (ALT_STEPPER_TYPE != STEPPER_TYPE_NONE) + return _stepsPerALTDegree; // u-steps/degree +#else + return 1; +#endif + } return 0; } @@ -1012,6 +1044,20 @@ void Mount::setStepsPerDegree(StepperAxis which, float steps) EEPROMStore::storeRAStepsPerDegree(_stepsPerRADegree); setSpeedCalibration(_trackingSpeedCalibration, false); } +#if (AZ_STEPPER_TYPE != STEPPER_TYPE_NONE) + else if (which == AZIMUTH_STEPS) + { + _stepsPerAZDegree = steps; + EEPROMStore::storeAZStepsPerDegree(_stepsPerAZDegree); + } +#endif +#if (ALT_STEPPER_TYPE != STEPPER_TYPE_NONE) + else if (which == ALTITUDE_STEPS) + { + _stepsPerALTDegree = steps; + EEPROMStore::storeALTStepsPerDegree(_stepsPerALTDegree); + } +#endif } ///////////////////////////////// @@ -1245,7 +1291,7 @@ void Mount::setLST(const DayTime &lst) { _LST = lst; _zeroPosRA = lst; -#ifdef OAM +#if defined(OAM) || defined(OAE) _zeroPosRA.addHours(6); // shift allcoordinates by 90° for EQ mount movement #endif LOG(DEBUG_MOUNT, "[MOUNT]: Set LST and ZeroPosRA to: %s", _LST.ToString()); @@ -1579,11 +1625,14 @@ void Mount::stopGuiding(bool ra, bool dec) // Stop DEC guiding and wait for it to stop. _stepperGUIDE->stop(); +#if !defined(ESP32BOARD) while (_stepperGUIDE->isRunning()) { _stepperGUIDE->run(); _stepperTRK->runSpeed(); } +#endif + _mountStatus &= ~STATUS_GUIDE_PULSE_DEC; } @@ -1903,11 +1952,11 @@ void Mount::getAZALTPositions(long &azPos, long &altPos) void Mount::moveAZALTToHome() { #if (AZ_STEPPER_TYPE != STEPPER_TYPE_NONE) - enableAzAltMotors(); + enableAzMotor(); _stepperAZ->moveTo(0); #endif #if (ALT_STEPPER_TYPE != STEPPER_TYPE_NONE) - enableAzAltMotors(); + enableAltMotor(); _stepperALT->moveTo(0); #endif } @@ -2002,7 +2051,7 @@ void Mount::moveBy(int direction, float arcMinutes) #if (AZ_STEPPER_TYPE != STEPPER_TYPE_NONE) if (direction == AZIMUTH_STEPS) { - enableAzAltMotors(); + enableAzMotor(); long stepsToMove = arcMinutes * AZIMUTH_STEPS_PER_ARC_MINUTE; _stepperAZ->move(stepsToMove); } @@ -2010,7 +2059,7 @@ void Mount::moveBy(int direction, float arcMinutes) #if (ALT_STEPPER_TYPE != STEPPER_TYPE_NONE) if (direction == ALTITUDE_STEPS) { - enableAzAltMotors(); + enableAltMotor(); long stepsToMove = arcMinutes * ALTITUDE_STEPS_PER_ARC_MINUTE; _stepperALT->move(stepsToMove); } @@ -2063,12 +2112,15 @@ void Mount::disableAzAltMotors() // enableAzAltMotors // ///////////////////////////////// -void Mount::enableAzAltMotors() +void Mount::enableAzMotor() { #if (AZ_STEPPER_TYPE != STEPPER_TYPE_NONE) digitalWrite(AZ_EN_PIN, LOW); // Logic LOW to enable driver #endif +} +void Mount::enableAltMotor() +{ #if (ALT_STEPPER_TYPE != STEPPER_TYPE_NONE) digitalWrite(ALT_EN_PIN, LOW); // Logic LOW to enable driver #endif @@ -2645,6 +2697,31 @@ void Mount::waitUntilStopped(byte direction) } } +///////////////////////////////// +// +// waitUntilAllStopped +// +///////////////////////////////// +// Block until all steppers are stopped +void Mount::waitUntilAllStopped() +{ + while (_stepperRA->isRunning() || _stepperDEC->isRunning() || (((_mountStatus & STATUS_TRACKING) == 0) && _stepperTRK->isRunning()) +#if FOCUS_STEPPER_TYPE != STEPPER_TYPE_NONE + || _stepperFocus->isRunning() +#endif +#if AZ_STEPPER_TYPE != STEPPER_TYPE_NONE + || _stepperAZ->isRunning() +#endif +#if ALT_STEPPER_TYPE != STEPPER_TYPE_NONE + || _stepperALT->isRunning() +#endif + ) + { + loop(); + yield(); + } +} + ///////////////////////////////// // // getCurrentStepperPosition @@ -2894,6 +2971,16 @@ void Mount::interruptLoop() _stepperRA->run(); } } + else if (!(_mountStatus & STATUS_TRACKING) && (_stepperTRK->isRunning())) + { + // If we are not tracking, but the tracking stepper is running, we need to let it move. + // This can happen when we need to compensate for a slew (during which the tracker is + // stopped). After the slew, the tracker is advanced by the distance it would have + // travelled during the slew if it had been tracking. + // That compensation uses goto mode (using runToNewPosition()), so we need to use run(), + // since runSpeed() only advances the stepper when it is in constant speed mode. + _stepperTRK->run(); + } if (_mountStatus & STATUS_FINDING_HOME) { @@ -2976,8 +3063,12 @@ void Mount::loop() // One of the motors was running last time through the loop, but not anymore, so shutdown the outputs. disableAzAltMotors(); _azAltWasRunning = false; + #if (AZ_STEPPER_TYPE != STEPPER_TYPE_NONE) EEPROMStore::storeAZPosition(_stepperAZ->currentPosition()); + #endif + #if (ALT_STEPPER_TYPE != STEPPER_TYPE_NONE) EEPROMStore::storeALTPosition(_stepperALT->currentPosition()); + #endif } oneIsRunning = false; @@ -3241,6 +3332,7 @@ void Mount::setupInfoDisplay() infoDisplay = new SDD1306OLED128x64(INFO_DISPLAY_I2C_ADDRESS, INFO_DISPLAY_I2C_SDA_PIN, INFO_DISPLAY_I2C_SCL_PIN); LOG(DEBUG_ANY, "[SYSTEM]: SSD1306 OLED created... initializing"); infoDisplay->init(); + infoDisplay->setConsoleMode(true); LOG(DEBUG_DISPLAY, "[DISPLAY]: Created and initialized SSD1306 OLED class..."); #endif } @@ -3251,6 +3343,7 @@ void Mount::updateInfoDisplay() // If we update this display too often while slewing, the serial port is unable to process commands fast enough. Which makes the driver // timeout, causing ASCOM errors. // We will update at 30Hz when idle, 5Hz when slewing one axis and skip updates when slewing both. + int refreshRateHz = 30; const bool isSlewingRAandDEC = (slewStatus() & (SLEWING_DEC | SLEWING_RA)) == (SLEWING_DEC | SLEWING_RA); if (isSlewingRAandDEC) @@ -3266,7 +3359,7 @@ void Mount::updateInfoDisplay() if (now - _lastInfoUpdate > (1000 / refreshRateHz)) { LOG(DEBUG_DISPLAY, "[DISPLAY]: Render state to OLED ..."); - infoDisplay->render(this); + infoDisplay->renderScreen((void *) this); LOG(DEBUG_DISPLAY, "[DISPLAY]: Rendered state to OLED ..."); _lastInfoUpdate = now; } @@ -3397,7 +3490,7 @@ void Mount::setHome(bool clearZeroPos) //LOG(DEBUG_MOUNT_VERBOSE, "[MOUNT]: setHomePre: targetRA is %s", targetRA().ToString()); //LOG(DEBUG_MOUNT_VERBOSE, "[MOUNT]: setHomePre: zeroPos is %s", _zeroPosRA.ToString()); _zeroPosRA = clearZeroPos ? DayTime(POLARIS_RA_HOUR, POLARIS_RA_MINUTE, POLARIS_RA_SECOND) : calculateLst(); -#ifdef OAM +#if defined(OAM) || defined(OAE) _zeroPosRA.addHours(6); // shift allcoordinates by 90° for EQ mount movement #endif _zeroPosDEC = 0.0f; @@ -3730,7 +3823,7 @@ void Mount::moveStepperBy(StepperAxis direction, long steps) case AZIMUTH_STEPS: { #if AZ_STEPPER_TYPE != STEPPER_TYPE_NONE - enableAzAltMotors(); + enableAzMotor(); LOG(DEBUG_STEPPERS, "[STEPPERS]: moveStepperBy: AZ from %l to %l", _stepperAZ->currentPosition(), @@ -3743,7 +3836,7 @@ void Mount::moveStepperBy(StepperAxis direction, long steps) case ALTITUDE_STEPS: { #if ALT_STEPPER_TYPE != STEPPER_TYPE_NONE - enableAzAltMotors(); + enableAltMotor(); _stepperALT->moveTo(_stepperALT->currentPosition() + steps); #endif } diff --git a/src/Mount.hpp b/src/Mount.hpp index b63632f4..7cf00a73 100644 --- a/src/Mount.hpp +++ b/src/Mount.hpp @@ -335,6 +335,9 @@ class Mount // Block until the motors specified (NORTH, EAST, TRACKING, etc.) are stopped void waitUntilStopped(byte direction); + // Block until all motors are stopped + void waitUntilAllStopped(); + // Same as Arduino delay() but keeps the tracker going. void delay(int ms); @@ -403,7 +406,7 @@ class Mount void setupInfoDisplay(); void updateInfoDisplay(); InfoDisplayRender *getInfoDisplay(); - long _lastInfoUpdate; + long _lastInfoUpdate = 0; // Last time the info display was updated #endif // Called by Meade processor every time a command is received. @@ -432,7 +435,8 @@ class Mount // Support for moving the mount in azimuth and altitude (requires extra hardware) void moveBy(int direction, float arcMinutes); void disableAzAltMotors(); - void enableAzAltMotors(); + void enableAzMotor(); + void enableAltMotor(); #endif #if (FOCUS_STEPPER_TYPE != STEPPER_TYPE_NONE) @@ -603,7 +607,7 @@ class Mount #else AccelStepper *_stepperAZ; #endif - const long _stepsPerAZDegree; // u-steps/degree (from CTOR) + float _stepsPerAZDegree; // u-steps/degree (from CTOR) #if AZ_DRIVER_TYPE == DRIVER_TYPE_TMC2209_UART TMC2209Stepper *_driverAZ; #endif @@ -614,7 +618,7 @@ class Mount #else AccelStepper *_stepperALT; #endif - const long _stepsPerALTDegree; // u-steps/degree (from CTOR) + float _stepsPerALTDegree; // u-steps/degree (from CTOR) #if ALT_DRIVER_TYPE == DRIVER_TYPE_TMC2209_UART TMC2209Stepper *_driverALT; #endif diff --git a/src/SSD1306_128x64_Display.cpp b/src/SSD1306_128x64_Display.cpp new file mode 100644 index 00000000..bae3c33b --- /dev/null +++ b/src/SSD1306_128x64_Display.cpp @@ -0,0 +1,419 @@ +#include "SSD1306_128x64_Display.hpp" + +#if defined(ESP32) + /* + * ESP32 PROGMEM is fake, and its pgm_read_byte macro makes a useless cast + * which errors out with Werror=useless-cast, which can't be suppressed by + * our PUSH/POP_NO_WARNINGS because the macro expands in OUR code, not their + * header :/ + */ + #undef pgm_read_byte + #define pgm_read_byte(addr) (*(addr)) +#endif + +Mount *SDD1306OLED128x64::_mount = nullptr; + +float sinLookup(float deg) +{ + while (deg < 0.0f) + deg += 360.0f; + while (deg > 360.0f) + deg -= 360.0f; + + if (deg <= 90) + { + int index = (int) roundf(sineSize * deg / 90.0f); + return 1.0f * pgm_read_byte(sineTable + index) / 255.0; + } + else if (deg <= 180) + { + int index = (int) roundf(sineSize * (180.0f - deg) / 90.0f); + return 1.0f * pgm_read_byte(sineTable + index) / 255.0; + } + else if (deg <= 270) + { + int index = (int) roundf(sineSize * (deg - 180.0f) / 90.0f); + return -1.0f * pgm_read_byte(sineTable + index) / 255.0; + } + else if (deg <= 360) + { + int index = (int) roundf(sineSize * (360.0f - deg) / 90.0f); + return -1.0f * pgm_read_byte(sineTable + index) / 255.0; + } + return 0.0f; +} + +SDD1306OLED128x64::SDD1306OLED128x64(uint8_t addr, int sda, int scl) : InfoDisplayRender() +{ + _display = new SSD1306Wire(addr, sda, scl, GEOMETRY_128_64); + _commLetter = ' '; +} + +void SDD1306OLED128x64::renderCallback(void *context) +{ + SDD1306OLED128x64 *display = static_cast(context); + display->drawScreen(); +} + +void SDD1306OLED128x64::drawScreen() +{ + _display->setColor(WHITE); + if (_consoleMode) + { + // Draw header only in console mode, in the area 0,0 to 127,20 + // Logo on the left. Base class renders console output text. + _display->setFont(OATLogo); + _display->drawString(0, 0, "!"); + + // Name on the right + _display->setFont(Bitmap5x7); +#ifdef OAE + _display->drawString(32, 6, F("OpenAstroExplorer")); +#elif defined(OAM) + _display->drawString(32, 6, F("OpenAstroMount")); +#else + _display->drawString(32, 6, F("OpenAstroTracker")); +#endif + } + else + { + // Draw indicators in all other modes + drawIndicators(SDD1306OLED128x64::_mount); + } +} + +// Build the display from the mount +void SDD1306OLED128x64::renderScreen(void *mount) +{ + _mount = (Mount *) mount; + // Call the base + this->InfoDisplayRender::render(renderCallback); +}; + +// Display the tiem left before tracking hits the limit +void SDD1306OLED128x64::drawTime(Mount *mount, String label, const DayTime &time) +{ + char achTemp[24]; + _display->setColor(WHITE); + _display->setFont(Bitmap3x5); + sprintf(achTemp, "%s%02d:%02d", label.c_str(), time.getHours(), time.getMinutes()); + _display->drawString(55, 59, achTemp); +} + +// Draw all the indicators on screen +void SDD1306OLED128x64::drawIndicators(Mount *mount) +{ + char scratchBuffer[24]; + _display->setFont(Bitmap5x7); + _display->setColor(WHITE); + + drawStepperStates(mount); + int ra, dec; + // If a slew is in progress, we don't display the safe time, version, and + // comms indicator, since the progress bar takes up the same space + if (mount->getStepperProgress(ra, dec)) + { + drawProgressBar(ra, dec); + } + else + { + long timeSecs = millis() / 2000; // Change every 2 secs + int index = timeSecs % 5; // Cycle through multiple data displays + + _display->setFont(CommSymbols); + _display->drawString(11, 59, F("L")); // Memory chip icon + _display->setFont(Bitmap3x5); + long availMem = freeMemory(); + if (availMem > 9999) + { + _display->drawString(20, 59, String(availMem / 1024) + "K"); + } + else + { + _display->drawString(20, 59, String(availMem)); + } + + switch (index) + { + case 0: + { + float hoursLeft = mount->checkRALimit(); + DayTime dt(hoursLeft); + drawTime(mount, F("REM "), dt); + } + break; + case 1: + { + drawTime(mount, F("LST "), mount->calculateLst()); + } + break; + case 2: + { + long now = millis(); + long msPerDay = 60L * 60 * 24 * 1000; + int days = (int) (now / msPerDay); + now -= days * msPerDay; + DayTime elapsed(1.0 * now / (1000.0 * 3600.0)); + drawTime(mount, F("UPT "), elapsed); + } + break; + case 3: + { + _display->drawString(55, 59, (String(F(" FW ")) + String(VERSION)).c_str()); + } + break; + case 4: + { + float lat = fabsf(mount->latitude().getTotalHours()); + float lng = fabsf(mount->longitude().getTotalHours()); + const char dirLat = (mount->latitude().getTotalHours() < 0) ? 'S' : 'N'; + const char dirLong = (mount->longitude().getTotalHours() < 0) ? 'W' : 'E'; + sprintf(scratchBuffer, "LOC %s%c %s%c", String(lat, 0).c_str(), dirLat, String(lng, 0).c_str(), dirLong); + _display->drawString(55, 59, scratchBuffer); + } + break; + } + drawCommunicationStatus(mount); + } + drawCoordinates(mount); + drawMountPosition(mount); + drawStatus(mount); +} + +// Display two 2-pixel high progress bar in the last 4 lines of the display +void SDD1306OLED128x64::drawProgressBar(int percRA, int percDEC) +{ + _display->setColor(WHITE); + _display->drawVerticalLine(127, 60, 4); + int raWidth = round(1.28f * percRA); + _display->fillRect(0, 60, raWidth, 2); + int decWidth = round(1.28f * percDEC); + _display->fillRect(0, 62, decWidth, 2); +} + +// Display a rectangle with the stepper label in it +void SDD1306OLED128x64::drawStepperState(String name, bool active, int xoff, int width, int textOffX) +{ + _display->setColor(WHITE); + if (active) + { + _display->fillRect(xoff, 0, width, 11); + } + else + { + _display->drawRect(xoff, 0, width, 11); + } + _display->setColor(INVERSE); + _display->drawString(xoff + 2 + textOffX, 2, name); +} + +// Display all the configured stepper status rectangles +// Focuser is currently not supported, but could be added here, if possible. +void SDD1306OLED128x64::drawStepperStates(Mount *mount) +{ + _display->setFont(Bitmap5x7); + drawStepperState(F("RA"), mount->isAxisRunning(RA_STEPS), 0, 15); + drawStepperState(F("DEC"), mount->isAxisRunning(DEC_STEPS), 16, 21); +#if (ALT_STEPPER_TYPE != STEPPER_TYPE_NONE) + drawStepperState(F("ALT"), mount->isRunningALT(), 38, 21); +#endif +#if (AZ_STEPPER_TYPE != STEPPER_TYPE_NONE) + drawStepperState(F("AZ"), mount->isRunningAZ(), 60, 16); +#endif + drawStepperState(F("GDE"), mount->isGuiding(), 83, 21); + drawStepperState(F("TRK"), mount->isSlewingTRK(), 105, 23, 1); +} + +void SDD1306OLED128x64::drawCommunicationStatus(Mount *mount) +{ + long recvdCmds = mount->getNumCommandsReceived(); + // If we have received any commands since the last display, draw the marker. + + if (_commLetter != ' ') + { + _display->setFont(CommSymbols); + _display->drawString(1, 59, String(_commLetter)); + _commLetter++; + if (_commLetter == 'G') // Past last communication animation frame (F) + { + _commLetter = ' '; + } + } + else if (recvdCmds != _lastNumCmds) + { + _commLetter = 'C'; // First communication animation frame + _lastNumCmds = recvdCmds; + } +} + +// Draw the given coordinate string at the given point +void SDD1306OLED128x64::drawCoordinate(int x, int y, const char *coord) +{ + char achCoord[30]; + char *n = achCoord; + // Since this is not a full font, remap the supported letters to the right character + for (const char *p = coord; *p != 0; p++) + { + switch (*p) + { + case 'R': + *n = '!'; + break; + case 'A': + *n = '&'; + break; + case 'D': + *n = '#'; + break; + case 'E': + *n = '$'; + break; + case 'C': + *n = '%'; + break; + case 'h': + *n = '<'; + break; + case 'm': + *n = ';'; + break; + case 's': + *n = '='; + break; + case '@': + *n = '('; + break; + default: + *n = *p; + break; + } + n++; + } + *n = 0; + _display->setFont(Bitmap7x15); + _display->setColor(WHITE); + _display->drawString(x, y, achCoord); +} + +// Draw the mounts celestial RA and DEC coordinates +void SDD1306OLED128x64::drawCoordinates(Mount *mount) +{ + String rc = mount->RAString(LCD_STRING | CURRENT_STRING); + String dc = mount->DECString(LCD_STRING | CURRENT_STRING); + drawCoordinate(8, 24, rc.c_str()); + drawCoordinate(0, 42, dc.c_str()); +} + +// Map the given RA coordinate to the pixel position on the display +int SDD1306OLED128x64::xRAPixel(float ra) +{ + float rangeRA = rightRA - leftRA; + int x = 4 + (int) round(1.0f * (_raSize - 9) * ((ra - leftRA) / rangeRA)); + return (_leftEdgeMount + x); +} + +// Map the given DEC coordinate to the pixel position on the display +int SDD1306OLED128x64::yDECPixel(float dec) +{ + int y = (int) round(1.0f * (_decSize) * ((dec - bottomDEC) / rangeDEC)); + return (_topEdgeMount + _decSize - y); +} + +// Draw the rectangle with the current and target positions +void SDD1306OLED128x64::drawMountPosition(Mount *mount) +{ + _display->setColor(WHITE); + _display->setFont(Bitmap3x5); + + // DEC tickmarks + for (int p = _topEdgeMount; p <= _topEdgeMount + _decSize; p += 2) + { + _display->setPixel(_decScalePos, p); + } +#if defined(OAM) || defined(OAE) + _display->drawHorizontalLine(_decScalePos - 1, yDECPixel(-180.0), 2); +#endif + _display->drawHorizontalLine(_decScalePos - 1, yDECPixel(-90.0), 2); + _display->drawHorizontalLine(_decScalePos - 1, yDECPixel(0.0), 2); + _display->drawHorizontalLine(_decScalePos - 1, yDECPixel(90.0), 2); + _display->drawHorizontalLine(_decScalePos - 1, yDECPixel(180.0), 2); +// DEC tickmark labels +#if defined(OAM) || defined(OAE) + _display->drawString(_decScalePos + 6, yDECPixel(-180.0f) - 2, F("180")); + _display->drawHorizontalLine(_decScalePos + 3, yDECPixel(-180.0), 2); // Smaller minus sign +#endif + _display->drawString(_decScalePos + 6, yDECPixel(-90.0f) - 2, F("90")); + _display->drawHorizontalLine(_decScalePos + 3, yDECPixel(-90.0), 2); // Smaller minus sign + _display->drawString(_decScalePos + 3, yDECPixel(0.0f) - 2, "0"); + _display->drawString(_decScalePos + 3, yDECPixel(90.0f) - 2, F("90")); + _display->drawString(_decScalePos + 3, yDECPixel(180.0f) - 2, F("180")); + + // DEC Pos Marker + float decStepsPerDeg = mount->getStepsPerDegree(StepperAxis::DEC_STEPS); + long decSteps = mount->getCurrentStepperPosition(StepperAxis::DEC_STEPS); + float decDegrees = decSteps / decStepsPerDeg; + int yMark = yDECPixel(decDegrees); + _display->setPixel(_decScalePos - 2, yMark); + _display->drawVerticalLine(_decScalePos - 3, yMark - 1, 3); + _display->drawVerticalLine(_decScalePos - 4, yMark - 2, 5); + + // RA tickmarks + for (int p = _leftEdgeMount; p <= _leftEdgeMount + _raSize; p += 2) + { + _display->setPixel(p, _raScalePos); + } + _display->drawVerticalLine(xRAPixel(-6.0f), _raScalePos - 1, 2); + _display->drawVerticalLine(xRAPixel(-3.0f), _raScalePos - 1, 2); + _display->drawVerticalLine(xRAPixel(0.0f), _raScalePos - 1, 2); + _display->drawVerticalLine(xRAPixel(3.0f), _raScalePos - 1, 2); + _display->drawVerticalLine(xRAPixel(6.0f), _raScalePos - 1, 2); + + // RA tickmark labels + _display->drawString(xRAPixel(-6.0f) - 1, _raScalePos + 2, "6"); + _display->drawHorizontalLine(xRAPixel(-6.0f) - 4, _raScalePos + 2 + 2, 2); // Smaller minus sign + _display->drawString(xRAPixel(-3.0f) - 1, _raScalePos + 2, "3"); + _display->drawHorizontalLine(xRAPixel(-3.0f) - 4, _raScalePos + 2 + 2, 2); // Smaller minus sign + _display->drawString(xRAPixel(0.0f) - 1, _raScalePos + 2, "0"); + _display->drawString(xRAPixel(3.0f) - 1, _raScalePos + 2, "3"); + _display->drawString(xRAPixel(6.0f) - 1, _raScalePos + 2, "6"); + + float raStepsPerDeg = mount->getStepsPerDegree(StepperAxis::RA_STEPS); + float trkSteps = 1.0f * mount->getCurrentStepperPosition(TRACKING) / (1.0f * RA_TRACKING_MICROSTEPPING / RA_SLEW_MICROSTEPPING); + long raSteps = mount->getCurrentStepperPosition(StepperAxis::RA_STEPS); + float raHours = (trkSteps + raSteps) / raStepsPerDeg / 15.0f; + + // RA Position Marker + int xMark = xRAPixel(raHours); + _display->setPixel(xMark, _raScalePos - 2); + _display->drawHorizontalLine(xMark - 1, _raScalePos - 3, 3); + _display->drawHorizontalLine(xMark - 2, _raScalePos - 4, 5); +} + +// Display the tiem left before tracking hits the limit +void SDD1306OLED128x64::drawSafeTime(Mount *mount) +{ + char achTemp[10]; + float hoursLeft = mount->checkRALimit(); + DayTime dt(hoursLeft); + _display->setColor(WHITE); + _display->setFont(CommSymbols); + _display->drawString(48, 59, "M"); // Clock sign + _display->setFont(Bitmap3x5); + sprintf(achTemp, "%02d:%02d", dt.getHours(), dt.getMinutes()); + _display->drawString(55, 59, achTemp); +} + +// Display the mount status string +void SDD1306OLED128x64::drawStatus(Mount *mount) +{ + _display->setColor(WHITE); + _display->setFont(Bitmap5x7); + String state = mount->getStatusStateString(); + state.toUpperCase(); + _display->drawString(4, 14, state.c_str()); + + // Bouncing pixel (bounce frequency every 1.5s). 180 degrees is one cap. + float deg = 180.0f * (millis() % 1500) / 1500.0f; + int pixPos = (int) round(1.0f * yMaxStatus * sinLookup(deg)); + _display->setPixel(0, 11 + yMaxStatus - pixPos); +} diff --git a/src/SSD1306_128x64_Display.hpp b/src/SSD1306_128x64_Display.hpp index 003f32cc..32f14633 100644 --- a/src/SSD1306_128x64_Display.hpp +++ b/src/SSD1306_128x64_Display.hpp @@ -1,5 +1,7 @@ #pragma once +#include #include "SSD1306Wire.h" +#include "Configuration.hpp" #include "Utility.hpp" #include "Version.h" #include "fonts128x64.h" @@ -20,10 +22,12 @@ const float sineSize = 18.0; const uint8_t sineTable[] PROGMEM = {0, 22, 44, 66, 87, 108, 128, 146, 164, 180, 195, 209, 221, 231, 240, 246, 251, 254, 255, 255}; +class Mount; + // This class renders the mount status to a 128x64 pixel display controlled by a SSD1306 chip. class SDD1306OLED128x64 : public InfoDisplayRender { -#ifdef OAM +#if defined(OAM) || defined(OAE) const float bottomDEC = -180.0f; const float rangeDEC = 360.0; #else @@ -43,453 +47,52 @@ class SDD1306OLED128x64 : public InfoDisplayRender const int yMaxStatus = 63 - 11; - SSD1306Wire *display; - int _sizeMount; - int _yStatus; - int _dirStatus; char _commLetter; - long _lastNumCmds; - long _lastUpdate; - bool _consoleMode; - String _textList[6]; // At most 6 lines of text in console mode - int _curLine; + static Mount *_mount; public: - SDD1306OLED128x64(byte addr, int sda, int scl) : InfoDisplayRender() - { - display = new SSD1306Wire(addr, sda, scl, GEOMETRY_128_64); - _sizeMount = 128 - _leftEdgeMount; - _consoleMode = true; - _curLine = 0; - _yStatus = 0; - _dirStatus = 1; - _commLetter = ' '; - for (int i = 0; i < 6; i++) - { - _textList[i] = ""; - } - } - - // Initialize the display - virtual void init() - { - display->init(); - display->clear(); - display->displayOn(); - }; + SDD1306OLED128x64(uint8_t addr, int sda, int scl); + void static renderCallback(void *context); + void drawScreen(); // Build the display from the mount - virtual void render(Mount *mount) - { - display->clear(); - if (_consoleMode) - { - display->setColor(WHITE); - - // Logo on the left - display->setFont(OATLogo); - display->drawString(0, 0, "!"); - - // Name on the right - display->setFont(Bitmap5x7); -#ifdef OAM - display->drawString(32, 6, F("OpenAstroMount")); -#else - display->drawString(32, 6, F("OpenAstroTracker")); -#endif - - // Other lines - int y = 21; - display->setFont(Bitmap3x5); - for (int i = 0; i < 6; i++) - { - if (_textList[i].length() != 0) - { - display->drawString(0, y, _textList[i]); - } - y += 7; - } - } - else - { - drawIndicators(mount); - } - display->display(); - }; - - virtual void setConsoleMode(bool active) - { - _consoleMode = active; - }; - - virtual int addConsoleText(String text, bool tinyFont) - { - _textList[_curLine++] = text; - render(NULL); - return _curLine - 1; - }; - - virtual void updateConsoleText(int line, String text) - { - _textList[line] = text; - render(NULL); - }; + void renderScreen(void *mount); // Display the tiem left before tracking hits the limit - void drawTime(Mount *mount, String label, const DayTime &time) - { - char achTemp[24]; - display->setColor(WHITE); - display->setFont(Bitmap3x5); - sprintf(achTemp, "%s%02d:%02d", label.c_str(), time.getHours(), time.getMinutes()); - display->drawString(55, 59, achTemp); - } + void drawTime(Mount *mount, String label, const DayTime &time); // Draw all the indicators on screen - void drawIndicators(Mount *mount) - { - char scratchBuffer[24]; - display->setFont(Bitmap5x7); - display->setColor(WHITE); - - drawStepperStates(mount); - int ra, dec; - // If a slew is in progress, we don't display the safe time, version, and - // comms indicator, since the progress bar takes up the same space - if (mount->getStepperProgress(ra, dec)) - { - drawProgressBar(ra, dec); - } - else - { - long timeSecs = millis() / 2000; // Change every 2 secs - int index = timeSecs % 5; // Cycle through multiple data displays - - display->setFont(CommSymbols); - display->drawString(11, 59, F("L")); // Memory chip icon - display->setFont(Bitmap3x5); - long availMem = freeMemory(); - if (availMem > 9999) - { - display->drawString(20, 59, String(availMem / 1024) + "K"); - } - else - { - display->drawString(20, 59, String(availMem)); - } - - switch (index) - { - case 0: - { - float hoursLeft = mount->checkRALimit(); - DayTime dt(hoursLeft); - drawTime(mount, F("REM "), dt); - } - break; - case 1: - { - drawTime(mount, F("LST "), mount->calculateLst()); - } - break; - case 2: - { - long now = millis(); - long msPerDay = 60L * 60 * 24 * 1000; - int days = (int) (now / msPerDay); - now -= days * msPerDay; - DayTime elapsed(1.0 * now / (1000.0 * 3600.0)); - drawTime(mount, F("UPT "), elapsed); - } - break; - case 3: - { - display->drawString(55, 59, (String(F(" FW ")) + String(VERSION)).c_str()); - } - break; - case 4: - { - float lat = fabsf(mount->latitude().getTotalHours()); - float lng = fabsf(mount->longitude().getTotalHours()); - const char dirLat = (mount->latitude().getTotalHours() < 0) ? 'S' : 'N'; - const char dirLong = (mount->longitude().getTotalHours() < 0) ? 'W' : 'E'; - sprintf(scratchBuffer, "LOC %s%c %s%c", String(lat, 0).c_str(), dirLat, String(lng, 0).c_str(), dirLong); - display->drawString(55, 59, scratchBuffer); - } - break; - } - drawCommunicationStatus(mount); - } - drawCoordinates(mount); - drawMountPosition(mount); - drawStatus(mount); - } + void drawIndicators(Mount *mount); // Display two 2-pixel high progress bar in the last 4 lines of the display - void drawProgressBar(int percRA, int percDEC) - { - display->setColor(WHITE); - display->drawVerticalLine(127, 60, 4); - int raWidth = round(1.28f * percRA); - display->fillRect(0, 60, raWidth, 2); - int decWidth = round(1.28f * percDEC); - display->fillRect(0, 62, decWidth, 2); - } + void drawProgressBar(int percRA, int percDEC); // Display a rectangle with the stepper label in it - void drawStepperState(String name, bool active, int xoff, int width, int textOffX = 0) - { - display->setColor(WHITE); - if (active) - { - display->fillRect(xoff, 0, width, 11); - } - else - { - display->drawRect(xoff, 0, width, 11); - } - display->setColor(INVERSE); - display->drawString(xoff + 2 + textOffX, 2, name); - } + void drawStepperState(String name, bool active, int xoff, int width, int textOffX = 0); // Display all the configured stepper status rectangles // Focuser is currently not supported, but could be added here, if possible. - void drawStepperStates(Mount *mount) - { - display->setFont(Bitmap5x7); - drawStepperState(F("RA"), mount->isAxisRunning(RA_STEPS), 0, 15); - drawStepperState(F("DEC"), mount->isAxisRunning(DEC_STEPS), 16, 21); -#if (ALT_STEPPER_TYPE != STEPPER_TYPE_NONE) - drawStepperState(F("ALT"), mount->isRunningALT(), 38, 21); -#endif -#if (AZ_STEPPER_TYPE != STEPPER_TYPE_NONE) - drawStepperState(F("AZ"), mount->isRunningAZ(), 60, 16); -#endif - drawStepperState(F("GDE"), mount->isGuiding(), 83, 21); - drawStepperState(F("TRK"), mount->isSlewingTRK(), 105, 23, 1); - } - - void drawCommunicationStatus(Mount *mount) - { - long recvdCmds = mount->getNumCommandsReceived(); - // If we have received any commands since the last display, draw the marker. + void drawStepperStates(Mount *mount); - if (_commLetter != ' ') - { - display->setFont(CommSymbols); - display->drawString(1, 59, String(_commLetter)); - _commLetter++; - if (_commLetter == 'G') // Past last communication animation frame (F) - { - _commLetter = ' '; - } - } - else if (recvdCmds != _lastNumCmds) - { - _commLetter = 'C'; // First communication animation frame - _lastNumCmds = recvdCmds; - } - } + void drawCommunicationStatus(Mount *mount); // Draw the given coordinate string at the given point - void drawCoordinate(int x, int y, const char *coord) - { - char achCoord[30]; - char *n = achCoord; - // Since this is not a full font, remap the supported letters to the right character - for (const char *p = coord; *p != 0; p++) - { - switch (*p) - { - case 'R': - *n = '!'; - break; - case 'A': - *n = '&'; - break; - case 'D': - *n = '#'; - break; - case 'E': - *n = '$'; - break; - case 'C': - *n = '%'; - break; - case 'h': - *n = '<'; - break; - case 'm': - *n = ';'; - break; - case 's': - *n = '='; - break; - case '@': - *n = '('; - break; - default: - *n = *p; - break; - } - n++; - } - *n = 0; - display->setFont(Bitmap7x15); - display->setColor(WHITE); - display->drawString(x, y, achCoord); - } + void drawCoordinate(int x, int y, const char *coord); // Draw the mounts celestial RA and DEC coordinates - void drawCoordinates(Mount *mount) - { - String rc = mount->RAString(LCD_STRING | CURRENT_STRING); - String dc = mount->DECString(LCD_STRING | CURRENT_STRING); - drawCoordinate(8, 24, rc.c_str()); - drawCoordinate(0, 42, dc.c_str()); - } + void drawCoordinates(Mount *mount); // Map the given RA coordinate to the pixel position on the display - int xRAPixel(float ra) - { - float rangeRA = rightRA - leftRA; - int x = 4 + (int) round(1.0f * (_raSize - 9) * ((ra - leftRA) / rangeRA)); - return (_leftEdgeMount + x); - } + int xRAPixel(float ra); // Map the given DEC coordinate to the pixel position on the display - int yDECPixel(float dec) - { - int y = (int) round(1.0f * (_decSize) * ((dec - bottomDEC) / rangeDEC)); - return (_topEdgeMount + _decSize - y); - } + int yDECPixel(float dec); // Draw the rectangle with the current and target positions - void drawMountPosition(Mount *mount) - { - display->setColor(WHITE); - display->setFont(Bitmap3x5); - - // DEC tickmarks - for (int p = _topEdgeMount; p <= _topEdgeMount + _decSize; p += 2) - { - display->setPixel(_decScalePos, p); - } -#ifdef OAM - display->drawHorizontalLine(_decScalePos - 1, yDECPixel(-180.0), 2); -#endif - display->drawHorizontalLine(_decScalePos - 1, yDECPixel(-90.0), 2); - display->drawHorizontalLine(_decScalePos - 1, yDECPixel(0.0), 2); - display->drawHorizontalLine(_decScalePos - 1, yDECPixel(90.0), 2); - display->drawHorizontalLine(_decScalePos - 1, yDECPixel(180.0), 2); -// DEC tickmark labels -#ifdef OAM - display->drawString(_decScalePos + 6, yDECPixel(-180.0f) - 2, F("180")); - display->drawHorizontalLine(_decScalePos + 3, yDECPixel(-180.0), 2); // Smaller minus sign -#endif - display->drawString(_decScalePos + 6, yDECPixel(-90.0f) - 2, F("90")); - display->drawHorizontalLine(_decScalePos + 3, yDECPixel(-90.0), 2); // Smaller minus sign - display->drawString(_decScalePos + 3, yDECPixel(0.0f) - 2, "0"); - display->drawString(_decScalePos + 3, yDECPixel(90.0f) - 2, F("90")); - display->drawString(_decScalePos + 3, yDECPixel(180.0f) - 2, F("180")); - - // DEC Pos Marker - float decStepsPerDeg = mount->getStepsPerDegree(StepperAxis::DEC_STEPS); - long decSteps = mount->getCurrentStepperPosition(StepperAxis::DEC_STEPS); - float decDegrees = decSteps / decStepsPerDeg; - int yMark = yDECPixel(decDegrees); - display->setPixel(_decScalePos - 2, yMark); - display->drawVerticalLine(_decScalePos - 3, yMark - 1, 3); - display->drawVerticalLine(_decScalePos - 4, yMark - 2, 5); - - // RA tickmarks - for (int p = _leftEdgeMount; p <= _leftEdgeMount + _raSize; p += 2) - { - display->setPixel(p, _raScalePos); - } - display->drawVerticalLine(xRAPixel(-6.0f), _raScalePos - 1, 2); - display->drawVerticalLine(xRAPixel(-3.0f), _raScalePos - 1, 2); - display->drawVerticalLine(xRAPixel(0.0f), _raScalePos - 1, 2); - display->drawVerticalLine(xRAPixel(3.0f), _raScalePos - 1, 2); - display->drawVerticalLine(xRAPixel(6.0f), _raScalePos - 1, 2); - - // RA tickmark labels - display->drawString(xRAPixel(-6.0f) - 1, _raScalePos + 2, "6"); - display->drawHorizontalLine(xRAPixel(-6.0f) - 4, _raScalePos + 2 + 2, 2); // Smaller minus sign - display->drawString(xRAPixel(-3.0f) - 1, _raScalePos + 2, "3"); - display->drawHorizontalLine(xRAPixel(-3.0f) - 4, _raScalePos + 2 + 2, 2); // Smaller minus sign - display->drawString(xRAPixel(0.0f) - 1, _raScalePos + 2, "0"); - display->drawString(xRAPixel(3.0f) - 1, _raScalePos + 2, "3"); - display->drawString(xRAPixel(6.0f) - 1, _raScalePos + 2, "6"); - - float raStepsPerDeg = mount->getStepsPerDegree(StepperAxis::RA_STEPS); - float trkSteps = 1.0f * mount->getCurrentStepperPosition(TRACKING) / (1.0f * RA_TRACKING_MICROSTEPPING / RA_SLEW_MICROSTEPPING); - long raSteps = mount->getCurrentStepperPosition(StepperAxis::RA_STEPS); - float raHours = (trkSteps + raSteps) / raStepsPerDeg / 15.0f; - - // RA Position Marker - int xMark = xRAPixel(raHours); - display->setPixel(xMark, _raScalePos - 2); - display->drawHorizontalLine(xMark - 1, _raScalePos - 3, 3); - display->drawHorizontalLine(xMark - 2, _raScalePos - 4, 5); - } - + void drawMountPosition(Mount *mount); // Display the tiem left before tracking hits the limit - void drawSafeTime(Mount *mount) - { - char achTemp[10]; - float hoursLeft = mount->checkRALimit(); - DayTime dt(hoursLeft); - display->setColor(WHITE); - display->setFont(CommSymbols); - display->drawString(48, 59, "M"); // Clock sign - display->setFont(Bitmap3x5); - sprintf(achTemp, "%02d:%02d", dt.getHours(), dt.getMinutes()); - display->drawString(55, 59, achTemp); - } - - float sinLookup(float deg) - { - while (deg < 0.0f) - deg += 360.0f; - while (deg > 360.0f) - deg -= 360.0f; - - if (deg <= 90) - { - int index = (int) roundf(sineSize * deg / 90.0f); - return 1.0f * pgm_read_byte(sineTable + index) / 255.0; - } - else if (deg <= 180) - { - int index = (int) roundf(sineSize * (180.0f - deg) / 90.0f); - return 1.0f * pgm_read_byte(sineTable + index) / 255.0; - } - else if (deg <= 270) - { - int index = (int) roundf(sineSize * (deg - 180.0f) / 90.0f); - return -1.0f * pgm_read_byte(sineTable + index) / 255.0; - } - else if (deg <= 360) - { - int index = (int) roundf(sineSize * (360.0f - deg) / 90.0f); - return -1.0f * pgm_read_byte(sineTable + index) / 255.0; - } - return 0.0f; - } + void drawSafeTime(Mount *mount); // Display the mount status string - void drawStatus(Mount *mount) - { - display->setColor(WHITE); - display->setFont(Bitmap5x7); - String state = mount->getStatusStateString(); - state.toUpperCase(); - display->drawString(4, 14, state.c_str()); - - // Bouncing pixel (bounce frequency every 1.5s). 180 degrees is one cap. - float deg = 180.0f * (millis() % 1500) / 1500.0f; - int pixPos = (int) round(1.0f * yMaxStatus * sinLookup(deg)); - display->setPixel(0, 11 + yMaxStatus - pixPos); - } + void drawStatus(Mount *mount); }; diff --git a/src/b_setup.hpp b/src/b_setup.hpp index cd99525e..0a4a1b81 100644 --- a/src/b_setup.hpp +++ b/src/b_setup.hpp @@ -94,6 +94,22 @@ void stepperControlTimerCallback(void *payload) #endif #endif +int addConsoleText(String text) +{ +#if (INFO_DISPLAY_TYPE != INFO_DISPLAY_TYPE_NONE) + return mount.getInfoDisplay()->addConsoleText(text, false); +#else + return -1; +#endif +} + +void updateConsoleText(int line, String newText) +{ +#if (INFO_DISPLAY_TYPE != INFO_DISPLAY_TYPE_NONE) + mount.getInfoDisplay()->updateConsoleText(line, newText); +#endif +} + ///////////////////////////////// // // Main program setup @@ -118,6 +134,8 @@ void setup() #if TEST_VERIFY_MODE == 1 #ifdef OAM Serial.print(F("Booting OAM Firmware ")); + #elif defined(OAE) + Serial.print(F("Booting OAE Firmware ")); #else Serial.print(F("Booting OAT Firmware ")); #endif @@ -134,32 +152,46 @@ void setup() #if (INFO_DISPLAY_TYPE != INFO_DISPLAY_TYPE_NONE) LOG(DEBUG_ANY, "[SYSTEM]: Get OLED info screen ready..."); mount.setupInfoDisplay(); + addConsoleText(F("BOOTING " VERSION)); LOG(DEBUG_ANY, "[SYSTEM]: OLED info screen ready!"); - mount.getInfoDisplay()->addConsoleText(F("BOOTING " VERSION), false); #endif #if USE_GPS == 1 + LOG(DEBUG_ANY, "[SYSTEM]: Initializing GPS..."); + #if (INFO_DISPLAY_TYPE != INFO_DISPLAY_TYPE_NONE) + int gpsLine = addConsoleText(F("Initialize GPS...")); + #endif GPS_SERIAL_PORT.begin(GPS_BAUD_RATE); + #if (INFO_DISPLAY_TYPE != INFO_DISPLAY_TYPE_NONE) + updateConsoleText(gpsLine, F("Initialize GPS... OK")); + #endif #endif //Turn on dew heater #if DEW_HEATER == 1 + LOG(DEBUG_ANY, "[SYSTEM]: Initializing dew heater..."); + int dewHeaterLine = addConsoleText(F("Enable Dew Heater...")); #if defined(DEW_HEATER_1_PIN) digitalWrite(DEW_HEATER_1_PIN, HIGH); #endif #if defined(DEW_HEATER_2_PIN) digitalWrite(DEW_HEATER_2_PIN, HIGH); #endif + updateConsoleText(dewHeaterLine, F("Enable Dew Heater... OK")); #endif #if (USE_RA_END_SWITCH == 1 || USE_DEC_END_SWITCH == 1) + int endSwitchesLine = addConsoleText(F("Init End Switches...")); LOG(DEBUG_ANY, "[SYSTEM]: Init EndSwitches..."); mount.setupEndSwitches(); + updateConsoleText(endSwitchesLine, F("Init End Switches... OK")); #endif ///////////////////////////////// // Microstepping/driver pins ///////////////////////////////// + int raLine = addConsoleText(F("Init RA axis...")); + LOG(DEBUG_ANY, "[SYSTEM]: Initializing RA microstepping/driver pins..."); pinMode(RA_EN_PIN, OUTPUT); digitalWrite(RA_EN_PIN, LOW); // ENABLE, LOW to enable #if RA_DRIVER_TYPE == DRIVER_TYPE_TMC2209_STANDALONE || RA_DRIVER_TYPE == DRIVER_TYPE_A4988_GENERIC @@ -174,12 +206,25 @@ void setup() #endif #endif #if RA_DRIVER_TYPE == DRIVER_TYPE_TMC2209_UART + LOG(DEBUG_ANY, "[SYSTEM]: Initializing TMC2209 UART pins and Serial port for RA..."); // include TMC2209 UART pins + #if defined(RA_DIAG_PIN) pinMode(RA_DIAG_PIN, INPUT); + #endif + #ifdef RA_SERIAL_PORT - RA_SERIAL_PORT.begin(57600); // Start HardwareSerial comms with driver + #ifdef OAE + RA_SERIAL_PORT.begin(57600, SERIAL_8N1, RA_TX_PIN, RA_RX_PIN); + #else + RA_SERIAL_PORT.begin(57600); // Start HardwareSerial comms with driver + #endif + // #endif #endif + updateConsoleText(raLine, F("Init RA axis... OK")); + + int decLine = addConsoleText(F("Init DEC axis...")); + LOG(DEBUG_ANY, "[SYSTEM]: Initializing DEC driver pin %s...", String(DEC_EN_PIN).c_str()); pinMode(DEC_EN_PIN, OUTPUT); digitalWrite(DEC_EN_PIN, LOW); // ENABLE, LOW to enable #if DEC_DRIVER_TYPE == DRIVER_TYPE_TMC2209_STANDALONE || DEC_DRIVER_TYPE == DRIVER_TYPE_A4988_GENERIC @@ -193,15 +238,27 @@ void setup() digitalWrite(DEC_MS2_PIN, HIGH); // MS3 #endif #endif + #if DEC_DRIVER_TYPE == DRIVER_TYPE_TMC2209_UART + LOG(DEBUG_ANY, "[SYSTEM]: Initializing TMC2209 UART pins and Serial port for DEC..."); // include TMC2209 UART pins + #if defined(DEC_DIAG_PIN) pinMode(DEC_DIAG_PIN, INPUT); + #endif #ifdef DEC_SERIAL_PORT + #ifdef OAE + DEC_SERIAL_PORT.begin(57600, SERIAL_8N1, DEC_TX_PIN, DEC_RX_PIN); + #else DEC_SERIAL_PORT.begin(57600); // Start HardwareSerial comms with driver + #endif #endif #endif + updateConsoleText(decLine, F("Init DEC axis... OK")); + LOG(DEBUG_ANY, "[SYSTEM]: RA/DEC init complete..."); #if (AZ_STEPPER_TYPE != STEPPER_TYPE_NONE) + int azLine = addConsoleText(F("Init AZ axis...")); + LOG(DEBUG_ANY, "[SYSTEM]: Initializing AZ microstepping/driver pins..."); pinMode(AZ_EN_PIN, OUTPUT); digitalWrite(AZ_EN_PIN, HIGH); // Logic HIGH to disable the driver initally #if AZ_DRIVER_TYPE == DRIVER_TYPE_TMC2209_UART @@ -211,9 +268,12 @@ void setup() AZ_SERIAL_PORT.begin(57600); // Start HardwareSerial comms with driver #endif #endif + updateConsoleText(azLine, F("Init AZ axis... OK")); #endif #if (ALT_STEPPER_TYPE != STEPPER_TYPE_NONE) + int altLine = addConsoleText(F("Init ALT axis...")); + LOG(DEBUG_ANY, "[SYSTEM]: Initializing ALT microstepping/driver pins..."); pinMode(ALT_EN_PIN, OUTPUT); digitalWrite(ALT_EN_PIN, HIGH); // Logic HIGH to disable the driver initally #if ALT_DRIVER_TYPE == DRIVER_TYPE_TMC2209_UART @@ -223,9 +283,11 @@ void setup() ALT_SERIAL_PORT.begin(57600); // Start HardwareSerial comms with driver #endif #endif + updateConsoleText(altLine, F("Init ALT axis... OK")); #endif #if (FOCUS_STEPPER_TYPE != STEPPER_TYPE_NONE) + int focusLine = addConsoleText(F("Init Focuser...")); LOG(DEBUG_FOCUS, "[FOCUS]: setup(): focus disabling enable pin"); pinMode(FOCUS_EN_PIN, OUTPUT); digitalWrite(FOCUS_EN_PIN, HIGH); // Logic HIGH to disable the driver initally @@ -236,38 +298,41 @@ void setup() FOCUS_SERIAL_PORT.begin(57600); // Start HardwareSerial comms with driver #endif #endif + updateConsoleText(focusLine, F("Init Focuser... OK")); #endif // end microstepping ------------------- -#if USE_HALL_SENSOR_RA_AUTOHOME == 1 +#if USE_HALL_SENSOR_RA_AUTOHOME == 1 || USE_HALL_SENSOR_DEC_AUTOHOME == 1 + int homingLine = addConsoleText(F("Init homing sensors...")); + #if USE_HALL_SENSOR_RA_AUTOHOME == 1 pinMode(RA_HOMING_SENSOR_PIN, INPUT); -#endif + #endif -#if USE_HALL_SENSOR_DEC_AUTOHOME == 1 + #if USE_HALL_SENSOR_DEC_AUTOHOME == 1 pinMode(DEC_HOMING_SENSOR_PIN, INPUT); + #endif + updateConsoleText(homingLine, F("Init homing sensors... OK")); #endif -#if (INFO_DISPLAY_TYPE != INFO_DISPLAY_TYPE_NONE) - int eepromLine = mount.getInfoDisplay()->addConsoleText(F("INIT EEPROM...")); -#endif + LOG(DEBUG_ANY, "[SYSTEM]: Initializing EEPROM store..."); + int eepromLine = addConsoleText(F("INIT EEPROM...")); - LOG(DEBUG_ANY, "[SYSTEM]: Get EEPROM store ready..."); EEPROMStore::initialize(); LOG(DEBUG_ANY, "[SYSTEM]: EEPROM store ready!"); - -#if (INFO_DISPLAY_TYPE != INFO_DISPLAY_TYPE_NONE) - mount.getInfoDisplay()->updateConsoleText(eepromLine, F("INIT EEPROM... OK")); -#endif + updateConsoleText(eepromLine, F("INIT EEPROM... OK")); // Calling the LCD startup here, I2C can't be found if called earlier #if DISPLAY_TYPE != DISPLAY_TYPE_NONE LOG(DEBUG_ANY, "[SYSTEM]: Get LCD ready..."); + int lcdLine = addConsoleText(F("Init LCD...")); lcdMenu.startup(); // Show a splash screen lcdMenu.setCursor(0, 0); #ifdef OAM lcdMenu.printMenu(" OpenAstroMount"); + #elif defined(OAE) + lcdMenu.printMenu("OpenAstroExplorer"); #else lcdMenu.printMenu("OpenAstroTracker"); #endif @@ -330,6 +395,7 @@ void setup() #if SUPPORT_INFO_DISPLAY == 1 lcdMenu.addItem("INFO", Status_Menu); #endif + updateConsoleText(lcdLine, F("Init LCD... OK")); #endif // DISPLAY_TYPE > 0 @@ -337,16 +403,16 @@ void setup() // Create the command processor singleton LOG(DEBUG_ANY, "[SYSTEM]: Initialize LX200 handler..."); + int commandProcessorLine = addConsoleText(F("Init MEADE handler...")); MeadeCommandProcessor::createProcessor(&mount, &lcdMenu); + updateConsoleText(commandProcessorLine, F("Init MEADE handler... OK")); #if (WIFI_ENABLED == 1) LOG(DEBUG_ANY, "[SYSTEM]: Setup Wifi..."); wifiControl.setup(); #endif -#if (INFO_DISPLAY_TYPE != INFO_DISPLAY_TYPE_NONE) - int stepperLine = mount.getInfoDisplay()->addConsoleText(F("INIT STEPPERS...")); -#endif + int stepperLine = addConsoleText(F("Energize Steppers...")); // Configure the mount // Delay for a while to get UARTs booted... @@ -419,6 +485,12 @@ void setup() #if (AZ_STEPPER_TYPE != STEPPER_TYPE_NONE) LOG(DEBUG_ANY, "[STEPPERS]: Configure AZ stepper..."); + LOG(DEBUG_ANY, "[STEPPERS]: AZ Microsteps : %d", AZ_MICROSTEPPING); + LOG(DEBUG_ANY, "[STEPPERS]: AZ Stepper SPR : %d", AZ_STEPPER_SPR); + LOG(DEBUG_ANY, "[STEPPERS]: AZ Circumference : %f", AZ_CIRCUMFERENCE); + LOG(DEBUG_ANY, "[STEPPERS]: AZ steps/rev : %f", AZIMUTH_STEPS_PER_REV); + LOG(DEBUG_ANY, "[STEPPERS]: AZ steps/deg : %f", mount.getStepsPerDegree(AZIMUTH_STEPS)); + LOG(DEBUG_ANY, "[STEPPERS]: AZ steps/minute : %f", AZIMUTH_STEPS_PER_ARC_MINUTE); mount.configureAZStepper(AZmotorPin1, AZmotorPin2, AZ_STEPPER_SPEED, AZ_STEPPER_ACCELERATION); #if AZ_DRIVER_TYPE == DRIVER_TYPE_TMC2209_UART LOG(DEBUG_ANY, "[STEPPERS]: Configure AZ driver..."); @@ -431,6 +503,12 @@ void setup() #endif #if (ALT_STEPPER_TYPE != STEPPER_TYPE_NONE) LOG(DEBUG_ANY, "[STEPPERS]: Configure Alt stepper..."); + LOG(DEBUG_ANY, "[STEPPERS]: ALT Microsteps : %d", ALT_MICROSTEPPING); + LOG(DEBUG_ANY, "[STEPPERS]: ALT Stepper SPR : %d", ALT_STEPPER_SPR); + LOG(DEBUG_ANY, "[STEPPERS]: ALT Circumference : %f", ALT_CIRCUMFERENCE); + LOG(DEBUG_ANY, "[STEPPERS]: ALT steps/rev : %f", ALTITUDE_STEPS_PER_REV); + LOG(DEBUG_ANY, "[STEPPERS]: ALT steps/deg : %f", mount.getStepsPerDegree(ALTITUDE_STEPS)); + LOG(DEBUG_ANY, "[STEPPERS]: ALT steps/minute : %f", ALTITUDE_STEPS_PER_ARC_MINUTE); mount.configureALTStepper(ALTmotorPin1, ALTmotorPin2, ALT_STEPPER_SPEED, ALT_STEPPER_ACCELERATION); #if ALT_DRIVER_TYPE == DRIVER_TYPE_TMC2209_UART LOG(DEBUG_ANY, "[STEPPERS]: Configure ALT driver..."); @@ -457,13 +535,10 @@ void setup() #endif #endif -#if (INFO_DISPLAY_TYPE != INFO_DISPLAY_TYPE_NONE) - mount.getInfoDisplay()->updateConsoleText(stepperLine, F("INIT STEPPERS... OK")); -#endif + LOG(DEBUG_ANY, "[SYSTEM]: Energize Steppers... OK"); + updateConsoleText(stepperLine, F("Energize Steppers... OK")); -#if (INFO_DISPLAY_TYPE != INFO_DISPLAY_TYPE_NONE) - mount.getInfoDisplay()->addConsoleText(F("CONFIGURING...")); -#endif + int configureLine = addConsoleText(F("Configure Mount...")); LOG(DEBUG_ANY, "[SYSTEM]: Read Configuration..."); @@ -484,7 +559,7 @@ void setup() // Setup service to periodically service the steppers. #if defined(ESP32) - + LOG(DEBUG_ANY, "[SYSTEM]: Setup StepperControlTask on Core 0..."); disableCore0WDT(); xTaskCreatePinnedToCore(stepperControlTask, // Function to run on this core "StepperControl", // Name of this task @@ -504,10 +579,10 @@ void setup() #endif #endif + updateConsoleText(configureLine, F("Configure Mount... OK")); + #if UART_CONNECTION_TEST_TX == 1 - #if (INFO_DISPLAY_TYPE != INFO_DISPLAY_TYPE_NONE) - int testLine = mount.getInfoDisplay()->addConsoleText(F("TEST STEPPERS...")); - #endif + int testLine = addConsoleText(F("Test UARTs...")); #if RA_DRIVER_TYPE == DRIVER_TYPE_TMC2209_UART LOG(DEBUG_STEPPERS, "[STEPPERS]: Moving RA axis using UART commands..."); mount.testRA_UART_TX(); @@ -519,9 +594,7 @@ void setup() mount.testDEC_UART_TX(); LOG(DEBUG_STEPPERS, "[STEPPERS]: Finished moving DEC axis using UART commands."); #endif - #if (INFO_DISPLAY_TYPE != INFO_DISPLAY_TYPE_NONE) - mount.getInfoDisplay()->updateConsoleText(testLine, F("TEST STEPPERS... OK")); - #endif + updateConsoleText(testLine, F("Test UARTs... OK")); #endif LOG(DEBUG_ANY, "[SYSTEM]: Setting %s hemisphere...", inNorthernHemisphere ? "northern" : "southern"); @@ -535,11 +608,12 @@ void setup() mount.bootComplete(); LOG(DEBUG_ANY, "[SYSTEM]: Boot complete!"); + addConsoleText(F("BOOT COMPLETE!")); #if (INFO_DISPLAY_TYPE != INFO_DISPLAY_TYPE_NONE) - mount.getInfoDisplay()->addConsoleText(F("BOOT COMPLETE!")); - delay(250); + delay(500); mount.getInfoDisplay()->setConsoleMode(false); #endif + #if TEST_VERIFY_MODE == 1 TestMenu::getCurrentMenu()->display(); #endif diff --git a/src/fonts128x64.h b/src/fonts128x64.h index be6c8bcb..a0aae3dd 100644 --- a/src/fonts128x64.h +++ b/src/fonts128x64.h @@ -1,3 +1,4 @@ +#pragma once #include // Font generated or edited with the glyphEditor diff --git a/src/testmenu.cpp b/src/testmenu.cpp index 6620f38c..1b0d1763 100644 --- a/src/testmenu.cpp +++ b/src/testmenu.cpp @@ -263,7 +263,11 @@ void TestMenu::listHardware() const #ifdef OAM Serial.println(F("OpenAstroMount (OAM)")); #else + #ifdef OAE + Serial.println(F("OpenAstroExplorer (OAE)")); + #else Serial.println(F("OpenAstroTracker (OAT)")); + #endif #endif while (p->length() > 0) @@ -529,7 +533,11 @@ void TestMenu::display() const #ifdef OAM Serial.println(F("*** OpenAstroMount (OAM) Test Menu ***")); #else + #ifdef OAE + Serial.println(F("*** OpenAstroExplorer (OAE) Test Menu ***")); + #else Serial.println(F("** OpenAstroTracker (OAT) Test Menu **")); + #endif #endif Serial.print(F("************* ")); Serial.print(freeMemory()); diff --git a/src/testmenudef.hpp b/src/testmenudef.hpp index eb959707..cbf18526 100644 --- a/src/testmenudef.hpp +++ b/src/testmenudef.hpp @@ -68,5 +68,5 @@ TestMenuItem menuItems[] = { TestMenuItem(MENU_FACTORY_RESET), }; -TestMenu mainTestMenu(0, "OAT/OAM Testing menu", "", menuItems, sizeof(menuItems) / sizeof(menuItems[0])); +TestMenu mainTestMenu(0, "OAT/OAM/OAE Testing menu", "", menuItems, sizeof(menuItems) / sizeof(menuItems[0])); #endif \ No newline at end of file