0

I am lost at this one. In Java, I would do it this way:

Inside the main sketch, I would instantiate the object from the class:

do = new DoClass(this);

I would also include a method inside the main sketch:

public void doSomething(){}

Then, inside the DoClass, I would have the following constructor:

    public class DoClass{
       Sketch sketch;
       public DoClass(Sketch skt){
          this.sketch = stk;
       }
 }

Then, at some point, I would call, from DoClass:

stk.doSomething():

which should be the same as calling:

doSomething();

from the main sketch. Any ideas how to achieve that? If yes, could you please show an example of how to achive the above example in Arduino?

2

Unlike Java, which insists on everything being inside a class, C++ allows “plain” functions which do not belong to any class. In fact, main() in standard C++, as well setup() and loop() in Arduino code, are all plain functions. Then, the main program (or “sketch” if you wish) is not an object, you cannot give it to the constructor of your class. Instead, you would give it a pointer to the particular function it needs. This is called a callback, because the library is calling back something from your main program.

Here is how I would write it in C++:

/*
 * Class definition.
 */

class DoClass {

    // Define a callback type: a pointer to a function taking no
    // arguments and returning void.
    typedef void (*callback_t)();

public:
    // Constructor.
    DoClass(callback_t _callback)
        // Initialize internal callback with the one given as parameter.
        : callback(_callback)
        // empty function body
        {}

    // This class method invokes the callback.
    void doIt() { callback(); }

private:
    // The callback is kept as private internal data.
    callback_t callback;
};

/*
 * Main program.
 */

// This is the function we are going to provide as a callback.
void doSomething()
{
    Serial.println(F("Doing some work..."));
}

// Instantiate the class statically.
DoClass doObject(doSomething);

void setup()
{
    Serial.begin(9600);
}

void loop()
{
    doObject.doIt();  // <- this will invoke our callback.
    delay(1000);
}

The class could be instantiated dynamically (DoClass *doObject = new DoClass(doSomething);). I prefer to do it statically when possible, because dynamic memory allocation can easily led to memory fragmentation problems in such small platforms.

| improve this answer | |
  • Precisely what I was looking for. Thanks! – Bob Jones Aug 29 '19 at 22:18
1

The great thing about Java is that it was designed to have a similar syntax as C++ and Arduino will gladly compile C++. So if you're familiar with Java this should be pretty easy for you.

check out This Tutorial

As for your example...

Much like Java, it is best practice to put C++ classes in their own files, but it is not required. If you use Java you are used to "importing" modules and classes into the class you are creating. Similarly C++ imports header files (behind the scenes it is much different, but functionally the same).

To do this first you would create a header file. This is just a text file with the extension ".h" or ".hpp" intead of ".txt" - traditionally .h is used only for c files and .hpp would be for c++. The header file will include the class and method prototypes.

Before I get to your example, as a side note:

Your example using the "sketch" variable is somewhat confusing because a sketch is just what the world of Arduino calls a program and it would not be used as variable.

"DoClass.hpp"

class DoClass { 
  int var; 
public: 
  DoClass(int var); 
  int getVar();
};

"DoClass.cpp"

#include "DoClass.hpp"

DoClass::DoClass(int variable){
  var = variable
}

int DoClass::getVar(){
  return var;
}

The "::" means "member of" so the getVar() is a method of DoClass.

These files should be saved in your sketch folder. If you are creating a class that will be reused you can place it in ../sketches/libraries/.

#include "DoClass.hpp"
setup(){
  ...
}

DoClass myClass(5);  // creates class
int testVal; 

loop(){
  ...
  testVal = myClass.getVar(); 

}
| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.