My Marlin configs for Fabrikator Mini and CTC i3 Pro B
Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940
  1. /**
  2. * Marlin 3D Printer Firmware
  3. * Copyright (C) 2016, 2017 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
  4. *
  5. * Based on Sprinter and grbl.
  6. * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
  7. *
  8. * This program is free software: you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License as published by
  10. * the Free Software Foundation, either version 3 of the License, or
  11. * (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  20. *
  21. */
  22. /**
  23. * About Marlin
  24. *
  25. * This firmware is a mashup between Sprinter and grbl.
  26. * - https://github.com/kliment/Sprinter
  27. * - https://github.com/simen/grbl
  28. */
  29. #include "Marlin.h"
  30. #include "lcd/ultralcd.h"
  31. #include "module/motion.h"
  32. #include "module/planner.h"
  33. #include "module/stepper.h"
  34. #include "module/endstops.h"
  35. #include "module/temperature.h"
  36. #include "sd/cardreader.h"
  37. #include "module/configuration_store.h"
  38. #ifdef ARDUINO
  39. #include <pins_arduino.h>
  40. #endif
  41. #include <math.h>
  42. #include "libs/nozzle.h"
  43. #include "libs/duration_t.h"
  44. #include "gcode/gcode.h"
  45. #include "gcode/parser.h"
  46. #include "gcode/queue.h"
  47. #if HAS_BUZZER && DISABLED(LCD_USE_I2C_BUZZER)
  48. #include "libs/buzzer.h"
  49. #endif
  50. #if HAS_ABL
  51. #include "libs/vector_3.h"
  52. #if ENABLED(AUTO_BED_LEVELING_LINEAR)
  53. #include "libs/least_squares_fit.h"
  54. #endif
  55. #elif ENABLED(MESH_BED_LEVELING)
  56. #include "feature/mbl/mesh_bed_leveling.h"
  57. #endif
  58. #if (ENABLED(SWITCHING_EXTRUDER) && !DONT_SWITCH) || ENABLED(SWITCHING_NOZZLE)
  59. #include "module/tool_change.h"
  60. #endif
  61. #if ENABLED(BEZIER_CURVE_SUPPORT)
  62. #include "module/planner_bezier.h"
  63. #endif
  64. #if ENABLED(MAX7219_DEBUG)
  65. #include "feature/Max7219_Debug_LEDs.h"
  66. #endif
  67. #if HAS_COLOR_LEDS
  68. #include "feature/leds/leds.h"
  69. #endif
  70. #if HAS_SERVOS
  71. #include "HAL/servo.h"
  72. #endif
  73. #if HAS_DIGIPOTSS
  74. #include <SPI.h>
  75. #endif
  76. #if ENABLED(DAC_STEPPER_CURRENT)
  77. #include "feature/dac/stepper_dac.h"
  78. #endif
  79. #if ENABLED(EXPERIMENTAL_I2CBUS)
  80. #include "feature/twibus.h"
  81. #endif
  82. #if ENABLED(I2C_POSITION_ENCODERS)
  83. #include "feature/I2CPositionEncoder.h"
  84. #endif
  85. #if ENABLED(ENDSTOP_INTERRUPTS_FEATURE)
  86. #include "HAL/HAL_endstop_interrupts.h"
  87. #endif
  88. #if ENABLED(M100_FREE_MEMORY_WATCHER)
  89. void M100_dump_routine(const char * const title, const char *start, const char *end);
  90. #endif
  91. #if ENABLED(SDSUPPORT)
  92. CardReader card;
  93. #endif
  94. #if ENABLED(EXPERIMENTAL_I2CBUS)
  95. TWIBus i2c;
  96. #endif
  97. #if ENABLED(G38_PROBE_TARGET)
  98. bool G38_move = false,
  99. G38_endstop_hit = false;
  100. #endif
  101. #if ENABLED(AUTO_BED_LEVELING_UBL)
  102. #include "feature/ubl/ubl.h"
  103. extern bool defer_return_to_status;
  104. unified_bed_leveling ubl;
  105. #define UBL_MESH_VALID !( ( ubl.z_values[0][0] == ubl.z_values[0][1] && ubl.z_values[0][1] == ubl.z_values[0][2] \
  106. && ubl.z_values[1][0] == ubl.z_values[1][1] && ubl.z_values[1][1] == ubl.z_values[1][2] \
  107. && ubl.z_values[2][0] == ubl.z_values[2][1] && ubl.z_values[2][1] == ubl.z_values[2][2] \
  108. && ubl.z_values[0][0] == 0 && ubl.z_values[1][0] == 0 && ubl.z_values[2][0] == 0 ) \
  109. || isnan(ubl.z_values[0][0]))
  110. #endif
  111. #if ENABLED(SENSORLESS_HOMING)
  112. #include "feature/tmc2130.h"
  113. #endif
  114. bool Running = true;
  115. /**
  116. * axis_homed
  117. * Flags that each linear axis was homed.
  118. * XYZ on cartesian, ABC on delta, ABZ on SCARA.
  119. *
  120. * axis_known_position
  121. * Flags that the position is known in each linear axis. Set when homed.
  122. * Cleared whenever a stepper powers off, potentially losing its position.
  123. */
  124. bool axis_homed[XYZ] = { false }, axis_known_position[XYZ] = { false };
  125. #if ENABLED(TEMPERATURE_UNITS_SUPPORT)
  126. TempUnit input_temp_units = TEMPUNIT_C;
  127. #endif
  128. /**
  129. * Feed rates are often configured with mm/m
  130. * but the planner and stepper like mm/s units.
  131. */
  132. static const float homing_feedrate_mm_s[] PROGMEM = {
  133. #if ENABLED(DELTA)
  134. MMM_TO_MMS(HOMING_FEEDRATE_Z), MMM_TO_MMS(HOMING_FEEDRATE_Z),
  135. #else
  136. MMM_TO_MMS(HOMING_FEEDRATE_XY), MMM_TO_MMS(HOMING_FEEDRATE_XY),
  137. #endif
  138. MMM_TO_MMS(HOMING_FEEDRATE_Z), 0
  139. };
  140. FORCE_INLINE float homing_feedrate(const AxisEnum a) { return pgm_read_float(&homing_feedrate_mm_s[a]); }
  141. static float saved_feedrate_mm_s;
  142. int16_t feedrate_percentage = 100, saved_feedrate_percentage,
  143. flow_percentage[EXTRUDERS] = ARRAY_BY_EXTRUDERS1(100);
  144. // Initialized by settings.load()
  145. bool volumetric_enabled;
  146. float filament_size[EXTRUDERS], volumetric_multiplier[EXTRUDERS];
  147. #if HAS_WORKSPACE_OFFSET
  148. #if HAS_POSITION_SHIFT
  149. // The distance that XYZ has been offset by G92. Reset by G28.
  150. float position_shift[XYZ] = { 0 };
  151. #endif
  152. #if HAS_HOME_OFFSET
  153. // This offset is added to the configured home position.
  154. // Set by M206, M428, or menu item. Saved to EEPROM.
  155. float home_offset[XYZ] = { 0 };
  156. #endif
  157. #if HAS_HOME_OFFSET && HAS_POSITION_SHIFT
  158. // The above two are combined to save on computes
  159. float workspace_offset[XYZ] = { 0 };
  160. #endif
  161. #endif
  162. #if FAN_COUNT > 0
  163. int16_t fanSpeeds[FAN_COUNT] = { 0 };
  164. #if ENABLED(PROBING_FANS_OFF)
  165. bool fans_paused = false;
  166. int16_t paused_fanSpeeds[FAN_COUNT] = { 0 };
  167. #endif
  168. #endif
  169. // For M109 and M190, this flag may be cleared (by M108) to exit the wait loop
  170. volatile bool wait_for_heatup = true;
  171. // For M0/M1, this flag may be cleared (by M108) to exit the wait-for-user loop
  172. #if HAS_RESUME_CONTINUE
  173. volatile bool wait_for_user = false;
  174. #endif
  175. // Inactivity shutdown
  176. millis_t previous_cmd_ms = 0;
  177. static millis_t max_inactive_time = 0;
  178. static millis_t stepper_inactive_time = (DEFAULT_STEPPER_DEACTIVE_TIME) * 1000UL;
  179. // Print Job Timer
  180. #if ENABLED(PRINTCOUNTER)
  181. PrintCounter print_job_timer = PrintCounter();
  182. #else
  183. Stopwatch print_job_timer = Stopwatch();
  184. #endif
  185. #if HAS_BED_PROBE
  186. float zprobe_zoffset; // Initialized by settings.load()
  187. #endif
  188. #if HAS_ABL
  189. float xy_probe_feedrate_mm_s = MMM_TO_MMS(XY_PROBE_SPEED);
  190. #define XY_PROBE_FEEDRATE_MM_S xy_probe_feedrate_mm_s
  191. #elif defined(XY_PROBE_SPEED)
  192. #define XY_PROBE_FEEDRATE_MM_S MMM_TO_MMS(XY_PROBE_SPEED)
  193. #else
  194. #define XY_PROBE_FEEDRATE_MM_S PLANNER_XY_FEEDRATE()
  195. #endif
  196. #if ENABLED(AUTO_BED_LEVELING_BILINEAR)
  197. #if ENABLED(DELTA)
  198. #define ADJUST_DELTA(V) \
  199. if (planner.abl_enabled) { \
  200. const float zadj = bilinear_z_offset(V); \
  201. delta[A_AXIS] += zadj; \
  202. delta[B_AXIS] += zadj; \
  203. delta[C_AXIS] += zadj; \
  204. }
  205. #else
  206. #define ADJUST_DELTA(V) if (planner.abl_enabled) { delta[Z_AXIS] += bilinear_z_offset(V); }
  207. #endif
  208. #elif IS_KINEMATIC
  209. #define ADJUST_DELTA(V) NOOP
  210. #endif
  211. #if ENABLED(Z_DUAL_ENDSTOPS)
  212. float z_endstop_adj;
  213. #endif
  214. // Extruder offsets
  215. #if HOTENDS > 1
  216. float hotend_offset[XYZ][HOTENDS]; // Initialized by settings.load()
  217. #endif
  218. #if HAS_Z_SERVO_ENDSTOP
  219. const int z_servo_angle[2] = Z_SERVO_ANGLES;
  220. #endif
  221. #if ENABLED(BARICUDA)
  222. uint8_t baricuda_valve_pressure = 0,
  223. baricuda_e_to_p_pressure = 0;
  224. #endif
  225. #if HAS_POWER_SWITCH
  226. bool powersupply_on =
  227. #if ENABLED(PS_DEFAULT_OFF)
  228. false
  229. #else
  230. true
  231. #endif
  232. ;
  233. #endif
  234. #if ENABLED(DELTA)
  235. float delta[ABC],
  236. endstop_adj[ABC] = { 0 };
  237. // Initialized by settings.load()
  238. float delta_radius,
  239. delta_tower_angle_trim[2],
  240. delta_tower[ABC][2],
  241. delta_diagonal_rod,
  242. delta_calibration_radius,
  243. delta_diagonal_rod_2_tower[ABC],
  244. delta_segments_per_second,
  245. delta_clip_start_height = Z_MAX_POS;
  246. float delta_safe_distance_from_top();
  247. #endif
  248. #if ENABLED(AUTO_BED_LEVELING_BILINEAR)
  249. int bilinear_grid_spacing[2], bilinear_start[2];
  250. float bilinear_grid_factor[2],
  251. z_values[GRID_MAX_POINTS_X][GRID_MAX_POINTS_Y];
  252. #endif
  253. #if IS_SCARA
  254. // Float constants for SCARA calculations
  255. const float L1 = SCARA_LINKAGE_1, L2 = SCARA_LINKAGE_2,
  256. L1_2 = sq(float(L1)), L1_2_2 = 2.0 * L1_2,
  257. L2_2 = sq(float(L2));
  258. float delta_segments_per_second = SCARA_SEGMENTS_PER_SECOND,
  259. delta[ABC];
  260. #endif
  261. float cartes[XYZ] = { 0 };
  262. #if ENABLED(FILAMENT_WIDTH_SENSOR)
  263. bool filament_sensor = false; // M405 turns on filament sensor control. M406 turns it off.
  264. float filament_width_nominal = DEFAULT_NOMINAL_FILAMENT_DIA, // Nominal filament width. Change with M404.
  265. filament_width_meas = DEFAULT_MEASURED_FILAMENT_DIA; // Measured filament diameter
  266. uint8_t meas_delay_cm = MEASUREMENT_DELAY_CM, // Distance delay setting
  267. measurement_delay[MAX_MEASUREMENT_DELAY + 1]; // Ring buffer to delayed measurement. Store extruder factor after subtracting 100
  268. int8_t filwidth_delay_index[2] = { 0, -1 }; // Indexes into ring buffer
  269. #endif
  270. #if ENABLED(FILAMENT_RUNOUT_SENSOR)
  271. static bool filament_ran_out = false;
  272. #endif
  273. #if ENABLED(ADVANCED_PAUSE_FEATURE)
  274. AdvancedPauseMenuResponse advanced_pause_menu_response;
  275. #endif
  276. #if ENABLED(MIXING_EXTRUDER)
  277. float mixing_factor[MIXING_STEPPERS]; // Reciprocal of mix proportion. 0.0 = off, otherwise >= 1.0.
  278. #if MIXING_VIRTUAL_TOOLS > 1
  279. float mixing_virtual_tool_mix[MIXING_VIRTUAL_TOOLS][MIXING_STEPPERS];
  280. #endif
  281. #endif
  282. #if HAS_SERVOS
  283. HAL_SERVO_LIB servo[NUM_SERVOS];
  284. #define MOVE_SERVO(I, P) servo[I].move(P)
  285. #if HAS_Z_SERVO_ENDSTOP
  286. #define DEPLOY_Z_SERVO() MOVE_SERVO(Z_ENDSTOP_SERVO_NR, z_servo_angle[0])
  287. #define STOW_Z_SERVO() MOVE_SERVO(Z_ENDSTOP_SERVO_NR, z_servo_angle[1])
  288. #endif
  289. #endif
  290. #ifdef CHDK
  291. millis_t chdkHigh = 0;
  292. bool chdkActive = false;
  293. #endif
  294. #if ENABLED(PID_EXTRUSION_SCALING)
  295. int lpq_len = 20;
  296. #endif
  297. #if ENABLED(HOST_KEEPALIVE_FEATURE)
  298. MarlinBusyState busy_state = NOT_BUSY;
  299. static millis_t next_busy_signal_ms = 0;
  300. uint8_t host_keepalive_interval = DEFAULT_KEEPALIVE_INTERVAL;
  301. #else
  302. #define host_keepalive() NOOP
  303. #endif
  304. #if ENABLED(I2C_POSITION_ENCODERS)
  305. I2CPositionEncodersMgr I2CPEM;
  306. uint8_t blockBufferIndexRef = 0;
  307. millis_t lastUpdateMillis;
  308. #endif
  309. #if ENABLED(CNC_WORKSPACE_PLANES)
  310. static WorkspacePlane workspace_plane = PLANE_XY;
  311. #endif
  312. /**
  313. * ***************************************************************************
  314. * ******************************** FUNCTIONS ********************************
  315. * ***************************************************************************
  316. */
  317. void stop();
  318. void get_cartesian_from_steppers();
  319. void set_current_from_steppers_for_axis(const AxisEnum axis);
  320. #if ENABLED(BEZIER_CURVE_SUPPORT)
  321. void plan_cubic_move(const float offset[4]);
  322. #endif
  323. void report_current_position();
  324. #if ENABLED(DIGIPOT_I2C)
  325. extern void digipot_i2c_set_current(uint8_t channel, float current);
  326. extern void digipot_i2c_init();
  327. #endif
  328. void setup_killpin() {
  329. #if HAS_KILL
  330. SET_INPUT_PULLUP(KILL_PIN);
  331. #endif
  332. }
  333. #if ENABLED(FILAMENT_RUNOUT_SENSOR)
  334. void setup_filrunoutpin() {
  335. #if ENABLED(ENDSTOPPULLUP_FIL_RUNOUT)
  336. SET_INPUT_PULLUP(FIL_RUNOUT_PIN);
  337. #else
  338. SET_INPUT(FIL_RUNOUT_PIN);
  339. #endif
  340. }
  341. #endif
  342. void setup_powerhold() {
  343. #if HAS_SUICIDE
  344. OUT_WRITE(SUICIDE_PIN, HIGH);
  345. #endif
  346. #if HAS_POWER_SWITCH
  347. #if ENABLED(PS_DEFAULT_OFF)
  348. OUT_WRITE(PS_ON_PIN, PS_ON_ASLEEP);
  349. #else
  350. OUT_WRITE(PS_ON_PIN, PS_ON_AWAKE);
  351. #endif
  352. #endif
  353. }
  354. void suicide() {
  355. #if HAS_SUICIDE
  356. OUT_WRITE(SUICIDE_PIN, LOW);
  357. #endif
  358. }
  359. void servo_init() {
  360. #if NUM_SERVOS >= 1 && HAS_SERVO_0
  361. servo[0].attach(SERVO0_PIN);
  362. servo[0].detach(); // Just set up the pin. We don't have a position yet. Don't move to a random position.
  363. #endif
  364. #if NUM_SERVOS >= 2 && HAS_SERVO_1
  365. servo[1].attach(SERVO1_PIN);
  366. servo[1].detach();
  367. #endif
  368. #if NUM_SERVOS >= 3 && HAS_SERVO_2
  369. servo[2].attach(SERVO2_PIN);
  370. servo[2].detach();
  371. #endif
  372. #if NUM_SERVOS >= 4 && HAS_SERVO_3
  373. servo[3].attach(SERVO3_PIN);
  374. servo[3].detach();
  375. #endif
  376. #if HAS_Z_SERVO_ENDSTOP
  377. /**
  378. * Set position of Z Servo Endstop
  379. *
  380. * The servo might be deployed and positioned too low to stow
  381. * when starting up the machine or rebooting the board.
  382. * There's no way to know where the nozzle is positioned until
  383. * homing has been done - no homing with z-probe without init!
  384. *
  385. */
  386. STOW_Z_SERVO();
  387. #endif
  388. }
  389. /**
  390. * Stepper Reset (RigidBoard, et.al.)
  391. */
  392. #if HAS_STEPPER_RESET
  393. void disableStepperDrivers() {
  394. OUT_WRITE(STEPPER_RESET_PIN, LOW); // drive it down to hold in reset motor driver chips
  395. }
  396. void enableStepperDrivers() { SET_INPUT(STEPPER_RESET_PIN); } // set to input, which allows it to be pulled high by pullups
  397. #endif
  398. #if ENABLED(EXPERIMENTAL_I2CBUS) && I2C_SLAVE_ADDRESS > 0
  399. void i2c_on_receive(int bytes) { // just echo all bytes received to serial
  400. i2c.receive(bytes);
  401. }
  402. void i2c_on_request() { // just send dummy data for now
  403. i2c.reply("Hello World!\n");
  404. }
  405. #endif
  406. #if HAS_WORKSPACE_OFFSET || ENABLED(DUAL_X_CARRIAGE)
  407. /**
  408. * Software endstops can be used to monitor the open end of
  409. * an axis that has a hardware endstop on the other end. Or
  410. * they can prevent axes from moving past endstops and grinding.
  411. *
  412. * To keep doing their job as the coordinate system changes,
  413. * the software endstop positions must be refreshed to remain
  414. * at the same positions relative to the machine.
  415. */
  416. void update_software_endstops(const AxisEnum axis) {
  417. const float offs = 0.0
  418. #if HAS_HOME_OFFSET
  419. + home_offset[axis]
  420. #endif
  421. #if HAS_POSITION_SHIFT
  422. + position_shift[axis]
  423. #endif
  424. ;
  425. #if HAS_HOME_OFFSET && HAS_POSITION_SHIFT
  426. workspace_offset[axis] = offs;
  427. #endif
  428. #if ENABLED(DUAL_X_CARRIAGE)
  429. if (axis == X_AXIS) {
  430. // In Dual X mode hotend_offset[X] is T1's home position
  431. float dual_max_x = max(hotend_offset[X_AXIS][1], X2_MAX_POS);
  432. if (active_extruder != 0) {
  433. // T1 can move from X2_MIN_POS to X2_MAX_POS or X2 home position (whichever is larger)
  434. soft_endstop_min[X_AXIS] = X2_MIN_POS + offs;
  435. soft_endstop_max[X_AXIS] = dual_max_x + offs;
  436. }
  437. else if (dual_x_carriage_mode == DXC_DUPLICATION_MODE) {
  438. // In Duplication Mode, T0 can move as far left as X_MIN_POS
  439. // but not so far to the right that T1 would move past the end
  440. soft_endstop_min[X_AXIS] = base_min_pos(X_AXIS) + offs;
  441. soft_endstop_max[X_AXIS] = min(base_max_pos(X_AXIS), dual_max_x - duplicate_extruder_x_offset) + offs;
  442. }
  443. else {
  444. // In other modes, T0 can move from X_MIN_POS to X_MAX_POS
  445. soft_endstop_min[axis] = base_min_pos(axis) + offs;
  446. soft_endstop_max[axis] = base_max_pos(axis) + offs;
  447. }
  448. }
  449. #elif ENABLED(DELTA)
  450. soft_endstop_min[axis] = base_min_pos(axis) + (axis == Z_AXIS ? 0 : offs);
  451. soft_endstop_max[axis] = base_max_pos(axis) + offs;
  452. #else
  453. soft_endstop_min[axis] = base_min_pos(axis) + offs;
  454. soft_endstop_max[axis] = base_max_pos(axis) + offs;
  455. #endif
  456. #if ENABLED(DEBUG_LEVELING_FEATURE)
  457. if (DEBUGGING(LEVELING)) {
  458. SERIAL_ECHOPAIR("For ", axis_codes[axis]);
  459. #if HAS_HOME_OFFSET
  460. SERIAL_ECHOPAIR(" axis:\n home_offset = ", home_offset[axis]);
  461. #endif
  462. #if HAS_POSITION_SHIFT
  463. SERIAL_ECHOPAIR("\n position_shift = ", position_shift[axis]);
  464. #endif
  465. SERIAL_ECHOPAIR("\n soft_endstop_min = ", soft_endstop_min[axis]);
  466. SERIAL_ECHOLNPAIR("\n soft_endstop_max = ", soft_endstop_max[axis]);
  467. }
  468. #endif
  469. #if ENABLED(DELTA)
  470. if (axis == Z_AXIS)
  471. delta_clip_start_height = soft_endstop_max[axis] - delta_safe_distance_from_top();
  472. #endif
  473. }
  474. #endif // HAS_WORKSPACE_OFFSET || DUAL_X_CARRIAGE
  475. #if HAS_M206_COMMAND
  476. /**
  477. * Change the home offset for an axis, update the current
  478. * position and the software endstops to retain the same
  479. * relative distance to the new home.
  480. *
  481. * Since this changes the current_position, code should
  482. * call sync_plan_position soon after this.
  483. */
  484. static void set_home_offset(const AxisEnum axis, const float v) {
  485. current_position[axis] += v - home_offset[axis];
  486. home_offset[axis] = v;
  487. update_software_endstops(axis);
  488. }
  489. #endif // HAS_M206_COMMAND
  490. /**
  491. * Set an axis' current position to its home position (after homing).
  492. *
  493. * For Core and Cartesian robots this applies one-to-one when an
  494. * individual axis has been homed.
  495. *
  496. * DELTA should wait until all homing is done before setting the XYZ
  497. * current_position to home, because homing is a single operation.
  498. * In the case where the axis positions are already known and previously
  499. * homed, DELTA could home to X or Y individually by moving either one
  500. * to the center. However, homing Z always homes XY and Z.
  501. *
  502. * SCARA should wait until all XY homing is done before setting the XY
  503. * current_position to home, because neither X nor Y is at home until
  504. * both are at home. Z can however be homed individually.
  505. *
  506. * Callers must sync the planner position after calling this!
  507. */
  508. static void set_axis_is_at_home(const AxisEnum axis) {
  509. #if ENABLED(DEBUG_LEVELING_FEATURE)
  510. if (DEBUGGING(LEVELING)) {
  511. SERIAL_ECHOPAIR(">>> set_axis_is_at_home(", axis_codes[axis]);
  512. SERIAL_CHAR(')');
  513. SERIAL_EOL();
  514. }
  515. #endif
  516. axis_known_position[axis] = axis_homed[axis] = true;
  517. #if HAS_POSITION_SHIFT
  518. position_shift[axis] = 0;
  519. update_software_endstops(axis);
  520. #endif
  521. #if ENABLED(DUAL_X_CARRIAGE)
  522. if (axis == X_AXIS && (active_extruder == 1 || dual_x_carriage_mode == DXC_DUPLICATION_MODE)) {
  523. current_position[X_AXIS] = x_home_pos(active_extruder);
  524. return;
  525. }
  526. #endif
  527. #if ENABLED(MORGAN_SCARA)
  528. /**
  529. * Morgan SCARA homes XY at the same time
  530. */
  531. if (axis == X_AXIS || axis == Y_AXIS) {
  532. float homeposition[XYZ];
  533. LOOP_XYZ(i) homeposition[i] = LOGICAL_POSITION(base_home_pos((AxisEnum)i), i);
  534. // SERIAL_ECHOPAIR("homeposition X:", homeposition[X_AXIS]);
  535. // SERIAL_ECHOLNPAIR(" Y:", homeposition[Y_AXIS]);
  536. /**
  537. * Get Home position SCARA arm angles using inverse kinematics,
  538. * and calculate homing offset using forward kinematics
  539. */
  540. inverse_kinematics(homeposition);
  541. forward_kinematics_SCARA(delta[A_AXIS], delta[B_AXIS]);
  542. // SERIAL_ECHOPAIR("Cartesian X:", cartes[X_AXIS]);
  543. // SERIAL_ECHOLNPAIR(" Y:", cartes[Y_AXIS]);
  544. current_position[axis] = LOGICAL_POSITION(cartes[axis], axis);
  545. /**
  546. * SCARA home positions are based on configuration since the actual
  547. * limits are determined by the inverse kinematic transform.
  548. */
  549. soft_endstop_min[axis] = base_min_pos(axis); // + (cartes[axis] - base_home_pos(axis));
  550. soft_endstop_max[axis] = base_max_pos(axis); // + (cartes[axis] - base_home_pos(axis));
  551. }
  552. else
  553. #endif
  554. {
  555. current_position[axis] = LOGICAL_POSITION(base_home_pos(axis), axis);
  556. }
  557. /**
  558. * Z Probe Z Homing? Account for the probe's Z offset.
  559. */
  560. #if HAS_BED_PROBE && Z_HOME_DIR < 0
  561. if (axis == Z_AXIS) {
  562. #if HOMING_Z_WITH_PROBE
  563. current_position[Z_AXIS] -= zprobe_zoffset;
  564. #if ENABLED(DEBUG_LEVELING_FEATURE)
  565. if (DEBUGGING(LEVELING)) {
  566. SERIAL_ECHOLNPGM("*** Z HOMED WITH PROBE (Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN) ***");
  567. SERIAL_ECHOLNPAIR("> zprobe_zoffset = ", zprobe_zoffset);
  568. }
  569. #endif
  570. #elif ENABLED(DEBUG_LEVELING_FEATURE)
  571. if (DEBUGGING(LEVELING)) SERIAL_ECHOLNPGM("*** Z HOMED TO ENDSTOP (Z_MIN_PROBE_ENDSTOP) ***");
  572. #endif
  573. }
  574. #endif
  575. #if ENABLED(DEBUG_LEVELING_FEATURE)
  576. if (DEBUGGING(LEVELING)) {
  577. #if HAS_HOME_OFFSET
  578. SERIAL_ECHOPAIR("> home_offset[", axis_codes[axis]);
  579. SERIAL_ECHOLNPAIR("] = ", home_offset[axis]);
  580. #endif
  581. DEBUG_POS("", current_position);
  582. SERIAL_ECHOPAIR("<<< set_axis_is_at_home(", axis_codes[axis]);
  583. SERIAL_CHAR(')');
  584. SERIAL_EOL();
  585. }
  586. #endif
  587. #if ENABLED(I2C_POSITION_ENCODERS)
  588. I2CPEM.homed(axis);
  589. #endif
  590. }
  591. /**
  592. * Some planner shorthand inline functions
  593. */
  594. inline float get_homing_bump_feedrate(const AxisEnum axis) {
  595. static const uint8_t homing_bump_divisor[] PROGMEM = HOMING_BUMP_DIVISOR;
  596. uint8_t hbd = pgm_read_byte(&homing_bump_divisor[axis]);
  597. if (hbd < 1) {
  598. hbd = 10;
  599. SERIAL_ECHO_START();
  600. SERIAL_ECHOLNPGM("Warning: Homing Bump Divisor < 1");
  601. }
  602. return homing_feedrate(axis) / hbd;
  603. }
  604. /**
  605. * Plan a move to (X, Y, Z) and set the current_position
  606. * The final current_position may not be the one that was requested
  607. */
  608. void do_blocking_move_to(const float &lx, const float &ly, const float &lz, const float &fr_mm_s/*=0.0*/) {
  609. const float old_feedrate_mm_s = feedrate_mm_s;
  610. #if ENABLED(DEBUG_LEVELING_FEATURE)
  611. if (DEBUGGING(LEVELING)) print_xyz(PSTR(">>> do_blocking_move_to"), NULL, lx, ly, lz);
  612. #endif
  613. #if ENABLED(DELTA)
  614. if (!position_is_reachable_xy(lx, ly)) return;
  615. feedrate_mm_s = fr_mm_s ? fr_mm_s : XY_PROBE_FEEDRATE_MM_S;
  616. set_destination_to_current(); // sync destination at the start
  617. #if ENABLED(DEBUG_LEVELING_FEATURE)
  618. if (DEBUGGING(LEVELING)) DEBUG_POS("set_destination_to_current", destination);
  619. #endif
  620. // when in the danger zone
  621. if (current_position[Z_AXIS] > delta_clip_start_height) {
  622. if (lz > delta_clip_start_height) { // staying in the danger zone
  623. destination[X_AXIS] = lx; // move directly (uninterpolated)
  624. destination[Y_AXIS] = ly;
  625. destination[Z_AXIS] = lz;
  626. prepare_uninterpolated_move_to_destination(); // set_current_to_destination
  627. #if ENABLED(DEBUG_LEVELING_FEATURE)
  628. if (DEBUGGING(LEVELING)) DEBUG_POS("danger zone move", current_position);
  629. #endif
  630. return;
  631. }
  632. else {
  633. destination[Z_AXIS] = delta_clip_start_height;
  634. prepare_uninterpolated_move_to_destination(); // set_current_to_destination
  635. #if ENABLED(DEBUG_LEVELING_FEATURE)
  636. if (DEBUGGING(LEVELING)) DEBUG_POS("zone border move", current_position);
  637. #endif
  638. }
  639. }
  640. if (lz > current_position[Z_AXIS]) { // raising?
  641. destination[Z_AXIS] = lz;
  642. prepare_uninterpolated_move_to_destination(); // set_current_to_destination
  643. #if ENABLED(DEBUG_LEVELING_FEATURE)
  644. if (DEBUGGING(LEVELING)) DEBUG_POS("z raise move", current_position);
  645. #endif
  646. }
  647. destination[X_AXIS] = lx;
  648. destination[Y_AXIS] = ly;
  649. prepare_move_to_destination(); // set_current_to_destination
  650. #if ENABLED(DEBUG_LEVELING_FEATURE)
  651. if (DEBUGGING(LEVELING)) DEBUG_POS("xy move", current_position);
  652. #endif
  653. if (lz < current_position[Z_AXIS]) { // lowering?
  654. destination[Z_AXIS] = lz;
  655. prepare_uninterpolated_move_to_destination(); // set_current_to_destination
  656. #if ENABLED(DEBUG_LEVELING_FEATURE)
  657. if (DEBUGGING(LEVELING)) DEBUG_POS("z lower move", current_position);
  658. #endif
  659. }
  660. #elif IS_SCARA
  661. if (!position_is_reachable_xy(lx, ly)) return;
  662. set_destination_to_current();
  663. // If Z needs to raise, do it before moving XY
  664. if (destination[Z_AXIS] < lz) {
  665. destination[Z_AXIS] = lz;
  666. prepare_uninterpolated_move_to_destination(fr_mm_s ? fr_mm_s : homing_feedrate(Z_AXIS));
  667. }
  668. destination[X_AXIS] = lx;
  669. destination[Y_AXIS] = ly;
  670. prepare_uninterpolated_move_to_destination(fr_mm_s ? fr_mm_s : XY_PROBE_FEEDRATE_MM_S);
  671. // If Z needs to lower, do it after moving XY
  672. if (destination[Z_AXIS] > lz) {
  673. destination[Z_AXIS] = lz;
  674. prepare_uninterpolated_move_to_destination(fr_mm_s ? fr_mm_s : homing_feedrate(Z_AXIS));
  675. }
  676. #else
  677. // If Z needs to raise, do it before moving XY
  678. if (current_position[Z_AXIS] < lz) {
  679. feedrate_mm_s = fr_mm_s ? fr_mm_s : homing_feedrate(Z_AXIS);
  680. current_position[Z_AXIS] = lz;
  681. line_to_current_position();
  682. }
  683. feedrate_mm_s = fr_mm_s ? fr_mm_s : XY_PROBE_FEEDRATE_MM_S;
  684. current_position[X_AXIS] = lx;
  685. current_position[Y_AXIS] = ly;
  686. line_to_current_position();
  687. // If Z needs to lower, do it after moving XY
  688. if (current_position[Z_AXIS] > lz) {
  689. feedrate_mm_s = fr_mm_s ? fr_mm_s : homing_feedrate(Z_AXIS);
  690. current_position[Z_AXIS] = lz;
  691. line_to_current_position();
  692. }
  693. #endif
  694. stepper.synchronize();
  695. feedrate_mm_s = old_feedrate_mm_s;
  696. #if ENABLED(DEBUG_LEVELING_FEATURE)
  697. if (DEBUGGING(LEVELING)) SERIAL_ECHOLNPGM("<<< do_blocking_move_to");
  698. #endif
  699. }
  700. void do_blocking_move_to_x(const float &lx, const float &fr_mm_s/*=0.0*/) {
  701. do_blocking_move_to(lx, current_position[Y_AXIS], current_position[Z_AXIS], fr_mm_s);
  702. }
  703. void do_blocking_move_to_z(const float &lz, const float &fr_mm_s/*=0.0*/) {
  704. do_blocking_move_to(current_position[X_AXIS], current_position[Y_AXIS], lz, fr_mm_s);
  705. }
  706. void do_blocking_move_to_xy(const float &lx, const float &ly, const float &fr_mm_s/*=0.0*/) {
  707. do_blocking_move_to(lx, ly, current_position[Z_AXIS], fr_mm_s);
  708. }
  709. //
  710. // Prepare to do endstop or probe moves
  711. // with custom feedrates.
  712. //
  713. // - Save current feedrates
  714. // - Reset the rate multiplier
  715. // - Reset the command timeout
  716. // - Enable the endstops (for endstop moves)
  717. //
  718. static void setup_for_endstop_or_probe_move() {
  719. #if ENABLED(DEBUG_LEVELING_FEATURE)
  720. if (DEBUGGING(LEVELING)) DEBUG_POS("setup_for_endstop_or_probe_move", current_position);
  721. #endif
  722. saved_feedrate_mm_s = feedrate_mm_s;
  723. saved_feedrate_percentage = feedrate_percentage;
  724. feedrate_percentage = 100;
  725. gcode.refresh_cmd_timeout();
  726. }
  727. static void clean_up_after_endstop_or_probe_move() {
  728. #if ENABLED(DEBUG_LEVELING_FEATURE)
  729. if (DEBUGGING(LEVELING)) DEBUG_POS("clean_up_after_endstop_or_probe_move", current_position);
  730. #endif
  731. feedrate_mm_s = saved_feedrate_mm_s;
  732. feedrate_percentage = saved_feedrate_percentage;
  733. gcode.refresh_cmd_timeout();
  734. }
  735. #if HAS_BED_PROBE
  736. /**
  737. * Raise Z to a minimum height to make room for a probe to move
  738. */
  739. inline void do_probe_raise(const float z_raise) {
  740. #if ENABLED(DEBUG_LEVELING_FEATURE)
  741. if (DEBUGGING(LEVELING)) {
  742. SERIAL_ECHOPAIR("do_probe_raise(", z_raise);
  743. SERIAL_CHAR(')');
  744. SERIAL_EOL();
  745. }
  746. #endif
  747. float z_dest = z_raise;
  748. if (zprobe_zoffset < 0) z_dest -= zprobe_zoffset;
  749. if (z_dest > current_position[Z_AXIS])
  750. do_blocking_move_to_z(z_dest);
  751. }
  752. #endif // HAS_BED_PROBE
  753. #if HAS_PROBING_PROCEDURE || HOTENDS > 1 || ENABLED(Z_PROBE_ALLEN_KEY) || ENABLED(Z_PROBE_SLED) || ENABLED(NOZZLE_CLEAN_FEATURE) || ENABLED(NOZZLE_PARK_FEATURE) || ENABLED(DELTA_AUTO_CALIBRATION)
  754. bool axis_unhomed_error(const bool x/*=true*/, const bool y/*=true*/, const bool z/*=true*/) {
  755. #if ENABLED(HOME_AFTER_DEACTIVATE)
  756. const bool xx = x && !axis_known_position[X_AXIS],
  757. yy = y && !axis_known_position[Y_AXIS],
  758. zz = z && !axis_known_position[Z_AXIS];
  759. #else
  760. const bool xx = x && !axis_homed[X_AXIS],
  761. yy = y && !axis_homed[Y_AXIS],
  762. zz = z && !axis_homed[Z_AXIS];
  763. #endif
  764. if (xx || yy || zz) {
  765. SERIAL_ECHO_START();
  766. SERIAL_ECHOPGM(MSG_HOME " ");
  767. if (xx) SERIAL_ECHOPGM(MSG_X);
  768. if (yy) SERIAL_ECHOPGM(MSG_Y);
  769. if (zz) SERIAL_ECHOPGM(MSG_Z);
  770. SERIAL_ECHOLNPGM(" " MSG_FIRST);
  771. #if ENABLED(ULTRA_LCD)
  772. lcd_status_printf_P(0, PSTR(MSG_HOME " %s%s%s " MSG_FIRST), xx ? MSG_X : "", yy ? MSG_Y : "", zz ? MSG_Z : "");
  773. #endif
  774. return true;
  775. }
  776. return false;
  777. }
  778. #endif
  779. #if ENABLED(Z_PROBE_SLED)
  780. #ifndef SLED_DOCKING_OFFSET
  781. #define SLED_DOCKING_OFFSET 0
  782. #endif
  783. /**
  784. * Method to dock/undock a sled designed by Charles Bell.
  785. *
  786. * stow[in] If false, move to MAX_X and engage the solenoid
  787. * If true, move to MAX_X and release the solenoid
  788. */
  789. static void dock_sled(bool stow) {
  790. #if ENABLED(DEBUG_LEVELING_FEATURE)
  791. if (DEBUGGING(LEVELING)) {
  792. SERIAL_ECHOPAIR("dock_sled(", stow);
  793. SERIAL_CHAR(')');
  794. SERIAL_EOL();
  795. }
  796. #endif
  797. // Dock sled a bit closer to ensure proper capturing
  798. do_blocking_move_to_x(X_MAX_POS + SLED_DOCKING_OFFSET - ((stow) ? 1 : 0));
  799. #if HAS_SOLENOID_1 && DISABLED(EXT_SOLENOID)
  800. WRITE(SOL1_PIN, !stow); // switch solenoid
  801. #endif
  802. }
  803. #elif ENABLED(Z_PROBE_ALLEN_KEY)
  804. FORCE_INLINE void do_blocking_move_to(const float logical[XYZ], const float &fr_mm_s) {
  805. do_blocking_move_to(logical[X_AXIS], logical[Y_AXIS], logical[Z_AXIS], fr_mm_s);
  806. }
  807. void run_deploy_moves_script() {
  808. #if defined(Z_PROBE_ALLEN_KEY_DEPLOY_1_X) || defined(Z_PROBE_ALLEN_KEY_DEPLOY_1_Y) || defined(Z_PROBE_ALLEN_KEY_DEPLOY_1_Z)
  809. #ifndef Z_PROBE_ALLEN_KEY_DEPLOY_1_X
  810. #define Z_PROBE_ALLEN_KEY_DEPLOY_1_X current_position[X_AXIS]
  811. #endif
  812. #ifndef Z_PROBE_ALLEN_KEY_DEPLOY_1_Y
  813. #define Z_PROBE_ALLEN_KEY_DEPLOY_1_Y current_position[Y_AXIS]
  814. #endif
  815. #ifndef Z_PROBE_ALLEN_KEY_DEPLOY_1_Z
  816. #define Z_PROBE_ALLEN_KEY_DEPLOY_1_Z current_position[Z_AXIS]
  817. #endif
  818. #ifndef Z_PROBE_ALLEN_KEY_DEPLOY_1_FEEDRATE
  819. #define Z_PROBE_ALLEN_KEY_DEPLOY_1_FEEDRATE 0.0
  820. #endif
  821. const float deploy_1[] = { Z_PROBE_ALLEN_KEY_DEPLOY_1_X, Z_PROBE_ALLEN_KEY_DEPLOY_1_Y, Z_PROBE_ALLEN_KEY_DEPLOY_1_Z };
  822. do_blocking_move_to(deploy_1, MMM_TO_MMS(Z_PROBE_ALLEN_KEY_DEPLOY_1_FEEDRATE));
  823. #endif
  824. #if defined(Z_PROBE_ALLEN_KEY_DEPLOY_2_X) || defined(Z_PROBE_ALLEN_KEY_DEPLOY_2_Y) || defined(Z_PROBE_ALLEN_KEY_DEPLOY_2_Z)
  825. #ifndef Z_PROBE_ALLEN_KEY_DEPLOY_2_X
  826. #define Z_PROBE_ALLEN_KEY_DEPLOY_2_X current_position[X_AXIS]
  827. #endif
  828. #ifndef Z_PROBE_ALLEN_KEY_DEPLOY_2_Y
  829. #define Z_PROBE_ALLEN_KEY_DEPLOY_2_Y current_position[Y_AXIS]
  830. #endif
  831. #ifndef Z_PROBE_ALLEN_KEY_DEPLOY_2_Z
  832. #define Z_PROBE_ALLEN_KEY_DEPLOY_2_Z current_position[Z_AXIS]
  833. #endif
  834. #ifndef Z_PROBE_ALLEN_KEY_DEPLOY_2_FEEDRATE
  835. #define Z_PROBE_ALLEN_KEY_DEPLOY_2_FEEDRATE 0.0
  836. #endif
  837. const float deploy_2[] = { Z_PROBE_ALLEN_KEY_DEPLOY_2_X, Z_PROBE_ALLEN_KEY_DEPLOY_2_Y, Z_PROBE_ALLEN_KEY_DEPLOY_2_Z };
  838. do_blocking_move_to(deploy_2, MMM_TO_MMS(Z_PROBE_ALLEN_KEY_DEPLOY_2_FEEDRATE));
  839. #endif
  840. #if defined(Z_PROBE_ALLEN_KEY_DEPLOY_3_X) || defined(Z_PROBE_ALLEN_KEY_DEPLOY_3_Y) || defined(Z_PROBE_ALLEN_KEY_DEPLOY_3_Z)
  841. #ifndef Z_PROBE_ALLEN_KEY_DEPLOY_3_X
  842. #define Z_PROBE_ALLEN_KEY_DEPLOY_3_X current_position[X_AXIS]
  843. #endif
  844. #ifndef Z_PROBE_ALLEN_KEY_DEPLOY_3_Y
  845. #define Z_PROBE_ALLEN_KEY_DEPLOY_3_Y current_position[Y_AXIS]
  846. #endif
  847. #ifndef Z_PROBE_ALLEN_KEY_DEPLOY_3_Z
  848. #define Z_PROBE_ALLEN_KEY_DEPLOY_3_Z current_position[Z_AXIS]
  849. #endif
  850. #ifndef Z_PROBE_ALLEN_KEY_DEPLOY_3_FEEDRATE
  851. #define Z_PROBE_ALLEN_KEY_DEPLOY_3_FEEDRATE 0.0
  852. #endif
  853. const float deploy_3[] = { Z_PROBE_ALLEN_KEY_DEPLOY_3_X, Z_PROBE_ALLEN_KEY_DEPLOY_3_Y, Z_PROBE_ALLEN_KEY_DEPLOY_3_Z };
  854. do_blocking_move_to(deploy_3, MMM_TO_MMS(Z_PROBE_ALLEN_KEY_DEPLOY_3_FEEDRATE));
  855. #endif
  856. #if defined(Z_PROBE_ALLEN_KEY_DEPLOY_4_X) || defined(Z_PROBE_ALLEN_KEY_DEPLOY_4_Y) || defined(Z_PROBE_ALLEN_KEY_DEPLOY_4_Z)
  857. #ifndef Z_PROBE_ALLEN_KEY_DEPLOY_4_X
  858. #define Z_PROBE_ALLEN_KEY_DEPLOY_4_X current_position[X_AXIS]
  859. #endif
  860. #ifndef Z_PROBE_ALLEN_KEY_DEPLOY_4_Y
  861. #define Z_PROBE_ALLEN_KEY_DEPLOY_4_Y current_position[Y_AXIS]
  862. #endif
  863. #ifndef Z_PROBE_ALLEN_KEY_DEPLOY_4_Z
  864. #define Z_PROBE_ALLEN_KEY_DEPLOY_4_Z current_position[Z_AXIS]
  865. #endif
  866. #ifndef Z_PROBE_ALLEN_KEY_DEPLOY_4_FEEDRATE
  867. #define Z_PROBE_ALLEN_KEY_DEPLOY_4_FEEDRATE 0.0
  868. #endif
  869. const float deploy_4[] = { Z_PROBE_ALLEN_KEY_DEPLOY_4_X, Z_PROBE_ALLEN_KEY_DEPLOY_4_Y, Z_PROBE_ALLEN_KEY_DEPLOY_4_Z };
  870. do_blocking_move_to(deploy_4, MMM_TO_MMS(Z_PROBE_ALLEN_KEY_DEPLOY_4_FEEDRATE));
  871. #endif
  872. #if defined(Z_PROBE_ALLEN_KEY_DEPLOY_5_X) || defined(Z_PROBE_ALLEN_KEY_DEPLOY_5_Y) || defined(Z_PROBE_ALLEN_KEY_DEPLOY_5_Z)
  873. #ifndef Z_PROBE_ALLEN_KEY_DEPLOY_5_X
  874. #define Z_PROBE_ALLEN_KEY_DEPLOY_5_X current_position[X_AXIS]
  875. #endif
  876. #ifndef Z_PROBE_ALLEN_KEY_DEPLOY_5_Y
  877. #define Z_PROBE_ALLEN_KEY_DEPLOY_5_Y current_position[Y_AXIS]
  878. #endif
  879. #ifndef Z_PROBE_ALLEN_KEY_DEPLOY_5_Z
  880. #define Z_PROBE_ALLEN_KEY_DEPLOY_5_Z current_position[Z_AXIS]
  881. #endif
  882. #ifndef Z_PROBE_ALLEN_KEY_DEPLOY_5_FEEDRATE
  883. #define Z_PROBE_ALLEN_KEY_DEPLOY_5_FEEDRATE 0.0
  884. #endif
  885. const float deploy_5[] = { Z_PROBE_ALLEN_KEY_DEPLOY_5_X, Z_PROBE_ALLEN_KEY_DEPLOY_5_Y, Z_PROBE_ALLEN_KEY_DEPLOY_5_Z };
  886. do_blocking_move_to(deploy_5, MMM_TO_MMS(Z_PROBE_ALLEN_KEY_DEPLOY_5_FEEDRATE));
  887. #endif
  888. }
  889. void run_stow_moves_script() {
  890. #if defined(Z_PROBE_ALLEN_KEY_STOW_1_X) || defined(Z_PROBE_ALLEN_KEY_STOW_1_Y) || defined(Z_PROBE_ALLEN_KEY_STOW_1_Z)
  891. #ifndef Z_PROBE_ALLEN_KEY_STOW_1_X
  892. #define Z_PROBE_ALLEN_KEY_STOW_1_X current_position[X_AXIS]
  893. #endif
  894. #ifndef Z_PROBE_ALLEN_KEY_STOW_1_Y
  895. #define Z_PROBE_ALLEN_KEY_STOW_1_Y current_position[Y_AXIS]
  896. #endif
  897. #ifndef Z_PROBE_ALLEN_KEY_STOW_1_Z
  898. #define Z_PROBE_ALLEN_KEY_STOW_1_Z current_position[Z_AXIS]
  899. #endif
  900. #ifndef Z_PROBE_ALLEN_KEY_STOW_1_FEEDRATE
  901. #define Z_PROBE_ALLEN_KEY_STOW_1_FEEDRATE 0.0
  902. #endif
  903. const float stow_1[] = { Z_PROBE_ALLEN_KEY_STOW_1_X, Z_PROBE_ALLEN_KEY_STOW_1_Y, Z_PROBE_ALLEN_KEY_STOW_1_Z };
  904. do_blocking_move_to(stow_1, MMM_TO_MMS(Z_PROBE_ALLEN_KEY_STOW_1_FEEDRATE));
  905. #endif
  906. #if defined(Z_PROBE_ALLEN_KEY_STOW_2_X) || defined(Z_PROBE_ALLEN_KEY_STOW_2_Y) || defined(Z_PROBE_ALLEN_KEY_STOW_2_Z)
  907. #ifndef Z_PROBE_ALLEN_KEY_STOW_2_X
  908. #define Z_PROBE_ALLEN_KEY_STOW_2_X current_position[X_AXIS]
  909. #endif
  910. #ifndef Z_PROBE_ALLEN_KEY_STOW_2_Y
  911. #define Z_PROBE_ALLEN_KEY_STOW_2_Y current_position[Y_AXIS]
  912. #endif
  913. #ifndef Z_PROBE_ALLEN_KEY_STOW_2_Z
  914. #define Z_PROBE_ALLEN_KEY_STOW_2_Z current_position[Z_AXIS]
  915. #endif
  916. #ifndef Z_PROBE_ALLEN_KEY_STOW_2_FEEDRATE
  917. #define Z_PROBE_ALLEN_KEY_STOW_2_FEEDRATE 0.0
  918. #endif
  919. const float stow_2[] = { Z_PROBE_ALLEN_KEY_STOW_2_X, Z_PROBE_ALLEN_KEY_STOW_2_Y, Z_PROBE_ALLEN_KEY_STOW_2_Z };
  920. do_blocking_move_to(stow_2, MMM_TO_MMS(Z_PROBE_ALLEN_KEY_STOW_2_FEEDRATE));
  921. #endif
  922. #if defined(Z_PROBE_ALLEN_KEY_STOW_3_X) || defined(Z_PROBE_ALLEN_KEY_STOW_3_Y) || defined(Z_PROBE_ALLEN_KEY_STOW_3_Z)
  923. #ifndef Z_PROBE_ALLEN_KEY_STOW_3_X
  924. #define Z_PROBE_ALLEN_KEY_STOW_3_X current_position[X_AXIS]
  925. #endif
  926. #ifndef Z_PROBE_ALLEN_KEY_STOW_3_Y
  927. #define Z_PROBE_ALLEN_KEY_STOW_3_Y current_position[Y_AXIS]
  928. #endif
  929. #ifndef Z_PROBE_ALLEN_KEY_STOW_3_Z
  930. #define Z_PROBE_ALLEN_KEY_STOW_3_Z current_position[Z_AXIS]
  931. #endif
  932. #ifndef Z_PROBE_ALLEN_KEY_STOW_3_FEEDRATE
  933. #define Z_PROBE_ALLEN_KEY_STOW_3_FEEDRATE 0.0
  934. #endif
  935. const float stow_3[] = { Z_PROBE_ALLEN_KEY_STOW_3_X, Z_PROBE_ALLEN_KEY_STOW_3_Y, Z_PROBE_ALLEN_KEY_STOW_3_Z };
  936. do_blocking_move_to(stow_3, MMM_TO_MMS(Z_PROBE_ALLEN_KEY_STOW_3_FEEDRATE));
  937. #endif
  938. #if defined(Z_PROBE_ALLEN_KEY_STOW_4_X) || defined(Z_PROBE_ALLEN_KEY_STOW_4_Y) || defined(Z_PROBE_ALLEN_KEY_STOW_4_Z)
  939. #ifndef Z_PROBE_ALLEN_KEY_STOW_4_X
  940. #define Z_PROBE_ALLEN_KEY_STOW_4_X current_position[X_AXIS]
  941. #endif
  942. #ifndef Z_PROBE_ALLEN_KEY_STOW_4_Y
  943. #define Z_PROBE_ALLEN_KEY_STOW_4_Y current_position[Y_AXIS]
  944. #endif
  945. #ifndef Z_PROBE_ALLEN_KEY_STOW_4_Z
  946. #define Z_PROBE_ALLEN_KEY_STOW_4_Z current_position[Z_AXIS]
  947. #endif
  948. #ifndef Z_PROBE_ALLEN_KEY_STOW_4_FEEDRATE
  949. #define Z_PROBE_ALLEN_KEY_STOW_4_FEEDRATE 0.0
  950. #endif
  951. const float stow_4[] = { Z_PROBE_ALLEN_KEY_STOW_4_X, Z_PROBE_ALLEN_KEY_STOW_4_Y, Z_PROBE_ALLEN_KEY_STOW_4_Z };
  952. do_blocking_move_to(stow_4, MMM_TO_MMS(Z_PROBE_ALLEN_KEY_STOW_4_FEEDRATE));
  953. #endif
  954. #if defined(Z_PROBE_ALLEN_KEY_STOW_5_X) || defined(Z_PROBE_ALLEN_KEY_STOW_5_Y) || defined(Z_PROBE_ALLEN_KEY_STOW_5_Z)
  955. #ifndef Z_PROBE_ALLEN_KEY_STOW_5_X
  956. #define Z_PROBE_ALLEN_KEY_STOW_5_X current_position[X_AXIS]
  957. #endif
  958. #ifndef Z_PROBE_ALLEN_KEY_STOW_5_Y
  959. #define Z_PROBE_ALLEN_KEY_STOW_5_Y current_position[Y_AXIS]
  960. #endif
  961. #ifndef Z_PROBE_ALLEN_KEY_STOW_5_Z
  962. #define Z_PROBE_ALLEN_KEY_STOW_5_Z current_position[Z_AXIS]
  963. #endif
  964. #ifndef Z_PROBE_ALLEN_KEY_STOW_5_FEEDRATE
  965. #define Z_PROBE_ALLEN_KEY_STOW_5_FEEDRATE 0.0
  966. #endif
  967. const float stow_5[] = { Z_PROBE_ALLEN_KEY_STOW_5_X, Z_PROBE_ALLEN_KEY_STOW_5_Y, Z_PROBE_ALLEN_KEY_STOW_5_Z };
  968. do_blocking_move_to(stow_5, MMM_TO_MMS(Z_PROBE_ALLEN_KEY_STOW_5_FEEDRATE));
  969. #endif
  970. }
  971. #endif
  972. #if ENABLED(PROBING_FANS_OFF)
  973. void fans_pause(const bool p) {
  974. if (p != fans_paused) {
  975. fans_paused = p;
  976. if (p)
  977. for (uint8_t x = 0; x < FAN_COUNT; x++) {
  978. paused_fanSpeeds[x] = fanSpeeds[x];
  979. fanSpeeds[x] = 0;
  980. }
  981. else
  982. for (uint8_t x = 0; x < FAN_COUNT; x++)
  983. fanSpeeds[x] = paused_fanSpeeds[x];
  984. }
  985. }
  986. #endif // PROBING_FANS_OFF
  987. #if HAS_BED_PROBE
  988. // TRIGGERED_WHEN_STOWED_TEST can easily be extended to servo probes, ... if needed.
  989. #if ENABLED(PROBE_IS_TRIGGERED_WHEN_STOWED_TEST)
  990. #if ENABLED(Z_MIN_PROBE_ENDSTOP)
  991. #define _TRIGGERED_WHEN_STOWED_TEST (READ(Z_MIN_PROBE_PIN) != Z_MIN_PROBE_ENDSTOP_INVERTING)
  992. #else
  993. #define _TRIGGERED_WHEN_STOWED_TEST (READ(Z_MIN_PIN) != Z_MIN_ENDSTOP_INVERTING)
  994. #endif
  995. #endif
  996. #if QUIET_PROBING
  997. void probing_pause(const bool p) {
  998. #if ENABLED(PROBING_HEATERS_OFF)
  999. thermalManager.pause(p);
  1000. #endif
  1001. #if ENABLED(PROBING_FANS_OFF)
  1002. fans_pause(p);
  1003. #endif
  1004. if (p) safe_delay(
  1005. #if DELAY_BEFORE_PROBING > 25
  1006. DELAY_BEFORE_PROBING
  1007. #else
  1008. 25
  1009. #endif
  1010. );
  1011. }
  1012. #endif // QUIET_PROBING
  1013. #if ENABLED(BLTOUCH)
  1014. void bltouch_command(int angle) {
  1015. MOVE_SERVO(Z_ENDSTOP_SERVO_NR, angle); // Give the BL-Touch the command and wait
  1016. safe_delay(BLTOUCH_DELAY);
  1017. }
  1018. bool set_bltouch_deployed(const bool deploy) {
  1019. if (deploy && TEST_BLTOUCH()) { // If BL-Touch says it's triggered
  1020. bltouch_command(BLTOUCH_RESET); // try to reset it.
  1021. bltouch_command(BLTOUCH_DEPLOY); // Also needs to deploy and stow to
  1022. bltouch_command(BLTOUCH_STOW); // clear the triggered condition.
  1023. safe_delay(1500); // Wait for internal self-test to complete.
  1024. // (Measured completion time was 0.65 seconds
  1025. // after reset, deploy, and stow sequence)
  1026. if (TEST_BLTOUCH()) { // If it still claims to be triggered...
  1027. SERIAL_ERROR_START();
  1028. SERIAL_ERRORLNPGM(MSG_STOP_BLTOUCH);
  1029. stop(); // punt!
  1030. return true;
  1031. }
  1032. }
  1033. bltouch_command(deploy ? BLTOUCH_DEPLOY : BLTOUCH_STOW);
  1034. #if ENABLED(DEBUG_LEVELING_FEATURE)
  1035. if (DEBUGGING(LEVELING)) {
  1036. SERIAL_ECHOPAIR("set_bltouch_deployed(", deploy);
  1037. SERIAL_CHAR(')');
  1038. SERIAL_EOL();
  1039. }
  1040. #endif
  1041. return false;
  1042. }
  1043. #endif // BLTOUCH
  1044. // returns false for ok and true for failure
  1045. bool set_probe_deployed(bool deploy) {
  1046. #if ENABLED(DEBUG_LEVELING_FEATURE)
  1047. if (DEBUGGING(LEVELING)) {
  1048. DEBUG_POS("set_probe_deployed", current_position);
  1049. SERIAL_ECHOLNPAIR("deploy: ", deploy);
  1050. }
  1051. #endif
  1052. if (endstops.z_probe_enabled == deploy) return false;
  1053. // Make room for probe
  1054. do_probe_raise(_Z_CLEARANCE_DEPLOY_PROBE);
  1055. #if ENABLED(Z_PROBE_SLED) || ENABLED(Z_PROBE_ALLEN_KEY)
  1056. #if ENABLED(Z_PROBE_SLED)
  1057. #define _AUE_ARGS true, false, false
  1058. #else
  1059. #define _AUE_ARGS
  1060. #endif
  1061. if (axis_unhomed_error(_AUE_ARGS)) {
  1062. SERIAL_ERROR_START();
  1063. SERIAL_ERRORLNPGM(MSG_STOP_UNHOMED);
  1064. stop();
  1065. return true;
  1066. }
  1067. #endif
  1068. const float oldXpos = current_position[X_AXIS],
  1069. oldYpos = current_position[Y_AXIS];
  1070. #ifdef _TRIGGERED_WHEN_STOWED_TEST
  1071. // If endstop is already false, the Z probe is deployed
  1072. if (_TRIGGERED_WHEN_STOWED_TEST == deploy) { // closed after the probe specific actions.
  1073. // Would a goto be less ugly?
  1074. //while (!_TRIGGERED_WHEN_STOWED_TEST) idle(); // would offer the opportunity
  1075. // for a triggered when stowed manual probe.
  1076. if (!deploy) endstops.enable_z_probe(false); // Switch off triggered when stowed probes early
  1077. // otherwise an Allen-Key probe can't be stowed.
  1078. #endif
  1079. #if ENABLED(SOLENOID_PROBE)
  1080. #if HAS_SOLENOID_1
  1081. WRITE(SOL1_PIN, deploy);
  1082. #endif
  1083. #elif ENABLED(Z_PROBE_SLED)
  1084. dock_sled(!deploy);
  1085. #elif HAS_Z_SERVO_ENDSTOP && DISABLED(BLTOUCH)
  1086. MOVE_SERVO(Z_ENDSTOP_SERVO_NR, z_servo_angle[deploy ? 0 : 1]);
  1087. #elif ENABLED(Z_PROBE_ALLEN_KEY)
  1088. deploy ? run_deploy_moves_script() : run_stow_moves_script();
  1089. #endif
  1090. #ifdef _TRIGGERED_WHEN_STOWED_TEST
  1091. } // _TRIGGERED_WHEN_STOWED_TEST == deploy
  1092. if (_TRIGGERED_WHEN_STOWED_TEST == deploy) { // State hasn't changed?
  1093. if (IsRunning()) {
  1094. SERIAL_ERROR_START();
  1095. SERIAL_ERRORLNPGM("Z-Probe failed");
  1096. LCD_ALERTMESSAGEPGM("Err: ZPROBE");
  1097. }
  1098. stop();
  1099. return true;
  1100. } // _TRIGGERED_WHEN_STOWED_TEST == deploy
  1101. #endif
  1102. do_blocking_move_to(oldXpos, oldYpos, current_position[Z_AXIS]); // return to position before deploy
  1103. endstops.enable_z_probe(deploy);
  1104. return false;
  1105. }
  1106. /**
  1107. * @brief Used by run_z_probe to do a single Z probe move.
  1108. *
  1109. * @param z Z destination
  1110. * @param fr_mm_s Feedrate in mm/s
  1111. * @return true to indicate an error
  1112. */
  1113. static bool do_probe_move(const float z, const float fr_mm_m) {
  1114. #if ENABLED(DEBUG_LEVELING_FEATURE)
  1115. if (DEBUGGING(LEVELING)) DEBUG_POS(">>> do_probe_move", current_position);
  1116. #endif
  1117. // Deploy BLTouch at the start of any probe
  1118. #if ENABLED(BLTOUCH)
  1119. if (set_bltouch_deployed(true)) return true;
  1120. #endif
  1121. #if QUIET_PROBING
  1122. probing_pause(true);
  1123. #endif
  1124. // Move down until probe triggered
  1125. do_blocking_move_to_z(z, MMM_TO_MMS(fr_mm_m));
  1126. // Check to see if the probe was triggered
  1127. const bool probe_triggered = TEST(Endstops::endstop_hit_bits,
  1128. #if ENABLED(Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN)
  1129. Z_MIN
  1130. #else
  1131. Z_MIN_PROBE
  1132. #endif
  1133. );
  1134. #if QUIET_PROBING
  1135. probing_pause(false);
  1136. #endif
  1137. // Retract BLTouch immediately after a probe if it was triggered
  1138. #if ENABLED(BLTOUCH)
  1139. if (probe_triggered && set_bltouch_deployed(false)) return true;
  1140. #endif
  1141. // Clear endstop flags
  1142. endstops.hit_on_purpose();
  1143. // Get Z where the steppers were interrupted
  1144. set_current_from_steppers_for_axis(Z_AXIS);
  1145. // Tell the planner where we actually are
  1146. SYNC_PLAN_POSITION_KINEMATIC();
  1147. #if ENABLED(DEBUG_LEVELING_FEATURE)
  1148. if (DEBUGGING(LEVELING)) DEBUG_POS("<<< do_probe_move", current_position);
  1149. #endif
  1150. return !probe_triggered;
  1151. }
  1152. /**
  1153. * @details Used by probe_pt to do a single Z probe.
  1154. * Leaves current_position[Z_AXIS] at the height where the probe triggered.
  1155. *
  1156. * @param short_move Flag for a shorter probe move towards the bed
  1157. * @return The raw Z position where the probe was triggered
  1158. */
  1159. static float run_z_probe(const bool short_move=true) {
  1160. #if ENABLED(DEBUG_LEVELING_FEATURE)
  1161. if (DEBUGGING(LEVELING)) DEBUG_POS(">>> run_z_probe", current_position);
  1162. #endif
  1163. // Prevent stepper_inactive_time from running out and EXTRUDER_RUNOUT_PREVENT from extruding
  1164. gcode.refresh_cmd_timeout();
  1165. #if ENABLED(PROBE_DOUBLE_TOUCH)
  1166. // Do a first probe at the fast speed
  1167. if (do_probe_move(-10, Z_PROBE_SPEED_FAST)) return NAN;
  1168. #if ENABLED(DEBUG_LEVELING_FEATURE)
  1169. float first_probe_z = current_position[Z_AXIS];
  1170. if (DEBUGGING(LEVELING)) SERIAL_ECHOLNPAIR("1st Probe Z:", first_probe_z);
  1171. #endif
  1172. // move up to make clearance for the probe
  1173. do_blocking_move_to_z(current_position[Z_AXIS] + Z_CLEARANCE_BETWEEN_PROBES, MMM_TO_MMS(Z_PROBE_SPEED_FAST));
  1174. #else
  1175. // If the nozzle is above the travel height then
  1176. // move down quickly before doing the slow probe
  1177. float z = Z_CLEARANCE_DEPLOY_PROBE;
  1178. if (zprobe_zoffset < 0) z -= zprobe_zoffset;
  1179. if (z < current_position[Z_AXIS]) {
  1180. // If we don't make it to the z position (i.e. the probe triggered), move up to make clearance for the probe
  1181. if (!do_probe_move(z, Z_PROBE_SPEED_FAST))
  1182. do_blocking_move_to_z(current_position[Z_AXIS] + Z_CLEARANCE_BETWEEN_PROBES, MMM_TO_MMS(Z_PROBE_SPEED_FAST));
  1183. }
  1184. #endif
  1185. // move down slowly to find bed
  1186. if (do_probe_move(-10 + (short_move ? 0 : -(Z_MAX_LENGTH)), Z_PROBE_SPEED_SLOW)) return NAN;
  1187. #if ENABLED(DEBUG_LEVELING_FEATURE)
  1188. if (DEBUGGING(LEVELING)) DEBUG_POS("<<< run_z_probe", current_position);
  1189. #endif
  1190. // Debug: compare probe heights
  1191. #if ENABLED(PROBE_DOUBLE_TOUCH) && ENABLED(DEBUG_LEVELING_FEATURE)
  1192. if (DEBUGGING(LEVELING)) {
  1193. SERIAL_ECHOPAIR("2nd Probe Z:", current_position[Z_AXIS]);
  1194. SERIAL_ECHOLNPAIR(" Discrepancy:", first_probe_z - current_position[Z_AXIS]);
  1195. }
  1196. #endif
  1197. return RAW_CURRENT_POSITION(Z) + zprobe_zoffset
  1198. #if ENABLED(DELTA)
  1199. + home_offset[Z_AXIS] // Account for delta height adjustment
  1200. #endif
  1201. ;
  1202. }
  1203. /**
  1204. * - Move to the given XY
  1205. * - Deploy the probe, if not already deployed
  1206. * - Probe the bed, get the Z position
  1207. * - Depending on the 'stow' flag
  1208. * - Stow the probe, or
  1209. * - Raise to the BETWEEN height
  1210. * - Return the probed Z position
  1211. */
  1212. float probe_pt(const float &lx, const float &ly, const bool stow, const uint8_t verbose_level, const bool printable=true) {
  1213. #if ENABLED(DEBUG_LEVELING_FEATURE)
  1214. if (DEBUGGING(LEVELING)) {
  1215. SERIAL_ECHOPAIR(">>> probe_pt(", lx);
  1216. SERIAL_ECHOPAIR(", ", ly);
  1217. SERIAL_ECHOPAIR(", ", stow ? "" : "no ");
  1218. SERIAL_ECHOLNPGM("stow)");
  1219. DEBUG_POS("", current_position);
  1220. }
  1221. #endif
  1222. const float nx = lx - (X_PROBE_OFFSET_FROM_EXTRUDER), ny = ly - (Y_PROBE_OFFSET_FROM_EXTRUDER);
  1223. if (printable
  1224. ? !position_is_reachable_xy(nx, ny)
  1225. : !position_is_reachable_by_probe_xy(lx, ly)
  1226. ) return NAN;
  1227. const float old_feedrate_mm_s = feedrate_mm_s;
  1228. #if ENABLED(DELTA)
  1229. if (current_position[Z_AXIS] > delta_clip_start_height)
  1230. do_blocking_move_to_z(delta_clip_start_height);
  1231. #endif
  1232. #if HAS_SOFTWARE_ENDSTOPS
  1233. // Store the status of the soft endstops and disable if we're probing a non-printable location
  1234. static bool enable_soft_endstops = soft_endstops_enabled;
  1235. if (!printable) soft_endstops_enabled = false;
  1236. #endif
  1237. feedrate_mm_s = XY_PROBE_FEEDRATE_MM_S;
  1238. // Move the probe to the given XY
  1239. do_blocking_move_to_xy(nx, ny);
  1240. float measured_z = NAN;
  1241. if (!DEPLOY_PROBE()) {
  1242. measured_z = run_z_probe(printable);
  1243. if (!stow)
  1244. do_blocking_move_to_z(current_position[Z_AXIS] + Z_CLEARANCE_BETWEEN_PROBES, MMM_TO_MMS(Z_PROBE_SPEED_FAST));
  1245. else
  1246. if (STOW_PROBE()) measured_z = NAN;
  1247. }
  1248. #if HAS_SOFTWARE_ENDSTOPS
  1249. // Restore the soft endstop status
  1250. soft_endstops_enabled = enable_soft_endstops;
  1251. #endif
  1252. if (verbose_level > 2) {
  1253. SERIAL_PROTOCOLPGM("Bed X: ");
  1254. SERIAL_PROTOCOL_F(lx, 3);
  1255. SERIAL_PROTOCOLPGM(" Y: ");
  1256. SERIAL_PROTOCOL_F(ly, 3);
  1257. SERIAL_PROTOCOLPGM(" Z: ");
  1258. SERIAL_PROTOCOL_F(measured_z, 3);
  1259. SERIAL_EOL();
  1260. }
  1261. #if ENABLED(DEBUG_LEVELING_FEATURE)
  1262. if (DEBUGGING(LEVELING)) SERIAL_ECHOLNPGM("<<< probe_pt");
  1263. #endif
  1264. feedrate_mm_s = old_feedrate_mm_s;
  1265. if (isnan(measured_z)) {
  1266. LCD_MESSAGEPGM(MSG_ERR_PROBING_FAILED);
  1267. SERIAL_ERROR_START();
  1268. SERIAL_ERRORLNPGM(MSG_ERR_PROBING_FAILED);
  1269. }
  1270. return measured_z;
  1271. }
  1272. #endif // HAS_BED_PROBE
  1273. #if HAS_LEVELING
  1274. bool leveling_is_valid() {
  1275. return
  1276. #if ENABLED(MESH_BED_LEVELING)
  1277. mbl.has_mesh()
  1278. #elif ENABLED(AUTO_BED_LEVELING_BILINEAR)
  1279. !!bilinear_grid_spacing[X_AXIS]
  1280. #elif ENABLED(AUTO_BED_LEVELING_UBL)
  1281. true
  1282. #else // 3POINT, LINEAR
  1283. true
  1284. #endif
  1285. ;
  1286. }
  1287. bool leveling_is_active() {
  1288. return
  1289. #if ENABLED(MESH_BED_LEVELING)
  1290. mbl.active()
  1291. #elif ENABLED(AUTO_BED_LEVELING_UBL)
  1292. ubl.state.active
  1293. #else
  1294. planner.abl_enabled
  1295. #endif
  1296. ;
  1297. }
  1298. /**
  1299. * Turn bed leveling on or off, fixing the current
  1300. * position as-needed.
  1301. *
  1302. * Disable: Current position = physical position
  1303. * Enable: Current position = "unleveled" physical position
  1304. */
  1305. void set_bed_leveling_enabled(const bool enable/*=true*/) {
  1306. #if ENABLED(AUTO_BED_LEVELING_BILINEAR)
  1307. const bool can_change = (!enable || leveling_is_valid());
  1308. #else
  1309. constexpr bool can_change = true;
  1310. #endif
  1311. if (can_change && enable != leveling_is_active()) {
  1312. #if ENABLED(MESH_BED_LEVELING)
  1313. if (!enable)
  1314. planner.apply_leveling(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS]);
  1315. const bool enabling = enable && leveling_is_valid();
  1316. mbl.set_active(enabling);
  1317. if (enabling) planner.unapply_leveling(current_position);
  1318. #elif ENABLED(AUTO_BED_LEVELING_UBL)
  1319. #if PLANNER_LEVELING
  1320. if (ubl.state.active) { // leveling from on to off
  1321. // change unleveled current_position to physical current_position without moving steppers.
  1322. planner.apply_leveling(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS]);
  1323. ubl.state.active = false; // disable only AFTER calling apply_leveling
  1324. }
  1325. else { // leveling from off to on
  1326. ubl.state.active = true; // enable BEFORE calling unapply_leveling, otherwise ignored
  1327. // change physical current_position to unleveled current_position without moving steppers.
  1328. planner.unapply_leveling(current_position);
  1329. }
  1330. #else
  1331. ubl.state.active = enable; // just flip the bit, current_position will be wrong until next move.
  1332. #endif
  1333. #else // ABL
  1334. #if ENABLED(AUTO_BED_LEVELING_BILINEAR)
  1335. // Force bilinear_z_offset to re-calculate next time
  1336. const float reset[XYZ] = { -9999.999, -9999.999, 0 };
  1337. (void)bilinear_z_offset(reset);
  1338. #endif
  1339. // Enable or disable leveling compensation in the planner
  1340. planner.abl_enabled = enable;
  1341. if (!enable)
  1342. // When disabling just get the current position from the steppers.
  1343. // This will yield the smallest error when first converted back to steps.
  1344. set_current_from_steppers_for_axis(
  1345. #if ABL_PLANAR
  1346. ALL_AXES
  1347. #else
  1348. Z_AXIS
  1349. #endif
  1350. );
  1351. else
  1352. // When enabling, remove compensation from the current position,
  1353. // so compensation will give the right stepper counts.
  1354. planner.unapply_leveling(current_position);
  1355. #endif // ABL
  1356. }
  1357. }
  1358. #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT)
  1359. void set_z_fade_height(const float zfh) {
  1360. const bool level_active = leveling_is_active();
  1361. #if ENABLED(AUTO_BED_LEVELING_UBL)
  1362. if (level_active)
  1363. set_bed_leveling_enabled(false); // turn off before changing fade height for proper apply/unapply leveling to maintain current_position
  1364. planner.z_fade_height = zfh;
  1365. planner.inverse_z_fade_height = RECIPROCAL(zfh);
  1366. if (level_active)
  1367. set_bed_leveling_enabled(true); // turn back on after changing fade height
  1368. #else
  1369. planner.z_fade_height = zfh;
  1370. planner.inverse_z_fade_height = RECIPROCAL(zfh);
  1371. if (level_active) {
  1372. set_current_from_steppers_for_axis(
  1373. #if ABL_PLANAR
  1374. ALL_AXES
  1375. #else
  1376. Z_AXIS
  1377. #endif
  1378. );
  1379. }
  1380. #endif
  1381. }
  1382. #endif // LEVELING_FADE_HEIGHT
  1383. /**
  1384. * Reset calibration results to zero.
  1385. */
  1386. void reset_bed_level() {
  1387. set_bed_leveling_enabled(false);
  1388. #if ENABLED(MESH_BED_LEVELING)
  1389. if (leveling_is_valid()) {
  1390. mbl.reset();
  1391. mbl.set_has_mesh(false);
  1392. }
  1393. #else
  1394. #if ENABLED(DEBUG_LEVELING_FEATURE)
  1395. if (DEBUGGING(LEVELING)) SERIAL_ECHOLNPGM("reset_bed_level");
  1396. #endif
  1397. #if ABL_PLANAR
  1398. planner.bed_level_matrix.set_to_identity();
  1399. #elif ENABLED(AUTO_BED_LEVELING_BILINEAR)
  1400. bilinear_start[X_AXIS] = bilinear_start[Y_AXIS] =
  1401. bilinear_grid_spacing[X_AXIS] = bilinear_grid_spacing[Y_AXIS] = 0;
  1402. for (uint8_t x = 0; x < GRID_MAX_POINTS_X; x++)
  1403. for (uint8_t y = 0; y < GRID_MAX_POINTS_Y; y++)
  1404. z_values[x][y] = NAN;
  1405. #elif ENABLED(AUTO_BED_LEVELING_UBL)
  1406. ubl.reset();
  1407. #endif
  1408. #endif
  1409. }
  1410. #endif // HAS_LEVELING
  1411. #if ENABLED(AUTO_BED_LEVELING_BILINEAR) || ENABLED(MESH_BED_LEVELING)
  1412. /**
  1413. * Enable to produce output in JSON format suitable
  1414. * for SCAD or JavaScript mesh visualizers.
  1415. *
  1416. * Visualize meshes in OpenSCAD using the included script.
  1417. *
  1418. * buildroot/shared/scripts/MarlinMesh.scad
  1419. */
  1420. //#define SCAD_MESH_OUTPUT
  1421. /**
  1422. * Print calibration results for plotting or manual frame adjustment.
  1423. */
  1424. static void print_2d_array(const uint8_t sx, const uint8_t sy, const uint8_t precision, float (*fn)(const uint8_t, const uint8_t)) {
  1425. #ifndef SCAD_MESH_OUTPUT
  1426. for (uint8_t x = 0; x < sx; x++) {
  1427. for (uint8_t i = 0; i < precision + 2 + (x < 10 ? 1 : 0); i++)
  1428. SERIAL_PROTOCOLCHAR(' ');
  1429. SERIAL_PROTOCOL((int)x);
  1430. }
  1431. SERIAL_EOL();
  1432. #endif
  1433. #ifdef SCAD_MESH_OUTPUT
  1434. SERIAL_PROTOCOLLNPGM("measured_z = ["); // open 2D array
  1435. #endif
  1436. for (uint8_t y = 0; y < sy; y++) {
  1437. #ifdef SCAD_MESH_OUTPUT
  1438. SERIAL_PROTOCOLPGM(" ["); // open sub-array
  1439. #else
  1440. if (y < 10) SERIAL_PROTOCOLCHAR(' ');
  1441. SERIAL_PROTOCOL((int)y);
  1442. #endif
  1443. for (uint8_t x = 0; x < sx; x++) {
  1444. SERIAL_PROTOCOLCHAR(' ');
  1445. const float offset = fn(x, y);
  1446. if (!isnan(offset)) {
  1447. if (offset >= 0) SERIAL_PROTOCOLCHAR('+');
  1448. SERIAL_PROTOCOL_F(offset, precision);
  1449. }
  1450. else {
  1451. #ifdef SCAD_MESH_OUTPUT
  1452. for (uint8_t i = 3; i < precision + 3; i++)
  1453. SERIAL_PROTOCOLCHAR(' ');
  1454. SERIAL_PROTOCOLPGM("NAN");
  1455. #else
  1456. for (uint8_t i = 0; i < precision + 3; i++)
  1457. SERIAL_PROTOCOLCHAR(i ? '=' : ' ');
  1458. #endif
  1459. }
  1460. #ifdef SCAD_MESH_OUTPUT
  1461. if (x < sx - 1) SERIAL_PROTOCOLCHAR(',');
  1462. #endif
  1463. }
  1464. #ifdef SCAD_MESH_OUTPUT
  1465. SERIAL_PROTOCOLCHAR(' ');
  1466. SERIAL_PROTOCOLCHAR(']'); // close sub-array
  1467. if (y < sy - 1) SERIAL_PROTOCOLCHAR(',');
  1468. #endif
  1469. SERIAL_EOL();
  1470. }
  1471. #ifdef SCAD_MESH_OUTPUT
  1472. SERIAL_PROTOCOLPGM("];"); // close 2D array
  1473. #endif
  1474. SERIAL_EOL();
  1475. }
  1476. #endif
  1477. #if ENABLED(AUTO_BED_LEVELING_BILINEAR)
  1478. /**
  1479. * Extrapolate a single point from its neighbors
  1480. */
  1481. static void extrapolate_one_point(const uint8_t x, const uint8_t y, const int8_t xdir, const int8_t ydir) {
  1482. #if ENABLED(DEBUG_LEVELING_FEATURE)
  1483. if (DEBUGGING(LEVELING)) {
  1484. SERIAL_ECHOPGM("Extrapolate [");
  1485. if (x < 10) SERIAL_CHAR(' ');
  1486. SERIAL_ECHO((int)x);
  1487. SERIAL_CHAR(xdir ? (xdir > 0 ? '+' : '-') : ' ');
  1488. SERIAL_CHAR(' ');
  1489. if (y < 10) SERIAL_CHAR(' ');
  1490. SERIAL_ECHO((int)y);
  1491. SERIAL_CHAR(ydir ? (ydir > 0 ? '+' : '-') : ' ');
  1492. SERIAL_CHAR(']');
  1493. }
  1494. #endif
  1495. if (!isnan(z_values[x][y])) {
  1496. #if ENABLED(DEBUG_LEVELING_FEATURE)
  1497. if (DEBUGGING(LEVELING)) SERIAL_ECHOLNPGM(" (done)");
  1498. #endif
  1499. return; // Don't overwrite good values.
  1500. }
  1501. SERIAL_EOL();
  1502. // Get X neighbors, Y neighbors, and XY neighbors
  1503. const uint8_t x1 = x + xdir, y1 = y + ydir, x2 = x1 + xdir, y2 = y1 + ydir;
  1504. float a1 = z_values[x1][y ], a2 = z_values[x2][y ],
  1505. b1 = z_values[x ][y1], b2 = z_values[x ][y2],
  1506. c1 = z_values[x1][y1], c2 = z_values[x2][y2];
  1507. // Treat far unprobed points as zero, near as equal to far
  1508. if (isnan(a2)) a2 = 0.0; if (isnan(a1)) a1 = a2;
  1509. if (isnan(b2)) b2 = 0.0; if (isnan(b1)) b1 = b2;
  1510. if (isnan(c2)) c2 = 0.0; if (isnan(c1)) c1 = c2;
  1511. const float a = 2 * a1 - a2, b = 2 * b1 - b2, c = 2 * c1 - c2;
  1512. // Take the average instead of the median
  1513. z_values[x][y] = (a + b + c) / 3.0;
  1514. // Median is robust (ignores outliers).
  1515. // z_values[x][y] = (a < b) ? ((b < c) ? b : (c < a) ? a : c)
  1516. // : ((c < b) ? b : (a < c) ? a : c);
  1517. }
  1518. //Enable this if your SCARA uses 180° of total area
  1519. //#define EXTRAPOLATE_FROM_EDGE
  1520. #if ENABLED(EXTRAPOLATE_FROM_EDGE)
  1521. #if GRID_MAX_POINTS_X < GRID_MAX_POINTS_Y
  1522. #define HALF_IN_X
  1523. #elif GRID_MAX_POINTS_Y < GRID_MAX_POINTS_X
  1524. #define HALF_IN_Y
  1525. #endif
  1526. #endif
  1527. /**
  1528. * Fill in the unprobed points (corners of circular print surface)
  1529. * using linear extrapolation, away from the center.
  1530. */
  1531. static void extrapolate_unprobed_bed_level() {
  1532. #ifdef HALF_IN_X
  1533. constexpr uint8_t ctrx2 = 0, xlen = GRID_MAX_POINTS_X - 1;
  1534. #else
  1535. constexpr uint8_t ctrx1 = (GRID_MAX_POINTS_X - 1) / 2, // left-of-center
  1536. ctrx2 = (GRID_MAX_POINTS_X) / 2, // right-of-center
  1537. xlen = ctrx1;
  1538. #endif
  1539. #ifdef HALF_IN_Y
  1540. constexpr uint8_t ctry2 = 0, ylen = GRID_MAX_POINTS_Y - 1;
  1541. #else
  1542. constexpr uint8_t ctry1 = (GRID_MAX_POINTS_Y - 1) / 2, // top-of-center
  1543. ctry2 = (GRID_MAX_POINTS_Y) / 2, // bottom-of-center
  1544. ylen = ctry1;
  1545. #endif
  1546. for (uint8_t xo = 0; xo <= xlen; xo++)
  1547. for (uint8_t yo = 0; yo <= ylen; yo++) {
  1548. uint8_t x2 = ctrx2 + xo, y2 = ctry2 + yo;
  1549. #ifndef HALF_IN_X
  1550. const uint8_t x1 = ctrx1 - xo;
  1551. #endif
  1552. #ifndef HALF_IN_Y
  1553. const uint8_t y1 = ctry1 - yo;
  1554. #ifndef HALF_IN_X
  1555. extrapolate_one_point(x1, y1, +1, +1); // left-below + +
  1556. #endif
  1557. extrapolate_one_point(x2, y1, -1, +1); // right-below - +
  1558. #endif
  1559. #ifndef HALF_IN_X
  1560. extrapolate_one_point(x1, y2, +1, -1); // left-above + -
  1561. #endif
  1562. extrapolate_one_point(x2, y2, -1, -1); // right-above - -
  1563. }
  1564. }
  1565. static void print_bilinear_leveling_grid() {
  1566. SERIAL_ECHOLNPGM("Bilinear Leveling Grid:");
  1567. print_2d_array(GRID_MAX_POINTS_X, GRID_MAX_POINTS_Y, 3,
  1568. [](const uint8_t ix, const uint8_t iy) { return z_values[ix][iy]; }
  1569. );
  1570. }
  1571. #if ENABLED(ABL_BILINEAR_SUBDIVISION)
  1572. #define ABL_GRID_POINTS_VIRT_X (GRID_MAX_POINTS_X - 1) * (BILINEAR_SUBDIVISIONS) + 1
  1573. #define ABL_GRID_POINTS_VIRT_Y (GRID_MAX_POINTS_Y - 1) * (BILINEAR_SUBDIVISIONS) + 1
  1574. #define ABL_TEMP_POINTS_X (GRID_MAX_POINTS_X + 2)
  1575. #define ABL_TEMP_POINTS_Y (GRID_MAX_POINTS_Y + 2)
  1576. float z_values_virt[ABL_GRID_POINTS_VIRT_X][ABL_GRID_POINTS_VIRT_Y];
  1577. int bilinear_grid_spacing_virt[2] = { 0 };
  1578. float bilinear_grid_factor_virt[2] = { 0 };
  1579. static void print_bilinear_leveling_grid_virt() {
  1580. SERIAL_ECHOLNPGM("Subdivided with CATMULL ROM Leveling Grid:");
  1581. print_2d_array(ABL_GRID_POINTS_VIRT_X, ABL_GRID_POINTS_VIRT_Y, 5,
  1582. [](const uint8_t ix, const uint8_t iy) { return z_values_virt[ix][iy]; }
  1583. );
  1584. }
  1585. #define LINEAR_EXTRAPOLATION(E, I) ((E) * 2 - (I))
  1586. float bed_level_virt_coord(const uint8_t x, const uint8_t y) {
  1587. uint8_t ep = 0, ip = 1;
  1588. if (!x || x == ABL_TEMP_POINTS_X - 1) {
  1589. if (x) {
  1590. ep = GRID_MAX_POINTS_X - 1;
  1591. ip = GRID_MAX_POINTS_X - 2;
  1592. }
  1593. if (WITHIN(y, 1, ABL_TEMP_POINTS_Y - 2))
  1594. return LINEAR_EXTRAPOLATION(
  1595. z_values[ep][y - 1],
  1596. z_values[ip][y - 1]
  1597. );
  1598. else
  1599. return LINEAR_EXTRAPOLATION(
  1600. bed_level_virt_coord(ep + 1, y),
  1601. bed_level_virt_coord(ip + 1, y)
  1602. );
  1603. }
  1604. if (!y || y == ABL_TEMP_POINTS_Y - 1) {
  1605. if (y) {
  1606. ep = GRID_MAX_POINTS_Y - 1;
  1607. ip = GRID_MAX_POINTS_Y - 2;
  1608. }
  1609. if (WITHIN(x, 1, ABL_TEMP_POINTS_X - 2))
  1610. return LINEAR_EXTRAPOLATION(
  1611. z_values[x - 1][ep],
  1612. z_values[x - 1][ip]
  1613. );
  1614. else
  1615. return LINEAR_EXTRAPOLATION(
  1616. bed_level_virt_coord(x, ep + 1),
  1617. bed_level_virt_coord(x, ip + 1)
  1618. );
  1619. }
  1620. return z_values[x - 1][y - 1];
  1621. }
  1622. static float bed_level_virt_cmr(const float p[4], const uint8_t i, const float t) {
  1623. return (
  1624. p[i-1] * -t * sq(1 - t)
  1625. + p[i] * (2 - 5 * sq(t) + 3 * t * sq(t))
  1626. + p[i+1] * t * (1 + 4 * t - 3 * sq(t))
  1627. - p[i+2] * sq(t) * (1 - t)
  1628. ) * 0.5;
  1629. }
  1630. static float bed_level_virt_2cmr(const uint8_t x, const uint8_t y, const float &tx, const float &ty) {
  1631. float row[4], column[4];
  1632. for (uint8_t i = 0; i < 4; i++) {
  1633. for (uint8_t j = 0; j < 4; j++) {
  1634. column[j] = bed_level_virt_coord(i + x - 1, j + y - 1);
  1635. }
  1636. row[i] = bed_level_virt_cmr(column, 1, ty);
  1637. }
  1638. return bed_level_virt_cmr(row, 1, tx);
  1639. }
  1640. void bed_level_virt_interpolate() {
  1641. bilinear_grid_spacing_virt[X_AXIS] = bilinear_grid_spacing[X_AXIS] / (BILINEAR_SUBDIVISIONS);
  1642. bilinear_grid_spacing_virt[Y_AXIS] = bilinear_grid_spacing[Y_AXIS] / (BILINEAR_SUBDIVISIONS);
  1643. bilinear_grid_factor_virt[X_AXIS] = RECIPROCAL(bilinear_grid_spacing_virt[X_AXIS]);
  1644. bilinear_grid_factor_virt[Y_AXIS] = RECIPROCAL(bilinear_grid_spacing_virt[Y_AXIS]);
  1645. for (uint8_t y = 0; y < GRID_MAX_POINTS_Y; y++)
  1646. for (uint8_t x = 0; x < GRID_MAX_POINTS_X; x++)
  1647. for (uint8_t ty = 0; ty < BILINEAR_SUBDIVISIONS; ty++)
  1648. for (uint8_t tx = 0; tx < BILINEAR_SUBDIVISIONS; tx++) {
  1649. if ((ty && y == GRID_MAX_POINTS_Y - 1) || (tx && x == GRID_MAX_POINTS_X - 1))
  1650. continue;
  1651. z_values_virt[x * (BILINEAR_SUBDIVISIONS) + tx][y * (BILINEAR_SUBDIVISIONS) + ty] =
  1652. bed_level_virt_2cmr(
  1653. x + 1,
  1654. y + 1,
  1655. (float)tx / (BILINEAR_SUBDIVISIONS),
  1656. (float)ty / (BILINEAR_SUBDIVISIONS)
  1657. );
  1658. }
  1659. }
  1660. #endif // ABL_BILINEAR_SUBDIVISION
  1661. // Refresh after other values have been updated
  1662. void refresh_bed_level() {
  1663. bilinear_grid_factor[X_AXIS] = RECIPROCAL(bilinear_grid_spacing[X_AXIS]);
  1664. bilinear_grid_factor[Y_AXIS] = RECIPROCAL(bilinear_grid_spacing[Y_AXIS]);
  1665. #if ENABLED(ABL_BILINEAR_SUBDIVISION)
  1666. bed_level_virt_interpolate();
  1667. #endif
  1668. }
  1669. #endif // AUTO_BED_LEVELING_BILINEAR
  1670. /**
  1671. * Home an individual linear axis
  1672. */
  1673. static void do_homing_move(const AxisEnum axis, const float distance, const float fr_mm_s=0.0) {
  1674. #if ENABLED(DEBUG_LEVELING_FEATURE)
  1675. if (DEBUGGING(LEVELING)) {
  1676. SERIAL_ECHOPAIR(">>> do_homing_move(", axis_codes[axis]);
  1677. SERIAL_ECHOPAIR(", ", distance);
  1678. SERIAL_ECHOPAIR(", ", fr_mm_s);
  1679. SERIAL_CHAR(')');
  1680. SERIAL_EOL();
  1681. }
  1682. #endif
  1683. #if HOMING_Z_WITH_PROBE && ENABLED(BLTOUCH)
  1684. const bool deploy_bltouch = (axis == Z_AXIS && distance < 0);
  1685. if (deploy_bltouch) set_bltouch_deployed(true);
  1686. #endif
  1687. #if QUIET_PROBING
  1688. if (axis == Z_AXIS) probing_pause(true);
  1689. #endif
  1690. // Tell the planner we're at Z=0
  1691. current_position[axis] = 0;
  1692. #if IS_SCARA
  1693. SYNC_PLAN_POSITION_KINEMATIC();
  1694. current_position[axis] = distance;
  1695. inverse_kinematics(current_position);
  1696. planner.buffer_line(delta[A_AXIS], delta[B_AXIS], delta[C_AXIS], current_position[E_AXIS], fr_mm_s ? fr_mm_s : homing_feedrate(axis), active_extruder);
  1697. #else
  1698. sync_plan_position();
  1699. current_position[axis] = distance;
  1700. planner.buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], fr_mm_s ? fr_mm_s : homing_feedrate(axis), active_extruder);
  1701. #endif
  1702. stepper.synchronize();
  1703. #if QUIET_PROBING
  1704. if (axis == Z_AXIS) probing_pause(false);
  1705. #endif
  1706. #if HOMING_Z_WITH_PROBE && ENABLED(BLTOUCH)
  1707. if (deploy_bltouch) set_bltouch_deployed(false);
  1708. #endif
  1709. endstops.hit_on_purpose();
  1710. #if ENABLED(DEBUG_LEVELING_FEATURE)
  1711. if (DEBUGGING(LEVELING)) {
  1712. SERIAL_ECHOPAIR("<<< do_homing_move(", axis_codes[axis]);
  1713. SERIAL_CHAR(')');
  1714. SERIAL_EOL();
  1715. }
  1716. #endif
  1717. }
  1718. /**
  1719. * TMC2130 specific sensorless homing using stallGuard2.
  1720. * stallGuard2 only works when in spreadCycle mode.
  1721. * spreadCycle and stealthChop are mutually exclusive.
  1722. */
  1723. #if ENABLED(SENSORLESS_HOMING)
  1724. void tmc2130_sensorless_homing(TMC2130Stepper &st, bool enable=true) {
  1725. #if ENABLED(STEALTHCHOP)
  1726. if (enable) {
  1727. st.coolstep_min_speed(1024UL * 1024UL - 1UL);
  1728. st.stealthChop(0);
  1729. }
  1730. else {
  1731. st.coolstep_min_speed(0);
  1732. st.stealthChop(1);
  1733. }
  1734. #endif
  1735. st.diag1_stall(enable ? 1 : 0);
  1736. }
  1737. #endif
  1738. /**
  1739. * Home an individual "raw axis" to its endstop.
  1740. * This applies to XYZ on Cartesian and Core robots, and
  1741. * to the individual ABC steppers on DELTA and SCARA.
  1742. *
  1743. * At the end of the procedure the axis is marked as
  1744. * homed and the current position of that axis is updated.
  1745. * Kinematic robots should wait till all axes are homed
  1746. * before updating the current position.
  1747. */
  1748. #define HOMEAXIS(LETTER) homeaxis(LETTER##_AXIS)
  1749. static void homeaxis(const AxisEnum axis) {
  1750. #if IS_SCARA
  1751. // Only Z homing (with probe) is permitted
  1752. if (axis != Z_AXIS) { BUZZ(100, 880); return; }
  1753. #else
  1754. #define CAN_HOME(A) \
  1755. (axis == A##_AXIS && ((A##_MIN_PIN > -1 && A##_HOME_DIR < 0) || (A##_MAX_PIN > -1 && A##_HOME_DIR > 0)))
  1756. if (!CAN_HOME(X) && !CAN_HOME(Y) && !CAN_HOME(Z)) return;
  1757. #endif
  1758. #if ENABLED(DEBUG_LEVELING_FEATURE)
  1759. if (DEBUGGING(LEVELING)) {
  1760. SERIAL_ECHOPAIR(">>> homeaxis(", axis_codes[axis]);
  1761. SERIAL_CHAR(')');
  1762. SERIAL_EOL();
  1763. }
  1764. #endif
  1765. const int axis_home_dir =
  1766. #if ENABLED(DUAL_X_CARRIAGE)
  1767. (axis == X_AXIS) ? x_home_dir(active_extruder) :
  1768. #endif
  1769. home_dir(axis);
  1770. // Homing Z towards the bed? Deploy the Z probe or endstop.
  1771. #if HOMING_Z_WITH_PROBE
  1772. if (axis == Z_AXIS && DEPLOY_PROBE()) return;
  1773. #endif
  1774. // Set a flag for Z motor locking
  1775. #if ENABLED(Z_DUAL_ENDSTOPS)
  1776. if (axis == Z_AXIS) stepper.set_homing_flag(true);
  1777. #endif
  1778. // Disable stealthChop if used. Enable diag1 pin on driver.
  1779. #if ENABLED(SENSORLESS_HOMING)
  1780. #if ENABLED(X_IS_TMC2130)
  1781. if (axis == X_AXIS) tmc2130_sensorless_homing(stepperX);
  1782. #endif
  1783. #if ENABLED(Y_IS_TMC2130)
  1784. if (axis == Y_AXIS) tmc2130_sensorless_homing(stepperY);
  1785. #endif
  1786. #endif
  1787. // Fast move towards endstop until triggered
  1788. #if ENABLED(DEBUG_LEVELING_FEATURE)
  1789. if (DEBUGGING(LEVELING)) SERIAL_ECHOLNPGM("Home 1 Fast:");
  1790. #endif
  1791. do_homing_move(axis, 1.5 * max_length(axis) * axis_home_dir);
  1792. // When homing Z with probe respect probe clearance
  1793. const float bump = axis_home_dir * (
  1794. #if HOMING_Z_WITH_PROBE
  1795. (axis == Z_AXIS) ? max(Z_CLEARANCE_BETWEEN_PROBES, home_bump_mm(Z_AXIS)) :
  1796. #endif
  1797. home_bump_mm(axis)
  1798. );
  1799. // If a second homing move is configured...
  1800. if (bump) {
  1801. // Move away from the endstop by the axis HOME_BUMP_MM
  1802. #if ENABLED(DEBUG_LEVELING_FEATURE)
  1803. if (DEBUGGING(LEVELING)) SERIAL_ECHOLNPGM("Move Away:");
  1804. #endif
  1805. do_homing_move(axis, -bump);
  1806. // Slow move towards endstop until triggered
  1807. #if ENABLED(DEBUG_LEVELING_FEATURE)
  1808. if (DEBUGGING(LEVELING)) SERIAL_ECHOLNPGM("Home 2 Slow:");
  1809. #endif
  1810. do_homing_move(axis, 2 * bump, get_homing_bump_feedrate(axis));
  1811. }
  1812. #if ENABLED(Z_DUAL_ENDSTOPS)
  1813. if (axis == Z_AXIS) {
  1814. float adj = FABS(z_endstop_adj);
  1815. bool lockZ1;
  1816. if (axis_home_dir > 0) {
  1817. adj = -adj;
  1818. lockZ1 = (z_endstop_adj > 0);
  1819. }
  1820. else
  1821. lockZ1 = (z_endstop_adj < 0);
  1822. if (lockZ1) stepper.set_z_lock(true); else stepper.set_z2_lock(true);
  1823. // Move to the adjusted endstop height
  1824. do_homing_move(axis, adj);
  1825. if (lockZ1) stepper.set_z_lock(false); else stepper.set_z2_lock(false);
  1826. stepper.set_homing_flag(false);
  1827. } // Z_AXIS
  1828. #endif
  1829. #if IS_SCARA
  1830. set_axis_is_at_home(axis);
  1831. SYNC_PLAN_POSITION_KINEMATIC();
  1832. #elif ENABLED(DELTA)
  1833. // Delta has already moved all three towers up in G28
  1834. // so here it re-homes each tower in turn.
  1835. // Delta homing treats the axes as normal linear axes.
  1836. // retrace by the amount specified in endstop_adj + additional 0.1mm in order to have minimum steps
  1837. if (endstop_adj[axis] * Z_HOME_DIR <= 0) {
  1838. #if ENABLED(DEBUG_LEVELING_FEATURE)
  1839. if (DEBUGGING(LEVELING)) SERIAL_ECHOLNPGM("endstop_adj:");
  1840. #endif
  1841. do_homing_move(axis, endstop_adj[axis] - 0.1);
  1842. }
  1843. #else
  1844. // For cartesian/core machines,
  1845. // set the axis to its home position
  1846. set_axis_is_at_home(axis);
  1847. sync_plan_position();
  1848. destination[axis] = current_position[axis];
  1849. #if ENABLED(DEBUG_LEVELING_FEATURE)
  1850. if (DEBUGGING(LEVELING)) DEBUG_POS("> AFTER set_axis_is_at_home", current_position);
  1851. #endif
  1852. #endif
  1853. // Re-enable stealthChop if used. Disable diag1 pin on driver.
  1854. #if ENABLED(SENSORLESS_HOMING)
  1855. #if ENABLED(X_IS_TMC2130)
  1856. if (axis == X_AXIS) tmc2130_sensorless_homing(stepperX, false);
  1857. #endif
  1858. #if ENABLED(Y_IS_TMC2130)
  1859. if (axis == Y_AXIS) tmc2130_sensorless_homing(stepperY, false);
  1860. #endif
  1861. #endif
  1862. // Put away the Z probe
  1863. #if HOMING_Z_WITH_PROBE
  1864. if (axis == Z_AXIS && STOW_PROBE()) return;
  1865. #endif
  1866. #if ENABLED(DEBUG_LEVELING_FEATURE)
  1867. if (DEBUGGING(LEVELING)) {
  1868. SERIAL_ECHOPAIR("<<< homeaxis(", axis_codes[axis]);
  1869. SERIAL_CHAR(')');
  1870. SERIAL_EOL();
  1871. }
  1872. #endif
  1873. } // homeaxis()
  1874. #if ENABLED(MIXING_EXTRUDER)
  1875. void normalize_mix() {
  1876. float mix_total = 0.0;
  1877. for (uint8_t i = 0; i < MIXING_STEPPERS; i++) mix_total += RECIPROCAL(mixing_factor[i]);
  1878. // Scale all values if they don't add up to ~1.0
  1879. if (!NEAR(mix_total, 1.0)) {
  1880. SERIAL_PROTOCOLLNPGM("Warning: Mix factors must add up to 1.0. Scaling.");
  1881. for (uint8_t i = 0; i < MIXING_STEPPERS; i++) mixing_factor[i] *= mix_total;
  1882. }
  1883. }
  1884. #if ENABLED(DIRECT_MIXING_IN_G1)
  1885. // Get mixing parameters from the GCode
  1886. // The total "must" be 1.0 (but it will be normalized)
  1887. // If no mix factors are given, the old mix is preserved
  1888. void gcode_get_mix() {
  1889. const char* mixing_codes = "ABCDHI";
  1890. byte mix_bits = 0;
  1891. for (uint8_t i = 0; i < MIXING_STEPPERS; i++) {
  1892. if (parser.seenval(mixing_codes[i])) {
  1893. SBI(mix_bits, i);
  1894. float v = parser.value_float();
  1895. NOLESS(v, 0.0);
  1896. mixing_factor[i] = RECIPROCAL(v);
  1897. }
  1898. }
  1899. // If any mixing factors were included, clear the rest
  1900. // If none were included, preserve the last mix
  1901. if (mix_bits) {
  1902. for (uint8_t i = 0; i < MIXING_STEPPERS; i++)
  1903. if (!TEST(mix_bits, i)) mixing_factor[i] = 0.0;
  1904. normalize_mix();
  1905. }
  1906. }
  1907. #endif
  1908. #endif
  1909. /**
  1910. * ***************************************************************************
  1911. * ***************************** G-CODE HANDLING *****************************
  1912. * ***************************************************************************
  1913. */
  1914. #if ENABLED(HOST_KEEPALIVE_FEATURE)
  1915. /**
  1916. * Output a "busy" message at regular intervals
  1917. * while the machine is not accepting commands.
  1918. */
  1919. void host_keepalive() {
  1920. const millis_t ms = millis();
  1921. if (host_keepalive_interval && busy_state != NOT_BUSY) {
  1922. if (PENDING(ms, next_busy_signal_ms)) return;
  1923. switch (busy_state) {
  1924. case IN_HANDLER:
  1925. case IN_PROCESS:
  1926. SERIAL_ECHO_START();
  1927. SERIAL_ECHOLNPGM(MSG_BUSY_PROCESSING);
  1928. break;
  1929. case PAUSED_FOR_USER:
  1930. SERIAL_ECHO_START();
  1931. SERIAL_ECHOLNPGM(MSG_BUSY_PAUSED_FOR_USER);
  1932. break;
  1933. case PAUSED_FOR_INPUT:
  1934. SERIAL_ECHO_START();
  1935. SERIAL_ECHOLNPGM(MSG_BUSY_PAUSED_FOR_INPUT);
  1936. break;
  1937. default:
  1938. break;
  1939. }
  1940. }
  1941. next_busy_signal_ms = ms + host_keepalive_interval * 1000UL;
  1942. }
  1943. #endif // HOST_KEEPALIVE_FEATURE
  1944. /**************************************************
  1945. ***************** GCode Handlers *****************
  1946. **************************************************/
  1947. #if ENABLED(ARC_SUPPORT)
  1948. #include "gcode/motion/G2_G3.h"
  1949. #endif
  1950. void dwell(millis_t time) {
  1951. gcode.refresh_cmd_timeout();
  1952. time += previous_cmd_ms;
  1953. while (PENDING(millis(), time)) idle();
  1954. }
  1955. #include "gcode/motion/G4.h"
  1956. #if ENABLED(BEZIER_CURVE_SUPPORT)
  1957. #include "gcode/motion/G5.h"
  1958. #endif
  1959. #if ENABLED(NOZZLE_CLEAN_FEATURE)
  1960. #include "gcode/feature/clean/G12.h"
  1961. #endif
  1962. #if ENABLED(CNC_WORKSPACE_PLANES)
  1963. #include "gcode/geometry/G17-G19.h"
  1964. #endif
  1965. #if ENABLED(INCH_MODE_SUPPORT)
  1966. #include "gcode/units/G20_G21.h"
  1967. #endif
  1968. #if ENABLED(UBL_G26_MESH_VALIDATION)
  1969. #include "gcode/calibrate/G26.h"
  1970. #endif
  1971. #if ENABLED(NOZZLE_PARK_FEATURE)
  1972. #include "gcode/feature/pause/G27.h"
  1973. #endif
  1974. #if ENABLED(PROBE_MANUALLY)
  1975. bool g29_in_progress = false;
  1976. #else
  1977. constexpr bool g29_in_progress = false;
  1978. #endif
  1979. #include "gcode/calibrate/G28.h"
  1980. void home_all_axes() { gcode_G28(true); }
  1981. #if HAS_PROBING_PROCEDURE
  1982. void out_of_range_error(const char* p_edge) {
  1983. SERIAL_PROTOCOLPGM("?Probe ");
  1984. serialprintPGM(p_edge);
  1985. SERIAL_PROTOCOLLNPGM(" position out of range.");
  1986. }
  1987. #endif
  1988. #include "gcode/calibrate/G29.h"
  1989. #if HAS_BED_PROBE
  1990. #include "gcode/probe/G30.h"
  1991. #if ENABLED(Z_PROBE_SLED)
  1992. #include "gcode/probe/G31_G32.h"
  1993. #endif
  1994. #endif
  1995. #if PROBE_SELECTED && ENABLED(DELTA_AUTO_CALIBRATION)
  1996. #include "gcode/calibrate/G33.h"
  1997. #endif
  1998. #if ENABLED(G38_PROBE_TARGET)
  1999. #include "gcode/probe/G38.h"
  2000. #endif
  2001. #if HAS_MESH
  2002. #include "gcode/probe/G42.h"
  2003. #endif
  2004. #include "gcode/geometry/G92.h"
  2005. #if HAS_RESUME_CONTINUE
  2006. #include "gcode/lcd/M0_M1.h"
  2007. #endif
  2008. #if ENABLED(SPINDLE_LASER_ENABLE)
  2009. #include "gcode/control/M3-M5.h"
  2010. #endif
  2011. #include "gcode/control/M17.h"
  2012. #if ENABLED(ADVANCED_PAUSE_FEATURE)
  2013. // For M125, M600, M24
  2014. #include "gcode/feature/pause/common.h"
  2015. #endif
  2016. #if ENABLED(SDSUPPORT)
  2017. #include "gcode/sdcard/M20.h" // M20 - List SD card. (Requires SDSUPPORT)
  2018. #include "gcode/sdcard/M21.h" // M21 - Init SD card. (Requires SDSUPPORT)
  2019. #include "gcode/sdcard/M22.h" // M22 - Release SD card. (Requires SDSUPPORT)
  2020. #include "gcode/sdcard/M23.h" // M23 - Select SD file: "M23 /path/file.gco". (Requires SDSUPPORT)
  2021. #include "gcode/sdcard/M24.h" // M24 - Start/resume SD print. (Requires SDSUPPORT)
  2022. #include "gcode/sdcard/M25.h" // M25 - Pause SD print. (Requires SDSUPPORT)
  2023. #include "gcode/sdcard/M26.h" // M26 - Set SD position in bytes: "M26 S12345". (Requires SDSUPPORT)
  2024. #include "gcode/sdcard/M27.h" // M27 - Report SD print status. (Requires SDSUPPORT)
  2025. #include "gcode/sdcard/M28.h" // M28 - Start SD write: "M28 /path/file.gco". (Requires SDSUPPORT)
  2026. #include "gcode/sdcard/M29.h" // M29 - Stop SD write. (Requires SDSUPPORT)
  2027. #include "gcode/sdcard/M30.h" // M30 - Delete file from SD: "M30 /path/file.gco"
  2028. #endif
  2029. #include "gcode/stats/M31.h" // M31: Get the time since the start of SD Print (or last M109)
  2030. #if ENABLED(SDSUPPORT)
  2031. #include "gcode/sdcard/M32.h"
  2032. #if ENABLED(LONG_FILENAME_HOST_SUPPORT)
  2033. #include "gcode/sdcard/M33.h"
  2034. #endif
  2035. #if ENABLED(SDCARD_SORT_ALPHA) && ENABLED(SDSORT_GCODE)
  2036. #include "gcode/sdcard/M34.h"
  2037. #endif
  2038. #include "gcode/sdcard/M928.h"
  2039. #endif
  2040. /**
  2041. * Sensitive pin test for M42, M226
  2042. */
  2043. static bool pin_is_protected(const int8_t pin) {
  2044. static const int8_t sensitive_pins[] PROGMEM = SENSITIVE_PINS;
  2045. for (uint8_t i = 0; i < COUNT(sensitive_pins); i++)
  2046. if (pin == (int8_t)pgm_read_byte(&sensitive_pins[i])) return true;
  2047. return false;
  2048. }
  2049. #include "gcode/control/M42.h"
  2050. #if ENABLED(PINS_DEBUGGING)
  2051. #include "gcode/config/M43.h"
  2052. #endif
  2053. #if ENABLED(Z_MIN_PROBE_REPEATABILITY_TEST)
  2054. #include "gcode/calibrate/M48.h"
  2055. #endif
  2056. #if ENABLED(AUTO_BED_LEVELING_UBL) && ENABLED(UBL_G26_MESH_VALIDATION)
  2057. #include "gcode/calibrate/M49.h"
  2058. #endif
  2059. #include "gcode/stats/M75.h"
  2060. #include "gcode/stats/M76.h"
  2061. #include "gcode/stats/M77.h"
  2062. #if ENABLED(PRINTCOUNTER)
  2063. #include "gcode/stats/M78.h"
  2064. #endif
  2065. #if HAS_TEMP_HOTEND || HAS_TEMP_BED
  2066. void print_heater_state(const float &c, const float &t,
  2067. #if ENABLED(SHOW_TEMP_ADC_VALUES)
  2068. const float r,
  2069. #endif
  2070. const int8_t e=-2
  2071. ) {
  2072. #if !(HAS_TEMP_BED && HAS_TEMP_HOTEND) && HOTENDS <= 1
  2073. UNUSED(e);
  2074. #endif
  2075. SERIAL_PROTOCOLCHAR(' ');
  2076. SERIAL_PROTOCOLCHAR(
  2077. #if HAS_TEMP_BED && HAS_TEMP_HOTEND
  2078. e == -1 ? 'B' : 'T'
  2079. #elif HAS_TEMP_HOTEND
  2080. 'T'
  2081. #else
  2082. 'B'
  2083. #endif
  2084. );
  2085. #if HOTENDS > 1
  2086. if (e >= 0) SERIAL_PROTOCOLCHAR('0' + e);
  2087. #endif
  2088. SERIAL_PROTOCOLCHAR(':');
  2089. SERIAL_PROTOCOL(c);
  2090. SERIAL_PROTOCOLPAIR(" /" , t);
  2091. #if ENABLED(SHOW_TEMP_ADC_VALUES)
  2092. SERIAL_PROTOCOLPAIR(" (", r / OVERSAMPLENR);
  2093. SERIAL_PROTOCOLCHAR(')');
  2094. #endif
  2095. }
  2096. void print_heaterstates() {
  2097. #if HAS_TEMP_HOTEND
  2098. print_heater_state(thermalManager.degHotend(gcode.target_extruder), thermalManager.degTargetHotend(gcode.target_extruder)
  2099. #if ENABLED(SHOW_TEMP_ADC_VALUES)
  2100. , thermalManager.rawHotendTemp(gcode.target_extruder)
  2101. #endif
  2102. );
  2103. #endif
  2104. #if HAS_TEMP_BED
  2105. print_heater_state(thermalManager.degBed(), thermalManager.degTargetBed(),
  2106. #if ENABLED(SHOW_TEMP_ADC_VALUES)
  2107. thermalManager.rawBedTemp(),
  2108. #endif
  2109. -1 // BED
  2110. );
  2111. #endif
  2112. #if HOTENDS > 1
  2113. HOTEND_LOOP() print_heater_state(thermalManager.degHotend(e), thermalManager.degTargetHotend(e),
  2114. #if ENABLED(SHOW_TEMP_ADC_VALUES)
  2115. thermalManager.rawHotendTemp(e),
  2116. #endif
  2117. e
  2118. );
  2119. #endif
  2120. SERIAL_PROTOCOLPGM(" @:");
  2121. SERIAL_PROTOCOL(thermalManager.getHeaterPower(gcode.target_extruder));
  2122. #if HAS_TEMP_BED
  2123. SERIAL_PROTOCOLPGM(" B@:");
  2124. SERIAL_PROTOCOL(thermalManager.getHeaterPower(-1));
  2125. #endif
  2126. #if HOTENDS > 1
  2127. HOTEND_LOOP() {
  2128. SERIAL_PROTOCOLPAIR(" @", e);
  2129. SERIAL_PROTOCOLCHAR(':');
  2130. SERIAL_PROTOCOL(thermalManager.getHeaterPower(e));
  2131. }
  2132. #endif
  2133. }
  2134. #endif // HAS_TEMP_HOTEND || HAS_TEMP_BED
  2135. #include "gcode/temperature/M105.h"
  2136. #if ENABLED(AUTO_REPORT_TEMPERATURES) && (HAS_TEMP_HOTEND || HAS_TEMP_BED)
  2137. static uint8_t auto_report_temp_interval;
  2138. static millis_t next_temp_report_ms;
  2139. inline void auto_report_temperatures() {
  2140. if (auto_report_temp_interval && ELAPSED(millis(), next_temp_report_ms)) {
  2141. next_temp_report_ms = millis() + 1000UL * auto_report_temp_interval;
  2142. print_heaterstates();
  2143. SERIAL_EOL();
  2144. }
  2145. }
  2146. #include "gcode/temperature/M155.h"
  2147. #endif // AUTO_REPORT_TEMPERATURES && (HAS_TEMP_HOTEND || HAS_TEMP_BED)
  2148. #if FAN_COUNT > 0
  2149. #include "gcode/temperature/M106.h"
  2150. #include "gcode/temperature/M107.h"
  2151. #endif
  2152. #if DISABLED(EMERGENCY_PARSER)
  2153. #include "gcode/control/M108.h"
  2154. #include "gcode/control/M112.h"
  2155. #include "gcode/control/M410.h"
  2156. #endif
  2157. #if HAS_TEMP_BED
  2158. #include "gcode/temperature/M190.h"
  2159. #endif
  2160. #include "gcode/host/M110.h"
  2161. #include "gcode/control/M111.h"
  2162. #if ENABLED(HOST_KEEPALIVE_FEATURE)
  2163. #include "gcode/host/M113.h"
  2164. #endif
  2165. #if ENABLED(BARICUDA)
  2166. #if HAS_HEATER_1
  2167. #include "gcode/feature/baricuda/M126.h"
  2168. #include "gcode/feature/baricuda/M127.h"
  2169. #endif
  2170. #if HAS_HEATER_2
  2171. #include "gcode/feature/baricuda/M128.h"
  2172. #include "gcode/feature/baricuda/M129.h"
  2173. #endif
  2174. #endif
  2175. #include "gcode/temperature/M140.h"
  2176. #if ENABLED(ULTIPANEL)
  2177. #include "gcode/lcd/M145.h"
  2178. #endif
  2179. #if ENABLED(TEMPERATURE_UNITS_SUPPORT)
  2180. #include "gcode/units/M149.h"
  2181. #endif
  2182. #if HAS_POWER_SWITCH
  2183. #include "gcode/control/M80.h"
  2184. #endif
  2185. #include "gcode/control/M81.h"
  2186. #include "gcode/units/M82_M83.h"
  2187. #include "gcode/control/M18_M84.h"
  2188. #include "gcode/control/M85.h"
  2189. #include "gcode/config/M92.h"
  2190. #if ENABLED(M100_FREE_MEMORY_WATCHER)
  2191. #include "gcode/calibrate/M100.h"
  2192. #endif
  2193. /**
  2194. * Output the current position to serial
  2195. */
  2196. void report_current_position() {
  2197. SERIAL_PROTOCOLPGM("X:");
  2198. SERIAL_PROTOCOL(current_position[X_AXIS]);
  2199. SERIAL_PROTOCOLPGM(" Y:");
  2200. SERIAL_PROTOCOL(current_position[Y_AXIS]);
  2201. SERIAL_PROTOCOLPGM(" Z:");
  2202. SERIAL_PROTOCOL(current_position[Z_AXIS]);
  2203. SERIAL_PROTOCOLPGM(" E:");
  2204. SERIAL_PROTOCOL(current_position[E_AXIS]);
  2205. stepper.report_positions();
  2206. #if IS_SCARA
  2207. SERIAL_PROTOCOLPAIR("SCARA Theta:", stepper.get_axis_position_degrees(A_AXIS));
  2208. SERIAL_PROTOCOLLNPAIR(" Psi+Theta:", stepper.get_axis_position_degrees(B_AXIS));
  2209. SERIAL_EOL();
  2210. #endif
  2211. }
  2212. #include "gcode/host/M114.h"
  2213. #include "gcode/host/M115.h"
  2214. #include "gcode/lcd/M117.h"
  2215. #include "gcode/host/M118.h"
  2216. #include "gcode/host/M119.h"
  2217. #include "gcode/control/M120_M121.h"
  2218. #if ENABLED(PARK_HEAD_ON_PAUSE)
  2219. #include "gcode/feature/pause/M125.h"
  2220. #endif
  2221. #if HAS_COLOR_LEDS
  2222. #include "gcode/feature/leds/M150.h"
  2223. #endif
  2224. #include "gcode/config/M201.h"
  2225. #if 0 // Not used for Sprinter/grbl gen6
  2226. #include "gcode/config/M202.h"
  2227. #endif
  2228. #include "gcode/config/M203.h"
  2229. #include "gcode/config/M204.h"
  2230. #include "gcode/config/M205.h"
  2231. #if HAS_M206_COMMAND
  2232. #include "gcode/geometry/M206.h"
  2233. #endif
  2234. #if IS_KINEMATIC
  2235. #include "gcode/calibrate/M665.h"
  2236. #endif
  2237. #if ENABLED(DELTA) || ENABLED(Z_DUAL_ENDSTOPS)
  2238. #include "gcode/calibrate/M666.h"
  2239. #endif
  2240. #include "gcode/control/M211.h"
  2241. #include "gcode/config/M220.h"
  2242. #include "gcode/control/M226.h"
  2243. #if ENABLED(EXPERIMENTAL_I2CBUS)
  2244. #include "gcode/feature/i2c/M260_M261.h"
  2245. #endif
  2246. #if HAS_SERVOS
  2247. #include "gcode/control/M280.h"
  2248. #endif
  2249. #if HAS_BUZZER
  2250. #include "gcode/lcd/M300.h"
  2251. #endif
  2252. #if ENABLED(PIDTEMP)
  2253. #include "gcode/config/M301.h"
  2254. #endif
  2255. #if ENABLED(PIDTEMPBED)
  2256. #include "gcode/config/M304.h"
  2257. #endif
  2258. #if defined(CHDK) || HAS_PHOTOGRAPH
  2259. #include "gcode/feature/camera/M240.h"
  2260. #endif
  2261. #if HAS_LCD_CONTRAST
  2262. #include "gcode/lcd/M250.h"
  2263. #endif
  2264. #if ENABLED(PREVENT_COLD_EXTRUSION)
  2265. #include "gcode/config/M302.h"
  2266. #endif
  2267. #if ENABLED(MORGAN_SCARA)
  2268. #include "gcode/scara/M360-M364.h"
  2269. #endif
  2270. #if ENABLED(EXT_SOLENOID)
  2271. #include "gcode/control/M380_M381.h"
  2272. #endif
  2273. #include "gcode/control/M400.h"
  2274. #if HAS_BED_PROBE
  2275. #include "gcode/probe/M401_M402.h"
  2276. #endif
  2277. #if ENABLED(FILAMENT_WIDTH_SENSOR)
  2278. #include "gcode/sensor/M404.h"
  2279. #include "gcode/sensor/M405.h"
  2280. #include "gcode/sensor/M406.h"
  2281. #include "gcode/sensor/M407.h"
  2282. #endif
  2283. void quickstop_stepper() {
  2284. stepper.quick_stop();
  2285. stepper.synchronize();
  2286. set_current_from_steppers_for_axis(ALL_AXES);
  2287. SYNC_PLAN_POSITION_KINEMATIC();
  2288. }
  2289. #if HAS_LEVELING
  2290. #include "gcode/calibrate/M420.h"
  2291. #include "gcode/calibrate/M421.h"
  2292. #endif
  2293. #if HAS_M206_COMMAND
  2294. #include "gcode/geometry/M428.h"
  2295. #endif
  2296. #include "gcode/eeprom/M500.h"
  2297. #include "gcode/eeprom/M501.h"
  2298. #include "gcode/eeprom/M502.h"
  2299. #if DISABLED(DISABLE_M503)
  2300. #include "gcode/eeprom/M503.h"
  2301. #endif
  2302. #if ENABLED(ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED)
  2303. #include "gcode/config/M540.h"
  2304. #endif
  2305. #if HAS_BED_PROBE
  2306. #include "gcode/probe/M851.h"
  2307. #endif
  2308. #if ENABLED(ADVANCED_PAUSE_FEATURE)
  2309. #include "gcode/feature/pause/M600.h"
  2310. #endif
  2311. #if ENABLED(MK2_MULTIPLEXER)
  2312. #include "gcode/feature/snmm/M702.h"
  2313. #endif
  2314. #if ENABLED(DUAL_X_CARRIAGE) || ENABLED(DUAL_NOZZLE_DUPLICATION_MODE)
  2315. #include "gcode/control/M605.h"
  2316. #endif
  2317. #if ENABLED(LIN_ADVANCE)
  2318. #include "gcode/feature/advance/M900.h"
  2319. #endif
  2320. #if ENABLED(HAVE_TMC2130)
  2321. #include "feature/tmc2130.h"
  2322. #include "gcode/feature/trinamic/M906.h"
  2323. #include "gcode/feature/trinamic/M911.h"
  2324. #include "gcode/feature/trinamic/M912.h"
  2325. #if ENABLED(HYBRID_THRESHOLD)
  2326. #include "gcode/feature/trinamic/M913.h"
  2327. #endif
  2328. #if ENABLED(SENSORLESS_HOMING)
  2329. #include "gcode/feature/trinamic/M914.h"
  2330. #endif
  2331. #endif
  2332. #include "gcode/feature/digipot/M907.h"
  2333. #if HAS_DIGIPOTSS || ENABLED(DAC_STEPPER_CURRENT)
  2334. #include "gcode/feature/digipot/M908.h"
  2335. #if ENABLED(DAC_STEPPER_CURRENT) // As with Printrbot RevF
  2336. #include "gcode/feature/digipot/M909.h"
  2337. #include "gcode/feature/digipot/M910.h"
  2338. #endif
  2339. #endif
  2340. #if HAS_MICROSTEPS
  2341. #include "gcode/control/M350.h"
  2342. #include "gcode/control/M351.h"
  2343. #endif
  2344. #include "gcode/feature/caselight/M355.h"
  2345. #if ENABLED(MIXING_EXTRUDER)
  2346. #include "gcode/feature/mixing/M163.h"
  2347. #if MIXING_VIRTUAL_TOOLS > 1
  2348. #include "gcode/feature/mixing/M164.h"
  2349. #endif
  2350. #if ENABLED(DIRECT_MIXING_IN_G1)
  2351. #include "gcode/feature/mixing/M165.h"
  2352. #endif
  2353. #endif
  2354. #include "gcode/control/M999.h"
  2355. #include "gcode/control/T.h"
  2356. #if ENABLED(AUTO_BED_LEVELING_BILINEAR)
  2357. #if ENABLED(ABL_BILINEAR_SUBDIVISION)
  2358. #define ABL_BG_SPACING(A) bilinear_grid_spacing_virt[A]
  2359. #define ABL_BG_FACTOR(A) bilinear_grid_factor_virt[A]
  2360. #define ABL_BG_POINTS_X ABL_GRID_POINTS_VIRT_X
  2361. #define ABL_BG_POINTS_Y ABL_GRID_POINTS_VIRT_Y
  2362. #define ABL_BG_GRID(X,Y) z_values_virt[X][Y]
  2363. #else
  2364. #define ABL_BG_SPACING(A) bilinear_grid_spacing[A]
  2365. #define ABL_BG_FACTOR(A) bilinear_grid_factor[A]
  2366. #define ABL_BG_POINTS_X GRID_MAX_POINTS_X
  2367. #define ABL_BG_POINTS_Y GRID_MAX_POINTS_Y
  2368. #define ABL_BG_GRID(X,Y) z_values[X][Y]
  2369. #endif
  2370. // Get the Z adjustment for non-linear bed leveling
  2371. float bilinear_z_offset(const float logical[XYZ]) {
  2372. static float z1, d2, z3, d4, L, D, ratio_x, ratio_y,
  2373. last_x = -999.999, last_y = -999.999;
  2374. // Whole units for the grid line indices. Constrained within bounds.
  2375. static int8_t gridx, gridy, nextx, nexty,
  2376. last_gridx = -99, last_gridy = -99;
  2377. // XY relative to the probed area
  2378. const float x = RAW_X_POSITION(logical[X_AXIS]) - bilinear_start[X_AXIS],
  2379. y = RAW_Y_POSITION(logical[Y_AXIS]) - bilinear_start[Y_AXIS];
  2380. #if ENABLED(EXTRAPOLATE_BEYOND_GRID)
  2381. // Keep using the last grid box
  2382. #define FAR_EDGE_OR_BOX 2
  2383. #else
  2384. // Just use the grid far edge
  2385. #define FAR_EDGE_OR_BOX 1
  2386. #endif
  2387. if (last_x != x) {
  2388. last_x = x;
  2389. ratio_x = x * ABL_BG_FACTOR(X_AXIS);
  2390. const float gx = constrain(FLOOR(ratio_x), 0, ABL_BG_POINTS_X - FAR_EDGE_OR_BOX);
  2391. ratio_x -= gx; // Subtract whole to get the ratio within the grid box
  2392. #if DISABLED(EXTRAPOLATE_BEYOND_GRID)
  2393. // Beyond the grid maintain height at grid edges
  2394. NOLESS(ratio_x, 0); // Never < 0.0. (> 1.0 is ok when nextx==gridx.)
  2395. #endif
  2396. gridx = gx;
  2397. nextx = min(gridx + 1, ABL_BG_POINTS_X - 1);
  2398. }
  2399. if (last_y != y || last_gridx != gridx) {
  2400. if (last_y != y) {
  2401. last_y = y;
  2402. ratio_y = y * ABL_BG_FACTOR(Y_AXIS);
  2403. const float gy = constrain(FLOOR(ratio_y), 0, ABL_BG_POINTS_Y - FAR_EDGE_OR_BOX);
  2404. ratio_y -= gy;
  2405. #if DISABLED(EXTRAPOLATE_BEYOND_GRID)
  2406. // Beyond the grid maintain height at grid edges
  2407. NOLESS(ratio_y, 0); // Never < 0.0. (> 1.0 is ok when nexty==gridy.)
  2408. #endif
  2409. gridy = gy;
  2410. nexty = min(gridy + 1, ABL_BG_POINTS_Y - 1);
  2411. }
  2412. if (last_gridx != gridx || last_gridy != gridy) {
  2413. last_gridx = gridx;
  2414. last_gridy = gridy;
  2415. // Z at the box corners
  2416. z1 = ABL_BG_GRID(gridx, gridy); // left-front
  2417. d2 = ABL_BG_GRID(gridx, nexty) - z1; // left-back (delta)
  2418. z3 = ABL_BG_GRID(nextx, gridy); // right-front
  2419. d4 = ABL_BG_GRID(nextx, nexty) - z3; // right-back (delta)
  2420. }
  2421. // Bilinear interpolate. Needed since y or gridx has changed.
  2422. L = z1 + d2 * ratio_y; // Linear interp. LF -> LB
  2423. const float R = z3 + d4 * ratio_y; // Linear interp. RF -> RB
  2424. D = R - L;
  2425. }
  2426. const float offset = L + ratio_x * D; // the offset almost always changes
  2427. /*
  2428. static float last_offset = 0;
  2429. if (FABS(last_offset - offset) > 0.2) {
  2430. SERIAL_ECHOPGM("Sudden Shift at ");
  2431. SERIAL_ECHOPAIR("x=", x);
  2432. SERIAL_ECHOPAIR(" / ", bilinear_grid_spacing[X_AXIS]);
  2433. SERIAL_ECHOLNPAIR(" -> gridx=", gridx);
  2434. SERIAL_ECHOPAIR(" y=", y);
  2435. SERIAL_ECHOPAIR(" / ", bilinear_grid_spacing[Y_AXIS]);
  2436. SERIAL_ECHOLNPAIR(" -> gridy=", gridy);
  2437. SERIAL_ECHOPAIR(" ratio_x=", ratio_x);
  2438. SERIAL_ECHOLNPAIR(" ratio_y=", ratio_y);
  2439. SERIAL_ECHOPAIR(" z1=", z1);
  2440. SERIAL_ECHOPAIR(" z2=", z2);
  2441. SERIAL_ECHOPAIR(" z3=", z3);
  2442. SERIAL_ECHOLNPAIR(" z4=", z4);
  2443. SERIAL_ECHOPAIR(" L=", L);
  2444. SERIAL_ECHOPAIR(" R=", R);
  2445. SERIAL_ECHOLNPAIR(" offset=", offset);
  2446. }
  2447. last_offset = offset;
  2448. //*/
  2449. return offset;
  2450. }
  2451. #endif // AUTO_BED_LEVELING_BILINEAR
  2452. #if ENABLED(DELTA)
  2453. /**
  2454. * Recalculate factors used for delta kinematics whenever
  2455. * settings have been changed (e.g., by M665).
  2456. */
  2457. void recalc_delta_settings(float radius, float diagonal_rod) {
  2458. const float trt[ABC] = DELTA_RADIUS_TRIM_TOWER,
  2459. drt[ABC] = DELTA_DIAGONAL_ROD_TRIM_TOWER;
  2460. delta_tower[A_AXIS][X_AXIS] = cos(RADIANS(210 + delta_tower_angle_trim[A_AXIS])) * (radius + trt[A_AXIS]); // front left tower
  2461. delta_tower[A_AXIS][Y_AXIS] = sin(RADIANS(210 + delta_tower_angle_trim[A_AXIS])) * (radius + trt[A_AXIS]);
  2462. delta_tower[B_AXIS][X_AXIS] = cos(RADIANS(330 + delta_tower_angle_trim[B_AXIS])) * (radius + trt[B_AXIS]); // front right tower
  2463. delta_tower[B_AXIS][Y_AXIS] = sin(RADIANS(330 + delta_tower_angle_trim[B_AXIS])) * (radius + trt[B_AXIS]);
  2464. delta_tower[C_AXIS][X_AXIS] = 0.0; // back middle tower
  2465. delta_tower[C_AXIS][Y_AXIS] = (radius + trt[C_AXIS]);
  2466. delta_diagonal_rod_2_tower[A_AXIS] = sq(diagonal_rod + drt[A_AXIS]);
  2467. delta_diagonal_rod_2_tower[B_AXIS] = sq(diagonal_rod + drt[B_AXIS]);
  2468. delta_diagonal_rod_2_tower[C_AXIS] = sq(diagonal_rod + drt[C_AXIS]);
  2469. }
  2470. #if ENABLED(DELTA_FAST_SQRT) && defined(ARDUINO_ARCH_AVR)
  2471. /**
  2472. * Fast inverse sqrt from Quake III Arena
  2473. * See: https://en.wikipedia.org/wiki/Fast_inverse_square_root
  2474. */
  2475. float Q_rsqrt(float number) {
  2476. long i;
  2477. float x2, y;
  2478. const float threehalfs = 1.5f;
  2479. x2 = number * 0.5f;
  2480. y = number;
  2481. i = * ( long * ) &y; // evil floating point bit level hacking
  2482. i = 0x5F3759DF - ( i >> 1 ); // what the f***?
  2483. y = * ( float * ) &i;
  2484. y = y * ( threehalfs - ( x2 * y * y ) ); // 1st iteration
  2485. // y = y * ( threehalfs - ( x2 * y * y ) ); // 2nd iteration, this can be removed
  2486. return y;
  2487. }
  2488. #define _SQRT(n) (1.0f / Q_rsqrt(n))
  2489. #else
  2490. #define _SQRT(n) SQRT(n)
  2491. #endif
  2492. /**
  2493. * Delta Inverse Kinematics
  2494. *
  2495. * Calculate the tower positions for a given logical
  2496. * position, storing the result in the delta[] array.
  2497. *
  2498. * This is an expensive calculation, requiring 3 square
  2499. * roots per segmented linear move, and strains the limits
  2500. * of a Mega2560 with a Graphical Display.
  2501. *
  2502. * Suggested optimizations include:
  2503. *
  2504. * - Disable the home_offset (M206) and/or position_shift (G92)
  2505. * features to remove up to 12 float additions.
  2506. *
  2507. * - Use a fast-inverse-sqrt function and add the reciprocal.
  2508. * (see above)
  2509. */
  2510. // Macro to obtain the Z position of an individual tower
  2511. #define DELTA_Z(T) raw[Z_AXIS] + _SQRT( \
  2512. delta_diagonal_rod_2_tower[T] - HYPOT2( \
  2513. delta_tower[T][X_AXIS] - raw[X_AXIS], \
  2514. delta_tower[T][Y_AXIS] - raw[Y_AXIS] \
  2515. ) \
  2516. )
  2517. #define DELTA_RAW_IK() do { \
  2518. delta[A_AXIS] = DELTA_Z(A_AXIS); \
  2519. delta[B_AXIS] = DELTA_Z(B_AXIS); \
  2520. delta[C_AXIS] = DELTA_Z(C_AXIS); \
  2521. }while(0)
  2522. #define DELTA_LOGICAL_IK() do { \
  2523. const float raw[XYZ] = { \
  2524. RAW_X_POSITION(logical[X_AXIS]), \
  2525. RAW_Y_POSITION(logical[Y_AXIS]), \
  2526. RAW_Z_POSITION(logical[Z_AXIS]) \
  2527. }; \
  2528. DELTA_RAW_IK(); \
  2529. }while(0)
  2530. #define DELTA_DEBUG() do { \
  2531. SERIAL_ECHOPAIR("cartesian X:", raw[X_AXIS]); \
  2532. SERIAL_ECHOPAIR(" Y:", raw[Y_AXIS]); \
  2533. SERIAL_ECHOLNPAIR(" Z:", raw[Z_AXIS]); \
  2534. SERIAL_ECHOPAIR("delta A:", delta[A_AXIS]); \
  2535. SERIAL_ECHOPAIR(" B:", delta[B_AXIS]); \
  2536. SERIAL_ECHOLNPAIR(" C:", delta[C_AXIS]); \
  2537. }while(0)
  2538. void inverse_kinematics(const float logical[XYZ]) {
  2539. DELTA_LOGICAL_IK();
  2540. // DELTA_DEBUG();
  2541. }
  2542. /**
  2543. * Calculate the highest Z position where the
  2544. * effector has the full range of XY motion.
  2545. */
  2546. float delta_safe_distance_from_top() {
  2547. float cartesian[XYZ] = {
  2548. LOGICAL_X_POSITION(0),
  2549. LOGICAL_Y_POSITION(0),
  2550. LOGICAL_Z_POSITION(0)
  2551. };
  2552. inverse_kinematics(cartesian);
  2553. float distance = delta[A_AXIS];
  2554. cartesian[Y_AXIS] = LOGICAL_Y_POSITION(DELTA_PRINTABLE_RADIUS);
  2555. inverse_kinematics(cartesian);
  2556. return FABS(distance - delta[A_AXIS]);
  2557. }
  2558. /**
  2559. * Delta Forward Kinematics
  2560. *
  2561. * See the Wikipedia article "Trilateration"
  2562. * https://en.wikipedia.org/wiki/Trilateration
  2563. *
  2564. * Establish a new coordinate system in the plane of the
  2565. * three carriage points. This system has its origin at
  2566. * tower1, with tower2 on the X axis. Tower3 is in the X-Y
  2567. * plane with a Z component of zero.
  2568. * We will define unit vectors in this coordinate system
  2569. * in our original coordinate system. Then when we calculate
  2570. * the Xnew, Ynew and Znew values, we can translate back into
  2571. * the original system by moving along those unit vectors
  2572. * by the corresponding values.
  2573. *
  2574. * Variable names matched to Marlin, c-version, and avoid the
  2575. * use of any vector library.
  2576. *
  2577. * by Andreas Hardtung 2016-06-07
  2578. * based on a Java function from "Delta Robot Kinematics V3"
  2579. * by Steve Graves
  2580. *
  2581. * The result is stored in the cartes[] array.
  2582. */
  2583. void forward_kinematics_DELTA(float z1, float z2, float z3) {
  2584. // Create a vector in old coordinates along x axis of new coordinate
  2585. float p12[3] = { delta_tower[B_AXIS][X_AXIS] - delta_tower[A_AXIS][X_AXIS], delta_tower[B_AXIS][Y_AXIS] - delta_tower[A_AXIS][Y_AXIS], z2 - z1 };
  2586. // Get the Magnitude of vector.
  2587. float d = SQRT( sq(p12[0]) + sq(p12[1]) + sq(p12[2]) );
  2588. // Create unit vector by dividing by magnitude.
  2589. float ex[3] = { p12[0] / d, p12[1] / d, p12[2] / d };
  2590. // Get the vector from the origin of the new system to the third point.
  2591. float p13[3] = { delta_tower[C_AXIS][X_AXIS] - delta_tower[A_AXIS][X_AXIS], delta_tower[C_AXIS][Y_AXIS] - delta_tower[A_AXIS][Y_AXIS], z3 - z1 };
  2592. // Use the dot product to find the component of this vector on the X axis.
  2593. float i = ex[0] * p13[0] + ex[1] * p13[1] + ex[2] * p13[2];
  2594. // Create a vector along the x axis that represents the x component of p13.
  2595. float iex[3] = { ex[0] * i, ex[1] * i, ex[2] * i };
  2596. // Subtract the X component from the original vector leaving only Y. We use the
  2597. // variable that will be the unit vector after we scale it.
  2598. float ey[3] = { p13[0] - iex[0], p13[1] - iex[1], p13[2] - iex[2] };
  2599. // The magnitude of Y component
  2600. float j = SQRT( sq(ey[0]) + sq(ey[1]) + sq(ey[2]) );
  2601. // Convert to a unit vector
  2602. ey[0] /= j; ey[1] /= j; ey[2] /= j;
  2603. // The cross product of the unit x and y is the unit z
  2604. // float[] ez = vectorCrossProd(ex, ey);
  2605. float ez[3] = {
  2606. ex[1] * ey[2] - ex[2] * ey[1],
  2607. ex[2] * ey[0] - ex[0] * ey[2],
  2608. ex[0] * ey[1] - ex[1] * ey[0]
  2609. };
  2610. // We now have the d, i and j values defined in Wikipedia.
  2611. // Plug them into the equations defined in Wikipedia for Xnew, Ynew and Znew
  2612. float Xnew = (delta_diagonal_rod_2_tower[A_AXIS] - delta_diagonal_rod_2_tower[B_AXIS] + sq(d)) / (d * 2),
  2613. Ynew = ((delta_diagonal_rod_2_tower[A_AXIS] - delta_diagonal_rod_2_tower[C_AXIS] + HYPOT2(i, j)) / 2 - i * Xnew) / j,
  2614. Znew = SQRT(delta_diagonal_rod_2_tower[A_AXIS] - HYPOT2(Xnew, Ynew));
  2615. // Start from the origin of the old coordinates and add vectors in the
  2616. // old coords that represent the Xnew, Ynew and Znew to find the point
  2617. // in the old system.
  2618. cartes[X_AXIS] = delta_tower[A_AXIS][X_AXIS] + ex[0] * Xnew + ey[0] * Ynew - ez[0] * Znew;
  2619. cartes[Y_AXIS] = delta_tower[A_AXIS][Y_AXIS] + ex[1] * Xnew + ey[1] * Ynew - ez[1] * Znew;
  2620. cartes[Z_AXIS] = z1 + ex[2] * Xnew + ey[2] * Ynew - ez[2] * Znew;
  2621. }
  2622. void forward_kinematics_DELTA(float point[ABC]) {
  2623. forward_kinematics_DELTA(point[A_AXIS], point[B_AXIS], point[C_AXIS]);
  2624. }
  2625. #endif // DELTA
  2626. /**
  2627. * Get the stepper positions in the cartes[] array.
  2628. * Forward kinematics are applied for DELTA and SCARA.
  2629. *
  2630. * The result is in the current coordinate space with
  2631. * leveling applied. The coordinates need to be run through
  2632. * unapply_leveling to obtain the "ideal" coordinates
  2633. * suitable for current_position, etc.
  2634. */
  2635. void get_cartesian_from_steppers() {
  2636. #if ENABLED(DELTA)
  2637. forward_kinematics_DELTA(
  2638. stepper.get_axis_position_mm(A_AXIS),
  2639. stepper.get_axis_position_mm(B_AXIS),
  2640. stepper.get_axis_position_mm(C_AXIS)
  2641. );
  2642. cartes[X_AXIS] += LOGICAL_X_POSITION(0);
  2643. cartes[Y_AXIS] += LOGICAL_Y_POSITION(0);
  2644. cartes[Z_AXIS] += LOGICAL_Z_POSITION(0);
  2645. #elif IS_SCARA
  2646. forward_kinematics_SCARA(
  2647. stepper.get_axis_position_degrees(A_AXIS),
  2648. stepper.get_axis_position_degrees(B_AXIS)
  2649. );
  2650. cartes[X_AXIS] += LOGICAL_X_POSITION(0);
  2651. cartes[Y_AXIS] += LOGICAL_Y_POSITION(0);
  2652. cartes[Z_AXIS] = stepper.get_axis_position_mm(Z_AXIS);
  2653. #else
  2654. cartes[X_AXIS] = stepper.get_axis_position_mm(X_AXIS);
  2655. cartes[Y_AXIS] = stepper.get_axis_position_mm(Y_AXIS);
  2656. cartes[Z_AXIS] = stepper.get_axis_position_mm(Z_AXIS);
  2657. #endif
  2658. }
  2659. /**
  2660. * Set the current_position for an axis based on
  2661. * the stepper positions, removing any leveling that
  2662. * may have been applied.
  2663. */
  2664. void set_current_from_steppers_for_axis(const AxisEnum axis) {
  2665. get_cartesian_from_steppers();
  2666. #if PLANNER_LEVELING
  2667. planner.unapply_leveling(cartes);
  2668. #endif
  2669. if (axis == ALL_AXES)
  2670. COPY(current_position, cartes);
  2671. else
  2672. current_position[axis] = cartes[axis];
  2673. }
  2674. #if ENABLED(USE_CONTROLLER_FAN)
  2675. void controllerFan() {
  2676. static millis_t lastMotorOn = 0, // Last time a motor was turned on
  2677. nextMotorCheck = 0; // Last time the state was checked
  2678. const millis_t ms = millis();
  2679. if (ELAPSED(ms, nextMotorCheck)) {
  2680. nextMotorCheck = ms + 2500UL; // Not a time critical function, so only check every 2.5s
  2681. if (X_ENABLE_READ == X_ENABLE_ON || Y_ENABLE_READ == Y_ENABLE_ON || Z_ENABLE_READ == Z_ENABLE_ON || thermalManager.soft_pwm_amount_bed > 0
  2682. || E0_ENABLE_READ == E_ENABLE_ON // If any of the drivers are enabled...
  2683. #if E_STEPPERS > 1
  2684. || E1_ENABLE_READ == E_ENABLE_ON
  2685. #if HAS_X2_ENABLE
  2686. || X2_ENABLE_READ == X_ENABLE_ON
  2687. #endif
  2688. #if E_STEPPERS > 2
  2689. || E2_ENABLE_READ == E_ENABLE_ON
  2690. #if E_STEPPERS > 3
  2691. || E3_ENABLE_READ == E_ENABLE_ON
  2692. #if E_STEPPERS > 4
  2693. || E4_ENABLE_READ == E_ENABLE_ON
  2694. #endif // E_STEPPERS > 4
  2695. #endif // E_STEPPERS > 3
  2696. #endif // E_STEPPERS > 2
  2697. #endif // E_STEPPERS > 1
  2698. ) {
  2699. lastMotorOn = ms; //... set time to NOW so the fan will turn on
  2700. }
  2701. // Fan off if no steppers have been enabled for CONTROLLERFAN_SECS seconds
  2702. uint8_t speed = (!lastMotorOn || ELAPSED(ms, lastMotorOn + (CONTROLLERFAN_SECS) * 1000UL)) ? 0 : CONTROLLERFAN_SPEED;
  2703. // allows digital or PWM fan output to be used (see M42 handling)
  2704. WRITE(CONTROLLER_FAN_PIN, speed);
  2705. analogWrite(CONTROLLER_FAN_PIN, speed);
  2706. }
  2707. }
  2708. #endif // USE_CONTROLLER_FAN
  2709. #if ENABLED(MORGAN_SCARA)
  2710. /**
  2711. * Morgan SCARA Forward Kinematics. Results in cartes[].
  2712. * Maths and first version by QHARLEY.
  2713. * Integrated into Marlin and slightly restructured by Joachim Cerny.
  2714. */
  2715. void forward_kinematics_SCARA(const float &a, const float &b) {
  2716. float a_sin = sin(RADIANS(a)) * L1,
  2717. a_cos = cos(RADIANS(a)) * L1,
  2718. b_sin = sin(RADIANS(b)) * L2,
  2719. b_cos = cos(RADIANS(b)) * L2;
  2720. cartes[X_AXIS] = a_cos + b_cos + SCARA_OFFSET_X; //theta
  2721. cartes[Y_AXIS] = a_sin + b_sin + SCARA_OFFSET_Y; //theta+phi
  2722. /*
  2723. SERIAL_ECHOPAIR("SCARA FK Angle a=", a);
  2724. SERIAL_ECHOPAIR(" b=", b);
  2725. SERIAL_ECHOPAIR(" a_sin=", a_sin);
  2726. SERIAL_ECHOPAIR(" a_cos=", a_cos);
  2727. SERIAL_ECHOPAIR(" b_sin=", b_sin);
  2728. SERIAL_ECHOLNPAIR(" b_cos=", b_cos);
  2729. SERIAL_ECHOPAIR(" cartes[X_AXIS]=", cartes[X_AXIS]);
  2730. SERIAL_ECHOLNPAIR(" cartes[Y_AXIS]=", cartes[Y_AXIS]);
  2731. //*/
  2732. }
  2733. /**
  2734. * Morgan SCARA Inverse Kinematics. Results in delta[].
  2735. *
  2736. * See http://forums.reprap.org/read.php?185,283327
  2737. *
  2738. * Maths and first version by QHARLEY.
  2739. * Integrated into Marlin and slightly restructured by Joachim Cerny.
  2740. */
  2741. void inverse_kinematics(const float logical[XYZ]) {
  2742. static float C2, S2, SK1, SK2, THETA, PSI;
  2743. float sx = RAW_X_POSITION(logical[X_AXIS]) - SCARA_OFFSET_X, // Translate SCARA to standard X Y
  2744. sy = RAW_Y_POSITION(logical[Y_AXIS]) - SCARA_OFFSET_Y; // With scaling factor.
  2745. if (L1 == L2)
  2746. C2 = HYPOT2(sx, sy) / L1_2_2 - 1;
  2747. else
  2748. C2 = (HYPOT2(sx, sy) - (L1_2 + L2_2)) / (2.0 * L1 * L2);
  2749. S2 = SQRT(1 - sq(C2));
  2750. // Unrotated Arm1 plus rotated Arm2 gives the distance from Center to End
  2751. SK1 = L1 + L2 * C2;
  2752. // Rotated Arm2 gives the distance from Arm1 to Arm2
  2753. SK2 = L2 * S2;
  2754. // Angle of Arm1 is the difference between Center-to-End angle and the Center-to-Elbow
  2755. THETA = ATAN2(SK1, SK2) - ATAN2(sx, sy);
  2756. // Angle of Arm2
  2757. PSI = ATAN2(S2, C2);
  2758. delta[A_AXIS] = DEGREES(THETA); // theta is support arm angle
  2759. delta[B_AXIS] = DEGREES(THETA + PSI); // equal to sub arm angle (inverted motor)
  2760. delta[C_AXIS] = logical[Z_AXIS];
  2761. /*
  2762. DEBUG_POS("SCARA IK", logical);
  2763. DEBUG_POS("SCARA IK", delta);
  2764. SERIAL_ECHOPAIR(" SCARA (x,y) ", sx);
  2765. SERIAL_ECHOPAIR(",", sy);
  2766. SERIAL_ECHOPAIR(" C2=", C2);
  2767. SERIAL_ECHOPAIR(" S2=", S2);
  2768. SERIAL_ECHOPAIR(" Theta=", THETA);
  2769. SERIAL_ECHOLNPAIR(" Phi=", PHI);
  2770. //*/
  2771. }
  2772. #endif // MORGAN_SCARA
  2773. #if ENABLED(TEMP_STAT_LEDS)
  2774. static bool red_led = false;
  2775. static millis_t next_status_led_update_ms = 0;
  2776. void handle_status_leds(void) {
  2777. if (ELAPSED(millis(), next_status_led_update_ms)) {
  2778. next_status_led_update_ms += 500; // Update every 0.5s
  2779. float max_temp = 0.0;
  2780. #if HAS_TEMP_BED
  2781. max_temp = MAX3(max_temp, thermalManager.degTargetBed(), thermalManager.degBed());
  2782. #endif
  2783. HOTEND_LOOP()
  2784. max_temp = MAX3(max_temp, thermalManager.degHotend(e), thermalManager.degTargetHotend(e));
  2785. const bool new_led = (max_temp > 55.0) ? true : (max_temp < 54.0) ? false : red_led;
  2786. if (new_led != red_led) {
  2787. red_led = new_led;
  2788. #if PIN_EXISTS(STAT_LED_RED)
  2789. WRITE(STAT_LED_RED_PIN, new_led ? HIGH : LOW);
  2790. #if PIN_EXISTS(STAT_LED_BLUE)
  2791. WRITE(STAT_LED_BLUE_PIN, new_led ? LOW : HIGH);
  2792. #endif
  2793. #else
  2794. WRITE(STAT_LED_BLUE_PIN, new_led ? HIGH : LOW);
  2795. #endif
  2796. }
  2797. }
  2798. }
  2799. #endif
  2800. #if ENABLED(FILAMENT_RUNOUT_SENSOR)
  2801. void handle_filament_runout() {
  2802. if (!filament_ran_out) {
  2803. filament_ran_out = true;
  2804. enqueue_and_echo_commands_P(PSTR(FILAMENT_RUNOUT_SCRIPT));
  2805. stepper.synchronize();
  2806. }
  2807. }
  2808. #endif // FILAMENT_RUNOUT_SENSOR
  2809. float calculate_volumetric_multiplier(const float diameter) {
  2810. if (!volumetric_enabled || diameter == 0) return 1.0;
  2811. return 1.0 / (M_PI * sq(diameter * 0.5));
  2812. }
  2813. void calculate_volumetric_multipliers() {
  2814. for (uint8_t i = 0; i < COUNT(filament_size); i++)
  2815. volumetric_multiplier[i] = calculate_volumetric_multiplier(filament_size[i]);
  2816. }
  2817. void enable_all_steppers() {
  2818. enable_X();
  2819. enable_Y();
  2820. enable_Z();
  2821. enable_E0();
  2822. enable_E1();
  2823. enable_E2();
  2824. enable_E3();
  2825. enable_E4();
  2826. }
  2827. void disable_e_steppers() {
  2828. disable_E0();
  2829. disable_E1();
  2830. disable_E2();
  2831. disable_E3();
  2832. disable_E4();
  2833. }
  2834. void disable_all_steppers() {
  2835. disable_X();
  2836. disable_Y();
  2837. disable_Z();
  2838. disable_e_steppers();
  2839. }
  2840. /**
  2841. * Manage several activities:
  2842. * - Check for Filament Runout
  2843. * - Keep the command buffer full
  2844. * - Check for maximum inactive time between commands
  2845. * - Check for maximum inactive time between stepper commands
  2846. * - Check if pin CHDK needs to go LOW
  2847. * - Check for KILL button held down
  2848. * - Check for HOME button held down
  2849. * - Check if cooling fan needs to be switched on
  2850. * - Check if an idle but hot extruder needs filament extruded (EXTRUDER_RUNOUT_PREVENT)
  2851. */
  2852. void manage_inactivity(bool ignore_stepper_queue/*=false*/) {
  2853. #if ENABLED(FILAMENT_RUNOUT_SENSOR)
  2854. if ((IS_SD_PRINTING || print_job_timer.isRunning()) && (READ(FIL_RUNOUT_PIN) == FIL_RUNOUT_INVERTING))
  2855. handle_filament_runout();
  2856. #endif
  2857. if (commands_in_queue < BUFSIZE) get_available_commands();
  2858. const millis_t ms = millis();
  2859. if (max_inactive_time && ELAPSED(ms, previous_cmd_ms + max_inactive_time)) {
  2860. SERIAL_ERROR_START();
  2861. SERIAL_ECHOLNPAIR(MSG_KILL_INACTIVE_TIME, parser.command_ptr);
  2862. kill(PSTR(MSG_KILLED));
  2863. }
  2864. // Prevent steppers timing-out in the middle of M600
  2865. #if ENABLED(ADVANCED_PAUSE_FEATURE) && ENABLED(PAUSE_PARK_NO_STEPPER_TIMEOUT)
  2866. #define MOVE_AWAY_TEST !move_away_flag
  2867. #else
  2868. #define MOVE_AWAY_TEST true
  2869. #endif
  2870. if (MOVE_AWAY_TEST && stepper_inactive_time && ELAPSED(ms, previous_cmd_ms + stepper_inactive_time)
  2871. && !ignore_stepper_queue && !planner.blocks_queued()) {
  2872. #if ENABLED(DISABLE_INACTIVE_X)
  2873. disable_X();
  2874. #endif
  2875. #if ENABLED(DISABLE_INACTIVE_Y)
  2876. disable_Y();
  2877. #endif
  2878. #if ENABLED(DISABLE_INACTIVE_Z)
  2879. disable_Z();
  2880. #endif
  2881. #if ENABLED(DISABLE_INACTIVE_E)
  2882. disable_e_steppers();
  2883. #endif
  2884. #if ENABLED(AUTO_BED_LEVELING_UBL) && ENABLED(ULTRA_LCD) // Only needed with an LCD
  2885. ubl_lcd_map_control = defer_return_to_status = false;
  2886. #endif
  2887. }
  2888. #ifdef CHDK // Check if pin should be set to LOW after M240 set it to HIGH
  2889. if (chdkActive && ELAPSED(ms, chdkHigh + CHDK_DELAY)) {
  2890. chdkActive = false;
  2891. WRITE(CHDK, LOW);
  2892. }
  2893. #endif
  2894. #if HAS_KILL
  2895. // Check if the kill button was pressed and wait just in case it was an accidental
  2896. // key kill key press
  2897. // -------------------------------------------------------------------------------
  2898. static int killCount = 0; // make the inactivity button a bit less responsive
  2899. const int KILL_DELAY = 750;
  2900. if (!READ(KILL_PIN))
  2901. killCount++;
  2902. else if (killCount > 0)
  2903. killCount--;
  2904. // Exceeded threshold and we can confirm that it was not accidental
  2905. // KILL the machine
  2906. // ----------------------------------------------------------------
  2907. if (killCount >= KILL_DELAY) {
  2908. SERIAL_ERROR_START();
  2909. SERIAL_ERRORLNPGM(MSG_KILL_BUTTON);
  2910. kill(PSTR(MSG_KILLED));
  2911. }
  2912. #endif
  2913. #if HAS_HOME
  2914. // Check to see if we have to home, use poor man's debouncer
  2915. // ---------------------------------------------------------
  2916. static int homeDebounceCount = 0; // poor man's debouncing count
  2917. const int HOME_DEBOUNCE_DELAY = 2500;
  2918. if (!IS_SD_PRINTING && !READ(HOME_PIN)) {
  2919. if (!homeDebounceCount) {
  2920. enqueue_and_echo_commands_P(PSTR("G28"));
  2921. LCD_MESSAGEPGM(MSG_AUTO_HOME);
  2922. }
  2923. if (homeDebounceCount < HOME_DEBOUNCE_DELAY)
  2924. homeDebounceCount++;
  2925. else
  2926. homeDebounceCount = 0;
  2927. }
  2928. #endif
  2929. #if ENABLED(USE_CONTROLLER_FAN)
  2930. controllerFan(); // Check if fan should be turned on to cool stepper drivers down
  2931. #endif
  2932. #if ENABLED(EXTRUDER_RUNOUT_PREVENT)
  2933. if (ELAPSED(ms, previous_cmd_ms + (EXTRUDER_RUNOUT_SECONDS) * 1000UL)
  2934. && thermalManager.degHotend(active_extruder) > EXTRUDER_RUNOUT_MINTEMP) {
  2935. #if ENABLED(SWITCHING_EXTRUDER)
  2936. const bool oldstatus = E0_ENABLE_READ;
  2937. enable_E0();
  2938. #else // !SWITCHING_EXTRUDER
  2939. bool oldstatus;
  2940. switch (active_extruder) {
  2941. default: oldstatus = E0_ENABLE_READ; enable_E0(); break;
  2942. #if E_STEPPERS > 1
  2943. case 1: oldstatus = E1_ENABLE_READ; enable_E1(); break;
  2944. #if E_STEPPERS > 2
  2945. case 2: oldstatus = E2_ENABLE_READ; enable_E2(); break;
  2946. #if E_STEPPERS > 3
  2947. case 3: oldstatus = E3_ENABLE_READ; enable_E3(); break;
  2948. #if E_STEPPERS > 4
  2949. case 4: oldstatus = E4_ENABLE_READ; enable_E4(); break;
  2950. #endif // E_STEPPERS > 4
  2951. #endif // E_STEPPERS > 3
  2952. #endif // E_STEPPERS > 2
  2953. #endif // E_STEPPERS > 1
  2954. }
  2955. #endif // !SWITCHING_EXTRUDER
  2956. gcode.refresh_cmd_timeout()
  2957. const float olde = current_position[E_AXIS];
  2958. current_position[E_AXIS] += EXTRUDER_RUNOUT_EXTRUDE;
  2959. planner.buffer_line_kinematic(current_position, MMM_TO_MMS(EXTRUDER_RUNOUT_SPEED), active_extruder);
  2960. current_position[E_AXIS] = olde;
  2961. planner.set_e_position_mm(olde);
  2962. stepper.synchronize();
  2963. #if ENABLED(SWITCHING_EXTRUDER)
  2964. E0_ENABLE_WRITE(oldstatus);
  2965. #else
  2966. switch (active_extruder) {
  2967. case 0: E0_ENABLE_WRITE(oldstatus); break;
  2968. #if E_STEPPERS > 1
  2969. case 1: E1_ENABLE_WRITE(oldstatus); break;
  2970. #if E_STEPPERS > 2
  2971. case 2: E2_ENABLE_WRITE(oldstatus); break;
  2972. #if E_STEPPERS > 3
  2973. case 3: E3_ENABLE_WRITE(oldstatus); break;
  2974. #if E_STEPPERS > 4
  2975. case 4: E4_ENABLE_WRITE(oldstatus); break;
  2976. #endif // E_STEPPERS > 4
  2977. #endif // E_STEPPERS > 3
  2978. #endif // E_STEPPERS > 2
  2979. #endif // E_STEPPERS > 1
  2980. }
  2981. #endif // !SWITCHING_EXTRUDER
  2982. }
  2983. #endif // EXTRUDER_RUNOUT_PREVENT
  2984. #if ENABLED(DUAL_X_CARRIAGE)
  2985. // handle delayed move timeout
  2986. if (delayed_move_time && ELAPSED(ms, delayed_move_time + 1000UL) && IsRunning()) {
  2987. // travel moves have been received so enact them
  2988. delayed_move_time = 0xFFFFFFFFUL; // force moves to be done
  2989. set_destination_to_current();
  2990. prepare_move_to_destination();
  2991. }
  2992. #endif
  2993. #if ENABLED(TEMP_STAT_LEDS)
  2994. handle_status_leds();
  2995. #endif
  2996. #if ENABLED(HAVE_TMC2130)
  2997. tmc2130_checkOverTemp();
  2998. #endif
  2999. planner.check_axes_activity();
  3000. }
  3001. /**
  3002. * Standard idle routine keeps the machine alive
  3003. */
  3004. void idle(
  3005. #if ENABLED(ADVANCED_PAUSE_FEATURE)
  3006. bool no_stepper_sleep/*=false*/
  3007. #endif
  3008. ) {
  3009. #if ENABLED(MAX7219_DEBUG)
  3010. Max7219_idle_tasks();
  3011. #endif // MAX7219_DEBUG
  3012. lcd_update();
  3013. host_keepalive();
  3014. #if ENABLED(AUTO_REPORT_TEMPERATURES) && (HAS_TEMP_HOTEND || HAS_TEMP_BED)
  3015. auto_report_temperatures();
  3016. #endif
  3017. manage_inactivity(
  3018. #if ENABLED(ADVANCED_PAUSE_FEATURE)
  3019. no_stepper_sleep
  3020. #endif
  3021. );
  3022. thermalManager.manage_heater();
  3023. #if ENABLED(PRINTCOUNTER)
  3024. print_job_timer.tick();
  3025. #endif
  3026. #if HAS_BUZZER && DISABLED(LCD_USE_I2C_BUZZER)
  3027. buzzer.tick();
  3028. #endif
  3029. #if ENABLED(I2C_POSITION_ENCODERS)
  3030. if (planner.blocks_queued() &&
  3031. ( (blockBufferIndexRef != planner.block_buffer_head) ||
  3032. ((lastUpdateMillis + I2CPE_MIN_UPD_TIME_MS) < millis())) ) {
  3033. blockBufferIndexRef = planner.block_buffer_head;
  3034. I2CPEM.update();
  3035. lastUpdateMillis = millis();
  3036. }
  3037. #endif
  3038. }
  3039. /**
  3040. * Kill all activity and lock the machine.
  3041. * After this the machine will need to be reset.
  3042. */
  3043. void kill(const char* lcd_msg) {
  3044. SERIAL_ERROR_START();
  3045. SERIAL_ERRORLNPGM(MSG_ERR_KILLED);
  3046. thermalManager.disable_all_heaters();
  3047. disable_all_steppers();
  3048. #if ENABLED(ULTRA_LCD)
  3049. kill_screen(lcd_msg);
  3050. #else
  3051. UNUSED(lcd_msg);
  3052. #endif
  3053. _delay_ms(600); // Wait a short time (allows messages to get out before shutting down.
  3054. cli(); // Stop interrupts
  3055. _delay_ms(250); //Wait to ensure all interrupts routines stopped
  3056. thermalManager.disable_all_heaters(); //turn off heaters again
  3057. #ifdef ACTION_ON_KILL
  3058. SERIAL_ECHOLNPGM("//action:" ACTION_ON_KILL);
  3059. #endif
  3060. #if HAS_POWER_SWITCH
  3061. SET_INPUT(PS_ON_PIN);
  3062. #endif
  3063. suicide();
  3064. while (1) {
  3065. #if ENABLED(USE_WATCHDOG)
  3066. watchdog_reset();
  3067. #endif
  3068. } // Wait for reset
  3069. }
  3070. /**
  3071. * Turn off heaters and stop the print in progress
  3072. * After a stop the machine may be resumed with M999
  3073. */
  3074. void stop() {
  3075. thermalManager.disable_all_heaters(); // 'unpause' taken care of in here
  3076. #if ENABLED(PROBING_FANS_OFF)
  3077. if (fans_paused) fans_pause(false); // put things back the way they were
  3078. #endif
  3079. if (IsRunning()) {
  3080. Stopped_gcode_LastN = gcode_LastN; // Save last g_code for restart
  3081. SERIAL_ERROR_START();
  3082. SERIAL_ERRORLNPGM(MSG_ERR_STOPPED);
  3083. LCD_MESSAGEPGM(MSG_STOPPED);
  3084. safe_delay(350); // allow enough time for messages to get out before stopping
  3085. Running = false;
  3086. }
  3087. }
  3088. /**
  3089. * Marlin entry-point: Set up before the program loop
  3090. * - Set up the kill pin, filament runout, power hold
  3091. * - Start the serial port
  3092. * - Print startup messages and diagnostics
  3093. * - Get EEPROM or default settings
  3094. * - Initialize managers for:
  3095. * • temperature
  3096. * • planner
  3097. * • watchdog
  3098. * • stepper
  3099. * • photo pin
  3100. * • servos
  3101. * • LCD controller
  3102. * • Digipot I2C
  3103. * • Z probe sled
  3104. * • status LEDs
  3105. */
  3106. void setup() {
  3107. #if ENABLED(MAX7219_DEBUG)
  3108. Max7219_init();
  3109. #endif
  3110. #ifdef DISABLE_JTAG
  3111. // Disable JTAG on AT90USB chips to free up pins for IO
  3112. MCUCR = 0x80;
  3113. MCUCR = 0x80;
  3114. #endif
  3115. #if ENABLED(FILAMENT_RUNOUT_SENSOR)
  3116. setup_filrunoutpin();
  3117. #endif
  3118. setup_killpin();
  3119. setup_powerhold();
  3120. #if HAS_STEPPER_RESET
  3121. disableStepperDrivers();
  3122. #endif
  3123. MYSERIAL.begin(BAUDRATE);
  3124. while(!MYSERIAL);
  3125. SERIAL_PROTOCOLLNPGM("start");
  3126. SERIAL_ECHO_START();
  3127. // Check startup - does nothing if bootloader sets MCUSR to 0
  3128. byte mcu = HAL_get_reset_source();
  3129. if (mcu & 1) SERIAL_ECHOLNPGM(MSG_POWERUP);
  3130. if (mcu & 2) SERIAL_ECHOLNPGM(MSG_EXTERNAL_RESET);
  3131. if (mcu & 4) SERIAL_ECHOLNPGM(MSG_BROWNOUT_RESET);
  3132. if (mcu & 8) SERIAL_ECHOLNPGM(MSG_WATCHDOG_RESET);
  3133. if (mcu & 32) SERIAL_ECHOLNPGM(MSG_SOFTWARE_RESET);
  3134. HAL_clear_reset_source();
  3135. #if ENABLED(USE_WATCHDOG) //reinit watchdog after HAL_get_reset_source call
  3136. watchdog_init();
  3137. #endif
  3138. SERIAL_ECHOPGM(MSG_MARLIN);
  3139. SERIAL_CHAR(' ');
  3140. SERIAL_ECHOLNPGM(SHORT_BUILD_VERSION);
  3141. SERIAL_EOL();
  3142. #if defined(STRING_DISTRIBUTION_DATE) && defined(STRING_CONFIG_H_AUTHOR)
  3143. SERIAL_ECHO_START();
  3144. SERIAL_ECHOPGM(MSG_CONFIGURATION_VER);
  3145. SERIAL_ECHOPGM(STRING_DISTRIBUTION_DATE);
  3146. SERIAL_ECHOLNPGM(MSG_AUTHOR STRING_CONFIG_H_AUTHOR);
  3147. SERIAL_ECHO_START();
  3148. SERIAL_ECHOLNPGM("Compiled: " __DATE__);
  3149. #endif
  3150. SERIAL_ECHO_START();
  3151. SERIAL_ECHOPAIR(MSG_FREE_MEMORY, freeMemory());
  3152. SERIAL_ECHOLNPAIR(MSG_PLANNER_BUFFER_BYTES, (int)sizeof(block_t)*BLOCK_BUFFER_SIZE);
  3153. queue_setup();
  3154. // Load data from EEPROM if available (or use defaults)
  3155. // This also updates variables in the planner, elsewhere
  3156. (void)settings.load();
  3157. #if HAS_M206_COMMAND
  3158. // Initialize current position based on home_offset
  3159. COPY(current_position, home_offset);
  3160. #else
  3161. ZERO(current_position);
  3162. #endif
  3163. // Vital to init stepper/planner equivalent for current_position
  3164. SYNC_PLAN_POSITION_KINEMATIC();
  3165. thermalManager.init(); // Initialize temperature loop
  3166. stepper.init(); // Initialize stepper, this enables interrupts!
  3167. servo_init();
  3168. #if HAS_PHOTOGRAPH
  3169. OUT_WRITE(PHOTOGRAPH_PIN, LOW);
  3170. #endif
  3171. #if HAS_CASE_LIGHT
  3172. case_light_on = CASE_LIGHT_DEFAULT_ON;
  3173. case_light_brightness = CASE_LIGHT_DEFAULT_BRIGHTNESS;
  3174. update_case_light();
  3175. #endif
  3176. #if ENABLED(SPINDLE_LASER_ENABLE)
  3177. OUT_WRITE(SPINDLE_LASER_ENABLE_PIN, !SPINDLE_LASER_ENABLE_INVERT); // init spindle to off
  3178. #if SPINDLE_DIR_CHANGE
  3179. OUT_WRITE(SPINDLE_DIR_PIN, SPINDLE_INVERT_DIR ? 255 : 0); // init rotation to clockwise (M3)
  3180. #endif
  3181. #if ENABLED(SPINDLE_LASER_PWM) && defined(SPINDLE_LASER_PWM_PIN) && SPINDLE_LASER_PWM_PIN >= 0
  3182. SET_OUTPUT(SPINDLE_LASER_PWM_PIN);
  3183. analogWrite(SPINDLE_LASER_PWM_PIN, SPINDLE_LASER_PWM_INVERT ? 255 : 0); // set to lowest speed
  3184. #endif
  3185. #endif
  3186. #if HAS_BED_PROBE
  3187. endstops.enable_z_probe(false);
  3188. #endif
  3189. #if ENABLED(USE_CONTROLLER_FAN)
  3190. SET_OUTPUT(CONTROLLER_FAN_PIN); //Set pin used for driver cooling fan
  3191. #endif
  3192. #if HAS_STEPPER_RESET
  3193. enableStepperDrivers();
  3194. #endif
  3195. #if ENABLED(DIGIPOT_I2C)
  3196. digipot_i2c_init();
  3197. #endif
  3198. #if ENABLED(DAC_STEPPER_CURRENT)
  3199. dac_init();
  3200. #endif
  3201. #if (ENABLED(Z_PROBE_SLED) || ENABLED(SOLENOID_PROBE)) && HAS_SOLENOID_1
  3202. OUT_WRITE(SOL1_PIN, LOW); // turn it off
  3203. #endif
  3204. #if HAS_HOME
  3205. SET_INPUT_PULLUP(HOME_PIN);
  3206. #endif
  3207. #if PIN_EXISTS(STAT_LED_RED)
  3208. OUT_WRITE(STAT_LED_RED_PIN, LOW); // turn it off
  3209. #endif
  3210. #if PIN_EXISTS(STAT_LED_BLUE)
  3211. OUT_WRITE(STAT_LED_BLUE_PIN, LOW); // turn it off
  3212. #endif
  3213. #if ENABLED(NEOPIXEL_RGBW_LED)
  3214. SET_OUTPUT(NEOPIXEL_PIN);
  3215. setup_neopixel();
  3216. #endif
  3217. #if ENABLED(RGB_LED) || ENABLED(RGBW_LED)
  3218. SET_OUTPUT(RGB_LED_R_PIN);
  3219. SET_OUTPUT(RGB_LED_G_PIN);
  3220. SET_OUTPUT(RGB_LED_B_PIN);
  3221. #if ENABLED(RGBW_LED)
  3222. SET_OUTPUT(RGB_LED_W_PIN);
  3223. #endif
  3224. #endif
  3225. #if ENABLED(MK2_MULTIPLEXER)
  3226. SET_OUTPUT(E_MUX0_PIN);
  3227. SET_OUTPUT(E_MUX1_PIN);
  3228. SET_OUTPUT(E_MUX2_PIN);
  3229. #endif
  3230. #if HAS_FANMUX
  3231. fanmux_init();
  3232. #endif
  3233. lcd_init();
  3234. #ifndef CUSTOM_BOOTSCREEN_TIMEOUT
  3235. #define CUSTOM_BOOTSCREEN_TIMEOUT 2500
  3236. #endif
  3237. #if ENABLED(SHOW_BOOTSCREEN)
  3238. #if ENABLED(DOGLCD) // On DOGM the first bootscreen is already drawn
  3239. #if ENABLED(SHOW_CUSTOM_BOOTSCREEN)
  3240. safe_delay(CUSTOM_BOOTSCREEN_TIMEOUT); // Custom boot screen pause
  3241. lcd_bootscreen(); // Show Marlin boot screen
  3242. #endif
  3243. safe_delay(BOOTSCREEN_TIMEOUT); // Pause
  3244. #elif ENABLED(ULTRA_LCD)
  3245. lcd_bootscreen();
  3246. #if DISABLED(SDSUPPORT)
  3247. lcd_init();
  3248. #endif
  3249. #endif
  3250. #endif
  3251. #if ENABLED(MIXING_EXTRUDER) && MIXING_VIRTUAL_TOOLS > 1
  3252. // Initialize mixing to 100% color 1
  3253. for (uint8_t i = 0; i < MIXING_STEPPERS; i++)
  3254. mixing_factor[i] = (i == 0) ? 1.0 : 0.0;
  3255. for (uint8_t t = 0; t < MIXING_VIRTUAL_TOOLS; t++)
  3256. for (uint8_t i = 0; i < MIXING_STEPPERS; i++)
  3257. mixing_virtual_tool_mix[t][i] = mixing_factor[i];
  3258. #endif
  3259. #if ENABLED(BLTOUCH)
  3260. // Make sure any BLTouch error condition is cleared
  3261. bltouch_command(BLTOUCH_RESET);
  3262. set_bltouch_deployed(true);
  3263. set_bltouch_deployed(false);
  3264. #endif
  3265. #if ENABLED(I2C_POSITION_ENCODERS)
  3266. I2CPEM.init();
  3267. #endif
  3268. #if ENABLED(EXPERIMENTAL_I2CBUS) && I2C_SLAVE_ADDRESS > 0
  3269. i2c.onReceive(i2c_on_receive);
  3270. i2c.onRequest(i2c_on_request);
  3271. #endif
  3272. #if ENABLED(ENDSTOP_INTERRUPTS_FEATURE)
  3273. setup_endstop_interrupts();
  3274. #endif
  3275. #if ENABLED(SWITCHING_EXTRUDER) && !DONT_SWITCH
  3276. move_extruder_servo(0); // Initialize extruder servo
  3277. #endif
  3278. #if ENABLED(SWITCHING_NOZZLE)
  3279. move_nozzle_servo(0); // Initialize nozzle servo
  3280. #endif
  3281. #if ENABLED(PARKING_EXTRUDER)
  3282. #if ENABLED(PARKING_EXTRUDER_SOLENOIDS_INVERT)
  3283. pe_activate_magnet(0);
  3284. pe_activate_magnet(1);
  3285. #else
  3286. pe_deactivate_magnet(0);
  3287. pe_deactivate_magnet(1);
  3288. #endif
  3289. #endif
  3290. }
  3291. /**
  3292. * The main Marlin program loop
  3293. *
  3294. * - Save or log commands to SD
  3295. * - Process available commands (if not saving)
  3296. * - Call heater manager
  3297. * - Call inactivity manager
  3298. * - Call endstop manager
  3299. * - Call LCD update
  3300. */
  3301. void loop() {
  3302. if (commands_in_queue < BUFSIZE) get_available_commands();
  3303. #if ENABLED(SDSUPPORT)
  3304. card.checkautostart(false);
  3305. #endif
  3306. advance_command_queue();
  3307. endstops.report_state();
  3308. idle();
  3309. }