RE: Writing a Library for Arduino

Hi Gang

I'm interested in learning how to create my own Arduino library. I've read the following articles but I'm still a little confused.

How to write libraries for the Arduino?

Writing a Library for Arduino

The second article is the one causing me grief. Specifically...

Morse::Morse(int pin)
{
  pinMode(pin, OUTPUT);
  _pin = pin;
}

There are a couple of strange things in this code. First is the Morse:: before the name of the function. This says that the function is part of the Morse class. You'll see this again in the other functions in the class. The second unusual thing is the underscore in the name of our private variable, _pin. This variable can actually have any name you want, as long as it matches the definition in the header file. Adding an underscore to the start of the name is a common convention to make it clear which variables are private, and also to distinguish the name from that of the argument to the function (pin in this case).

I don't understand the significance of _pin. Why does pin have to be allocated to _pin? Is it to 'quarantine' it?

If I look at the first article, specifically their example the function...

void LED13::blink(int time)

This slight of hand (time allocated to _time) doesn't seemed to be required. Why? Is it because it's not a constructor?

I hope someone can shed some light on this?

Cheers

Jase :confused:

ilovetoflyfpv:

Morse::Morse(int pin)

{
  pinMode(pin, OUTPUT);
  _pin = pin;
}




I don't understand the significance of _pin. Why does pin have to be allocated to _pin? Is it to 'quarantine' it?

If you don't do that, other methods can't access it.

ilovetoflyfpv:
Hi Gang

I don’t understand the significance of _pin. Why does pin have to be allocated to _pin? Is it to ‘quarantine’ it?

in a way, yes. You see, a class (library) will allow you to create several instances of the class and then control each of them (utilize member functions) individually and separately. Each member variable is encapsulated within the instance of the class!

#include <Morse.h>

Morse morse1(13);   // first instance
Morse morse2(12); // second instance on pin 12!!

void setup()
{
}

void loop()
{
  morse2.dot(); morse2.dot(); morse2.dot();  // these functions will output morse code on pin 12
  morse1.dash(); morse1.dash(); morse1.dash();  // these functions will output morse code on pin 13!
  delay(3000);
}

aarg:
If you don't do that, other methods can't access it.

Hi aarg

Thanks for your quick reply. The method...

Morse::Morse(int pin)
{
  pinMode(pin, OUTPUT);
  _pin = pin;
}

Is a public function so shouldn't pin be available both externally and internally?

In the other article/example the method...

void LED13::blink(int time)

The variable time is used directly.

I'm obviously not getting something.

Cheers

Jase :slight_smile:

BulldogLowell:
in a way, yes. You see, a class (library) will allow you to create several instances of the class and then control each of them (utilize member functions) individually and separately. Each member variable is encapsulated within the instance of the class!

#include <Morse.h>

Morse morse1(13);   // first instance
Morse morse2(12); // second instance on pin 12!!

void setup()
{
}

void loop()
{
 morse2.dot(); morse2.dot(); morse2.dot();  // these functions will output morse code on pin 12
 morse1.dash(); morse1.dash(); morse1.dash();  // these functions will output morse code on pin 13!
 delay(3000);
}

Hi BulldogLowell

Thanks for your reply. So how do I know what methods do I need to create private properties? Will I need to do the following?

class Test
{
 public:
   double angle(double xA, double yA, double xB, double yB);
 private:
  _double xA;
  _double yA;
  _double xB;
  _double yB;
};

void Test::double angle(double xA, double pos yA, double xB, double yB){
_double xA = double xA;
_double yA = double yA;
_double xB = double xB;
_double yB = double yB;
//And some code...
}

Cheers

Jase :slight_smile:

Is a public function so shouldn't pin be available both externally and internally?

No. The argument pin is passed to the method by value. No other method in the class has access to the arguments of some other method, unless the method explicitly stores the argument value somewhere that other methods have access to.

ilovetoflyfpv:
Hi BulldogLowell

Thanks for your reply. So how do I know what methods do I need to create private properties? Will I need to do the following?

class Test

{
public:
  double angle(double xA, double yA, double xB, double yB);
private:
  _double xA;
  _double yA;
  _double xB;
  _double yB;
};

void Test::double angle(double xA, double pos yA, double xB, double yB){
_double xA = double xA;
_double yA = double yA;
_double xB = double xB;
_double yB = double yB;
//And some code...
}





Cheers

Jase :)

Honestly, the two examples you are using are at the 'crappy' end of the educational stick.

I suggest that you go through a proper on-line tutorial on Classes and learn how scope works.

So much clearer using the "this"-pointer i c++

File X.h

#ifndef X_H
#define X_H

class X {
private:
int pin;
public:
// Constructor
X (int pin);
// method
int getPin();
}
#endif

File X.cpp / X.ino

#include "X.h"

// Constructor body
X::X (int pin) {
this->pin=pin;
}

// Method body
int X::getPin() {
return this->pin; // or just return pin; since there is no local variable "pin"
}

So much clearer using the "this"-pointer i c++

In my opinion, it is not.

There is no reason to name the argument the same as the member variable.

X::X (int pinIn)
{
   pin=pinIn;
}

PaulS:
There is no reason to name the argument the same as the member variable.

and a lot of great reasons not to use the same names!!!

Hi Guys

Thanks for the replies. I think I get it now. It's simply a matter of scope. In the example below; int i is only available to the method Morse (also the constructor in this case). In order for int i to be available to other methods we create a private property _pin so that methods dash() and dot() can access it. Is this correct?

Just in case anyone reads this down the track. It's well worth having a good understanding of Functions and Classes/Objects before attempting creating a Library.

Cheers

Jase :slight_smile:

PS I agree with BulldogLowell;

Honestly, the two examples you are using are at the 'crappy' end of the educational stick.

HEADER

/*
  Morse.h - Library for flashing Morse code.
  Created by David A. Mellis, November 2, 2007.
  Released into the public domain.
*/
#ifndef Morse_h
#define Morse_h

#include "Arduino.h"

class Morse
{
  public:
    Morse(int pin);
    void dot();
    void dash();
  private:
    int _pin;
};

#endif

SOURCE

/*
  Morse.cpp - Library for flashing Morse code.
  Created by David A. Mellis, November 2, 2007.
  Released into the public domain.
*/

#include "Arduino.h"
#include "Morse.h"

Morse::Morse(int pin)
{
  pinMode(pin, OUTPUT);
  _pin = pin;
}

void Morse::dot()
{
  digitalWrite(_pin, HIGH);
  delay(250);
  digitalWrite(_pin, LOW);
  delay(250);  
}

void Morse::dash()
{
  digitalWrite(_pin, HIGH);
  delay(1000);
  digitalWrite(_pin, LOW);
  delay(250);
}

ilovetoflyfpv:
Hi Guys

Thanks for the replies. I think I get it now. It's simply a matter of scope. In the example below; int i is only available to the method Morse (also the constructor in this case).

available only to the member functions (a..k.a methods) of Morse class, I would say.

ilovetoflyfpv:
In order for int i to be available to other methods we create a private property

or a private variable

ilovetoflyfpv:
_pin so that methods dash() and dot() can access it. Is this correct?

Just in case anyone reads this down the track. It's well worth having a good understanding of Functions and Classes/Objects before attempting creating a Library.

yup

:slight_smile: