Moving from C to C++ (easy question)

Hi,

I've been using C for my Arduino programs, but now I've learnt C++, and would like to transition over to using it in my sketches. I want to start with the basic blink sketch.

I've modified it to this code just to make an LED blink on and off:

/*
 - Blinks an LED
 - Code is adapted from C to C++
 */
 
//int led = 13;  // LED connected at pin 13
 
class LED_Blink
{
  public:
  
    void blinking()
    {
      digitalWrite(led, HIGH);   // turn the LED on (HIGH is the voltage level)
      delay(1000);               // wait for a second
      digitalWrite(led, LOW);    // turn the LED off by making the voltage LOW
      delay(1000);               // wait for a second
    }
  
  private:
     
   static const int led = 13;  // LED connected at pin 13

};

void setup() 
{                
  pinMode(led, OUTPUT);     
}

void loop() 
{
  // FORM:  Class_Name object   (Class_Name [space] object)
  LED_Blink blinker;  // creates an object, "blinker", which will point to a function within the class "LED_Blink"
  
     // FORM:  object.member_function()    (object [dot] class member_function)
     blinker.blinking();
}

My problem is that the with the line of code,

   static const int led = 13;  // LED connected at pin 13

declared in the private access specifier, it will not run.

However, if I delete this line, and use the global variable instead for the led,

int led = 13;  // LED connected at pin 13

, it will work as it should.

I'm confused because I thought that the variable led = 13 is specific to only to the class LED_Blink, and I should put it there in the private.

What am I doing wrong?

The original sketch was in C++ or as it is normally written C/C++.

Mark

When you use led in the 1st example, the program don't know what led is. You only declare it later.

Do the experienced arudino programmers on here prefer C or C++? I'm just curious

Do the experienced arudino programmers on here prefer C or C++? I'm just curious

Since C++ is a superset of C, it isn't an either/or question.

Hi project science

I'm confused because I thought that the variable led = 13 is specific to only to the class LED_Blink, and I should put it there in the private.

You also try to use the variable in setup() when you call pinMode(led, OUTPUT), which is what gives the compilation error.

Since you want to keep the details of the LED pin private to the class, try the following ...

Remove the global declaration you added, and put back in the private declaration.

Add another public method to your class:

void begin()
{
    pinMode(led, OUTPUT);
}

In loop(), call blinker.begin() after you create the object instance.

Note: When writing a class that interacts with the Arduino hardware like this, it is good practice to have a begin() method like this, which you call in setup() or loop(), to initialise the hardware. There can be problems if you try to initialise the hardware in the class constructor function.

As your next exercise :slight_smile: you could look at how to modify your class so that the LED pin number is passed as an argument to the constructor.

Regards

Ray

The transition is such an anti climax. Going from Z80 to X86 was much more painful.

KenF:
The transition is such an anti climax. Going from Z80 to X86 was much more painful.

Yep. Took me hours to realise that I couldn't use RET NZ in X86.

Henry_Best:
Yep. Took me hours to realise that I couldn't use RET NZ in X86.

Exactly! and then along came the 286 with all the issues around A20. Absolute nightmares.

Hackscribble:
Hi project science

You also try to use the variable in setup() when you call pinMode(led, OUTPUT), which is what gives the compilation error.

Since you want to keep the details of the LED pin private to the class, try the following ...

Remove the global declaration you added, and put back in the private declaration.

Add another public method to your class:

void begin()

{
   pinMode(led, OUTPUT);
}




In loop(), call blinker.begin() after you create the object instance.

Note: When writing a class that interacts with the Arduino hardware like this, it is good practice to have a begin() method like this, which you call in setup() or loop(), to initialise the hardware. There can be problems if you try to initialise the hardware in the class constructor function.

As your next exercise :) you could look at how to modify your class so that the LED pin number is passed as an argument to the constructor.

Regards

Ray

@Hackscribble - great answer! I used your suggestion and got it working.

I do have a question about general structure with initializing hardware in the setup() as you mentioned. It makes sense to add the pin output of the LED to the setup() so it is only called once. (It seems redundant to put it in the loop() which would call it every loop, at least to me.)

However, when I initialize the output pin in setup(), it doesn't run, unless I also place the class object in there as well, so that I can reference the class member function.

But, then I ALSO have to place the class object in the loop() again, in order to be able to reference the class, which seems redundant.

What is the proper way to structure this when using classes?

/*
 - Blinks an LED
 - Code is adpated from C to C++
 */
 
/* Hardware pins used (only for reference, not for code)
  
    int led = 13;   
*/
 
class LED_Blink
{
  public:
  
    void blinking()
    {
      digitalWrite(led, HIGH);   // turn the LED on (HIGH is the voltage level)
      delay(1000);               // wait for a second
      digitalWrite(led, LOW);    // turn the LED off by making the voltage LOW
      delay(1000);               // wait for a second
    }
    
    void begin()
    {
      pinMode(led, OUTPUT);
    }
  
  private:
     
   static const int led = 13;  // LED connected at pin 13
};

void setup() 
{                
LED_Blink blinker;  // creates an object, "blinker", which will point to a function within the class "LED_Blink"
  blinker.begin();  // pinMode(led, OUTPUT)
}

void loop() 
{
  // FORM:  Class_Name object   (Class_Name [space] object)
  LED_Blink blinker;  // creates an object, "blinker", which will point to a function within the class "LED_Blink"
      
     // FORM:  object.member_function()    (object [dot] member_function)
       //blinker.begin();  // pinMode(led, OUTPUT)
         blinker.blinking();
   
}

The class is NOT an object. It's the definition of an object. Just as int, char, and byte are all types of object (but relatively simple ones).

So before you can use your class, you need to create an instance of the class (Just as you've done in your example there.) This instance is then an object, that you can kick around anyway you like. The instance has to have a name to distinguish it from any other objects.

Thomas499:
Do the experienced arudino programmers on here prefer C or C++? I'm just curious

C++. You get templates, classes and stuff.

The class is NOT an object.

Think of a class, like a dog. Fido is a dog, but "dog" is not something you have as a pet. You have an instance of a dog (eg. Fido). However "dog" is a type of animal, not a particular instance of that type.

void setup() 
{                
LED_Blink blinker;  // creates an object, "blinker", which will point to a function within the class "LED_Blink"
  blinker.begin();  // pinMode(led, OUTPUT)
}

void loop() 
{
  // FORM:  Class_Name object   (Class_Name [space] object)
  LED_Blink blinker;  // creates an object, "blinker", which will point to a function within the class "LED_Blink"
      
     // FORM:  object.member_function()    (object [dot] member_function)
       //blinker.begin();  // pinMode(led, OUTPUT)
         blinker.blinking();
   
}

This is completely wrong. You have two "blinker" here. One in setup and one in loop. Why do you do that?

That's like having two dogs. One in my house and one in yours. If I wash my dog, is yours also washed? I think not.

Better would be this:

LED_Blink blinker;  
void setup() 
{                
  blinker.begin(); 
}
void loop() 
{
   blinker.blinking();
}

Ken - that was the details of a class I needed.

Nick - great and easy example to follow. I knew I was off a bit, but this makes sense. I got it now - thanks!