I am writing a library which can run 2 stepper motors. so, instead of step (200), you send the instruction step(200,100). All fine. But there are occasions when the stepping will be cancelled part way through, say after 100 steps of motor 1 and 50 steps of motor 2 (they run synchronously). i need to be able the library to report back both results: 100 done on stepper 1 and 50 done on stepper 2.
Becuse there are two results to be passed back I can't use the usual 'return' method because I can't return two results. (I could of course send a single result in a string but that's messy.)
So instead I thought about amending two global variables that are created by the sketch but can i do this? nope. Any ideas?
If you take a C programming course, you will learn that arrays are pointers and that pointers are arrays. When you allocate an array, you get a pointer to the first element of the block of memory conventionally thought of as an array. The compiler has no idea that you think of a contiguous block of memory addresses as an array.
So, wherever you would use an array, you can use a pointer, and wherever you would use a pointer, you can use an array.
So, OP can use an array to pass values to and from a C routine, either implicitly using pointer notation:
void func(int *vals)
or explicitly using array notation:
void func(int vals[2])
The function won't know or care that the mean different things to you and me.
The typical solution to returning multiple values is to add reference variables to your function as in the following:
void step(m1_steps, m2_steps, &m1_done, &m2_done)
{
...
m1_done = m1_steps_completed;
m2_done = m2_steps_completed;
}
// call function as follows
unsigned int step1,step2;
step(100,50,step1,step2);
// on return step1 and step2 will receive number of steps completed
// as per your step function
You could also skip the first two value parameters and use the reference parameters to pass data in both directions. There is also a wide range of other possibilities including:
global variables (as suggested by your subject)
create private library instance varaiables to hold steps completed for each motor and add a method to return steps completed for each
create public library instance variables and access these directly from your sketch through the library instance variable after each call to "step"
if steps are small (e.g. max 255 or 65535) you could combine the values for each motor into a 16 bit or 32 bit value and return this from your function.
Passing array's as values however is not possible.
BenF, could you tell me more about what you said three posts back? I'm still learning and have a few questions.
Is the "&variable" thing arduino specific, C++ specific, or should it also work in C? I'm waiting on my arduino to arrive, so all I have is a C simulator.
How could a function in a library modify a global variable? Is it just like if the function was in "loop()"?
And could you explain your third bullet?
These all look like great ideas, and I want to be able to understand them better. Thanks!
Is the "&variable" thing arduino specific, C++ specific, or should it also work in C? I'm waiting on my arduino to arrive, so all I have is a C simulator.
This is a C++ feature. In "C" we would use the pointer and reference operators to do the same thing.
There is no need to wait for the board to arrive as you can download the Arduinbo IDE right now and write/compile as much as you like.
How could a function in a library modify a global variable? Is it just like if the function was in "loop()"?
There is no magic to this. Any variable defined with a global scope (and seen by the library source) can be accessed from within the library.
And could you explain your third bullet?
Given this simple class declaration:
class MyClass {
public:
int function1(int arg1);
int step1;
int step2;
private:
};
You can then declare an instance of the above class and access the public variables step1 and step2 from your main sketch as follows:
MyClass Test; // declare instance of class MyClass
Test.step1 = 1; // write to public class variable
Test.step2 = 2; // write to public class variable
Test.function1(123); // call function1
Serial.println(Test.step1); // access public class variable
Serial.println(Test.step2); // access public class variable
Likewise, function1 can access these variables (read or write) for whatever purpose you see fit.
Yeah, I have the IDE, I just wish I had a simulator. My C simulator is for a robotics team I am on, and, for example, if I used the printf() function, it would print to a command prompt window. Also, I could toggle digital and control analog pins, view outputs, etc. I wish there was one like that for the arduino. EDIT: Virtual Breadboard actually is better than I asked for, just I hadn't used it since I downloaded it as I couldn't find how to put programs on it at first. Too bad I can't test a virtual arduino on an oscilloscope, though.
And with the global thing, I guess I was thinking along the lines of calling a program and running it in its own separate "space", aside from the loop with the only connections being arguments and returns. Thanks for clearing that up.
And yeah, I have written quite a bit so far. I use Notepad++ as my editor, and I made a custom language for the arduino, but I can't get the folding code to work. Oh well.