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 /src | |
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
Diffstat (limited to 'src')
-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" |