Creating a new library. Tutorial please

Hi there folks.

I'm trying to create my own library and I've followed the Morse-code tutorial exactly the way it is, and Ive downloaded the morse.h and .cpp files and everything, but it just wont work.

I get all kinds of error messages.

Does anybody have a link to a better tutorial?

Or maybe I could get a couple of answers and hopefully some code from sombody right here and now;

What I want to do is to create a library that has a function that returns a string.
thats pretty much all haha

No but for real though its a lot more complicated than that but thats all I need to know for now.

Thanks :slight_smile:

I get all kinds of error messages.

Which are?

This is one: ISO C++ forbids declaration of 'Testing' with no type
and depending on what I change I get some other errors.

ISO C++ forbids declaration of 'Testing' with no type

Well, that's very true, it does do that.

SerialPreset.h

#ifndef SerialPreset_h
#define SerialPreset_h

#include  "Arduino.h"

class SerialPreset
{
  public:
    SerialPreset();
    String SerialRead();
};

extern SerialPreset SerialPreset;

#endif

SerialPreset.cpp

#include "Arduino.h"
#include "SerialPreset.h"

#define SOP  '<'   //Start of packet
#define EOP  '>'   //End of packet

String SOCP = "([";
String EOCP = ")]";
String CPS  = ",|";

bool started = false;
bool ended = false;

char inData[256];
byte index;
boolean Echo;
String HardwareCommands[4] = {"Analog", "Digital", "PWM", "Tx"};


SerialPreset::SerialPreset(){  }

String SerialPreset::SerialRead()  {
 while(Serial.available() > 0)
  {
    //Start serial thingy now!
    
    char inChar = Serial.read();
    if(inChar == SOP)
    {
       index = 0;
       inData[index] = '\0';
       started = true;
       ended = false;
    }
    else if(inChar == EOP)
    {
       ended = true;
       break;
    }
    else
    {
      if(index < 256)
      {
        inData[index] = inChar;
        index++;
        inData[index] = '\0';
      }
    }
  }

  // We are here either because all pending serial
  // data has been read OR because an end of
  // packet marker arrived. Which is it?
  if(started && ended)
  {
    // The end of packet marker arrived. Return the packet
    return inData;
    // Reset for the next packet
    started = false;
    ended = false;
    index = 0;
    inData[index] = '\0';
  }  
}

You'll probably recognize the above code, I found it here on the forum.
I just figured that my sketches would be more organized if I put the code in a serparate library.

Unfortunately writing a library exposes you to a bit more C++ than writing a sketch. A good starting point is an existing library - have a look at several and you'll soon get a feel for the form of things.

Did you put the contents of Morse.zip in the right place (The Morse directory inside your libraries directory)?

I've had a look at Morse.zip - its not yet 1.0 compatible - just change

#include "WProgram.h"

to

#if defined(ARDUINO) && ARDUINO >= 100
  #include "Arduino.h"
#else
  #include "WProgram.h"
#endif

in the .h and .cpp files

aaah I see I see.

but what about my library, do you know how to get it to work?

I changed the lines that you suggested for the Morse library.

I tried this sketch:

#include <Morse.h>

void setup()
{
}

void loop(){
  Morse.dot();
}

I get this error: expected unqualified-id before '.' token

Why?

    return inData;
    // Reset for the next packet
    started = false;
    ended = false;
    index = 0;
    inData[index] = '\0';

Several problems here. First, nothing after the return statement will be executed. Second, inData is a char array, not a String, so the function return type does not match what you are trying to return.

but what about my library, do you know how to get it to work?

Where is your sketch?

ISO C++ forbids declaration of 'Testing' with no type

I don't see a declaration of anything called Testing, with or without a type. Post ALL of the errors, and ALL the code being compiled when the errors are generated.

I get this error: expected unqualified-id before '.' token

Why?

Because the compiler has no idea what a Morse is. You need to create an instance of the class in order to use it's non-static methods.

Okay.

Here's SerialPreset.h

/*
  SerialPreset.h - Library for serial packets.
  Created by Aid Vllasaliu, 24 pril 2012.
  Use it as you want :)
  Found useful code in the Arduino Forum.

  delphuino.blogspot.com
*/

#ifndef SerialPreset_h
#define SerialPreset_h

#include  "Arduino.h"

class SerialPreset
{
  public:
    SerialPreset();
    String SerialRead();
};

extern SerialPreset SerialPreset;

#endif

...and SerialPreset.cpp

