I cannot simply copy and paste a working sketch inside a function
Well, I'm not sure exactly what you have in mind that you can't do, so I'll show you what I had in mind that I can do.
If it doesn't suit your style or meet your needs, then I'm sorry for wasting time and bandwidth.
I will make two sketches, each of which takes up more than 1K bytes of RAM. Since the sketches will be used as "applet" functions, for testing them, I will make them exit at the end of loop() rather than repeating endlessly as the Arduino main() function normally dictates. In other words, the "loop" is one-shot and done.
I will test them thouroughly.
Then I will make a "master" sketch whose loop repeatedly calls two functions based on the two sketches. The two "applet" functions and the controlling sketch are, perhaps, overly simplistic, but I just want to show what could be done without much editing of the tested sketches. (And with nary a dreaded "goto" or any of those dang superfluous global variables in sight!)
Note that any RAM taken by global variables or by local variables in the "master" sketch is still in place when the functions are called, but the massive (for an ATmega328) amounts for each function are automatically released as each function returns. (Which was kind of the point.)
Anyhow...
Here's the first sketch:
//Sketch1
void setup()
{
Serial.begin(9600);
}
void loop()
{
long int x[250] = {0};
char buffer[256];
x[249] = 42;
sprintf(buffer, "sizeof(x) = %d, sizeof(buffer) = %d\n",
sizeof(x), sizeof(buffer));
Serial.print(buffer);
Serial.println(millis());
sprintf(buffer, "In sketch1: x[249] = %d at ", x[249]);
delay(1000);
Serial.println("End of loop() in sketch1");
Serial.println();
//
// The Arduino way is that a main() function runs and reruns the loop continuously.
// For our purposes, we want the "sketch" to quit after it does its business
// one time. In general, there may be some amount of logic that controls when the
// "sketch" is really through.
exit(0);
}
Here's the second:
//Sketch2
void setup()
{
Serial.begin(9600);
}
void loop()
{
long int x[250] = {0};
char buffer[256];
x[249] = -42;
sprintf(buffer, "sizeof(x) = %d, sizeof(buffer) = %d\n",
sizeof(x), sizeof(buffer));
Serial.print(buffer);
sprintf(buffer, "In sketch2: x[249] = %d at ", x[249]);
Serial.print(buffer);
Serial.println(millis());
delay(1000);
Serial.println("End of loop() in sketch2");
Serial.println();
// The Arduino way is that a main() function runs and reruns the loop continously.
// For our purposes, we want the "sketch" to quit after it does its business
// one time. In general, there may be some logic that controls when the
// "sketch" is really through.
exit(0);
}
Here's the "master" sketch with the two functions made from the two "applet" sketches:
//
// Main control function: sketchmaster
// This sketch calls functions made from previously
// tested sketch1 and sketch2
//
// Serial is a (global) instance of the HardwareSerial
// class, instantiated in HardwareSerial.cpp, and
// is linked automatically when you build from
// within the Arduino IDE.
//
// All other variables are local (automatic) within their
// functions.
//
void setup()
{
Serial.begin(9600);
}
//
// Of course you could have lots of conditionals and other
// logic to determine which function to call and when.
//
// For this simple case, we simply call them in direct rotation.
//
void loop()
{
Serial.println("main loop calling function1()");
function1();
Serial.println("main loop calling function2()");
function2();
}
//
// Was loop() in Sketch2
//
// Note that the two arrays take up a total
// of 1256 bytes (over half of the total 2K
// of the ATmega328p). If sketch2 had a setup()
// that didn't involve Serial or other main function
// globals, put its setup() stuff at the beginning
// of function2
//
void function2()
{
long int x[250] = {0};
char buffer[256];
x[249] = -42;
sprintf(buffer, "sizeof(x) = %d, sizeof(buffer) = %d\n",
sizeof(x), sizeof(buffer));
Serial.print(buffer);
sprintf(buffer, "In sketch2: x[249] = %d at ", x[249]);
Serial.print(buffer);
Serial.println(millis());
delay(1000);
Serial.println("End of loop in sketch2");
Serial.println();
// The Arduino way is that a main() function runs and reruns the loop continuously.
// For our purposes, we want the "sketch" to quit after it does its business
// one time. In general, there may be some logic that controls when the
// "sketch" is really through.
// Since this is now a function, we merely return, not exit()
// exit(0);
// A void function can return by merely dropping off of the end.
}
//
//Was loop() in Sketch1
//
// Note that the two arrays take up a total
// of 1256 bytes (over half of the total 2K
// of the ATmega328p). If sketch1 had a setup()
// that didn't involve Serial or other main function
// globals, put its setup() stuff at the beginning
// of function1()
//
void function1()
{
long int x[250] = {0};
char buffer[256];
x[249] = 42;
sprintf(buffer, "sizeof(x) = %d, sizeof(buffer) = %d\n",
sizeof(x), sizeof(buffer));
Serial.print(buffer);
sprintf(buffer, "In sketch1: x[249] = %d at ", x[249]);
Serial.print(buffer);
Serial.println(millis());
delay(1000);
Serial.println("End of loop in sketch1");
Serial.println();
// The Arduino way is that a main() function runs and reruns the loop continously.
// For our purposes, we want the "sketch" to quit after it does its business
// one time. In general, there may be some logic that controls when the
// "sketch" is really through.
// Since this is now a function, we merely return, not exit()
// exit(0);
// A void function can return by merely dropping off of the end.
}
//
//Was loop() in Sketch1
//
// Note that the two arrays take up a total
// of 1256 bytes (over half of the total 2K
// of the ATmega328p). If sketch1 had a setup()
// that didn't involve Serial or other main function
// globals, put its setup() stuff at the beginning
// of function1()
//
void function1()
{
long int x[250] = {0};
unsigned timeNow;
char buffer[256];
x[249] = 42;
sprintf(buffer, "sizeof(x) = %d, sizeof(buffer) = %d\n",
sizeof(x), sizeof(buffer));
Serial.print(buffer);
timeNow = millis();
sprintf(buffer, "In sketch1: x[249] = %d at ", x[249]);
Serial.print(buffer);
Serial.println(millis());
delay(1000);
Serial.println("End of loop in sketch1");
Serial.println();
// The Arduino way is that a main() function runs and reruns the loop continuously.
// For our purposes, we want the "sketch" to quit after it does its business
// one time. In general, there may be some logic that controls when the
// "sketch" is really through.
// Since this is now a function, we merely return, not exit()
// exit(0);
// A void function can return by merely dropping off of the end.
}
Output of the master:
main loop calling function1()
sizeof(x) = 1000, sizeof(buffer) = 256
In sketch1: x[249] = 42 at 98
End of loop in sketch1
main loop calling function2()
sizeof(x) = 1000, sizeof(buffer) = 256
In sketch2: x[249] = -42 at 1229
End of loop in sketch2
main loop calling function1()
sizeof(x) = 1000, sizeof(buffer) = 256
In sketch1: x[249] = 42 at 2362
End of loop in sketch1
main loop calling function2()
sizeof(x) = 1000, sizeof(buffer) = 256
In sketch2: x[249] = -42 at 3496
.
.
.
Regards,
Dave
Footnote: Instead of putting the source code for the functions in the master sketch, you could, of course, put the functions (together or separately) into a library (or libraries) and import the library (or libraries) into your master sketch. Instead of functions, they could be made into classes, and your master sketch could instantiate objects in sequence in its loop() function. Whatever...
The title that you gave the thread is "Best way..." I make no claims of best, but it is a way.