diff --git a/Tools/mqttecho/README.md b/Scripts/MQTTDemo/README.md similarity index 98% rename from Tools/mqttecho/README.md rename to Scripts/MQTTDemo/README.md index c0aac8d366..3f25da4bab 100644 --- a/Tools/mqttecho/README.md +++ b/Scripts/MQTTDemo/README.md @@ -1,7 +1,7 @@ # Requirements -- [Python](https://www.python.org/downloads/) - runs the demo script, `echo.py`, which runs broker and `echo` client +- [Python](https://www.python.org/downloads/) - runs the demo script, `echo.py`, which runs broker and `echo` client; additional pip dependencies: - [Paho](https://www.eclipse.org/paho/index.php?page=clients/python/index.php) - used to implement the `echo` MQTT client - [Colorama](https://pypi.org/project/colorama/) - used to colorize log output of `echo.py` diff --git a/Tools/mqttecho/echo.py b/Scripts/MQTTDemo/echo.py similarity index 100% rename from Tools/mqttecho/echo.py rename to Scripts/MQTTDemo/echo.py diff --git a/Tools/mqttecho/mosquitto.conf b/Scripts/MQTTDemo/mosquitto.conf similarity index 100% rename from Tools/mqttecho/mosquitto.conf rename to Scripts/MQTTDemo/mosquitto.conf diff --git a/Tools/mqttecho/passwords.txt b/Scripts/MQTTDemo/passwords.txt similarity index 100% rename from Tools/mqttecho/passwords.txt rename to Scripts/MQTTDemo/passwords.txt diff --git a/WHATS_NEW_UNIFIED.md b/WHATS_NEW_UNIFIED.md index e4a0cbbaaf..57d015f87e 100644 --- a/WHATS_NEW_UNIFIED.md +++ b/WHATS_NEW_UNIFIED.md @@ -3,7 +3,7 @@ Version 3.5beta2_102 * Duet3d 3.5beta2 * Enable MQTT support (requires ESP firmware >= V2.1b3) * STM32F4: Add support for MCP2518FD SP CAN-FD interfaces -* SYM32F4: Improved SPI1 support (allow interrupt operation) +* STM32F4: Improved SPI1 support (allow interrupt operation) * Increase open files to 20 * Ensure ESP32 modules are fully disabled by M552 s-1 diff --git a/src/GCodes/GCodeBuffer/StringParser.cpp b/src/GCodes/GCodeBuffer/StringParser.cpp index f2f0f5516d..c9cf049bae 100644 --- a/src/GCodes/GCodeBuffer/StringParser.cpp +++ b/src/GCodes/GCodeBuffer/StringParser.cpp @@ -35,7 +35,7 @@ StringParser::StringParser(GCodeBuffer& gcodeBuffer) noexcept void StringParser::Init() noexcept { gcodeLineEnd = 0; - commandStart = commandLength = 0; // set both to zero so that calls to GetFilePosition don't return negative values + commandStart = commandCharsRead = 0; // set both to zero so that calls to GetFilePosition don't return negative values readPointer = -1; hadLineNumber = hadChecksum = overflowed = seenExpression = false; computedChecksum = 0; @@ -74,6 +74,11 @@ inline void StringParser::StoreAndAddToChecksum(char c) noexcept // If true, it is complete and ready to be acted upon and 'indent' is the number of leading white space characters. bool StringParser::Put(char c) noexcept { + if (c != 0) + { + ++commandCharsRead; + } + // We now discard CR if we are reading from file. It makes line number counting easier and it's unlikely that a pre-OSX Mac will be used with a Duet. // When not reading from file we still accept CR as a line terminator, for compatibility with Putty and some other terminal emulators. if (c == '\r' && gb.IsDoingFile()) @@ -81,11 +86,6 @@ bool StringParser::Put(char c) noexcept return false; } - if (c != 0) - { - ++commandLength; - } - if (c == 0 || c == '\n' || c == '\r') { return LineFinished(); @@ -1167,7 +1167,7 @@ FilePosition StringParser::GetFilePosition() const noexcept # endif ) { - return gb.LatestMachineState().fileState.GetPosition() - gb.fileInput->BytesCached() - commandLength + commandStart; + return gb.LatestMachineState().fileState.GetPosition() - gb.fileInput->BytesCached() - commandCharsRead + commandStart; } #endif return noFilePosition; diff --git a/src/GCodes/GCodeBuffer/StringParser.h b/src/GCodes/GCodeBuffer/StringParser.h index 6510ab10ee..2120e9e48f 100644 --- a/src/GCodes/GCodeBuffer/StringParser.h +++ b/src/GCodes/GCodeBuffer/StringParser.h @@ -132,7 +132,7 @@ class StringParser unsigned int commandStart; // Index in the buffer of the command letter of this command unsigned int parameterStart; unsigned int commandEnd; // Index in the buffer of one past the last character of this command - unsigned int commandLength; // Number of characters we read to build this command including the final \r or \n + unsigned int commandCharsRead; // Number of characters we read to build this command including the final \r or \n unsigned int braceCount; // how many nested { } we are inside unsigned int gcodeLineEnd; // Number of characters in the entire line of gcode ParameterLettersBitmap parametersPresent; // which parameters are present in this command diff --git a/src/GCodes/GCodes.h b/src/GCodes/GCodes.h index 5ec7b1fe48..cdd3766132 100644 --- a/src/GCodes/GCodes.h +++ b/src/GCodes/GCodes.h @@ -241,6 +241,12 @@ class GCodes return workplaceCoordinates[GetConstMovementState(gb).currentCoordinateSystem][axis]; } +#if SUPPORT_KEEPOUT_ZONES + size_t GetNumKeepoutZones() const noexcept { return (keepoutZone.IsDefined()) ? 1 : 0; } + bool IsKeepoutZoneDefined(size_t n) const noexcept { return n == 0 && keepoutZone.IsDefined(); } + const KeepoutZone *GetKeepoutZone(size_t) const noexcept { return &keepoutZone; } +#endif + #if SUPPORT_OBJECT_MODEL float GetWorkplaceOffset(size_t axis, size_t workplaceNumber) const noexcept { diff --git a/src/GCodes/KeepoutZone.cpp b/src/GCodes/KeepoutZone.cpp index a8b6e2530f..4fbbf60544 100644 --- a/src/GCodes/KeepoutZone.cpp +++ b/src/GCodes/KeepoutZone.cpp @@ -15,6 +15,42 @@ #define ARC_DEBUG 0 +#define OBJECT_MODEL_FUNC(...) OBJECT_MODEL_FUNC_BODY(KeepoutZone, __VA_ARGS__) +#define OBJECT_MODEL_FUNC_IF(...) OBJECT_MODEL_FUNC_IF_BODY(KeepoutZone, __VA_ARGS__) + +constexpr ObjectModelArrayTableEntry KeepoutZone::objectModelArrayTable[] = +{ + // 0. Axis coordinates + { + nullptr, // no lock needed + [] (const ObjectModel *self, const ObjectExplorationContext&) noexcept -> size_t { return reprap.GetGCodes().GetTotalAxes(); }, + [] (const ObjectModel *self, ObjectExplorationContext& context) noexcept -> ExpressionValue + { return (((const KeepoutZone*)self)->axesChecked.IsBitSet(context.GetLastIndex())) ? ExpressionValue(self, 1) : ExpressionValue(nullptr); } + }, +}; + +DEFINE_GET_OBJECT_MODEL_ARRAY_TABLE(KeepoutZone) + +constexpr ObjectModelTableEntry KeepoutZone::objectModelTable[] = +{ + // Within each group, these entries must be in alphabetical order + // 0. KeepoutZone members + { "active", OBJECT_MODEL_FUNC(self->active), ObjectModelEntryFlags::none }, + { "coords", OBJECT_MODEL_FUNC_ARRAY(0), ObjectModelEntryFlags::none }, + // 1. KeepoutZone.coords[] members + { "max", OBJECT_MODEL_FUNC(self->coords[context.GetLastIndex()][1]), ObjectModelEntryFlags::none }, + { "min", OBJECT_MODEL_FUNC(self->coords[context.GetLastIndex()][0]), ObjectModelEntryFlags::none }, +}; + +constexpr uint8_t KeepoutZone::objectModelTableDescriptor[] = +{ + 2, // number of sections + 2, + 2 +}; + +DEFINE_GET_OBJECT_MODEL_TABLE(KeepoutZone) + GCodeResult KeepoutZone::Configure(GCodeBuffer &gb, const StringRef &reply) THROWS(GCodeException) { // See if any axes have been given @@ -36,14 +72,21 @@ GCodeResult KeepoutZone::Configure(GCodeBuffer &gb, const StringRef &reply) THRO } // See if enabled or disabled + bool seen = false; if (gb.Seen('S')) { + seen = true; active = (gb.GetUIValue() != 0); } else if (seenAxis) { active = true; } + + if (seenAxis || seen) + { + reprap.MoveUpdated(); + } else if (axesChecked.IsEmpty()) { reply.copy("No keepout zone"); diff --git a/src/GCodes/KeepoutZone.h b/src/GCodes/KeepoutZone.h index d1fd172763..70b89cad1e 100644 --- a/src/GCodes/KeepoutZone.h +++ b/src/GCodes/KeepoutZone.h @@ -12,16 +12,19 @@ #if SUPPORT_KEEPOUT_ZONES +#include #include "GCodeException.h" #include // This class represents a keepout zone in the form of a hypercuboid -class KeepoutZone +class KeepoutZone INHERIT_OBJECT_MODEL { public: // Constructor KeepoutZone() noexcept : active(false) { } // the BitMap default constructor will clear axesChecked + bool IsDefined() const noexcept { return !axesChecked.IsEmpty(); } + // Configure or report this zone GCodeResult Configure(GCodeBuffer& gb, const StringRef& reply) THROWS(GCodeException); @@ -40,6 +43,9 @@ class KeepoutZone AxesBitmap cosineAxes, AxesBitmap sineAxes, bool clockwise, bool wholeCircle) const noexcept; +protected: + DECLARE_OBJECT_MODEL_WITH_ARRAYS + private: AxesBitmap axesChecked; // which axes have defined limits float coords[MaxAxes][2]; // the lower and upper limits for each axis, lower < upper diff --git a/src/Movement/Move.cpp b/src/Movement/Move.cpp index 7911f20f22..65bb1da29b 100644 --- a/src/Movement/Move.cpp +++ b/src/Movement/Move.cpp @@ -79,19 +79,27 @@ constexpr ObjectModelArrayTableEntry Move::objectModelArrayTable[] = nullptr, // no lock needed [] (const ObjectModel *self, const ObjectExplorationContext&) noexcept -> size_t { return ARRAY_SIZE(rings); }, [] (const ObjectModel *self, ObjectExplorationContext& context) noexcept -> ExpressionValue { return ExpressionValue(&((const Move*)self)->rings[context.GetLastIndex()]); } - } + }, #if SUPPORT_COORDINATE_ROTATION - , // 3. Rotation centre coordinates { nullptr, // no lock needed [] (const ObjectModel *self, const ObjectExplorationContext&) noexcept -> size_t { return 2; }, [] (const ObjectModel *self, ObjectExplorationContext& context) noexcept -> ExpressionValue { return ExpressionValue(reprap.GetGCodes().GetRotationCentre(context.GetLastIndex())); } - } -}; + }, +#endif +#if SUPPORT_KEEPOUT_ZONES + // 4. Keepout zone list + { + nullptr, // no lock needed + [] (const ObjectModel *self, const ObjectExplorationContext&) noexcept -> size_t { return reprap.GetGCodes().GetNumKeepoutZones(); }, + [] (const ObjectModel *self, ObjectExplorationContext& context) noexcept -> ExpressionValue + { return (reprap.GetGCodes().IsKeepoutZoneDefined(context.GetLastIndex())) ? ExpressionValue(reprap.GetGCodes().GetKeepoutZone(context.GetLastIndex())) : ExpressionValue(nullptr); } + }, #endif +}; DEFINE_GET_OBJECT_MODEL_ARRAY_TABLE(Move) @@ -106,6 +114,9 @@ constexpr ObjectModelTableEntry Move::objectModelTable[] = { "currentMove", OBJECT_MODEL_FUNC(self, 2), ObjectModelEntryFlags::live }, { "extruders", OBJECT_MODEL_FUNC_ARRAY(1), ObjectModelEntryFlags::live }, { "idle", OBJECT_MODEL_FUNC(self, 1), ObjectModelEntryFlags::none }, +#if SUPPORT_KEEPOUT_ZONES + { "keepout", OBJECT_MODEL_FUNC_ARRAY(4), ObjectModelEntryFlags::none }, +#endif { "kinematics", OBJECT_MODEL_FUNC(self->kinematics), ObjectModelEntryFlags::none }, { "limitAxes", OBJECT_MODEL_FUNC_NOSELF(reprap.GetGCodes().LimitAxes()), ObjectModelEntryFlags::none }, { "noMovesBeforeHoming", OBJECT_MODEL_FUNC_NOSELF(reprap.GetGCodes().NoMovesBeforeHoming()), ObjectModelEntryFlags::none }, @@ -119,7 +130,6 @@ constexpr ObjectModelTableEntry Move::objectModelTable[] = { "travelAcceleration", OBJECT_MODEL_FUNC_NOSELF(InverseConvertAcceleration(reprap.GetGCodes().GetPrimaryMaxTravelAcceleration()), 1), ObjectModelEntryFlags::none }, { "virtualEPos", OBJECT_MODEL_FUNC_NOSELF(reprap.GetGCodes().GetCurrentMovementState(context).latestVirtualExtruderPosition, 5), ObjectModelEntryFlags::live }, { "workplaceNumber", OBJECT_MODEL_FUNC_NOSELF((int32_t)reprap.GetGCodes().GetPrimaryWorkplaceCoordinateSystemNumber() - 1), ObjectModelEntryFlags::none }, - { "workspaceNumber", OBJECT_MODEL_FUNC_NOSELF((int32_t)reprap.GetGCodes().GetPrimaryWorkplaceCoordinateSystemNumber()), ObjectModelEntryFlags::obsolete }, // 1. Move.Idle members { "factor", OBJECT_MODEL_FUNC_NOSELF(reprap.GetPlatform().GetIdleCurrentFactor(), 1), ObjectModelEntryFlags::none }, @@ -180,7 +190,7 @@ constexpr ObjectModelTableEntry Move::objectModelTable[] = constexpr uint8_t Move::objectModelTableDescriptor[] = { 9 + SUPPORT_COORDINATE_ROTATION, - 18 + SUPPORT_WORKPLACE_COORDINATES, + 17 + SUPPORT_WORKPLACE_COORDINATES + SUPPORT_KEEPOUT_ZONES, 2, 5 + SUPPORT_LASER, 3, diff --git a/src/Platform/Platform.cpp b/src/Platform/Platform.cpp index 3f5a14584f..c97cff79a5 100644 --- a/src/Platform/Platform.cpp +++ b/src/Platform/Platform.cpp @@ -319,6 +319,7 @@ constexpr ObjectModelTableEntry Platform::objectModelTable[] = #ifndef DUET_NG { "percentStstCurrent", OBJECT_MODEL_FUNC((int32_t)(self->GetMotorCurrent(context.GetLastIndex(), 917))), ObjectModelEntryFlags::none }, #endif + { "reducedAcceleration", OBJECT_MODEL_FUNC(InverseConvertAcceleration(self->Acceleration(context.GetLastIndex(), true)), 1), ObjectModelEntryFlags::none }, { "speed", OBJECT_MODEL_FUNC(InverseConvertSpeedToMmPerMin(self->MaxFeedrate(context.GetLastIndex())), 1), ObjectModelEntryFlags::none }, { "stepsPerMm", OBJECT_MODEL_FUNC(self->driveStepsPerUnit[context.GetLastIndex()], 2), ObjectModelEntryFlags::none }, { "userPosition", OBJECT_MODEL_FUNC_NOSELF(reprap.GetGCodes().GetUserCoordinate(reprap.GetGCodes().GetCurrentMovementState(context), context.GetLastIndex()), 3), ObjectModelEntryFlags::live }, @@ -326,7 +327,7 @@ constexpr ObjectModelTableEntry Platform::objectModelTable[] = { "workplaceOffsets", OBJECT_MODEL_FUNC_ARRAY(1), ObjectModelEntryFlags::none }, // 4. move.extruders[] members - { "acceleration", OBJECT_MODEL_FUNC(InverseConvertAcceleration(self->NormalAcceleration(ExtruderToLogicalDrive(context.GetLastIndex()))), 1), ObjectModelEntryFlags::none }, + { "acceleration", OBJECT_MODEL_FUNC(InverseConvertAcceleration(self->NormalAcceleration(ExtruderToLogicalDrive(context.GetLastIndex()))), 1), ObjectModelEntryFlags::none }, { "current", OBJECT_MODEL_FUNC((int32_t)(self->GetMotorCurrent(ExtruderToLogicalDrive(context.GetLastIndex()), 906))), ObjectModelEntryFlags::none }, { "driver", OBJECT_MODEL_FUNC(self->extruderDrivers[context.GetLastIndex()]), ObjectModelEntryFlags::none }, { "factor", OBJECT_MODEL_FUNC_NOSELF(reprap.GetGCodes().GetExtrusionFactor(context.GetLastIndex()), 3), ObjectModelEntryFlags::none }, @@ -388,10 +389,10 @@ constexpr uint8_t Platform::objectModelTableDescriptor[] = 0, // section 2: vIn #endif #ifdef DUET_NG // Duet WiFi/Ethernet doesn't have settable standstill current - 20, // section 3: move.axes[] + 21, // section 3: move.axes[] 15, // section 4: move.extruders[] #else - 21, // section 3: move.axes[] + 22, // section 3: move.axes[] 16, // section 4: move.extruders[] #endif 3, // section 5: move.extruders[].nonlinear diff --git a/src/Tools/Spindle.cpp b/src/Tools/Spindle.cpp index 5b45675a49..eff81e056a 100644 --- a/src/Tools/Spindle.cpp +++ b/src/Tools/Spindle.cpp @@ -152,11 +152,8 @@ void Spindle::SetRpm(uint32_t rpm) noexcept void Spindle::SetState(const SpindleState newState) noexcept { - if (state != newState) - { - state = newState; - SetRpm(configuredRpm); // Depending on the configured SpindleState this might actually stop the spindle - } + state = newState; + SetRpm(configuredRpm); // depending on the configured SpindleState this might actually stop the spindle } // End diff --git a/src/Version.h b/src/Version.h index 246878cf2d..b9ef126224 100644 --- a/src/Version.h +++ b/src/Version.h @@ -10,7 +10,7 @@ #ifndef VERSION // Note: the complete VERSION string must be in standard version number format and must not contain spaces! This is so that DWC can parse it. -# define MAIN_VERSION "3.5beta2_102" +# define MAIN_VERSION "3.5beta2+_103" # ifdef USE_CAN0 # define VERSION_SUFFIX "(CAN0)" # else