#include "Arduino.h"
#include "SerialPreset.h"

#define SOP  '<'   //Start of packet
#define EOP  '>'   //End of packet

String SOCP = "([";
String EOCP = ")]";
String CPS  = ",|";

bool started = false;
bool ended = false;

char inData[256];
byte index;
boolean Echo;
String HardwareCommands[4] = {"Analog", "Digital", "PWM", "Tx"};


SerialPreset::SerialPreset(){  }

String SerialPreset::SerialRead()  {
 while(Serial.available() > 0)
  {
    //Start serial thingy now!
    
    char inChar = Serial.read();
    if(inChar == SOP)
    {
       index = 0;
       inData[index] = '\0';
       started = true;
       ended = false;
    }
    else if(inChar == EOP)
    {
       ended = true;
       break;
    }
    else
    {
      if(index < 256)
      {
        inData[index] = inChar;
        index++;
        inData[index] = '\0';
      }
    }
  }

  // We are here either because all pending serial
  // data has been read OR because an end of
  // packet marker arrived. Which is it?
  if(started && ended)
  {
    // The end of packet marker arrived. Return the packet
    return inData;
    // Reset for the next packet
    started = false;
    ended = false;
    index = 0;
    inData[index] = '\0';
  }  
}

... and finally the sketch:

#include <SerialPreset.h>

void setup()
{
  //Set Serial Baudrate
   Serial.begin(115200);
}

void loop(){
  String InData = SerialPreset.SerialRead();
  if (InData<>""){
    //Do something
  }
}

PaulS:

I get this error: expected unqualified-id before '.' token

Why?

Because the compiler has no idea what a Morse is. You need to create an instance of the class in order to use it's non-static methods.

Oh ok, how is that done? :slight_smile:

extern SerialPreset SerialPreset;

What do you think that this is doing? It probably is not doing what you think it is.

Oh ok, how is that done?

Morse telegraph; // Create in instance
.
.
.
void loop()
{
   telegraph.dot();
}

PaulS:

extern SerialPreset SerialPreset;

What do you think that this is doing? It probably is not doing what you think it is.

I have no idea what it should be doing to be honest. I'm brand new on this library stuff but I really want to learn this.

Morse telegraph; // Create in instance
.
.
.
void loop()
{
telegraph.dot();
}

I cant see "telegraph" in the original morse code.
Did you change it?

I have no idea what it should be doing to be honest. I'm brand new on this library stuff but I really want to learn this.

What that bit of code is says is that there is somewhere, outside of this file (extern), an object, of type SerialPreset, named SerialPreset.

So, where do you actually create that object? The problem is that you don't. Having an object with a name that is the same as the class is likely going to cause you problems. So, you need to change the object name in the header file, and you actually need to create the object in the source file. Look at how HardwareSerial.h and HardwareSerial.cpp create an instance called Serial.

I cant see "telegraph" in the original morse code.

I can't see the original morse code, so, we're even.

umm.... u really should learn a bit more about object oriented programming in c++ before you tackle Arduino libraries. Arduino libraries are typically implemented as c++ classes. There are good reasons why you would want to put things into classes & u need to evaluate if your need for "organizing code" falls in that land.

Google for "C++ classes tutorial" or try this one Introduction to C++ Classes and Objects

if you are merely looking to keep related function definitions "organized" in different source files, you can always create .cpp containing the function defs & .h file containing the function declarations and #include ".h" in both your .ino sketch & .cpp files. There are some gotchas in this approach also (variable scope & the like) and again you need to read up more.

PaulS:
I can't see the original morse code, so, we're even.

haha touché :stuck_out_tongue_winking_eye:

umm.... u really should learn a bit more about object oriented programming in c++ before you tackle Arduino libraries. Arduino libraries are typically implemented as c++ classes. There are good reasons why you would want to put things into classes & u need to evaluate if your need for "organizing code" falls in that land.

Google for "C++ classes tutorial" or try this one http://cplus.about.com/od/learning1/ss/cppobjects.htm

if you are merely looking to keep related function definitions "organized" in different source files, you can always create <filename>.cpp containing the function defs & <filename>.h file containing the function declarations and #include "<filename>.h" in both your .ino sketch & <filename>.cpp files. There are some gotchas in this approach also (variable scope & the like) and again you need to read up more.

I finally figured it out. It was pretty straight forward once I tweaked the code a bit here and there.

I'll post a download link of the library together with a couple of examples when I'm done with it :slight_smile:

I think some people will find it pretty useful :slight_smile: