Go Down

Topic: #include madness (Read 899 times) previous topic - next topic

dgrat

I tried to include a header file.
Unfortunately I was not able to find a way to set include paths in the IDE so I had to do the following:
Code: [Select]
#include "C:\Users\dgrat\Documents\Arduino\RPiAPMCopter\RPiAPMCopterDefs.h" // The fuck ?!

It makes me mad, so where to set paths?

KeithRB

What is this? For a library? Just some constants and declarations? The arduino has defined places for all of these. If it is just for your .ino, just put it in the same directory.

dgrat

It is more or less for constants. I put it into the same dir.
But: #include "foo.h" is not working.

KeithRB

http://forum.arduino.cc/index.php/topic,37371.0.html

PeterH


I tried to include a header file.
Unfortunately I was not able to find a way


The Arduino does some peculiar mucking around behind the scenes before it compiles your code, so you as the programmer don't control the compilation files and paths in the same way you would for a conventional C++ development environment.

If your .h file is in the same directory as your sketch, and you #include it using double quotes around the file name (no path), then that will work:

Code: [Select]

#include "foo.h"


If your .h file is not part of a sketch then it needs to be part of an Arduino library in order to be used. An Arduino library consists of a directory under the libraries directory of your Arduino sketch directory (preferred) or under the libraries directory under the Arduino software installation directory. The name of the directory is the name of the library. The directory must contain a file with the same name as the library with a .h extension. You include the library in your sketch by #including the library .h file inside double quotes into your sketch .ino file - just the file name, no path.

Code: [Select]

// includes the whole SoftwareSerial library in your sketch, as well as including the .h file in this compilation unit
#include "SoftwareSerial.h"
I only provide help via the forum - please do not contact me for private consultancy.

HazardsMind

#5
Sep 27, 2013, 05:50 am Last Edit: Sep 27, 2013, 05:51 am by HazardsMind Reason: 1
I have a question about that, what if you want to include another library inside your own library, can that be done?

So say I make a library and I want to use a function from someone else's library like SoftwareSerial. Could I get access to SoftwareSerial's functions, and if so how would I go about doing that?
My GitHub:
https://github.com/AndrewMascolo?tab=repositories

Nick Gammon


I tried to include a header file.
Unfortunately I was not able to find a way to set include paths in the IDE so I had to do the following:
...
It makes me mad, so where to set paths?


More details are required than one line. Is this inside the .ino file or another file? If another file there is a reasonably well-documented requirement that you also have to include your file in the .ino file, whether it is obvious you have to or not.
Please post technical questions on the forum, not by personal message. Thanks!

More info:
http://www.gammon.com.au/electronics

Nick Gammon


So say I make a library and I want to use a function from someone else's library like SoftwareSerial. Could I get access to SoftwareSerial's functions, and if so how would I go about doing that?


Why don't you try it and see? However I have certainly written libraries that use Wire.h or SPI.h.

However as I said in the reply above, the main sketch then needs to include those.

It's just a line or two, and that can be part of the library documentation. In fact, it helps in a way to make it clear what libraries your sketch requires (including libraries included by libraries). So, it's a feature!
Please post technical questions on the forum, not by personal message. Thanks!

More info:
http://www.gammon.com.au/electronics

HazardsMind

Quote
Why don't you try it and see? However I have certainly written libraries that use Wire.h or SPI.h.


I have tried it but, I just can't get it to work. I don't know what I'm missing. I know the answer is staring me right in the face, but I just don't see it.

.h file
Code: [Select]
//CustServo.h
#ifndef CustServo_h
#define CustServo_h

#include <Arduino.h>
#include<SoftwareSerial.h>
class CustServo
{
 public:

    void Number_of_Channels(uint8_t channel = 4);
    void SetBaud(unsigned long baud);
    void SetBaud(long baud, uint8_t TX);
    void Move(uint8_t channel, uint8_t position);
};
#endif


.cpp file
Code: [Select]
//CustServo.cpp

#include "CustServo.h"
#include <SoftwareSerial.h>
#include <HardwareSerial.h>

int ServoNum[40];
bool SoftSerial = false;


void CustServo::Number_of_Channels(uint8_t channel)
{
   for(int i = 0; i < channel; i++)
   {
     ServoNum[i] = i + 48;
   }
 // more channels to be added later
}

void CustServo::SetBaud(long baud, uint8_t TX)
{
 SoftwareSerial(-1, TX,false);
 begin(baud);
 SoftSerial = true;
}
void CustServo::SetBaud(unsigned long baud)
{
 Serial.begin(baud);
}

