diff options
Diffstat (limited to 'src/Fans')
-rw-r--r-- | src/Fans/Fan.cpp | 73 | ||||
-rw-r--r-- | src/Fans/Fan.h | 5 | ||||
-rw-r--r-- | src/Fans/FansManager.cpp | 2 | ||||
-rw-r--r-- | src/Fans/LocalFan.cpp | 73 | ||||
-rw-r--r-- | src/Fans/RemoteFan.cpp | 2 |
5 files changed, 60 insertions, 95 deletions
diff --git a/src/Fans/Fan.cpp b/src/Fans/Fan.cpp index 01ad62a6..98b5c1f5 100644 --- a/src/Fans/Fan.cpp +++ b/src/Fans/Fan.cpp @@ -21,28 +21,30 @@ constexpr ObjectModelArrayDescriptor Fan::monitoredSensorsArrayDescriptor = { nullptr, - [] (const ObjectModel *self, const ObjectExplorationContext&) noexcept -> size_t { return ((const Fan*)self)->GetNumMonitoredSensors(); }, - [] (const ObjectModel *self, ObjectExplorationContext& context) noexcept -> ExpressionValue { return ExpressionValue((int32_t)((const Fan*)self)->GetMonitoredSensorNumber(context.GetLastIndex())); } + [] (const ObjectModel *self, const ObjectExplorationContext&) noexcept -> size_t + { return ((const Fan*)self)->sensorsMonitored.CountSetBits(); }, + [] (const ObjectModel *self, ObjectExplorationContext& context) noexcept -> ExpressionValue + { return ExpressionValue((int32_t)((const Fan*)self)->sensorsMonitored.GetSetBitNumber(context.GetLastIndex())); } }; constexpr ObjectModelTableEntry Fan::objectModelTable[] = { // Within each group, these entries must be in alphabetical order // 0. Fan members - { "actualValue", OBJECT_MODEL_FUNC(self->lastVal), ObjectModelEntryFlags::live }, - { "blip", OBJECT_MODEL_FUNC(0.001f * (float)self->blipTime), ObjectModelEntryFlags::none }, - { "max", OBJECT_MODEL_FUNC(self->maxVal), ObjectModelEntryFlags::none }, - { "min", OBJECT_MODEL_FUNC(self->minVal), ObjectModelEntryFlags::none }, + { "actualValue", OBJECT_MODEL_FUNC(self->lastVal, 1), 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 }, { "name", OBJECT_MODEL_FUNC(self->name.c_str()), ObjectModelEntryFlags::none }, - { "requestedValue", OBJECT_MODEL_FUNC(self->val), ObjectModelEntryFlags::live }, + { "requestedValue", OBJECT_MODEL_FUNC(self->val, 2), ObjectModelEntryFlags::live }, { "rpm", OBJECT_MODEL_FUNC(self->GetRPM()), ObjectModelEntryFlags::live }, { "thermostatic", OBJECT_MODEL_FUNC(self, 1), ObjectModelEntryFlags::none }, // 1. Fan.thermostatic members - { "control", OBJECT_MODEL_FUNC(self->sensorsMonitored != 0), ObjectModelEntryFlags::none }, - { "heaters", OBJECT_MODEL_FUNC_IF(self->sensorsMonitored != 0, &monitoredSensorsArrayDescriptor), ObjectModelEntryFlags::none }, - { "highTemperature", OBJECT_MODEL_FUNC_IF(self->sensorsMonitored != 0, self->triggerTemperatures[1]), ObjectModelEntryFlags::none }, - { "lowTemperature", OBJECT_MODEL_FUNC_IF(self->sensorsMonitored != 0, self->triggerTemperatures[0]), ObjectModelEntryFlags::none }, + { "control", OBJECT_MODEL_FUNC(self->sensorsMonitored.IsNonEmpty()), ObjectModelEntryFlags::none }, + { "heaters", OBJECT_MODEL_FUNC_IF(self->sensorsMonitored.IsNonEmpty(), &monitoredSensorsArrayDescriptor), ObjectModelEntryFlags::none }, + { "highTemperature", OBJECT_MODEL_FUNC_IF(self->sensorsMonitored.IsNonEmpty(), self->triggerTemperatures[1], 1), ObjectModelEntryFlags::none }, + { "lowTemperature", OBJECT_MODEL_FUNC_IF(self->sensorsMonitored.IsNonEmpty(), self->triggerTemperatures[0], 1), ObjectModelEntryFlags::none }, }; constexpr uint8_t Fan::objectModelTableDescriptor[] = { 2, 8, 4 }; @@ -58,7 +60,6 @@ Fan::Fan(unsigned int fanNum) noexcept maxVal(1.0), // 100% maximum fan speed lastRpm(-1), whenLastRpmSet(0), blipTime(DefaultFanBlipTime), - sensorsMonitored(0), isConfigured(false) { triggerTemperatures[0] = triggerTemperatures[1] = DefaultHotEndFanTemperature; @@ -128,7 +129,7 @@ bool Fan::Configure(unsigned int mcode, size_t fanNum, GCodeBuffer& gb, const St gb.GetIntArray(sensors, numH, false); // Note that M106 H-1 disables thermostatic mode. The following code implements that automatically. - sensorsMonitored = 0; + sensorsMonitored.Clear(); for (size_t h = 0; h < numH; ++h) { const int hnum = sensors[h]; @@ -136,7 +137,7 @@ bool Fan::Configure(unsigned int mcode, size_t fanNum, GCodeBuffer& gb, const St { if (hnum < (int)MaxSensors) { - SetBit(sensorsMonitored, (unsigned int)hnum); + sensorsMonitored.SetBit((unsigned int)hnum); } else { @@ -145,7 +146,7 @@ bool Fan::Configure(unsigned int mcode, size_t fanNum, GCodeBuffer& gb, const St } } } - if (sensorsMonitored != 0) + if (sensorsMonitored.IsNonEmpty()) { val = 1.0; // default the fan speed to full for safety } @@ -186,16 +187,10 @@ bool Fan::Configure(unsigned int mcode, size_t fanNum, GCodeBuffer& gb, const St (int)(maxVal * 100.0), (double)(blipTime * MillisToSeconds) ); - if (sensorsMonitored != 0) + if (sensorsMonitored.IsNonEmpty()) { reply.catf(", temperature: %.1f:%.1fC, sensors:", (double)triggerTemperatures[0], (double)triggerTemperatures[1]); - SensorsBitmap copySensorsMonitored = sensorsMonitored; - while (copySensorsMonitored != 0) - { - const unsigned int sensorNum = LowestSetBit(copySensorsMonitored); - ClearBit(copySensorsMonitored, sensorNum); - reply.catf(" %u", sensorNum); - } + sensorsMonitored.Iterate([&reply](unsigned int sensorNum) { reply.catf(" %u", sensorNum); }); reply.catf(", current speed: %d%%:", (int)(lastVal * 100.0)); } } @@ -220,42 +215,12 @@ int32_t Fan::GetRPM() const noexcept return lastRpm; } -// Object model support functions -size_t Fan::GetNumMonitoredSensors() const noexcept -{ - static constexpr uint8_t bitCount[16] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 }; - SensorsBitmap copySensorsMonitored = sensorsMonitored; - size_t count = 0; - while (copySensorsMonitored != 0) - { - count += bitCount[copySensorsMonitored & 0x0F]; - copySensorsMonitored >>= 4; - } - return count; -} - -int32_t Fan::GetMonitoredSensorNumber(size_t index) const noexcept -{ - SensorsBitmap copySensorsMonitored = sensorsMonitored; - while (copySensorsMonitored != 0) - { - const unsigned int lowestBit = LowestSetBit(copySensorsMonitored); - if (index == 0) - { - return (int32_t)lowestBit; - } - ClearBit(copySensorsMonitored, lowestBit); - --index; - } - return -1; -} - #if HAS_MASS_STORAGE // Save the settings of this fan if it isn't thermostatic bool Fan::WriteSettings(FileStore *f, size_t fanNum) const noexcept { - if (sensorsMonitored == 0) + if (sensorsMonitored.IsNonEmpty()) { String<StringLength20> fanCommand; fanCommand.printf("M106 P%u S%.2f\n", fanNum, (double)val); diff --git a/src/Fans/Fan.h b/src/Fans/Fan.h index f6552b9d..2e8e9bd2 100644 --- a/src/Fans/Fan.h +++ b/src/Fans/Fan.h @@ -45,7 +45,7 @@ public: int32_t GetRPM() const noexcept; GCodeResult SetPwm(float speed, const StringRef& reply) noexcept; - bool HasMonitoredSensors() const noexcept { return sensorsMonitored != 0; } + bool HasMonitoredSensors() const noexcept { return sensorsMonitored.IsNonEmpty(); } const char *GetName() const noexcept { return name.c_str(); } #if HAS_MASS_STORAGE @@ -63,9 +63,6 @@ protected: void SetLastRpm(float rpm) noexcept { lastRpm = rpm; whenLastRpmSet = millis(); } - size_t GetNumMonitoredSensors() const noexcept; - int32_t GetMonitoredSensorNumber(size_t index) const noexcept; - unsigned int fanNumber; // Variables that control the fan diff --git a/src/Fans/FansManager.cpp b/src/Fans/FansManager.cpp index 8558225b..a1f5337a 100644 --- a/src/Fans/FansManager.cpp +++ b/src/Fans/FansManager.cpp @@ -103,7 +103,7 @@ GCodeResult FansManager::ConfigureFanPort(uint32_t fanNum, GCodeBuffer& gb, cons WriteLocker lock(fansLock); Fan *oldFan = nullptr; - std::swap(oldFan, fans[fanNum]); + std::swap<Fan*>(oldFan, fans[fanNum]); delete oldFan; const PwmFrequency freq = (gb.Seen('Q')) ? gb.GetPwmFrequency() : DefaultFanPwmFreq; diff --git a/src/Fans/LocalFan.cpp b/src/Fans/LocalFan.cpp index 4d3daf21..9980d91d 100644 --- a/src/Fans/LocalFan.cpp +++ b/src/Fans/LocalFan.cpp @@ -70,10 +70,10 @@ void LocalFan::InternalRefresh() noexcept { float reqVal; #if HAS_SMART_DRIVERS - uint32_t driverChannelsMonitored = 0; + DriverChannelsBitmap driverChannelsMonitored; #endif - if (sensorsMonitored == 0) + if (sensorsMonitored.IsEmpty()) { reqVal = val; } @@ -81,40 +81,43 @@ void LocalFan::InternalRefresh() noexcept { reqVal = 0.0; const bool bangBangMode = (triggerTemperatures[1] <= triggerTemperatures[0]); - SensorsBitmap copySensorsMonitored = sensorsMonitored; - while (copySensorsMonitored != 0) - { - const unsigned int sensorNum = LowestSetBit(copySensorsMonitored); - ClearBit(copySensorsMonitored, sensorNum); - const auto sensor = reprap.GetHeat().FindSensor(sensorNum); - if (sensor.IsNotNull()) + sensorsMonitored.Iterate + ([&reqVal, bangBangMode, this +#if HAS_SMART_DRIVERS + , &driverChannelsMonitored +#endif + ](unsigned int sensorNum) { - //TODO we used to turn the fan on if the associated heater was being tuned - float ht; - const TemperatureError err = sensor->GetLatestTemperature(ht); - if (err != TemperatureError::success || ht < BadLowTemperature || ht >= triggerTemperatures[1]) - { - reqVal = max<float>(reqVal, (bangBangMode) ? max<float>(0.5, val) : 1.0); - } - else if (!bangBangMode && ht > triggerTemperatures[0]) - { - // We already know that ht < triggerTemperatures[1], therefore unless we have NaNs it is safe to divide by (triggerTemperatures[1] - triggerTemperatures[0]) - reqVal = max<float>(reqVal, (ht - triggerTemperatures[0])/(triggerTemperatures[1] - triggerTemperatures[0])); - } - else if (lastVal != 0.0 && ht + ThermostatHysteresis > triggerTemperatures[0]) // if the fan is on, add a hysteresis before turning it off + const auto sensor = reprap.GetHeat().FindSensor(sensorNum); + if (sensor.IsNotNull()) { - const float minFanSpeed = (bangBangMode) ? max<float>(0.5, val) : minVal; - reqVal = constrain<float>(reqVal, minFanSpeed, maxVal); - } + //TODO we used to turn the fan on if the associated heater was being tuned + float ht; + const TemperatureError err = sensor->GetLatestTemperature(ht); + if (err != TemperatureError::success || ht < BadLowTemperature || ht >= triggerTemperatures[1]) + { + reqVal = max<float>(reqVal, (bangBangMode) ? max<float>(0.5, val) : 1.0); + } + else if (!bangBangMode && ht > triggerTemperatures[0]) + { + // We already know that ht < triggerTemperatures[1], therefore unless we have NaNs it is safe to divide by (triggerTemperatures[1] - triggerTemperatures[0]) + reqVal = max<float>(reqVal, (ht - triggerTemperatures[0])/(triggerTemperatures[1] - triggerTemperatures[0])); + } + else if (lastVal != 0.0 && ht + ThermostatHysteresis > triggerTemperatures[0]) // if the fan is on, add a hysteresis before turning it off + { + const float minFanSpeed = (bangBangMode) ? max<float>(0.5, val) : minVal; + reqVal = constrain<float>(reqVal, minFanSpeed, maxVal); + } #if HAS_SMART_DRIVERS - const int channel = sensor->GetSmartDriversChannel(); - if (channel >= 0) - { - driverChannelsMonitored |= 1 << (unsigned int)channel; - } + const int channel = sensor->GetSmartDriversChannel(); + if (channel >= 0) + { + driverChannelsMonitored.SetBit((unsigned int)channel); + } #endif + } } - } + ); } if (reqVal > 0.0) @@ -124,7 +127,7 @@ void LocalFan::InternalRefresh() noexcept { // We are turning this fan on #if HAS_SMART_DRIVERS - if (driverChannelsMonitored != 0) + if (driverChannelsMonitored.IsNonEmpty()) { reprap.GetPlatform().DriverCoolingFansOnOff(driverChannelsMonitored, true); // tell Platform that we have started a fan that cools drivers } @@ -150,7 +153,7 @@ void LocalFan::InternalRefresh() noexcept } } #if HAS_SMART_DRIVERS - else if (driverChannelsMonitored != 0 && lastVal != 0.0) + else if (driverChannelsMonitored.IsNonEmpty() && lastVal != 0.0) { reprap.GetPlatform().DriverCoolingFansOnOff(driverChannelsMonitored, false); // tell Platform that we have stopped a fan that cools drivers } @@ -185,11 +188,11 @@ bool LocalFan::UpdateFanConfiguration(const StringRef& reply) noexcept bool LocalFan::Check() noexcept { - if (sensorsMonitored != 0 || blipping) + if (sensorsMonitored.IsNonEmpty() || blipping) { InternalRefresh(); } - return sensorsMonitored != 0 && lastVal != 0.0; + return sensorsMonitored.IsNonEmpty() && lastVal != 0.0; } bool LocalFan::AssignPorts(const char *pinNames, const StringRef& reply) noexcept diff --git a/src/Fans/RemoteFan.cpp b/src/Fans/RemoteFan.cpp index 178608d4..79216346 100644 --- a/src/Fans/RemoteFan.cpp +++ b/src/Fans/RemoteFan.cpp @@ -85,7 +85,7 @@ bool RemoteFan::UpdateFanConfiguration(const StringRef& reply) noexcept msg->maxVal = maxVal; msg->triggerTemperatures[0] = triggerTemperatures[0]; msg->triggerTemperatures[1] = triggerTemperatures[1]; - msg->sensorsMonitored = sensorsMonitored; + msg->sensorsMonitored = sensorsMonitored.GetRaw(); return CanInterface::SendRequestAndGetStandardReply(buf, rid, reply) == GCodeResult::ok; } |