Creating a library

I wish to create a library from the following code:

#define SOP '<'
#define EOP '>'
bool started = false;
bool ended = false;
char inData[80];
byte index;
char delimiters[] = ",";
char* valPosition;
double angle[] = {0, 0, 0};


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

void loop() {
 
  readserialtochars();
  parsedata();
 
 
  

}

void readserialtochars() {
   while(Serial.available() > 0)
  {
    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 < 79)
      {
        inData[index] = inChar;
        index++;
        inData[index] = '\0';
      }
    }
  }
 }
void parsedata() {
 if(started && ended)
  {
  valPosition = strtok(inData, delimiters);
   for(int i = 0; i < 3; i++){
    angle[i] = atof(valPosition);
    Serial.println(angle[i]);
    valPosition = strtok(NULL, delimiters);
    }
    
    started = false;
    ended = false;
    index = 0;
    inData[index] = '\0';
  }
}

My respective cpp and h filer are :
serial.cpp

#include "Arduino.h"
#include <serial.h>



bserial::bserial(double* gains[3])
{
	
}

void bserial::readserialtochars() {
	while (Serial.available() > 0)
	{
		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 < 79)
			{
				inData[index] = inChar;
				index++;
				inData[index] = '\0';
			}
		}
	}
}

void bserial::parsedata() {
	if (started && ended)
	{
		valPosition = strtok(inData, delimiters);
		for (int i = 0; i < 3; i++){
			angle[i] = atof(valPosition);
			Serial.println(angle[i]);
			valPosition = strtok(NULL, delimiters);
		}

		started = false;
		ended = false;
		index = 0;
		inData[index] = '\0';
	}
}

serial.h

#ifndef bserial
#define bserial

#include "Arduino.h"

class bserial
{
public:
	bserial(double*);
	void readserialtochars();
	void parsedata();
private:
 #define SOP '<'
 #define EOP '>'
	bool started = false;
	bool ended = false;
	char inData[80];
	byte index;
	char delimiters[] = ",";
	char* valPosition;
};

#endif

Arduino IDE does not seem to like this. Have i correctly constructed the libraries?

Arduino IDE does not seem to like this.

Please post the errors you are getting, and the code of the program which uses the library.

#include <serial.h>
double gains[3];
bserial bserial(gains[3]);

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

void loop() {
   bserial.readserialtochars();
   bserial.parsedata();
}

this is my sketch with the library error is

