diff options
-rw-r--r-- | src/CAN/CanInterface.cpp | 41 | ||||
-rw-r--r-- | src/CAN/CanInterface.h | 2 | ||||
-rw-r--r-- | src/CAN/CanMotion.cpp | 8 | ||||
-rw-r--r-- | src/CAN/CanMotion.h | 2 | ||||
-rw-r--r-- | src/Duet3_V06/Pins_Duet3_V06.h | 4 | ||||
-rw-r--r-- | src/GCodes/GCodes2.cpp | 43 | ||||
-rw-r--r-- | src/Heating/Heat.cpp | 32 | ||||
-rw-r--r-- | src/Heating/Heater.cpp | 7 | ||||
-rw-r--r-- | src/Heating/Heater.h | 4 | ||||
-rw-r--r-- | src/Heating/LocalHeater.h | 1 | ||||
-rw-r--r-- | src/Heating/RemoteHeater.cpp | 17 | ||||
-rw-r--r-- | src/Heating/RemoteHeater.h | 1 | ||||
-rw-r--r-- | src/Movement/DDA.cpp | 87 | ||||
-rw-r--r-- | src/Movement/DDA.h | 4 | ||||
-rw-r--r-- | src/Movement/DriveMovement.cpp | 4 | ||||
-rw-r--r-- | src/Platform.cpp | 69 | ||||
-rw-r--r-- | src/Platform.h | 2 | ||||
-rw-r--r-- | src/Version.h | 2 |
18 files changed, 242 insertions, 88 deletions
diff --git a/src/CAN/CanInterface.cpp b/src/CAN/CanInterface.cpp index 326a4d60..c3eda44b 100644 --- a/src/CAN/CanInterface.cpp +++ b/src/CAN/CanInterface.cpp @@ -476,7 +476,7 @@ static bool SetRemoteDriverValues(const CanDriversData& data, const StringRef& r { break; } - CanMessageBuffer * buf = CanMessageBuffer::Allocate(); + CanMessageBuffer * const buf = CanMessageBuffer::Allocate(); if (buf == nullptr) { reply.lcat("No CAN buffer available"); @@ -514,7 +514,7 @@ static bool SetRemoteDriverStates(const CanDriversList& drivers, const StringRef { break; } - CanMessageBuffer * buf = CanMessageBuffer::Allocate(); + CanMessageBuffer * const buf = CanMessageBuffer::Allocate(); if (buf == nullptr) { reply.lcat("No CAN buffer available"); @@ -697,6 +697,12 @@ bool CanInterface::SetRemoteDriverMicrostepping(const CanDriversData& data, cons return SetRemoteDriverValues(data, reply, CanMessageType::setMicrostepping); } +// Set the pressure advance on remote drivers, returning true if successful +bool CanInterface::SetRemotePressureAdvance(const CanDriversData& data, const StringRef& reply) +{ + return SetRemoteDriverValues(data, reply, CanMessageType::setPressureAdvance); +} + // Handle M569 for a remote driver GCodeResult CanInterface::ConfigureRemoteDriver(DriverId driver, GCodeBuffer& gb, const StringRef& reply) pre(driver.IsRemote()) @@ -734,8 +740,7 @@ GCodeResult CanInterface::SetRemoteDriverStallParameters(const CanDriversList& d return GCodeResult::ok; } -// Get diagnostics from and expansion board -GCodeResult CanInterface::RemoteDiagnostics(MessageType mt, uint32_t boardAddress, GCodeBuffer& gb, const StringRef& reply) +static GCodeResult GetRemoteInfo(uint8_t infoType, uint32_t boardAddress, GCodeBuffer& gb, const StringRef& reply) { if (boardAddress > CanId::MaxNormalAddress) { @@ -750,11 +755,31 @@ GCodeResult CanInterface::RemoteDiagnostics(MessageType mt, uint32_t boardAddres return GCodeResult::error; } + const CanRequestId rid = CanInterface::AllocateRequestId(boardAddress); + auto msg = buf->SetupRequestMessage<CanMessageReturnInfo>(rid, CanId::MasterAddress, (CanAddress)boardAddress); + msg->type = infoType; + return CanInterface::SendRequestAndGetStandardReply(buf, rid, reply); +} + +// Get diagnostics from and expansion board +GCodeResult CanInterface::RemoteDiagnostics(MessageType mt, uint32_t boardAddress, GCodeBuffer& gb, const StringRef& reply) +{ reply.printf("Diagnostics for board %u:", (unsigned int)boardAddress); - const CanRequestId rid = AllocateRequestId(boardAddress); - auto msg = buf->SetupRequestMessage<CanMessageDiagnostics>(rid, CanId::MasterAddress, (CanAddress)boardAddress); - msg->type = 0; - return SendRequestAndGetStandardReply(buf, rid, reply); + GCodeResult rslt = GetRemoteInfo(CanMessageReturnInfo::typeFirmwareVersion, boardAddress, gb, reply); + if (rslt == GCodeResult::ok) + { + rslt = GetRemoteInfo(CanMessageReturnInfo::typeMemory, boardAddress, gb, reply); + } + if (rslt == GCodeResult::ok) + { + rslt = GetRemoteInfo(CanMessageReturnInfo::typePressureAdvance, boardAddress, gb, reply); + } + return rslt; +} + +GCodeResult CanInterface::GetRemoteFirmwareDetails(uint32_t boardAddress, GCodeBuffer& gb, const StringRef& reply) +{ + return GetRemoteInfo(CanMessageReturnInfo::typeFirmwareVersion, boardAddress, gb, reply); } // Tell an expansion board to update diff --git a/src/CAN/CanInterface.h b/src/CAN/CanInterface.h index b201fed4..f66b4a4a 100644 --- a/src/CAN/CanInterface.h +++ b/src/CAN/CanInterface.h @@ -66,6 +66,7 @@ namespace CanInterface void SendResponse(CanMessageBuffer *buf); void SendBroadcast(CanMessageBuffer *buf); + GCodeResult GetRemoteFirmwareDetails(uint32_t boardAddress, GCodeBuffer& gb, const StringRef& reply); GCodeResult RemoteDiagnostics(MessageType mt, uint32_t boardAddress, GCodeBuffer& gb, const StringRef& reply); GCodeResult UpdateRemoteFirmware(uint32_t boardAddress, GCodeBuffer& gb, const StringRef& reply); @@ -76,6 +77,7 @@ namespace CanInterface bool SetRemoteStandstillCurrentPercent(const CanDriversData& data, const StringRef& reply); bool SetRemoteDriverCurrents(const CanDriversData& data, const StringRef& reply); bool SetRemoteDriverMicrostepping(const CanDriversData& data, const StringRef& reply); + bool SetRemotePressureAdvance(const CanDriversData& data, const StringRef& reply); GCodeResult ConfigureRemoteDriver(DriverId driver, GCodeBuffer& gb, const StringRef& reply); GCodeResult SetRemoteDriverStallParameters(const CanDriversList& drivers, GCodeBuffer& gb, const StringRef& reply); } diff --git a/src/CAN/CanMotion.cpp b/src/CAN/CanMotion.cpp index bea0c271..6a69b516 100644 --- a/src/CAN/CanMotion.cpp +++ b/src/CAN/CanMotion.cpp @@ -41,7 +41,7 @@ void CanMotion::StartMovement(const DDA& dda) // This is called by DDA::Prepare for each active CAN DM in the move // If steps == 0 then the drivers just need to be enabled -void CanMotion::AddMovement(const DDA& dda, const PrepParams& params, DriverId canDriver, int32_t steps) +void CanMotion::AddMovement(const DDA& dda, const PrepParams& params, DriverId canDriver, int32_t steps, bool usePressureAdvance) { // Search for the correct movement buffer CanMessageBuffer* buf = movementBufferList; @@ -71,9 +71,9 @@ void CanMotion::AddMovement(const DDA& dda, const PrepParams& params, DriverId c move->decelClocks = lrintf(params.decelTime * StepTimer::StepClockRate); move->initialSpeedFraction = params.initialSpeedFraction; move->finalSpeedFraction = params.finalSpeedFraction; + move->pressureAdvanceDrives = 0; move->deltaDrives = 0; //TODO move->endStopsToCheck = 0; //TODO - move->pressureAdvanceDrives = 0; //TODO move->stopAllDrivesOnEndstopHit = false; //TODO // Additional parameters for delta movements @@ -91,6 +91,10 @@ void CanMotion::AddMovement(const DDA& dda, const PrepParams& params, DriverId c } buf->msg.move.perDrive[canDriver.localDriver].steps = steps; + if (usePressureAdvance) + { + buf->msg.move.pressureAdvanceDrives |= 1u << canDriver.localDriver; + } } // This is called by DDA::Prepare when all DMs for CAN drives have been processed diff --git a/src/CAN/CanMotion.h b/src/CAN/CanMotion.h index 8d384c1c..da0f87eb 100644 --- a/src/CAN/CanMotion.h +++ b/src/CAN/CanMotion.h @@ -18,7 +18,7 @@ namespace CanMotion { void Init(); void StartMovement(const DDA& dda); - void AddMovement(const DDA& dda, const PrepParams& params, DriverId canDriver, int32_t steps); + void AddMovement(const DDA& dda, const PrepParams& params, DriverId canDriver, int32_t steps, bool usePressureAdvance); void FinishMovement(uint32_t moveStartTime); bool CanPrepareMove(); void InsertHiccup(uint32_t numClocks); diff --git a/src/Duet3_V06/Pins_Duet3_V06.h b/src/Duet3_V06/Pins_Duet3_V06.h index 1ed452d6..3b7a2c6f 100644 --- a/src/Duet3_V06/Pins_Duet3_V06.h +++ b/src/Duet3_V06/Pins_Duet3_V06.h @@ -129,9 +129,9 @@ constexpr Pin DiagPin = PortCPin(20); // SD cards constexpr size_t NumSdCards = 1; -constexpr Pin SdCardDetectPins[1] = { NoPin }; +constexpr Pin SdCardDetectPins[1] = { PortAPin(29) }; constexpr Pin SdWriteProtectPins[1] = { NoPin }; -constexpr Pin SdSpiCSPins[1] = { PortAPin(29) }; +constexpr Pin SdSpiCSPins[1] = { NoPin }; constexpr uint32_t ExpectedSdCardSpeed = 25000000; // Ethernet diff --git a/src/GCodes/GCodes2.cpp b/src/GCodes/GCodes2.cpp index 545917ae..606a8ec1 100644 --- a/src/GCodes/GCodes2.cpp +++ b/src/GCodes/GCodes2.cpp @@ -1475,6 +1475,17 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, const StringRef& reply) } else { +#if SUPPORT_CAN_EXPANSION + if (gb.Seen('B')) + { + const uint32_t board = gb.GetUIValue(); + if (board != CanId::MasterAddress) + { + result = CanInterface::GetRemoteFirmwareDetails(board, gb, reply); + break; + } + } +#endif reply.printf("FIRMWARE_NAME: %s FIRMWARE_VERSION: %s ELECTRONICS: %s", FIRMWARE_NAME, VERSION, platform.GetElectronicsString()); #ifdef DUET_NG const char* const expansionName = DuetExpansion::GetExpansionBoardName(); @@ -3358,40 +3369,12 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, const StringRef& reply) case 572: // Set/report pressure advance if (gb.Seen('S')) { + const float advance = gb.GetFValue(); if (!LockMovementAndWaitForStandstill(gb)) { return false; } - const float advance = gb.GetFValue(); - if (gb.Seen('D')) - { - uint32_t eDrive[MaxExtruders]; - size_t eCount = MaxExtruders; - gb.GetUnsignedArray(eDrive, eCount, false); - for (size_t i = 0; i < eCount; i++) - { - if (eDrive[i] >= numExtruders) - { - reply.printf("Invalid extruder number '%" PRIu32 "'", eDrive[i]); - result = GCodeResult::error; - break; - } - platform.SetPressureAdvance(eDrive[i], advance); - } - } - else - { - const Tool * const ct = reprap.GetCurrentTool(); - if (ct == nullptr) - { - reply.copy("No tool selected"); - result = GCodeResult::error; - } - else - { - ct->IterateExtruders([advance](unsigned int extruder) { reprap.GetPlatform().SetPressureAdvance(extruder, advance); }); - } - } + result = platform.SetPressureAdvance(advance, gb, reply); } else { diff --git a/src/Heating/Heat.cpp b/src/Heating/Heat.cpp index 43ce31a2..2f2b024f 100644 --- a/src/Heating/Heat.cpp +++ b/src/Heating/Heat.cpp @@ -752,22 +752,24 @@ bool Heat::WriteModelParameters(FileStore *f) const // Process M570 GCodeResult Heat::ConfigureHeaterMonitoring(size_t heater, GCodeBuffer& gb, const StringRef& reply) { - if (heater < MaxHeaters && heaters[heater] != nullptr) + const auto h = FindHeater(heater); + if (h.IsNull()) { - bool seenValue = false; - float maxTempExcursion, maxFaultTime; - heaters[heater]->GetFaultDetectionParameters(maxTempExcursion, maxFaultTime); - gb.TryGetFValue('P', maxFaultTime, seenValue); - gb.TryGetFValue('T', maxTempExcursion, seenValue); - if (seenValue) - { - heaters[heater]->SetFaultDetectionParameters(maxTempExcursion, maxFaultTime); - } - else - { - reply.printf("Heater %u allowed excursion %.1f" DEGREE_SYMBOL "C, fault trigger time %.1f seconds", heater, (double)maxTempExcursion, (double)maxFaultTime); - } + reply.printf("Heater %u not found", heater); + return GCodeResult::error; + } + + bool seenValue = false; + float maxTempExcursion, maxFaultTime; + h->GetFaultDetectionParameters(maxTempExcursion, maxFaultTime); + gb.TryGetFValue('P', maxFaultTime, seenValue); + gb.TryGetFValue('T', maxTempExcursion, seenValue); + if (seenValue) + { + return h->SetFaultDetectionParameters(maxTempExcursion, maxFaultTime, reply); } + + reply.printf("Heater %u allowed excursion %.1f" DEGREE_SYMBOL "C, fault trigger time %.1f seconds", heater, (double)maxTempExcursion, (double)maxFaultTime); return GCodeResult::ok; } @@ -949,6 +951,8 @@ HeaterProtection& Heat::AccessHeaterProtection(size_t index) const // Updates the PIDs and HeaterProtection items after a heater change void Heat::UpdateHeaterProtection() { + ReadLocker lock(heatersLock); + // Reassign the first mapped heater protection item of each PID where applicable // and rebuild the linked list of heater protection elements per heater for (size_t heater : ARRAY_INDICES(heaters)) diff --git a/src/Heating/Heater.cpp b/src/Heating/Heater.cpp index ac66a8ea..a5ecb54c 100644 --- a/src/Heating/Heater.cpp +++ b/src/Heating/Heater.cpp @@ -57,6 +57,13 @@ GCodeResult Heater::SetModel(float gain, float tc, float td, float maxPwm, float return GCodeResult::error; } +GCodeResult Heater::SetFaultDetectionParameters(float pMaxTempExcursion, float pMaxFaultTime, const StringRef& reply) +{ + maxTempExcursion = pMaxTempExcursion; + maxHeatingFaultTime = pMaxFaultTime; + return UpdateFaultDetectionParameters(reply); +} + HeaterStatus Heater::GetStatus() const { const HeaterMode mode = GetMode(); diff --git a/src/Heating/Heater.h b/src/Heating/Heater.h index 53bfcada..1d358bbe 100644 --- a/src/Heating/Heater.h +++ b/src/Heating/Heater.h @@ -60,8 +60,7 @@ public: void GetFaultDetectionParameters(float& pMaxTempExcursion, float& pMaxFaultTime) const { pMaxTempExcursion = maxTempExcursion; pMaxFaultTime = maxHeatingFaultTime; } - void SetFaultDetectionParameters(float pMaxTempExcursion, float pMaxFaultTime) - { maxTempExcursion = pMaxTempExcursion; maxHeatingFaultTime = pMaxFaultTime; } + GCodeResult SetFaultDetectionParameters(float pMaxTempExcursion, float pMaxFaultTime, const StringRef& reply); float GetHighestTemperatureLimit() const; // Get the highest temperature limit float GetLowestTemperatureLimit() const; // Get the lowest temperature limit @@ -103,6 +102,7 @@ protected: virtual HeaterMode GetMode() const = 0; virtual GCodeResult SwitchOn(const StringRef& reply) = 0; virtual GCodeResult UpdateModel(const StringRef& reply) = 0; + virtual GCodeResult UpdateFaultDetectionParameters(const StringRef& reply) = 0; int GetSensorNumber() const { return sensorNumber; } void SetSensorNumber(int sn) { sensorNumber = sn; } diff --git a/src/Heating/LocalHeater.h b/src/Heating/LocalHeater.h index dc76e69c..5c207714 100644 --- a/src/Heating/LocalHeater.h +++ b/src/Heating/LocalHeater.h @@ -51,6 +51,7 @@ protected: HeaterMode GetMode() const override { return mode; } GCodeResult SwitchOn(const StringRef& reply) override; // Turn the heater on and set the mode GCodeResult UpdateModel(const StringRef& reply) override; // Called when the heater model has been changed + GCodeResult UpdateFaultDetectionParameters(const StringRef& reply) override { return GCodeResult::ok; } private: void SetHeater(float power) const; // Power is a fraction in [0,1] diff --git a/src/Heating/RemoteHeater.cpp b/src/Heating/RemoteHeater.cpp index c425213b..a1510a8d 100644 --- a/src/Heating/RemoteHeater.cpp +++ b/src/Heating/RemoteHeater.cpp @@ -197,6 +197,23 @@ GCodeResult RemoteHeater::UpdateModel(const StringRef& reply) return GCodeResult::error; } +GCodeResult RemoteHeater::UpdateFaultDetectionParameters(const StringRef& reply) +{ + CanMessageBuffer *buf = CanMessageBuffer::Allocate(); + if (buf != nullptr) + { + const CanRequestId rid = CanInterface::AllocateRequestId(boardAddress); + CanMessageSetHeaterFaultDetectionParameters * const msg = buf->SetupRequestMessage<CanMessageSetHeaterFaultDetectionParameters>(rid, CanInterface::GetCanAddress(), boardAddress); + msg->heater = GetHeaterNumber(); + msg->maxFaultTime = GetMaxHeatingFaultTime(); + msg->maxTempExcursion = GetMaxTemperatureExcursion(); + return CanInterface::SendRequestAndGetStandardReply(buf, rid, reply); + } + + reply.copy("No CAN buffer"); + return GCodeResult::error; +} + void RemoteHeater::UpdateRemoteStatus(CanAddress src, const CanHeaterReport& report) { if (src == boardAddress) diff --git a/src/Heating/RemoteHeater.h b/src/Heating/RemoteHeater.h index 3e9c0b12..f373f84a 100644 --- a/src/Heating/RemoteHeater.h +++ b/src/Heating/RemoteHeater.h @@ -38,6 +38,7 @@ protected: HeaterMode GetMode() const override; GCodeResult SwitchOn(const StringRef& reply) override; // Turn the heater on and set the mode GCodeResult UpdateModel(const StringRef& reply) override; // Called when the heater model has been changed + GCodeResult UpdateFaultDetectionParameters(const StringRef& reply) override; private: static constexpr uint32_t RemoteStatusTimeout = 2000; diff --git a/src/Movement/DDA.cpp b/src/Movement/DDA.cpp index afb7a520..df134dff 100644 --- a/src/Movement/DDA.cpp +++ b/src/Movement/DDA.cpp @@ -1261,7 +1261,7 @@ void DDA::Prepare(uint8_t simMode, float extrusionPending[]) #if SUPPORT_CAN_EXPANSION if (driver.IsRemote()) { - CanMotion::AddMovement(*this, params, driver, delta); + CanMotion::AddMovement(*this, params, driver, delta, false); } else #endif @@ -1322,7 +1322,7 @@ void DDA::Prepare(uint8_t simMode, float extrusionPending[]) const DriverId driver = config.driverNumbers[i]; if (driver.IsRemote()) { - CanMotion::AddMovement(*this, params, driver, delta); + CanMotion::AddMovement(*this, params, driver, delta, false); } } #endif @@ -1377,7 +1377,7 @@ void DDA::Prepare(uint8_t simMode, float extrusionPending[]) const DriverId driver = config.driverNumbers[i]; if (driver.IsRemote()) { - CanMotion::AddMovement(*this, params, driver, delta); + CanMotion::AddMovement(*this, params, driver, delta, false); } } #endif @@ -1385,15 +1385,11 @@ void DDA::Prepare(uint8_t simMode, float extrusionPending[]) additionalAxisMotorsToEnable |= reprap.GetMove().GetKinematics().GetConnectedAxes(drive); } } - else if (drive >= MaxAxes) + else { // It's an extruder drive if (directionVector[drive] != 0.0) { - //TODO For now we allocate a DM even if the drive is remote so that we can use the code in PreparExtruder, but we ought to factor it out - //TODO For remote drivers, I think we may be adjusting the net steps twice for pressure advance, once here in prepareExtruder and once on the expansion board - DriveMovement* const pdm = DriveMovement::Allocate(drive, DMState::moving); - // If there is any extruder jerk in this move, in theory that means we need to instantly extrude or retract some amount of filament. // Pass the speed change to PrepareExtruder float speedChange; @@ -1407,17 +1403,21 @@ void DDA::Prepare(uint8_t simMode, float extrusionPending[]) speedChange = 0.0; } - const bool stepsToDo = pdm->PrepareExtruder(*this, params, extrusionPending[drive - MaxAxes], speedChange, flags.usePressureAdvance); - #if SUPPORT_CAN_EXPANSION const DriverId driver = platform.GetExtruderDriver(drive - MaxAxes); if (driver.IsRemote()) { - CanMotion::AddMovement(*this, params, driver, pdm->GetSteps()); + const int32_t rawSteps = PrepareRemoteExtruder(drive, extrusionPending[drive - MaxAxes], speedChange); + if (rawSteps != 0) + { + CanMotion::AddMovement(*this, params, driver, rawSteps, flags.usePressureAdvance); + } } -#endif - if (platform.GetDriversBitmap(drive) != 0) // if any of the drives is local + else { +#endif + DriveMovement* const pdm = DriveMovement::Allocate(drive, DMState::moving); + const bool stepsToDo = pdm->PrepareExtruder(*this, params, extrusionPending[drive - MaxAxes], speedChange, flags.usePressureAdvance); reprap.GetPlatform().EnableLocalDrivers(drive); if (stepsToDo) @@ -1444,12 +1444,6 @@ void DDA::Prepare(uint8_t simMode, float extrusionPending[]) completedDMs = pdm; } } - else - { - pdm->state = DMState::idle; - pdm->nextDM = completedDMs; - completedDMs = pdm; - } } } } @@ -1472,7 +1466,7 @@ void DDA::Prepare(uint8_t simMode, float extrusionPending[]) const DriverId driver = config.driverNumbers[i]; if (driver.IsRemote()) { - CanMotion::AddMovement(*this, params, driver, 0); + CanMotion::AddMovement(*this, params, driver, 0, false); } } #endif @@ -1481,7 +1475,7 @@ void DDA::Prepare(uint8_t simMode, float extrusionPending[]) const DDAState st = prev->state; afterPrepare.moveStartTime = (st == DDAState::executing || st == DDAState::frozen) - ? prev->afterPrepare.moveStartTime + prev->clocksNeeded // this move will follow the previous one, so calculate the start time assuming no more hiccups + ? prev->afterPrepare.moveStartTime + prev->clocksNeeded // this move will follow the previous one, so calculate the start time assuming no more hiccups : StepTimer::GetInterruptClocks() + MovementStartDelayClocks; // else this move is the first so start it after a short delay #if SUPPORT_CAN_EXPANSION @@ -2031,6 +2025,56 @@ void DDA::LimitSpeedAndAcceleration(float maxSpeed, float maxAcceleration) } } +#if SUPPORT_CAN_EXPANSION + +// Prepare a remote extruder, returning the number of steps we are going to do before allowing for pressure advance. +// This replicates some of the functionality that DriveMovement::PrepareExtruder does for local extruder drives. +int32_t DDA::PrepareRemoteExtruder(size_t drive, float& extrusionPending, float speedChange) const +{ + // Calculate the requested extrusion amount and a few other things + float extrusionRequired = totalDistance * directionVector[drive]; + +#if SUPPORT_NONLINEAR_EXTRUSION + // Add the nonlinear extrusion correction to totalExtrusion + if (flags.isPrintingMove) + { + float a, b, limit; + if (reprap.GetPlatform().GetExtrusionCoefficients(drive - MaxAxes, a, b, limit)) + { + const float averageExtrusionSpeed = (extrusionRequired * StepTimer::StepClockRate)/clocksNeeded; + const float factor = 1.0 + min<float>((averageExtrusionSpeed * a) + (averageExtrusionSpeed * averageExtrusionSpeed * b), limit); + extrusionRequired *= factor; + } + } +#endif + + // Add on any fractional extrusion pending from the previous move + extrusionRequired += extrusionPending; + const float rawStepsPerMm = reprap.GetPlatform().DriveStepsPerUnit(drive); + const int32_t originalSteps = lrintf(extrusionRequired * rawStepsPerMm); + int32_t netSteps; + + if (flags.usePressureAdvance && extrusionRequired >= 0.0) + { + // Calculate the pressure advance parameters + const float compensationTime = reprap.GetPlatform().GetPressureAdvance(drive - MaxAxes); + + // Calculate the net total extrusion to allow for compensation. It may be negative. + const float dv = extrusionRequired/totalDistance; + extrusionRequired += (endSpeed - startSpeed) * compensationTime * dv; + netSteps = lrintf(extrusionRequired * rawStepsPerMm); + } + else + { + netSteps = originalSteps; + } + + extrusionPending = extrusionRequired - (float)netSteps/rawStepsPerMm; + return originalSteps; +} + +#endif + #if SUPPORT_LASER // Manage the laser power. Return the number of ticks until we should be called again, or 0 to be called at the start of the next move. @@ -2082,4 +2126,5 @@ uint32_t DDA::ManageLaserPower() const } #endif + // End diff --git a/src/Movement/DDA.h b/src/Movement/DDA.h index 90f8c501..0799b96b 100644 --- a/src/Movement/DDA.h +++ b/src/Movement/DDA.h @@ -178,6 +178,10 @@ private: float NormaliseXYZ(); // Make the direction vector unit-normal in XYZ void AdjustAcceleration(); // Adjust the acceleration and deceleration to reduce ringing +#if SUPPORT_CAN_EXPANSION + int32_t PrepareRemoteExtruder(size_t drive, float& extrusionPending, float speedChange) const; +#endif + static void DoLookahead(DDARing& ring, DDA *laDDA) __attribute__ ((hot)); // Try to smooth out moves in the queue static float Normalise(float v[], size_t dim1, size_t dim2); // Normalise a vector of dim1 dimensions to unit length in the first dim1 dimensions static void Absolute(float v[], size_t dimensions); // Put a vector in the positive hyperquadrant diff --git a/src/Movement/DriveMovement.cpp b/src/Movement/DriveMovement.cpp index 015f3540..2d990b1c 100644 --- a/src/Movement/DriveMovement.cpp +++ b/src/Movement/DriveMovement.cpp @@ -211,7 +211,7 @@ bool DriveMovement::PrepareExtruder(const DDA& dda, const PrepParams& params, fl // Add on any fractional extrusion pending from the previous move extrusionRequired += extrusionPending; dv = extrusionRequired/dda.totalDistance; - direction = (dv >= 0.0); + direction = (extrusionRequired >= 0.0); const float rawStepsPerMm = reprap.GetPlatform().DriveStepsPerUnit(drive); const float effectiveStepsPerMm = fabsf(dv) * rawStepsPerMm; @@ -249,7 +249,7 @@ bool DriveMovement::PrepareExtruder(const DDA& dda, const PrepParams& params, fl mp.cart.accelStopStep = (uint32_t)(params.accelDistance * effectiveStepsPerMm) + 1; } - int32_t netSteps = (int32_t)(extrusionRequired * rawStepsPerMm); + int32_t netSteps = lrintf(extrusionRequired * rawStepsPerMm); extrusionPending = extrusionRequired - (float)netSteps/rawStepsPerMm; if (!direction) diff --git a/src/Platform.cpp b/src/Platform.cpp index 259cae88..d937891b 100644 --- a/src/Platform.cpp +++ b/src/Platform.cpp @@ -506,7 +506,7 @@ void Platform::Init() { extruderDrivers[extr].SetLocal(extr + MinAxes); // set up default extruder drive mapping driveDriverBits[extr + MaxAxes] = StepPins::CalcDriverBitmap(extr + MinAxes); - SetPressureAdvance(extr, 0.0); // no pressure advance + pressureAdvance[extr] = 0.0; #if SUPPORT_NONLINEAR_EXTRUSION nonlinearExtrusionA[extr] = nonlinearExtrusionB[extr] = 0.0; nonlinearExtrusionLimit[extr] = DefaultNonlinearExtrusionLimit; @@ -3592,12 +3592,73 @@ void Platform::AtxPowerOff(bool defer) } } -void Platform::SetPressureAdvance(size_t extruder, float factor) +GCodeResult Platform::SetPressureAdvance(float advance, GCodeBuffer& gb, const StringRef& reply) { - if (extruder < MaxExtruders) + GCodeResult rslt = GCodeResult::ok; + +#if SUPPORT_CAN_EXPANSION + CanDriversData canDriversToUpdate; +#endif + + if (gb.Seen('D')) { - pressureAdvance[extruder] = factor; + uint32_t eDrive[MaxExtruders]; + size_t eCount = MaxExtruders; + gb.GetUnsignedArray(eDrive, eCount, false); + for (size_t i = 0; i < eCount; i++) + { + const uint32_t extruder = eDrive[i]; + if (extruder >= reprap.GetGCodes().GetNumExtruders()) + { + reply.printf("Invalid extruder number '%" PRIu32 "'", extruder); + rslt = GCodeResult::error; + break; + } + pressureAdvance[extruder] = advance; +#if SUPPORT_CAN_EXPANSION + if (extruderDrivers[extruder].IsRemote()) + { + canDriversToUpdate.AddEntry(extruderDrivers[extruder], (uint16_t)(advance * 1000.0)); + } +#endif + } } + else + { + const Tool * const ct = reprap.GetCurrentTool(); + if (ct == nullptr) + { + reply.copy("No tool selected"); + rslt = GCodeResult::error; + } + else + { +#if SUPPORT_CAN_EXPANSION + ct->IterateExtruders([this, advance, &canDriversToUpdate](unsigned int extruder) + { + pressureAdvance[extruder] = advance; + if (extruderDrivers[extruder].IsRemote()) + { + canDriversToUpdate.AddEntry(extruderDrivers[extruder], (uint16_t)(advance * 1000.0)); + } + } + ); +#else + ct->IterateExtruders([this, advance](unsigned int extruder) + { + pressureAdvance[extruder] = advance; + } + ); +#endif + } + } + +#if SUPPORT_CAN_EXPANSION + const bool remoteOk = CanInterface::SetRemotePressureAdvance(canDriversToUpdate, reply); + return (remoteOk) ? rslt : GCodeResult::error; +#else + return rslt; +#endif } #if SUPPORT_NONLINEAR_EXTRUSION diff --git a/src/Platform.h b/src/Platform.h index ecc3a971..590ecc05 100644 --- a/src/Platform.h +++ b/src/Platform.h @@ -413,7 +413,7 @@ public: void SetAxisMinimum(size_t axis, float value, bool byProbing); float AxisTotalLength(size_t axis) const; float GetPressureAdvance(size_t extruder) const; - void SetPressureAdvance(size_t extruder, float factor); + GCodeResult SetPressureAdvance(float advance, GCodeBuffer& gb, const StringRef& reply); const AxisDriversConfig& GetAxisDriversConfig(size_t axis) const pre(axis < MaxAxes) diff --git a/src/Version.h b/src/Version.h index 20d110d4..9a8fd5b3 100644 --- a/src/Version.h +++ b/src/Version.h @@ -20,7 +20,7 @@ #endif #ifndef DATE -# define DATE "2019-09-06b1" +# define DATE "2019-09-09b2" #endif #define AUTHORS "reprappro, dc42, chrishamm, t3p3, dnewman, printm3d" |