void CustServo::Move(uint8_t chan, uint8_t position)
{
 if(SoftSerial){
   // mySerial.write(ServoNum[chan]);              
   // write(map(position,0,180,7,247));
 }
 else {
   Serial.write(ServoNum[chan]);            // What channel to use  
   Serial.write(map(position,0,180,7,247)); // send position command
 }
}
My GitHub:
https://github.com/AndrewMascolo?tab=repositories

Nick Gammon

What isn't working? (error message).

What is your main sketch?
Please post technical questions on the forum, not by personal message. Thanks!

More info:
http://www.gammon.com.au/electronics

Nick Gammon

Your code has errors, for example:

Code: [Select]

  begin(baud);


But nothing to do with #include madness, that I can see.
Please post technical questions on the forum, not by personal message. Thanks!

More info:
http://www.gammon.com.au/electronics

HazardsMind

#11
Sep 27, 2013, 07:28 am Last Edit: Sep 27, 2013, 07:30 am by HazardsMind Reason: 1
I know that's an error, I didn't change it back when I posted it.

Sketch:
Code: [Select]
#include "CustServo.h"
#include<SoftwareSerial.h>

CustServo myServo;

void setup(){
  myServo.Number_of_Channels(4);
  delay(100);
  myServo.SetBaud(19200);
}

void loop() {
  for (int i = 0; i <= 180; i+=10){
  myServo.Move(1,i);
  delay(100);
  }
}


Errors:
SoftwareSerial.begin(baud);  => error: expected unqualified-id before '.' token
SoftwareSerial begin(baud);  => error: no matching function for call to 'SoftwareSerial::SoftwareSerial(long int&)'
SoftwareSerial::begin(baud);  => error: cannot call member function 'void SoftwareSerial::begin(long int)' without object

Like I said, I know the answer is simple but I just don't see it.
My GitHub:
https://github.com/AndrewMascolo?tab=repositories

Nick Gammon

#12
Sep 27, 2013, 07:33 am Last Edit: Sep 27, 2013, 07:36 am by Nick Gammon Reason: 1
Here's a simple way of doing what you are attempting:

CustServo.cpp:

Code: [Select]

//CustServo.cpp

#include "CustServo.h"

int ServoNum[40];

void CustServo::Number_of_Channels(uint8_t channel)
{
   for(int i = 0; i < channel; i++)
   {
     ServoNum[i] = i + 48;
   }
 // more channels to be added later
}

void CustServo::Move(uint8_t chan, uint8_t position)
{
   port_.write (ServoNum[chan]);            // What channel to use  
   port_.write (map(position,0,180,7,247)); // send position command
}


CustServo.h:

Code: [Select]

//CustServo.h
#ifndef CustServo_h
#define CustServo_h

#include <Arduino.h>

class CustServo
{
 Stream & port_;   // generic serial port
 
 public:
 // constructor
 CustServo (Stream & port) : port_ (port) { }
 
 // methods
 void Number_of_Channels(uint8_t channel = 4);
 void Move(uint8_t channel, uint8_t position);
};
#endif


Sketch using SoftwareSerial:

Code: [Select]

#include "CustServo.h"
#include <SoftwareSerial.h>

const byte TX = 5;

SoftwareSerial mySerial (-1, TX, false);
CustServo servo (mySerial);

void setup ()
 {
 mySerial.begin (9600);
 }  // end of setup

void loop () { }


Now with HardwareSerial:

Code: [Select]

#include "CustServo.h"

CustServo servo (Serial);

void setup ()
 {
 Serial.begin (9600);
 }  // end of setup

void loop () { }
Please post technical questions on the forum, not by personal message. Thanks!

More info:
http://www.gammon.com.au/electronics

HazardsMind

#13
Sep 27, 2013, 07:53 am Last Edit: Mar 20, 2014, 07:21 am by HazardsMind Reason: 1
Ok I went about it the wrong way. Yours works, but what I don't understand is "Stream & port_; " What is this doing?

Update: Library provided.
My GitHub:
https://github.com/AndrewMascolo?tab=repositories

Nick Gammon

SoftwareSerial and HardwareSerial are both derived from Stream.

eg.

Code: [Select]

class SoftwareSerial : public Stream

...

class HardwareSerial : public Stream


Thus it is valid to use Stream in your class instead of either of them. It is Stream that declares read, write, available etc.

Both SoftwareSerial and HardwareSerial override these virtual methods:

Code: [Select]

    virtual int available() = 0;
    virtual int read() = 0;
    virtual int peek() = 0;
    virtual void flush() = 0;


So, a call to port_.write() calls either SoftwareSerial.write() or HardwareSerial.write() as applicable.

By storing a reference to the Stream (the & operator) we can use the one which you instance in your main sketch. So all we have to do is pass down the appropriate instance in the constructor.
Please post technical questions on the forum, not by personal message. Thanks!

More info:
http://www.gammon.com.au/electronics

Go Up