Creating a Composite Object ...

I'm fairly new to object creation in c++ and need some help creating a
composite object (utilizing has-a relationships). This is for an
Arduino library I'm creating, so I believe it's using gcc.

I have 2 existing objects called: Encoder_AS5045 & Mtr_DRV8833. These objects
are working fine by themselves. They each currently only have a parameterized
constructor defined as follows:

1
2
3
4
5
6
7
8
9
Encoder_AS5045::Encoder_AS5045 (byte byCLK_pin, byte byCSn_pin, byte byDO_pin)
{
   ... initialization code ...
}

Mtr_DRV8833::Mtr_DRV8833 (byte byOUT1_pin, byte byOUT2_pin)
{
   ... initialization code ...
}


Here is the header file code I'm using to create the composite object (Easy_Motor):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
/*
  Easy_Motor.h - Header for easy MOTOR driver.  This includes an Encoder and TI DRV8833 DC
                 Motor Driver	and limit switches and provides basic rotory movement commands
								 (i.e. angle & revs).
	
	Revision History:
	-----------------
	03/23/13  CKL  1.0  Initial Version.
*/

#ifndef Easy_Motor_h
	#define Easy_Motor_h

	#define FORWARD 0
	#define REVERSE 1
	#define BRAKE true
	#define COAST false
	
	#ifndef Arduino_h
          #include "Arduino.h"
          #define Arduino_h
        #endif
        #include <Mtr_DRV8833.h>
	#include <Encoder_AS5045.h>

	typedef struct Location
	{
		int iAngle;
		float f_mm;
        } Location;	
	
	typedef struct SwitchState
	{
		boolean bSwitchHome,
	                bSwitchLimit;
	} SwitchState;
						 

	class Easy_Motor
	{						
		public:
		   Easy_Motor (
				byte byMtrA_1_pin,  // DRV8833 Motor Output PIN 1
                                byte byMtrA_2_pin,  // DRV8833 Motor Output PIN 2
                                byte byMtr_Encoder_DO_pin,  	// AS5045 Encoder DATA-IN PIN 
                                byte byMtr_Encoder_CSn_pin, 	// AS5045 Encoder CHIP-SELECT PIN
                                byte byMtr_Encoder_CLK_pin, 	// AS5045 Encoder CLOCK PIN
                                byte bySwitch_Home_pin,     	// HOME Switch Input PIN
                                byte bySwitch_Limit_pin,    	// LIMIT Switch Input PIN
                                boolean bSwitch_HI_LO,      	// Switch PIN state when MADE (True = HI (+), False = LO (Gnd))
				int _iEncoder_Counts_per_REV	// Counts per REV:																	        // (AS5048A/B -- 16384, AS5045 -- 4096, AS5040 -- 1024, AS5132 -- 360)
			       );
			
		   void setHomeAngle (float fHomeAngle);
		   void direction (boolean);
		   void toggle_dir ();
		   boolean getMtrDirection ();
		   void speed (int);
		   int getMtrSpeed ();
		   int getMtrAngle ();	
		   SwitchState getSwitchState ();
		// Will need a method to get the Encoder status.  Will need to make updates to 
		// the encoder object first.			
		   void start ();		
		   void stop (boolean);
                   void toggle_run (boolean);			
		   boolean isRunning ();
		   Location whereAmI (); 

		// ABSOLUTE - Will move in currently defined direction (use .direction() to update prior to this call)
                //            ** On call, test that [360 <= abs(fAngle) >= 0]			
	   	   float moveToA_degree (float fAngle);
		// RELATIVE - Will move in currently defined direction (use .direction() to update prior to this call)                                                       			
   		   float moveToR_degree (float fAngle);
			
		   float moveTo_revs (float fRevs_Target);
						
		private:
		   Mtr_DRV8833 _MyMtr;
   		   Encoder_AS5045 _MyEncoder;
			
		   SwitchState _MySwitchState;
			
	           byte _byEncoderCLKpin,
		        _byEncoderCSNpin,
			_byEncoderDOpin,
   	                _byMtrA_1pin,
			_byMtrA_2pin,
			_bySwitchHomepin,
			_bySwitchLimitpin;
	};
#endif 


I'm defining the class definitions in an include file (.h) and providing the
code in a .cpp file. I'm sure you can see where the error is occurring. I'm
trying to define references to the 2 composite objects in the private section:

Mtr_DRV8833 _MyMtr;
Encoder_AS5045 _MyEncoder;

I'm getting does not name a type errors on these lines. Yes, I
know I'm not providing a () constructor for these objects. In order to
properly configure these objects I need to call the parameterized constructor
(or break that out as an .init function and call that separately) but I won't
have the parameters until the Easy_Motor object is created. I know I'm
confusing a few concepts here, so what is the best way to do this?


I tried playing with initialization lists to address this but I wasn't
able to get something to work. I thought the use of initialization
lists
allowed a simple reference to the object to be defined (i.e. what I
tried to do above) and then I could fully define using something like this as
the Easy_Motor constructor:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Easy_Motor::Easy_Motor(
                	byte byMtrA_1_pin,
			byte byMtrA_2_pin,
			byte byMtr_Encoder_DO_pin,
			byte byMtr_Encoder_CSn_pin,
                        byte byMtr_Encoder_CLK_pin,
                        byte bySwitch_Home_pin,
                        byte bySwitch_Limit_pin,
                        boolean bSwitch_HI_LO,
                        int _iEncoder_Counts_per_REV
                      ) : _MyMtr(byMtrA_1_pin,
                                 byMtrA_2_pin),
                          _MyEncoder(byMtr_Encoder_CLK_pin,
                                     byMtr_Encoder_CSn_pin,
                                     byMtr_Encoder_DO_pin)
{
  ... rest of Easy_Motor initialization code ...
}  


But I wasn't able to get this to compile. Any help is greatly appreciated.

Thanks.
Last edited on
Have you tried writing #include "Mtr_DRV8833.h" and #include "Encoder_AS5045.h"
instead of #include <Mtr_DRV8833.h> and #include <Encoder_AS5045.h> ?
I believe the "x" include will only search in the source files directory while the <x> should search the include path. Changing existing <>'s to ""'s doesn't fix the compilation issue.

However, if I go back to the code version including the initialization list approach, I CAN get it to work IF I add specific includes to the headers for Mtr_DRV8833 & Encoder_AS5045 into the test program. So, this test program (compiled/linked from the Arduino IDE) compiles and appears to work:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <Easy_Motor.h>
// WITHOUT THESE NEXT 2 INCLUDES, DOES NOT COMPILE ...
#include <Mtr_DRV8833.h>
#include <Encoder_AS5045.h>

Easy_Motor MyMtr(3,4,7,6,2,5,6,true,4096);

void setup()
{
  Serial.begin(9600);
  
  if (MyMtr.isRunning() == false) Serial.println("Motor is STOPPED.");
  else Serial.println("Motor is RUNNING.");
  
  Location MyLoc = MyMtr.whereAmI();
  Serial.println(MyLoc.iAngle);
  Serial.println(MyLoc.f_mm);
}

void loop()
{
}


This seems odd since these 2 includes are in Easy_Motor.h header. Not sure why the compiler is not finding the includes in Easy_Motor.h. From a C++ perspective, any ideas?
Topic archived. No new replies allowed.