diff options
author | David Crocker <dcrocker@eschertech.com> | 2020-02-27 00:27:36 +0300 |
---|---|---|
committer | David Crocker <dcrocker@eschertech.com> | 2020-02-27 00:27:36 +0300 |
commit | 3fbc0f408c19aaa040e52771b834a7c4a3b0bf9c (patch) | |
tree | 2e76704a0042e9d38d3f35043448fa95593564c5 | |
parent | 46eba53f32abc43abd3b3b1ee8b8165c74647907 (diff) |
More changes for 3.02-RC3
Support M122 P1001 and P1004
Return fan.actualValue to 2dp not 1dp
Reworked heater fault generation code
In delta kinematics, number of towers can't exceed number of total axes
-rw-r--r-- | src/CAN/CanInterface.cpp | 51 | ||||
-rw-r--r-- | src/Fans/Fan.cpp | 2 | ||||
-rw-r--r-- | src/GCodes/GCodes.cpp | 2 | ||||
-rw-r--r-- | src/GCodes/GCodes.h | 2 | ||||
-rw-r--r-- | src/GCodes/GCodes2.cpp | 3 | ||||
-rw-r--r-- | src/GPIO/GpioPorts.cpp | 7 | ||||
-rw-r--r-- | src/Heating/HeaterMonitor.cpp | 29 | ||||
-rw-r--r-- | src/Heating/HeaterMonitor.h | 5 | ||||
-rw-r--r-- | src/Heating/LocalHeater.cpp | 163 | ||||
-rw-r--r-- | src/Heating/LocalHeater.h | 1 | ||||
-rw-r--r-- | src/Movement/Kinematics/LinearDeltaKinematics.cpp | 2 | ||||
-rw-r--r-- | src/Version.h | 2 |
12 files changed, 143 insertions, 126 deletions
diff --git a/src/CAN/CanInterface.cpp b/src/CAN/CanInterface.cpp index f82e859e..5a0a1e7b 100644 --- a/src/CAN/CanInterface.cpp +++ b/src/CAN/CanInterface.cpp @@ -901,28 +901,41 @@ static GCodeResult GetRemoteInfo(uint8_t infoType, uint32_t boardAddress, uint8_ // Get diagnostics from an expansion board GCodeResult CanInterface::RemoteDiagnostics(MessageType mt, uint32_t boardAddress, unsigned int type, GCodeBuffer& gb, const StringRef& reply) { - Platform& p = reprap.GetPlatform(); + CanInterface::CheckCanAddress(boardAddress, gb); - uint8_t currentPart = 0; - uint8_t lastPart; - GCodeResult res; - do + if (type <= 15) { - res = GetRemoteInfo(CanMessageReturnInfo::typeDiagnosticsPart0 + currentPart, boardAddress, type, gb, reply, &lastPart); - if (res != GCodeResult::ok) - { - return res; - } - if (type == 0 && currentPart == 0) + Platform& p = reprap.GetPlatform(); + + uint8_t currentPart = 0; + uint8_t lastPart; + GCodeResult res; + do { - p.MessageF(mt, "Diagnostics for board %u:\n", (unsigned int)boardAddress); - } - reply.cat('\n'); - p.Message(mt, reply.c_str()); - reply.Clear(); - ++currentPart; - } while (currentPart <= lastPart); - return res; + res = GetRemoteInfo(CanMessageReturnInfo::typeDiagnosticsPart0 + currentPart, boardAddress, type, gb, reply, &lastPart); + if (res != GCodeResult::ok) + { + return res; + } + if (type == 0 && currentPart == 0) + { + p.MessageF(mt, "Diagnostics for board %u:\n", (unsigned int)boardAddress); + } + reply.cat('\n'); + p.Message(mt, reply.c_str()); + reply.Clear(); + ++currentPart; + } while (currentPart <= lastPart); + return res; + } + + // It's a diagnostic test + CanMessageBuffer * const buf = AllocateBuffer(gb); + const CanRequestId rid = CanInterface::AllocateRequestId(boardAddress); + auto const msg = buf->SetupRequestMessage<CanMessageDiagnosticTest>(rid, CanId::MasterAddress, (CanAddress)boardAddress); + msg->testType = type; + msg->invertedTestType = ~type; + return SendRequestAndGetStandardReply(buf, rid, reply); // we may not actually get a reply if the test is one that crashes the expansion board } GCodeResult CanInterface::RemoteM408(uint32_t boardAddress, unsigned int type, GCodeBuffer& gb, const StringRef& reply) diff --git a/src/Fans/Fan.cpp b/src/Fans/Fan.cpp index 1f89c8f6..8199e617 100644 --- a/src/Fans/Fan.cpp +++ b/src/Fans/Fan.cpp @@ -22,7 +22,7 @@ constexpr ObjectModelTableEntry Fan::objectModelTable[] = { // Within each group, these entries must be in alphabetical order // 0. Fan members - { "actualValue", OBJECT_MODEL_FUNC(self->lastVal, 1), ObjectModelEntryFlags::live }, + { "actualValue", OBJECT_MODEL_FUNC(self->lastVal, 2), ObjectModelEntryFlags::live }, { "blip", OBJECT_MODEL_FUNC(0.001f * (float)self->blipTime, 2), ObjectModelEntryFlags::none }, { "max", OBJECT_MODEL_FUNC(self->maxVal, 2), ObjectModelEntryFlags::none }, { "min", OBJECT_MODEL_FUNC(self->minVal, 2), ObjectModelEntryFlags::none }, diff --git a/src/GCodes/GCodes.cpp b/src/GCodes/GCodes.cpp index 4f825c74..5b723d75 100644 --- a/src/GCodes/GCodes.cpp +++ b/src/GCodes/GCodes.cpp @@ -4350,7 +4350,7 @@ const char* GCodes::GetMachineModeString() const noexcept // Respond to a heater fault. The heater has already been turned off and its status set to 'fault' when this is called from the Heat module. // The Heat module will generate an appropriate error message, so no need to do that here. -void GCodes::HandleHeaterFault(int heater) noexcept +void GCodes::HandleHeaterFault() noexcept { if (heaterFaultState == HeaterFaultState::noFault && fileGCode->OriginalMachineState().DoingFile()) { diff --git a/src/GCodes/GCodes.h b/src/GCodes/GCodes.h index 6ce1285b..71016e80 100644 --- a/src/GCodes/GCodes.h +++ b/src/GCodes/GCodes.h @@ -157,7 +157,7 @@ public: const char* GetMachineModeString() const noexcept; // Get the name of the current machine mode void FilamentError(size_t extruder, FilamentSensorStatus fstat) noexcept; - void HandleHeaterFault(int heater) noexcept; // Respond to a heater fault + void HandleHeaterFault() noexcept; // Respond to a heater fault #if HAS_VOLTAGE_MONITOR bool LowVoltagePause() noexcept; diff --git a/src/GCodes/GCodes2.cpp b/src/GCodes/GCodes2.cpp index 4b4f0eaf..cb79b9be 100644 --- a/src/GCodes/GCodes2.cpp +++ b/src/GCodes/GCodes2.cpp @@ -1649,7 +1649,7 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, const StringRef& reply) THROWS(GCodeEx case 122: { const unsigned int type = (gb.Seen('P')) ? gb.GetIValue() : 0; - const MessageType mt = (MessageType)(gb.GetResponseMessageType() | PushFlag); + const MessageType mt = (MessageType)(gb.GetResponseMessageType() | PushFlag); // set the Push flag to combine multiple messages into a single OutputBuffer chain #if SUPPORT_CAN_EXPANSION const uint32_t board = (gb.Seen('B')) ? gb.GetUIValue() : 0; if (board != CanId::MasterAddress) @@ -1660,7 +1660,6 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, const StringRef& reply) THROWS(GCodeEx #endif if (type == 0) { - // Set the Push flag to combine multiple messages into a single OutputBuffer chain reprap.Diagnostics(mt); } else diff --git a/src/GPIO/GpioPorts.cpp b/src/GPIO/GpioPorts.cpp index 7498dc8d..7c9cafba 100644 --- a/src/GPIO/GpioPorts.cpp +++ b/src/GPIO/GpioPorts.cpp @@ -71,9 +71,12 @@ GCodeResult GpInputPort::Configure(uint32_t gpinNumber, GCodeBuffer &gb, const S #if SUPPORT_CAN_EXPANSION if (boardAddress != CanId::MasterAddress) { - if (CanInterface::DeleteHandle(boardAddress, handle, reply) != GCodeResult::ok) + const GCodeResult rslt = CanInterface::DeleteHandle(boardAddress, handle, reply); + if (rslt != GCodeResult::ok) { - reprap.GetPlatform().Message(AddWarning(gb.GetResponseMessageType()), reply.c_str()); + reply.cat('\n'); + const MessageType mtype = (rslt == GCodeResult::warning) ? AddWarning(gb.GetResponseMessageType()) : AddError(gb.GetResponseMessageType()); + reprap.GetPlatform().Message(mtype, reply.c_str()); reply.Clear(); } boardAddress = CanId::MasterAddress; diff --git a/src/Heating/HeaterMonitor.cpp b/src/Heating/HeaterMonitor.cpp index 92a585e9..1b895215 100644 --- a/src/Heating/HeaterMonitor.cpp +++ b/src/Heating/HeaterMonitor.cpp @@ -65,31 +65,18 @@ void HeaterMonitor::Report(unsigned int heater, unsigned int index, const String const char *actionString, *triggerString; switch (action) { - case HeaterMonitorAction::GenerateFault: - actionString = "generate a heater fault"; - break; - case HeaterMonitorAction::PermanentSwitchOff: - actionString = "permanently switch off"; - break; - case HeaterMonitorAction::TemporarySwitchOff: - actionString = "temporarily switch off"; - break; - default: - actionString = "(undefined)"; - break; + case HeaterMonitorAction::GenerateFault: actionString = "generate a heater fault"; break; + case HeaterMonitorAction::PermanentSwitchOff: actionString = "permanently switch off"; break; + case HeaterMonitorAction::TemporarySwitchOff: actionString = "temporarily switch off"; break; + case HeaterMonitorAction::ShutDown: actionString = "shut down the printer"; break; + default: actionString = "(undefined)"; break; } switch (trigger) { - case HeaterMonitorTrigger::TemperatureExceeded: - triggerString = "exceeds"; - break; - case HeaterMonitorTrigger::TemperatureTooLow: - triggerString = "falls below"; - break; - default: - triggerString = "(undefined)"; - break; + case HeaterMonitorTrigger::TemperatureExceeded: triggerString = "exceeds"; break; + case HeaterMonitorTrigger::TemperatureTooLow: triggerString = "falls below"; break; + default: triggerString = "(undefined)"; break; } reply.catf("uses sensor %d to %s if the reading %s %.1f" DEGREE_SYMBOL "C", sensorNumber, actionString, triggerString, (double)limit); diff --git a/src/Heating/HeaterMonitor.h b/src/Heating/HeaterMonitor.h index 2b4fb322..441dbf26 100644 --- a/src/Heating/HeaterMonitor.h +++ b/src/Heating/HeaterMonitor.h @@ -26,10 +26,11 @@ enum class HeaterMonitorAction : uint8_t { GenerateFault = 0, PermanentSwitchOff, - TemporarySwitchOff + TemporarySwitchOff, + ShutDown }; -const HeaterMonitorAction MaxHeaterMonitorAction = HeaterMonitorAction::TemporarySwitchOff; +const HeaterMonitorAction MaxHeaterMonitorAction = HeaterMonitorAction::ShutDown; // A note about using this class. Its size is currently 8 bytes, and will be 12 bytes of object model support is added. // - If we allocate them statically within the heater object, then assuming 3 per heater we need 24 bytes, or 36 bytes with OM support. diff --git a/src/Heating/LocalHeater.cpp b/src/Heating/LocalHeater.cpp index f4429f87..40efd5f3 100644 --- a/src/Heating/LocalHeater.cpp +++ b/src/Heating/LocalHeater.cpp @@ -211,17 +211,12 @@ void LocalHeater::Spin() noexcept badTemperatureCount++; if (badTemperatureCount > MaxBadTemperatureCount) { - lastPwm = 0.0; - SetHeater(0.0); // do this here just to be sure, in case the call to platform.Message causes a delay if (mode >= HeaterMode::tuning0) { delete tuningTempReadings; tuningTempReadings = nullptr; } - mode = HeaterMode::fault; - reprap.GetGCodes().HandleHeaterFault(GetHeaterNumber()); - reprap.GetPlatform().MessageF(ErrorMessage, "Temperature reading fault on heater %u: %s\n", GetHeaterNumber(), TemperatureErrorString(err)); - reprap.FlagTemperatureFault(GetHeaterNumber()); + RaiseHeaterFault("Temperature reading fault on heater %u: %s\n", GetHeaterNumber(), TemperatureErrorString(err)); } } // We leave lastPWM alone if we have a temporary temperature reading error @@ -271,12 +266,8 @@ void LocalHeater::Spin() noexcept ++heatingFaultCount; if (heatingFaultCount * HeatSampleIntervalMillis > GetMaxHeatingFaultTime() * SecondsToMillis) { - SetHeater(0.0); // do this here just to be sure - mode = HeaterMode::fault; - reprap.GetGCodes().HandleHeaterFault(GetHeaterNumber()); - reprap.GetPlatform().MessageF(ErrorMessage, "Heating fault on heater %d, temperature rising much more slowly than the expected %.1f" DEGREE_SYMBOL "C/sec\n", - GetHeaterNumber(), (double)expectedRate); - reprap.FlagTemperatureFault(GetHeaterNumber()); + RaiseHeaterFault("Heating fault on heater %d, temperature rising much more slowly than the expected %.1f" DEGREE_SYMBOL "C/sec\n", + GetHeaterNumber(), (double)expectedRate); } } else if (heatingFaultCount != 0) @@ -297,11 +288,8 @@ void LocalHeater::Spin() noexcept ++heatingFaultCount; if (heatingFaultCount * HeatSampleIntervalMillis > GetMaxHeatingFaultTime() * SecondsToMillis) { - SetHeater(0.0); // do this here just to be sure - mode = HeaterMode::fault; - reprap.GetGCodes().HandleHeaterFault(GetHeaterNumber()); - reprap.GetPlatform().MessageF(ErrorMessage, "Heating fault on heater %u, temperature excursion exceeded %.1f" DEGREE_SYMBOL "C\n", - GetHeaterNumber(), (double)GetMaxTemperatureExcursion()); + RaiseHeaterFault("Heating fault on heater %u, temperature excursion exceeded %.1f" DEGREE_SYMBOL "C\n", + GetHeaterNumber(), (double)GetMaxTemperatureExcursion()); } } else if (heatingFaultCount != 0) @@ -329,69 +317,76 @@ void LocalHeater::Spin() noexcept } // Calculate the PWM - if (mode <= HeaterMode::suspended) + if (mode >= HeaterMode::tuning0) { - lastPwm = 0.0; + DoTuningStep(); } - else if (mode < HeaterMode::tuning0) + else { - // Performing normal temperature control - if (GetModel().UsePid()) + if (mode <= HeaterMode::suspended) + { + lastPwm = 0.0; + } + else { - // Using PID mode. Determine the PID parameters to use. - const bool inLoadMode = (mode == HeaterMode::stable) || fabsf(error) < 3.0; // use standard PID when maintaining temperature - const PidParameters& params = GetModel().GetPidParameters(inLoadMode); - - // If the P and D terms together demand that the heater is full on or full off, disregard the I term - const float errorMinusDterm = error - (params.tD * derivative); - const float pPlusD = params.kP * errorMinusDterm; - const float expectedPwm = constrain<float>((temperature - NormalAmbientTemperature)/GetModel().GetGain(), 0.0, GetModel().GetMaxPwm()); - if (pPlusD + expectedPwm > GetModel().GetMaxPwm()) + // Performing normal temperature control + if (GetModel().UsePid()) { - lastPwm = GetModel().GetMaxPwm(); - // If we are heating up, preset the I term to the expected PWM at this temperature, ready for the switch over to PID - if (mode == HeaterMode::heating && error > 0.0 && derivative > 0.0) + // Using PID mode. Determine the PID parameters to use. + const bool inLoadMode = (mode == HeaterMode::stable) || fabsf(error) < 3.0; // use standard PID when maintaining temperature + const PidParameters& params = GetModel().GetPidParameters(inLoadMode); + + // If the P and D terms together demand that the heater is full on or full off, disregard the I term + const float errorMinusDterm = error - (params.tD * derivative); + const float pPlusD = params.kP * errorMinusDterm; + const float expectedPwm = constrain<float>((temperature - NormalAmbientTemperature)/GetModel().GetGain(), 0.0, GetModel().GetMaxPwm()); + if (pPlusD + expectedPwm > GetModel().GetMaxPwm()) { - iAccumulator = expectedPwm; + lastPwm = GetModel().GetMaxPwm(); + // If we are heating up, preset the I term to the expected PWM at this temperature, ready for the switch over to PID + if (mode == HeaterMode::heating && error > 0.0 && derivative > 0.0) + { + iAccumulator = expectedPwm; + } } - } - else if (pPlusD + expectedPwm < 0.0) - { - lastPwm = 0.0; - } - else - { - const float errorToUse = error; - iAccumulator = constrain<float> - (iAccumulator + (errorToUse * params.kP * params.recipTi * HeatSampleIntervalMillis * MillisToSeconds), - 0.0, GetModel().GetMaxPwm()); - lastPwm = constrain<float>(pPlusD + iAccumulator, 0.0, GetModel().GetMaxPwm()); - } -#if HAS_VOLTAGE_MONITOR - // Scale the PID based on the current voltage vs. the calibration voltage - if (lastPwm < 1.0 && GetModel().GetVoltage() >= 10.0) // if heater is not fully on and we know the voltage we tuned the heater at - { - if (!reprap.GetHeat().IsBedOrChamberHeater(GetHeaterNumber())) + else if (pPlusD + expectedPwm < 0.0) { - const float currentVoltage = reprap.GetPlatform().GetCurrentPowerVoltage(); - if (currentVoltage >= 10.0) // if we have a sensible reading + lastPwm = 0.0; + } + else + { + const float errorToUse = error; + iAccumulator = constrain<float> + (iAccumulator + (errorToUse * params.kP * params.recipTi * HeatSampleIntervalMillis * MillisToSeconds), + 0.0, GetModel().GetMaxPwm()); + lastPwm = constrain<float>(pPlusD + iAccumulator, 0.0, GetModel().GetMaxPwm()); + } + #if HAS_VOLTAGE_MONITOR + // Scale the PID based on the current voltage vs. the calibration voltage + if (lastPwm < 1.0 && GetModel().GetVoltage() >= 10.0) // if heater is not fully on and we know the voltage we tuned the heater at + { + if (!reprap.GetHeat().IsBedOrChamberHeater(GetHeaterNumber())) { - lastPwm = min<float>(lastPwm * fsquare(GetModel().GetVoltage()/currentVoltage), 1.0); // adjust the PWM by the square of the voltage ratio + const float currentVoltage = reprap.GetPlatform().GetCurrentPowerVoltage(); + if (currentVoltage >= 10.0) // if we have a sensible reading + { + lastPwm = min<float>(lastPwm * fsquare(GetModel().GetVoltage()/currentVoltage), 1.0); // adjust the PWM by the square of the voltage ratio + } } } + #endif + } + else + { + // Using bang-bang mode + lastPwm = (error > 0.0) ? GetModel().GetMaxPwm() : 0.0; } -#endif - } - else - { - // Using bang-bang mode - lastPwm = (error > 0.0) ? GetModel().GetMaxPwm() : 0.0; - } - // Check if the generated PWM signal needs to be inverted for inverse temperature control - if (GetModel().IsInverted()) - { - lastPwm = GetModel().GetMaxPwm() - lastPwm; + // Check if the generated PWM signal needs to be inverted for inverse temperature control + if (GetModel().IsInverted()) + { + lastPwm = GetModel().GetMaxPwm() - lastPwm; + } } // Verify that everything is operating in the required temperature range @@ -402,10 +397,13 @@ void LocalHeater::Spin() noexcept lastPwm = 0.0; switch (prot.GetAction()) { + case HeaterMonitorAction::ShutDown: + reprap.GetHeat().SwitchOffAll(true); + reprap.GetPlatform().AtxPowerOff(false); + break; + case HeaterMonitorAction::GenerateFault: - mode = HeaterMode::fault; - reprap.GetGCodes().HandleHeaterFault(GetHeaterNumber()); - reprap.GetPlatform().MessageF(ErrorMessage, "Heating fault on heater %u: heater monitor was triggered\n", GetHeaterNumber()); + RaiseHeaterFault("Heating fault on heater %u: heater monitor was triggered\n", GetHeaterNumber()); break; case HeaterMonitorAction::TemporarySwitchOff: @@ -413,16 +411,15 @@ void LocalHeater::Spin() noexcept break; case HeaterMonitorAction::PermanentSwitchOff: - SwitchOff(); + if (mode != HeaterMode::fault) + { + SwitchOff(); + } break; } } } } - else - { - DoTuningStep(); - } } else { @@ -908,4 +905,20 @@ void LocalHeater::Suspend(bool sus) noexcept } } +void LocalHeater::RaiseHeaterFault(const char *format, ...) noexcept +{ + lastPwm = 0.0; + SetHeater(0.0); + if (mode != HeaterMode::fault) + { + mode = HeaterMode::fault; + va_list vargs; + va_start(vargs, format); + reprap.GetPlatform().MessageF(ErrorMessage, format, vargs); + va_end(vargs); + } + reprap.GetGCodes().HandleHeaterFault(); + reprap.FlagTemperatureFault(GetHeaterNumber()); +} + // End diff --git a/src/Heating/LocalHeater.h b/src/Heating/LocalHeater.h index c4e283ef..de6f7d39 100644 --- a/src/Heating/LocalHeater.h +++ b/src/Heating/LocalHeater.h @@ -65,6 +65,7 @@ private: void CalculateModel() noexcept; // Calculate G, td and tc from the accumulated readings void DisplayBuffer(const char *intro) noexcept; // Debug helper float GetExpectedHeatingRate() const noexcept; // Get the minimum heating rate we expect + void RaiseHeaterFault(const char *format, ...) noexcept; PwmPort port; // The port that drives the heater float temperature; // The current temperature diff --git a/src/Movement/Kinematics/LinearDeltaKinematics.cpp b/src/Movement/Kinematics/LinearDeltaKinematics.cpp index 225a59e1..d0847a46 100644 --- a/src/Movement/Kinematics/LinearDeltaKinematics.cpp +++ b/src/Movement/Kinematics/LinearDeltaKinematics.cpp @@ -845,7 +845,7 @@ bool LinearDeltaKinematics::Configure(unsigned int mCode, GCodeBuffer& gb, const if (gb.Seen('L')) { seen = true; - size_t numValues = MaxAxes; + size_t numValues = min<size_t>(reprap.GetGCodes().GetTotalAxes(), MaxTowers); gb.GetFloatArray(diagonals, numValues, false); while (numValues < 3) { diff --git a/src/Version.h b/src/Version.h index b4891bc5..add0e50a 100644 --- a/src/Version.h +++ b/src/Version.h @@ -19,7 +19,7 @@ #endif #ifndef DATE -# define DATE "2020-02-25b2" +# define DATE "2020-02-26b1" #endif #define AUTHORS "reprappro, dc42, chrishamm, t3p3, dnewman, printm3d" |