Hi all,
I just configured auto bed leveling in Marlin, but when uploading to the board, the following error was received:
Sketch uses 66,392 bytes (102%) of program storage space. Maximum is 64,512 bytes.
Is there something to be done that could reduce 2k of Marlin binary?
Specs:
Tks in adv.
Hi
I looked through your config and sadly from what i know it cant be any smaller.
The real limit here is the 644p chip
btw.. did you fork the RCbugfix branch or RC7? you should go for the first one
Hi boelle,
Is it feasible to disable PID controller?
Tks for the attention and fast response.
If you can live with 3-Point leveling, you should be able to fit into the 64Kb foot print. Just leave the Auto Bed Leveling turned on, but turn off the Grid Based Leveling. That will keep the QR-Solve library from being pulled in and will save over 10Kb.
I have the code to do an iterative grid solution that produces the exact same results as QR-Solve but I haven't integrated it yet. It takes 15 seconds to converge on the answer, but it saves over 10 Kb of code size. The code is fully debugged and works correctly under all test conditions.
Maybe @thinkyhead would be willing to think about the right way to allow a user to turn off the inclusion of qr_solve and to get this code to compile in. If there was a way to get this into RC-7 (without qr_solve being included) you would be able to do Grid Based Leveling.
The Code
// This code is an alternate implementation of the Least Squares Best Fit algorythm that
// is used to calculate the plane the print bed lies in. It is an optional replacement for the
// more proven and much larger QR_SOLVE code base that is being used in the Marlin Code base.
//
// Using this code as a solution for the Least Squares Best fit by the Auto Bed Leveling code
// will save you almost exactly 10 Kb of firmware space. It will cost you several seconds of
// time after all the points are sampled as it iteratively converges on a Least Squares Error
// solution for the plane.
//
// This code was donated by Roxy-3D!
#include "configuration.h"
#include "Iterative_LSF.h"
double coefficients[3]; // We need a place to return the coefficients we found.
// This is where we do that!
//double * iterative_LSF(int abl2, int n, double *eqnA, double *eqnB)
double *qr_solve(int abl2, int n, double *eqnA, double *eqnB)
{
double a= 0.0, b= 0.0, c=1.0, d=Z_PROBE_OFFSET_FROM_EXTRUDER; // Start with some reasonable values for our coefficients
double current, plus_next, minus_next, delta_size=.1;
int flag, dflag, dir=1;
int cnt=0;
do {
idle(); // or we risk the system thinking we are locked up!
cnt++; // How many times we have gone through the loop. Only used for debug print outs
flag = 0; // a flag to tell us if anything got adjusted this time through the loop.
//
// The strategy is we figure out our current error amount based on the current values of the coefficient.
// We then look at what our error will be if we adjust the current coefficient by the delta amount.
//
// We adjust the 'a' coeffiecent first:
//
current = summation_of_least_square_error_data(a, b, c, d, abl2, eqnA, eqnB);
plus_next = summation_of_least_square_error_data(a+delta_size, b, c, d, abl2, eqnA, eqnB);
if ( plus_next<current) {
a = a+delta_size;
flag++;
}
//
// If we didn't adjust the 'a' coefficient in the plus direction, we have to compute where we will be if
// we move it in the minus direction. As a speed optimization, we don't do the calculation unless the
// previous plus movement will not help our values.
//
else {
minus_next = summation_of_least_square_error_data(a-delta_size, b, c, d, abl2, eqnA, eqnB);
if (minus_next<current) {
a = a-delta_size;
flag++;
}
}
//
// Now we adjust the 'b' coefficient: It is the same logic as above for the 'a' coefficient
//
current = summation_of_least_square_error_data(a, b, c, d, abl2, eqnA, eqnB);
plus_next = summation_of_least_square_error_data(a, b+delta_size, c, d, abl2, eqnA, eqnB);
if ( plus_next<current) {
b = b+delta_size;
flag++;
}
else {
minus_next = summation_of_least_square_error_data(a, b-delta_size, c, d, abl2, eqnA, eqnB);
if (minus_next<current) {
b = b-delta_size;
flag++;
}
}
//
// We handle the 'd' coefficient in a special manner. Especially towards the end of the iteration
// when we have several significant digits of precision on 'a' and 'b', there is no reason to
// adjust 'a' and 'b' while we adjust 'd'. Doing so just slows down the algorythm dramatically.
// Instead, what we do is adjust 'd' as much as we can before going back and adjusting 'a' and 'b'.
// Also, because we are just focused on 'd', we can keep the last value we moved to as our 'current' value
// for the next comparision. As a result of this, we can adjust the 'd' value much faster.
dflag = 0; // flag that tells us if we are done adjusting 'd'
current = summation_of_least_square_error_data(a, b, c, d, abl2, eqnA, eqnB);
do {
plus_next = summation_of_least_square_error_data(a,b,c,d+delta_size, abl2, eqnA, eqnB );
if ( plus_next<current) {
d = d+delta_size;
current = plus_next;
flag++;
}
else {
minus_next = summation_of_least_square_error_data(a,b,c,d-delta_size, abl2, eqnA, eqnB );
if (minus_next<current) {
d = d-delta_size;
current = minus_next;
flag++;
} else
dflag++; // If we get here, we did not adjust the 'd' value up or down
// So, we want to exit the special case loop and go back to
// adjusting 'a' and 'b'.
}
} while (dflag==0);
// If flag==0 it means that we did not find a better value for the Least Squares Error by shifting any of
// the coefficients this time through the loop. What this means is the amount we were trying to shift the
// coefficients by was too big. We have to back off some. We will try again the next time through the loop
// with a smaller delta amount!
if (flag==0) {
//
// The following debug code can be uncommented to help understand the convergance process.
//
/*
current = summation_of_least_square_error_data(a, b, c, d, abl2, eqnA, eqnB);
SERIAL_PROTOCOLPGM("error=");
SERIAL_PROTOCOL_F(current, 8);
SERIAL_PROTOCOLPGM(" delta_size=");
SERIAL_PROTOCOL_F(delta_size, 8);
SERIAL_PROTOCOLPGM(" a=");
SERIAL_PROTOCOL_F(a, 8);
SERIAL_PROTOCOLPGM(" b=");
SERIAL_PROTOCOL_F(b, 8);
SERIAL_PROTOCOLPGM(" d=");
SERIAL_PROTOCOL_F(d, 8);
SERIAL_PROTOCOLPGM(" cnt=");
SERIAL_PROTOCOL_F(cnt, 8);
SERIAL_PROTOCOLPGM("\n");
*/
delta_size = delta_size / 2.0;
}
} while ( flag!=0 || delta_size>.00000005 ); // We keep running the loop until nothing is changing
// and the size of delta_size gets so small it is almost
// pointless to continue.
coefficients[0] = -a; // Save the values we have found
coefficients[1] = -b; // and return them to the caller!
coefficients[2] = -d;
return coefficients;
}
//
// This function loops through all of the supplied data points and uses the specified coefficients to
// calculation the summation of the least squares error for the data. It uses the formula
// D = (ax + by +cz + d) / sqrt( a*a + b*b + c*c)
// For speed, the normalization [ sqrt( a*a + b*b + c*c) ] is just calculated once.
//
double summation_of_least_square_error_data(double A, double B, double C, double D, int n, double *eqn_A, double *eqn_B )
{
int i;
double normal, distance, sum = 0.0;
normal = sqrt( A*A + B*B + C*C);
for(i=0; i<n; i++) {
distance = abs( A*eqn_A[i] + B*eqn_A[i+n] + C*eqn_B[i] + D) / normal ;
sum += distance*distance;
}
return sum;
}
@niksoley
Actually.... Save a copy of your Marlin directory before you do this.... But if you delete the qr_solve.cpp file and replace its contents with the file up above, it should compile and save 10Kb. You might need to create a
#include "Iterative_LSF.h"
file that has these lines in it:
// This code is an alternate implementation of the Least Squares Best Fit algorythm that
// is used to calculate the plane the print bed lies in. It is an optional replacement for the
// more proven and much larger QR_SOLVE code base that is being used in the Marlin Code base.
//
// Using this code as a solution for the Least Squares Best fit by the Auto Bed Leveling code
// will save you almost exactly 10 Kb of firmware space. It will cost you several seconds of
// time after all the points are sampled as it iteratively converges on a Least Squares Error
// solution for the plane.
//
// This code was donated by Roxy-3DPrintBoard!
#include "configuration.h"
double summation_of_least_square_error_data(double , double , double , double , int , double *, double * );
//double * iterative_LSF(int , int , double *, double *);
double *qr_solve(int , int , double *, double *);
Give it a try... And you should have enough room in the Flash Memory to turn on a bunch of other options.
@Roxy-3D
I did something wrong, receiving
the following error
Idle was not declared in this scope;
In file included from sketch/qr_solve.cpp:12:0:
sketch/configuration.h:145:12: error: missing binary operator before token "("
#if ENABLED(SWITCHING_EXTRUDER)
^
sketch/configuration.h:160:12: error: missing binary operator before token "("
#if ENABLED(MIXING_EXTRUDER)
^
In file included from sketch/qr_solve.cpp:12:0:
sketch/configuration.h:275:12: error: missing binary operator before token "("
#if ENABLED(PIDTEMP)
^
sketch/configuration.h:327:12: error: missing binary operator before token "("
#if ENABLED(PIDTEMPBED)
^
sketch/configuration.h:411:13: error: missing binary operator before token "("
#if DISABLED(ENDSTOPPULLUPS)
^
sketch/configuration.h:622:12: error: missing binary operator before token "("
#if ENABLED(FILAMENT_RUNOUT_SENSOR)
^
sketch/configuration.h:634:12: error: missing binary operator before token "("
#if ENABLED(MESH_BED_LEVELING)
^
sketch/configuration.h:663:12: error: missing binary operator before token "("
#if ENABLED(AUTO_BED_LEVELING_FEATURE)
^
sketch/configuration.h:736:12: error: missing binary operator before token "("
#if ENABLED(Z_SAFE_HOMING)
^
sketch/configuration.h:782:12: error: missing binary operator before token "("
#if ENABLED(EEPROM_SETTINGS)
^
sketch/configuration.h:841:12: error: missing binary operator before token "("
#if ENABLED(NOZZLE_PARK_FEATURE)
^
sketch/configuration.h:882:12: error: missing binary operator before token "("
#if ENABLED(NOZZLE_CLEAN_FEATURE)
^
In file included from sketch/qr_solve.cpp:12:0:
sketch/configuration.h:1222:12: error: missing binary operator before token "("
#if ENABLED(SAV_3DGLCD)
^
In file included from sketch/qr_solve.cpp:12:0:
sketch/configuration.h:1313:12: error: missing binary operator before token "("
#if ENABLED(FILAMENT_WIDTH_SENSOR)
^
sketch/qr_solve.cpp: In function 'double* qr_solve(int, int, double*, double*)':
qr_solve.cpp:27: error: 'idle' was not declared in this scope
idle(); // or we risk the system thinking we are locked up!
^
sketch/qr_solve.cpp: In function 'double summation_of_least_square_error_data(double, double, double, double, int, double*, double*)':
qr_solve.cpp:160: error: 'sqrt' was not declared in this scope
normal = sqrt( A*A + B*B + C*C);
^
qr_solve.cpp:162: error: 'abs' was not declared in this scope
distance = abs( A*eqn_A[i] + B*eqn_A[i+n] + C*eqn_B[i] + D) / normal ;
^
exit status 1
'idle' was not declared in this scope
It looks like the configuration.h file got corrupted. Maybe a missing ; or something?
The complaint about qr_solve.cpp:27: error: 'idle' was not declared in this scope
can be fixed very easily. We just add a line at the top of qr_solve.cpp that says:
void idle();
The qr_solve.cpp:160: error: 'sqrt' was not declared in this scope
normal = sqrt( A_A + B_B + C_C);
^
qr_solve.cpp:162: error: 'abs' was not declared in this scope
distance = abs( A_eqn_A[i] + B_eqn_A[i+n] + C_eqn_B[i] + D) / normal ;
Errors can probably be fixed by adding a line at the top of qr_solve.cpp that says:
#include "math.h"
@Roxy-3D
I've created the "Size-Reduction" branch for those tests, it is at https://github.com/niksoley/Marlin-RC/tree/Size-Reduction.
I made the changes, and still receiving
the following error
In file included from sketch/qr_solve.cpp:12:0:
sketch/configuration.h:145:12: error: missing binary operator before token "("
#if ENABLED(SWITCHING_EXTRUDER)
^
sketch/configuration.h:160:12: error: missing binary operator before token "("
#if ENABLED(MIXING_EXTRUDER)
^
In file included from sketch/qr_solve.cpp:12:0:
sketch/configuration.h:275:12: error: missing binary operator before token "("
#if ENABLED(PIDTEMP)
^
sketch/configuration.h:327:12: error: missing binary operator before token "("
#if ENABLED(PIDTEMPBED)
^
sketch/configuration.h:411:13: error: missing binary operator before token "("
#if DISABLED(ENDSTOPPULLUPS)
^
sketch/configuration.h:622:12: error: missing binary operator before token "("
#if ENABLED(FILAMENT_RUNOUT_SENSOR)
^
sketch/configuration.h:634:12: error: missing binary operator before token "("
#if ENABLED(MESH_BED_LEVELING)
^
sketch/configuration.h:663:12: error: missing binary operator before token "("
#if ENABLED(AUTO_BED_LEVELING_FEATURE)
^
sketch/configuration.h:736:12: error: missing binary operator before token "("
#if ENABLED(Z_SAFE_HOMING)
^
sketch/configuration.h:782:12: error: missing binary operator before token "("
#if ENABLED(EEPROM_SETTINGS)
^
sketch/configuration.h:841:12: error: missing binary operator before token "("
#if ENABLED(NOZZLE_PARK_FEATURE)
^
sketch/configuration.h:882:12: error: missing binary operator before token "("
#if ENABLED(NOZZLE_CLEAN_FEATURE)
^
In file included from sketch/qr_solve.cpp:12:0:
sketch/configuration.h:1222:12: error: missing binary operator before token "("
#if ENABLED(SAV_3DGLCD)
^
In file included from sketch/qr_solve.cpp:12:0:
sketch/configuration.h:1313:12: error: missing binary operator before token "("
#if ENABLED(FILAMENT_WIDTH_SENSOR)
^
sketch/qr_solve.cpp: In function 'double summation_of_least_square_error_data(double, double, double, double, int, double*, double*)':
qr_solve.cpp:165: error: 'abs' was not declared in this scope
distance = abs( A*eqn_A[i] + B*eqn_A[i+n] + C*eqn_B[i] + D) / normal ;
^
exit status 1
'abs' was not declared in this scope
If you replace the current contents of qr_solve.cpp with this code... I think it will compile and work for you. Compiling for a RAMPS board (I don't have the 64Kb boards loaded...) Arduino says:
Sketch uses 61,148 bytes (24%) of program storage space. Maximum is 253,952 bytes.
Global variables use 2,677 bytes (32%) of dynamic memory, leaving 5,515 bytes for local variables. Maximum is 8,192 bytes.
So... You should have enough room to add a few options now. (Assuming the code is still compatible with Marlin.)
Either way... Please let us know if it works for you! Because we really should make this a #define option to save 10KB of program space.
The Code
// This code is an alternate implementation of the Least Squares Best Fit algorythm that
// is used to calculate the plane the print bed lies in. It is an optional replacement for the
// more proven and much larger QR_SOLVE code base that is being used in the Marlin Code base.
//
// Using this code as a solution for the Least Squares Best fit by the Auto Bed Leveling code
// will save you almost exactly 10 Kb of firmware space. It will cost you several seconds of
// time after all the points are sampled as it iteratively converges on a Least Squares Error
// solution for the plane.
//
// This code was donated by Roxy-3D!
#include "Marlin.h"
#include "configuration.h"
#include "ultralcd.h"
#include "planner.h"
#include "stepper.h"
#include "endstops.h"
#include "temperature.h"
#include "cardreader.h"
#include "configuration_store.h"
#include "language.h"
#include "pins_arduino.h"
#include "math.h"
#include "nozzle.h"
#include "duration_t.h"
#include "types.h"
#include "Iterative_LSF.h"
void idle();
double coefficients[3]; // We need a place to return the coefficients we found.
// This is where we do that!
//double * iterative_LSF(int abl2, int n, double *eqnA, double *eqnB)
double *qr_solve(double coeff[3], int abl2, int n, double *eqnA, double *eqnB)
{
double a= 0.0, b= 0.0, c=1.0, d=Z_PROBE_OFFSET_FROM_EXTRUDER; // Start with some reasonable values for our coefficients
double current, plus_next, minus_next, delta_size=.1;
int flag, dflag, dir=1;
int cnt=0;
do {
idle(); // or we risk the system thinking we are locked up!
cnt++; // How many times we have gone through the loop. Only used for debug print outs
flag = 0; // a flag to tell us if anything got adjusted this time through the loop.
//
// The strategy is we figure out our current error amount based on the current values of the coefficient.
// We then look at what our error will be if we adjust the current coefficient by the delta amount.
//
// We adjust the 'a' coeffiecent first:
//
current = summation_of_least_square_error_data(a, b, c, d, abl2, eqnA, eqnB);
plus_next = summation_of_least_square_error_data(a+delta_size, b, c, d, abl2, eqnA, eqnB);
if ( plus_next<current) {
a = a+delta_size;
flag++;
}
//
// If we didn't adjust the 'a' coefficient in the plus direction, we have to compute where we will be if
// we move it in the minus direction. As a speed optimization, we don't do the calculation unless the
// previous plus movement will not help our values.
//
else {
minus_next = summation_of_least_square_error_data(a-delta_size, b, c, d, abl2, eqnA, eqnB);
if (minus_next<current) {
a = a-delta_size;
flag++;
}
}
//
// Now we adjust the 'b' coefficient: It is the same logic as above for the 'a' coefficient
//
current = summation_of_least_square_error_data(a, b, c, d, abl2, eqnA, eqnB);
plus_next = summation_of_least_square_error_data(a, b+delta_size, c, d, abl2, eqnA, eqnB);
if ( plus_next<current) {
b = b+delta_size;
flag++;
}
else {
minus_next = summation_of_least_square_error_data(a, b-delta_size, c, d, abl2, eqnA, eqnB);
if (minus_next<current) {
b = b-delta_size;
flag++;
}
}
//
// We handle the 'd' coefficient in a special manner. Especially towards the end of the iteration
// when we have several significant digits of precision on 'a' and 'b', there is no reason to
// adjust 'a' and 'b' while we adjust 'd'. Doing so just slows down the algorythm dramatically.
// Instead, what we do is adjust 'd' as much as we can before going back and adjusting 'a' and 'b'.
// Also, because we are just focused on 'd', we can keep the last value we moved to as our 'current' value
// for the next comparision. As a result of this, we can adjust the 'd' value much faster.
dflag = 0; // flag that tells us if we are done adjusting 'd'
current = summation_of_least_square_error_data(a, b, c, d, abl2, eqnA, eqnB);
do {
plus_next = summation_of_least_square_error_data(a,b,c,d+delta_size, abl2, eqnA, eqnB );
if ( plus_next<current) {
d = d+delta_size;
current = plus_next;
flag++;
}
else {
minus_next = summation_of_least_square_error_data(a,b,c,d-delta_size, abl2, eqnA, eqnB );
if (minus_next<current) {
d = d-delta_size;
current = minus_next;
flag++;
} else
dflag++; // If we get here, we did not adjust the 'd' value up or down
// So, we want to exit the special case loop and go back to
// adjusting 'a' and 'b'.
}
} while (dflag==0);
// If flag==0 it means that we did not find a better value for the Least Squares Error by shifting any of
// the coefficients this time through the loop. What this means is the amount we were trying to shift the
// coefficients by was too big. We have to back off some. We will try again the next time through the loop
// with a smaller delta amount!
if (flag==0) {
//
// The following debug code can be uncommented to help understand the convergance process.
//
/*
current = summation_of_least_square_error_data(a, b, c, d, abl2, eqnA, eqnB);
SERIAL_PROTOCOLPGM("error=");
SERIAL_PROTOCOL_F(current, 8);
SERIAL_PROTOCOLPGM(" delta_size=");
SERIAL_PROTOCOL_F(delta_size, 8);
SERIAL_PROTOCOLPGM(" a=");
SERIAL_PROTOCOL_F(a, 8);
SERIAL_PROTOCOLPGM(" b=");
SERIAL_PROTOCOL_F(b, 8);
SERIAL_PROTOCOLPGM(" d=");
SERIAL_PROTOCOL_F(d, 8);
SERIAL_PROTOCOLPGM(" cnt=");
SERIAL_PROTOCOL_F(cnt, 8);
SERIAL_PROTOCOLPGM("\n");
*/
delta_size = delta_size / 2.0;
}
} while ( flag!=0 || delta_size>.00000005 ); // We keep running the loop until nothing is changing
// and the size of delta_size gets so small it is almost
// pointless to continue.
coefficients[0] = -a; // Save the values we have found
coefficients[1] = -b; // and return them to the caller!
coefficients[2] = -d;
coeff[0] = -a; // Save the values we have found
coeff[1] = -b; // and return them to the caller!
coeff[2] = -d;
return coefficients;
}
//
// This function loops through all of the supplied data points and uses the specified coefficients to
// calculation the summation of the least squares error for the data. It uses the formula
// D = (ax + by +cz + d) / sqrt( a*a + b*b + c*c)
// For speed, the normalization [ sqrt( a*a + b*b + c*c) ] is just calculated once.
//
double summation_of_least_square_error_data(double A, double B, double C, double D, int n, double *eqn_A, double *eqn_B )
{
int i;
double normal, distance, sum = 0.0;
normal = sqrt( A*A + B*B + C*C);
for(i=0; i<n; i++) {
distance = abs( A*eqn_A[i] + B*eqn_A[i+n] + C*eqn_B[i] + D) / normal ;
sum += distance*distance;
}
return sum;
}
It worked really well, tks @Roxy-3D !
You are very welcome! And if you uncomment those SERIAL_PROTOCOL()
lines at the end of the function... It is kind of fun to watch it converge on a solution. The real qr_solve
can find an answer very quickly. But it takes a huge amount of program code and RAM space to do that. This routine does a brute force search but can be coded with a very small memory foot print.
Maybe @thinkyhead would be willing to think about the right way to allow a user to turn off the inclusion of
qr_solve
In RCBugFix
the qr_solve
code is only included if using AUTO_BED_LEVELING_LINEAR
. And BILINEAR
is more recommended.
Greetings!
Can you give me the file "configuration.h" final, (which works property). Because I have the same problem, my sketch is too big with the bltouch activated on marlin 1.1.8 It is at 103%.
A huge thank you all.
What options do you have turned on? The suggested change up above is not a modification to configuration.h. It is the removal of the qr_solve library. If you turn on Bi-Linear bed leveling... It is my belief that library will not be included.
@Roxy-3D I can say that with Marlin 1.1.x (and using the Makefile) I get a huge blob (77.5kB, 117% of an 644P) when selecting BILINEAR. When selecting LINEAR, its 69.8kB (106.5% Full).
When using 3POINT bed leveling, I get 64.1kB (97.9% Full). So I will settle for this now.
Note that I had to remove EEPROM/thermal runaway protection/minimum extrusion temp protection/etc support for this in order to fit in an ATMEGA 644P.
I am trying to get power loss recovery on my original CR-10 that I just upgraded firmware to 1.1.9.
I updated configuration_adv.h (from CR-10 example folder) to enable PLR as below
_#define POWER_LOSS_RECOVERY
#if ENABLED(POWER_LOSS_RECOVERY)
#define POWER_LOSS_PIN 17 // Pin to detect power loss
#define POWER_LOSS_STATE HIGH // State of pin indicating power loss
#endif_
I got the compilation error below.
Sketch uses 130634 bytes (100%) of program storage space. Maximum is 130048 bytes.
_Global variables use 16770 bytes (102%) of dynamic memory, leaving -386 bytes for local variables. Maximum is 16384 bytes.
Any tips to free up some memory?
thanks in advance
John
Hi, try more this options:
//#define NO_WORKSPACE_OFFSETS // Disables M206 and M428
//#define ARC_SUPPORT //Disable
//#define DOGM_SD_PERCENT //Disable
//#define SPEAKER // Disable beeper if you don't want it. ~ 1664 bytes
//#define PID_EDIT_MENU //Disable~700 bytes
//#define PID_AUTOTUNE_MENU //Disable~250 bytes
This configuration used with Marlin 2.0.5.3 to Ender 3 Pro. Deployed with success.
This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.
This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.
Most helpful comment
Hi, try more this options:
define SLIM_LCD_MENUS //Enable
define DISABLE_M503 //Enable
//#define NO_WORKSPACE_OFFSETS // Disables M206 and M428
//#define ARC_SUPPORT //Disable
//#define DOGM_SD_PERCENT //Disable
//#define SPEAKER // Disable beeper if you don't want it. ~ 1664 bytes
//#define PID_EDIT_MENU //Disable~700 bytes
//#define PID_AUTOTUNE_MENU //Disable~250 bytes
This configuration used with Marlin 2.0.5.3 to Ender 3 Pro. Deployed with success.