Add Bed zones - #28431
Draft
ellensp wants to merge 12 commits into
Draft
Conversation
Contributor
Author
|
Thoughts? G-codes use? Parameter letters? over all? |
- marlinui.cpp: apply_preheat() now passes bed_zone_mask to
setTargetBed() so LCD preheat presets only heat active zones
- docs/BedZones.md:
- Fix §3.1 parameter letter I→A ("neither K nor A")
- Fix §3.5 M304 parameter J→A throughout (code always used A;
§7.2 was already correct)
- §4.4 probe.cpp: mark done — setTargetBed default mask=0xFFFF
heats all zones; wholeDegBed/degTargetBed already zone-aware
- §4.5 marlinui.cpp: mark done
- §4.7 G76_M871.cpp: mark done — same no-op rationale as probe.cpp
- §8 Non-Goals: mark per-zone PID in EEPROM as done (was already
implemented); remove "Dynamic pin assignment at runtime"
- Phase 4 status: Partial → Done
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
This PR adds a BED_ZONES feature that divides a heated print bed into independently controlled heating zones. Each zone has its own heater output pin and thermistor input pin. Zones are selected individually or in groups via a bitmask.
The primary motivation is large-format printers and specialty beds where different physical areas need independent temperature control — e.g. heating only the front half of the bed for a small print, or tuning PID independently per zone.
What is implemented
Configuration (
Configuration_adv.h)#define BED_ZONES— opt-in feature flag, guarded byHAS_HEATED_BEDBED_ZONES_COUNT— number of zones (1–16, must be an explicit integer literal for preprocessor use)BED_ZONE_HEATER_PINS/BED_ZONE_SENSOR_PINS— per-zone pin arrays; zone 0 always maps toHEATER_BED_PIN/TEMP_BED_PINBED_ZONE_MASK_COUNT/BED_ZONE_MASKS— optional numbered bitmask presets (no string names; presets referenced by index only)BED_ZONE_PID_VALUES— per-zone default PID coefficientsSanityCheck.h—static_assertvalidates pin array lengths matchBED_ZONES_COUNT; error ifBED_ZONESenabled withoutHAS_HEATED_BEDTemperature Core (
temperature.cpp/temperature.h)temp_bedexpanded from scalarTempInfototemp_bed[BED_ZONES_COUNT]arraydegBed()/wholeDegBed()/degTargetBed()return the hottest active zone value (safety-relevant, matches what the status screen shows)setTargetBed(celsius, mask)— applies target to all zones selected by bitmaskisHeatingBed()/isCoolingBed()— zone-mask-awarewait_for_bed()— waits until all active-mask zones reach target withinTEMP_BED_HYSTERESISWRITE_HEATER_BED/soft_pwm_bed; zones 1+ useextDigitalWritewithsoft_pwm_bed_zone[](required for runtime-variable pins on AVR)PrepareTemp_BED_ZONEn/MeasureTemp_BED_ZONEnISR state pair;analog_to_celsius_bedtakes an optionalzoneparameterBED_ZONE_SENSOR_TYPES— per-zone thermistor type override (defaults toTEMP_SENSOR_BED); full thermistor table dispatch per zonetr_state_machine_bed[BED_ZONES_COUNT]gives each zone an independentTHERMAL_PROTECTION_BEDstate machine; MAXTEMP/MINTEMP checked per zonewatch_bed_zone[BED_ZONES_COUNT]replaces scalarwatch_bedpinMode+extDigitalWriteG-Code
M140/M190A<index>(single zone) andK<bitmask>(zone group) parameters; falls back to persistent active maskM142(new)K<mask>,A<index>,P<preset>M105B0:<t>/<target> B1:… B<n>@:<pwm>for all zonesM303A<index>parameter to autotune a specific bed zone; autotune finish message and result line use zone-aware format (M304 A<n> P… I… D…)M304A<index>parameter to set/report PID for a specific zone;M503reports oneecho: M304 A<n> …line per zoneEEPROM (
settings.cpp)bed_zone_mask) stored and restoredbedZonePIDs[BED_ZONES_COUNT]) stored and restoredLCD Menus
menu_temperature.cpp/menu_tune.cpp: singleBeditem replaced by per-zoneBed Zone 0…Bed Zone N-1loop whenHAS_BED_ZONES; all zone temperatures visible and editable from the standard temperature/tune menus (no separate detail screen needed)menu_advanced.cpp: per-zone P/I/D edit items and per-zone PID autotune items (PID_EDIT_MENU+PID_AUTOTUNE_MENU)language_en.h: addedMSG_BED_ZONE_N = _UxGT("Bed Zone ~")(tilde replaced by zone index at render time)B:field: shows hottest active zone (via updateddegBed()/degTargetBed())Controller Fan
CONTROLLER_FAN_BED_HEATINGuses zone-mask-awareisHeatingBed()Probing / Calibration (
probe.cpp,G76_M871.cpp)setTargetBed()calls inprobe.cppandG76_M871.cpppass no mask and use the zone-aware overload's defaultmask=0xFFFF— all zones are heated before probing/calibration. Since zone geometry is not stored there is no way to know which zone is under the probe; heating all zones is the only correct behaviour.wholeDegBed(),degTargetBed(), andwait_for_bed_heating()are already zone-aware (return/compare against the hottest active zone). No code changes were required in either file.LCD Preheat (
marlinui.cpp)apply_preheat()passesbed_zone_masktosetTargetBed()so preheat presets (M145 / LCD preheat menu) only heat the currently active zones.Build / Feature Guards
HAS_BED_ZONESmacro: true whenBED_ZONESenabled andBED_ZONES_COUNT > 1features.ini:HAS_BED_ZONES = build_src_filter=+<src/gcode/temp/M142.cpp>#if HAS_BED_ZONES/#elseguards — non-zone builds are unaffectedRequirements
HAS_HEATED_BEDandPIDTEMPBEDrecommended (bang-bang also works per-zone)ellensp/MarlinSimUItest-bed-zonesbranch (fetched automatically vialib_deps)Benefits
BED_ZONESdisabled) compile and behave identically to before; all new paths are behindHAS_BED_ZONESguardsConfigurations
Currently tested with:
mega2560(AVR ATmega2560) — clean build, no regressionssimulator_linux_debug(Linux native sim) — builds and runs; M105/M140/M190/M142/M303/M304/M503 verified via terminaltest_config_for_sim.zip
Related Issues