A bug in an oobject using an other objet

Hey guys,

I m trying to program my arduino Mega 2560.
I created two libraries : 1 called "Relay" and an other called "shutter".
The second library use the first library in its code. But I ve got this message error :

Shutter\Shutter.cpp.o: In function `Shutter':
C:\Program Files (x86)\Arduino\libraries\Shutter/Shutter.cpp:11: undefined reference to `Relay::Relay(int)'
C:\Program Files (x86)\Arduino\libraries\Shutter/Shutter.cpp:11: undefined reference to `Relay::Relay(int)'

I think I don't have any error in my library called Ralay because I have already tested it. So I think that it's an error in my constructor of my class shutter.

I let you look at my general code :

#include <Shutter.h>
/* 
shutter shuterTest(pin_of_the_relay1, pin_of_the_relay2, pin_of_the_button);
*/

Shutter shutterTest(1,2,3);

void setup()
{
  
}

void loop()
{
  
}

then I let you look at my library "shutter"

shutter.h :

#ifndef SHUTTER_h
#define SHUTTER_h

#include "Arduino.h"

#include "..\Relay\relay.h"

class Shutter // Object Shutter 
{

	public :
        Shutter(int pinRelay1, int pinRelay2, int pinBouton);
		void open();													//open the shutter
		void close();												//close the shutter
		bool isPushed();											//Is the button of the shutter pushed ? 1 if yes 0 if no
		bool isActivated();											//Is the button of the shutter activated ? 1 if yes 0 if no
		void setActivated(boolean a);								//Change the value of _activated
		void stopAction();											//Some times after using the open or close method, you should use this method.
		
    private :
		boolean _activated;
		int _pinBouton;
                Relay _relay1;
		Relay _relay2;
 
    
};
 
#endif

shutter.cpp :

/*
Shutter.cpp - Bibliothèque pour gérer les volets.	        |	Shutter.cpp - Library to manage shutters
_________						        |	
auteur Frank FILODA 					        |	
création : 19/12/2014						|	

*/

#include "Shutter.h"

	Shutter::Shutter(int pinRelay1, int pinRelay2, int pinBouton) : _pinBouton(pinBouton), _activated(1), _relay1(pinRelay1), _relay2(pinRelay2)
	{
	
	}

	void Shutter::open()
	{
		_relay2.off();
		_relay1.on();
		_relay2.on();
	}

	void Shutter::close()
	{
		_relay2.off();
		_relay1.off();
		_relay2.on();
	}
	
	bool Shutter::isPushed()
	{
		return 1;
	}
	
	bool Shutter::isActivated()
	{
		return _activated;
	}

	void Shutter::setActivated(boolean a)
	{
		if(a)
		{
			_activated = 1;
		}
		else
		{
			_activated = 0;
		}
	}	
	
	void Shutter::stopAction()
	{
		_relay2.off();
	}

If you have any questions about my project or my code I can answer you.

Thank you,

Frank

You are including relay.h wrong. Your sketch is copied to another location to compile and your relay lib does not exist there. You need to get the IDE to import it with the shutter library. More info: http://arduino.land/FAQ/content/1/3/en/what-does-the-ide-change-in-my-sketch.html << third bullet point explains.

Also ensure the lib.h is the same as the folder, even case matters ( relay or Relay ):

In your sketch you need to include both libs:

#include <Shutter.h>
#include <Relay.h>
/* 
shutter shuterTest(pin_of_the_relay1, pin_of_the_relay2, pin_of_the_button);
*/
 
Shutter shutterTest(1,2,3);
 
void setup()
{
   
}
 
void loop()
{
   
}

And Shutter.h

#ifndef SHUTTER_h
#define SHUTTER_h
 
#include "Arduino.h"
 
#include <Relay.h>
 
class Shutter // Object Shutter 
{

Hi Frank

Could you please post Relay.h and Relay.cpp as well?

Thanks

Ray

Thank you for your quick help,

@pYro_65 : Yes, It s not reallly clear. My library Shutter is composed of Shutter.cpp and Shutter.h
and the librairy Relay is composed of relay.cpp and relay.h

@Hackscribble : I post immediately the files :

relay.h :

#ifndef RELAY_h
#define RELAY_h

#include "Arduino.h"

class Relay // Objet Relay
{
   private:
       int _pin;               
       boolean _isOFF;           

   public:
       Relay(int pin);              
       void off();              //Put in position close
       void on();               //Put in position open
       bool isStateOFF() const;    //Return TRUE if the relay is open
       void switchState();      //switch the relay position
};

#endif

and relay.cpp :

/*
Relay.cpp - Bibliothèque pour gérer les relais.
_________
auteur Frank FILODA 
création : 19/12/2014

*/

#include "relay.h"


Relay::Relay(int pin)
{
   _pin = pin;
   pinMode(_pin, OUTPUT);
   _isOFF = true;
}

bool Relay::isStateOFF() const
{
   return (_isOFF);
}

void Relay::on()
{
   digitalWrite(_pin,HIGH);
   _isOFF = false;
}

void Relay::off()
{
   digitalWrite(_pin,LOW);
   _isOFF = true;
}

void Relay::switchState()
{
   if(_isOFF)
   {
       on();
   }
   else
   {
       off();
   }
}

Thanks, Frank.

Have pYro_65's suggestions fixed the compile problem?

Not related to your compile error, I can see a potential issue in relay.cpp - I know you said it works but it might cause problems at some point.

Relay::Relay(int pin)
{
   _pin = pin;
   pinMode(_pin, OUTPUT);
   _isOFF = true;
}

It's good practice on the Arduino that doing stuff with hardware (such as pinMode()) should not be included in an object constructor. The object could be created before the Arduino environment has been initialised and the hardware calls may therefore fail.

The recommended approach is to add a public begin() method to the class, move the hardware-related code into it, and call it from setup(), at which time the Arduino environment will be active.

EDIT

I have attached a simple example of an object inside an object doing hardware stuff and use of the begin() method. LEDhandler is the lower-level object (like your relay) and Toggler is the higher-level (like your Shutter).

toolkit_object_in_object.zip (1.21 KB)

Thank you Hackscribble,

Your example was very usefull ! I did not think about the problem of the function pinMode()... My bad.

Just a quote, I must not use the pointer. I post my new files :

shutter.h :

#ifndef SHUTTER_h
#define SHUTTER_h

#include "Arduino.h"
#include "..\Relay\relay.h"

class Shutter // Object Shutter 
{

 public :
        Shutter(int pinRelay1, int pinRelay2, int pinBouton);
 void begin();
 void open(); //open the shutter
 void close(); //close the shutter
 bool isPushed(); //Is the button of the shutter pushed ? 1 if yes 0 if no
 bool isActivated(); //Is the button of the shutter activated ? 1 if yes 0 if no
 void setActivated(boolean a); //Change the value of _activated
 void stopAction(); //Some time after using the open or close method, you should use this method.
 
    private :
 boolean _activated;
 int _pinBouton;
        Relay _relay1;
 Relay _relay2;
 
 
};
 
#endif

shutter.cpp :

/*
Shutter.cpp - Bibliothèque pour gérer les volets. | Shutter.cpp - Library to manage shutters
_________ | 
auteur Frank FILODA | 
création : 19/12/2014 | 

*/

#include "Shutter.h"

 Shutter::Shutter(int pinRelay1, int pinRelay2, int pinBouton) : _pinBouton(pinBouton), _activated(1), _relay1(pinRelay1), _relay2(pinRelay2)
 {
 
 }
 
 void Shutter::begin()
 {
 _relay1.begin();
 _relay2.begin();
 }

 void Shutter::open()
 {
 _relay2.off();
 _relay1.on();
 _relay2.on();
 }

 void Shutter::close()
 {
 _relay2.off();
 _relay1.off();
 _relay2.on();
 }
 
 bool Shutter::isPushed()
 {
 return 1;
 }
 
 bool Shutter::isActivated()
 {
 return _activated;
 }

 void Shutter::setActivated(boolean a)
 {
 if(a)
 {
 _activated = 1;
 }
 else
 {
 _activated = 0;
 }
 } 
 
 void Shutter::stopAction()
 {
 _relay2.off();
 }

relay.h

#ifndef RELAY_h
#define RELAY_h


#include "Arduino.h"

class Relay // Objet Relay
{
    private:
        int _pin;               
        boolean _isOFF;           
 
    public:
        Relay(int pin);              
        void off();              
        void on();               
        bool isStateOFF() const;   
        void switchState();      
        void begin();
};
 
#endif
/*
Relay.cpp - Bibliothèque pour gérer les relais.
_________
auteur Frank FILODA 		
création : 19/12/2014

*/

#include "relay.h"
 
 
Relay::Relay(int pin)
{
    _pin = pin;
    _isOFF = true;
}

void Relay::begin()
{
    pinMode(_pin, OUTPUT);
}

bool Relay::isStateOFF() const
{
    return (_isOFF);
}

void Relay::on()
{
    digitalWrite(_pin,HIGH);
    _isOFF = false;
}

void Relay::off()
{
    digitalWrite(_pin,LOW);
    _isOFF = true;
}

void Relay::switchState()
{
    if(_isOFF)
    {
        on();
    }
    else
    {
        off();
    }
}

Thank you so much for your help.

Frank