Classes with Arduino

I'm really surprised Object Oriented Programming is not given more prominence in the Arduino environment.

The Language Reference doesn't even mention "Class" when describing the Structure elements of Arduino C++ language, which led me (as an Arduino newby) to initially believe Arduino really supported a sort of C rather than real C++.

But this code works fine:

//
// Flashes the built in LED once per second without using the 'delay' function.
// Written in object orientated style.
//
// Public Domain: Please feel free to use but citation appreciated
// JIT 06/01/23
//


class LED {
  private: bool state; // whether the LED is on or off
  private: unsigned long flashtime;
  public: void Flash(unsigned long current_time) {
    if (( flashtime + 1000) < current_time) {

      if ( state ) {
        digitalWrite(LED_BUILTIN, LOW);   // turn the LED off by making the voltage LOW
      } else
      {
        digitalWrite(LED_BUILTIN, HIGH);  // turn the LED on (HIGH is the voltage level)}
    }
    state = !state;
    flashtime = millis();
  }};
};

LED builtinled;

void setup() {
    pinMode(LED_BUILTIN, OUTPUT);     // initialize digital pin LED_BUILTIN as an output.
}

void loop() {
  builtinled.Flash(millis());
}

Why is "class" not mentioned in the documents?

Am I missing something?

1 Like

The intended audience are folks who have never programmed. Object oriented programming is not appropriate for such folks.

frightening word to blink a led :slight_smile:

That initial belief was jumping to the wrong conclusion.

C++ is C++.

BTW
A Structure is nearly identical to a Class

A function call is missing in a structure, but can be insert as a member of the structure.

Yes, as here:


//********************************************^************************************************
//a structure that creates TIMER objects
struct makeTimer
{
  //previousTime   = the time this TIMER was (re)started
  //waitInterval   = delay time (ms/us)we are looking for
  //restart        = do we start this TIMER again and again
  //enableFlag     = is this TIMER enabled/allowed to be accessed
  //timeType       = true = millis(), false = micros()
  //
  //**********************
  //For each TIMER object we need to define it:
  //Example:
  //   makeTimer myTimer =           //give the TIMER a name "myTimer"
  //   {
  //     0, 200UL, true, true, true  //previousTime, waitInterval, restart, enableFlag, timeType
  //   };
  // You have access to:
  // Variables: myTimer.previousTime, myTimer.waitInterval, myTimer.restart, myTimer.enableFlag, myTimer.timeType,
  // Functions: myTimer.checkTime(), myTimer.enableTimer(), myTimer.expireTimer()
  //**********************

  unsigned long previousTime;
  unsigned long waitInterval;
  bool          restart;
  bool          enableFlag;
  bool          timeType;

  unsigned long currentTime;

  //******************************************
  //Function to check if this TIMER has expired ex: myTimer.checkTime();
  bool checkTime()
  {
    if (timeType == true)
    {
      currentTime = millis();
    }
    else
    {
      currentTime = micros();
    }

    //has this TIMER expired ?
    if (enableFlag == true && currentTime - previousTime >= waitInterval)
      //Note: if delays of < 2 millis are needed, use micros() and adjust waitInterval as needed
    {
      //should this TIMER start again?
      if (restart)
      {
        //get ready for the next iteration
        previousTime = currentTime;
      }
      //TIMER has expired
      return true;
    }

    //TIMER has not expired or is disabled
    return false;

  } //END of   checkTime()

  //******************************************
  //Function to enable and initialize this TIMER, ex: myTimer.enableTimer();
  void enableTimer()
  {
    enableFlag = true;

    //initialize previousTime to current millis() or micros()
    if (timeType == true)
    {
      previousTime = millis();
    }
    else
    {
      previousTime = micros();
    }

  } //END of   enableTimer()

  //******************************************
  //Function to force this TIMER to expire ex: myTimer.expireTimer();
  void expireTimer()
  {
    //force this TIMER to expire now
    previousTime = currentTime - waitInterval;

  } //END of   expireTimer()

}; //END of   structure “makeTimer”

//********************************************^************************************************

C O P I E D :nerd_face:

The only difference between a struct and a class in C++ is that a struct has public access by default.

1 Like

nice to know, thanks


}; //END of   structure “makeTimer”

//********************************************^************************************************

//Let's create and and initialize 2 "makeTimer" objects

//***************************
makeTimer redLEDtimer =                     //create redLEDtimer
{
  0, redLEDonOffInterval, true, true, true  //previousTime, waitInterval, restart, enableFlag, true=millis/false=micros
};

//***************************
makeTimer greenLEDtimer =                   //create greenLEDtimer
{
  0, greenLEDoffInterval, true, true, true  //previousTime, waitInterval, restart, enableFlag, true=millis/false=micros
};

In general, Arduino documentation does not mention "advanced" features of the underlying language. I don't think you'll find "struct" mentioned in the Arduino docs, either. Certainly not "typedef"...
This is an attempt to cater to "beginners" - the idea is that if you need info about t the language beyond what's in the Arduino docs, you need to consult the language references instead (or "in addition")

1 Like

I wonder about that premise. If you're starting from zero, is learning OOP really more difficult than procedural coding? Since I learned the latter first, I have no way of knowing.

It's impossible to understand polymorphism without an understand of functions. Learning object oriented program requires some foundation.

The Arduino documentation is weak on encouraging "procedures" as well.
All the time you see posted code with all of the user program logic stuffed into loop(), and people unclear on the idea that loop() and setup() are just procedures.
"Procedures" == "functions", in C.

1 Like

No, they're "voids" :sweat_smile: :rofl: :joy: :laughing:

3 Likes

Aren't we talking about sub-routines?

bsr.l  askStupidQuestions 

:nerd_face:

Does struct provide data protection as is done by class?

What do you mean by data protection?

Abstraction, encapsulation, inheritance, and polymorphism are four of the key principles of object-oriented programming you need to understand and master. Data "protection" can be a side effect of abstraction or encapsulation.depending how you define protection (private?)

a struct has the same access modifier public, protected, private like a class. Only the default behaviour is different like already mentioned (struct-public, class-private).

https://cplusplus.com/doc/tutorial/inheritance/