In file included from serialexample.ino:1:
Arduino\libraries\serial/serial.h:10: error: expected unqualified-id before 'double'
Arduino\libraries\serial/serial.h:10: error: expected `)' before 'double'
Arduino\libraries\serial/serial.h:16: error: ISO C++ forbids initialization of member 'started'
Arduino\libraries\serial/serial.h:16: error: making 'started' static
Arduino\libraries\serial/serial.h:16: error: ISO C++ forbids in-class initialization of non-const static member 'started'
Arduino\libraries\serial/serial.h:17: error: ISO C++ forbids initialization of member 'ended'
Arduino\libraries\serial/serial.h:17: error: making 'ended' static
Arduino\libraries\serial/serial.h:17: error: ISO C++ forbids in-class initialization of non-const static member 'ended'
Arduino\libraries\serial/serial.h:20: error: ISO C++ forbids initialization of member 'delimiters'
Arduino\libraries\serial/serial.h:20: error: making 'delimiters' static
Arduino\libraries\serial/serial.h:20: error: invalid in-class initialization of static data member of non-integral type 'char [0]'
Arduino\libraries\serial/serial.h:8: error: an anonymous struct cannot have function members
Arduino\libraries\serial/serial.h:22: error: abstract declarator '<anonymous class>' used as declaration
serialexample:3: error: expected constructor, destructor, or type conversion before ';' token
serialexample.ino: In function 'void loop()':
serialexample:10: error: expected primary-expression before '.' token
serialexample:11: error: expected primary-expression before '.' token

In your header file, change the constructor to match what you have in the .cpp file:

bserial(double* gains[3]);

Also in the header file, remove the initialisations. For example, have just this:

	bool started;
	bool ended;

Instead, put assignment statements in the constructor in the .cpp file.

bserial::bserial(double* gains[3])
{
	started = false;
	ended = false;
}

In your example program, I don't think you can call the instance of the class the same name as the class itself:

bserial bserial(gains[3]);

And what is the reason for passing the global array gains to the constructor? It does not get used elsewhere in the program.

Hackscribble:

bserial bserial(gains[3]);

And what is the reason for passing the global array gains to the constructor? It does not get used elsewhere in the program.

oh that was and error in the library, the array called angle[] in the function "void parsedata()" should have been renamed to gains.
The idea was to have the library directly change the values in the array that is declared in the main sketch, through use of pointers.

I think you should remove the "*" from the constructor. Otherwise, you'll define the argument as an array of pointers.

bserial::bserial(double gains[3])

And you just need the array name when you instance the class:

double myGains[3];
bserial myBSerial(myGains);

Ditch the class and just make functions. The problem your trying to solve doesn't need the principles of object oriented-code.

Hackscribble:

double myGains[3];

bserial myBSerial(myGains);

With this will any change to the array mGains inside the object myBSerial also change the myGains array i declare in the sketch?
The function needs to be able to output 3 doubles

Arrch:
Ditch the class and just make functions. The problem your trying to solve doesn't need the principles of object oriented-code.

My sketch is looking too cluttered and its becoming a pain to do any sort of error handling, my goal is to call some functions in another page eg. motor functions and variables in page1
sensor functions and variables in page2
communication functions and variables in page 3 ect..
how can i achieve this in the simplest way?

zer044:
how can i achieve this in the simplest way?

Easiest way is to move everything into a seperate source file:

Foo.cpp

void myFooFunction()
{
   // do stuff
}

On your main page, use extern to tell the compiler about the function:

MySketch.ino

extern void myFooFunction(void);

The proper way to do it would be with a header file, but this requires slightly less code and, less file, and is much simpler than trying to make an object out of it.

Arrch:
Foo.cpp

void myFooFunction()

{
   // do stuff
}




On your main page, use extern to tell the compiler about the function:

MySketch.ino


extern void myFooFunction(void);




The proper way to do it would be with a header file, but this requires slightly less code and, less file, and is much simpler than trying to make an object out of it.

With this method will foo.cpp inherit variables in mysketch.ino?

No, you'll need to declare then at the top of the file using the extern keyword

Ok so i try that and i get an error
Sketch code

extern double angle[] = {0, 0, 0};


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

void loop() {
 
 extern readserialtochars();
 extern parsedata();
}

and the cpp file
more.cpp

#include"Arduino.h"
#define SOP '<'
#define EOP '>'
bool started = false;
bool ended = false;
char inData[80];
byte index;
char delimiters[] = ",";
char* valPosition;
double angle[] = {0, 0, 0};

 void readserialtochars() {
   while(Serial.available() > 0)
  {
    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 < 79)
      {
        inData[index] = inChar;
        index++;
        inData[index] = '\0';
      }
    }
  }
 }

void parsedata() {
 if(started && ended)
  {
  valPosition = strtok(inData, delimiters);
   for(int i = 0; i < 3; i++){
    angle[i] = atof(valPosition);
    Serial.println(angle[i]);
    valPosition = strtok(NULL, delimiters);
    }
    
    started = false;
    ended = false;
    index = 0;
    inData[index] = '\0';
  }
}

the error i get is

Serialintodouble.ino: In function 'void loop()':
Serialintodouble:11: error: ISO C++ forbids declaration of 'readserialtochars' with no type
Serialintodouble:12: error: ISO C++ forbids declaration of 'parsedata' with no type

Addition:
I changed the more.cpp to more.ino and removed use of extern completely and it works, seems the compiler already sorts out the global variables for me.

Extern isn't used to call the function, it's used to declare the function. You need to declare it at the top in the global scope with the extern keyword. In your loop function, you should be calling the functions as normal.

extern double angle[] = {0, 0, 0};

Extern tells the compiler: This is a variable or function that I am using on this page, but it is initialized on some other page, so don't worry about it when you compile this page; the linker will take care of it.

With that understanding, it doesn't make sense to do an extern of a variable that you don't use on that page. Overall, you're better of adding a parameter to your function, instead of relying on a global variable shared between the pages.