Pages: [1]   Go Down
Author Topic: How to initiate a class within a class definition  (Read 756 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 2
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hello
I want to create a wrapper library around the TFT library in order to manage e.g. deletion of the screen before writing new text and to implement a kind of screen saver if the application in waiting for user input and thus not changing for a while.
In order to do that I created a new class that holds some variables (such as the text to erase before writing new text) and has some functions to write to different areas of the Adafruit TFT display.
I need to initialize an instance of the TFT class from the TFT library. I tried different ways to do that. The last one was to insert a forward declaration as private variable in the class definition within the header file and to actually create the instance in the constructor code of the new class variable.
So my code fragments look like this:

// ***** TFTNew.h *****
#include <TFT.h>

class NewTFT {
public:
  NewTFT(void); // constructor
  void WriteText(char *text);
private:   
  TFT TFTScreen(uint8_t, uint8_t, uint8_t);
  char oldstr[8];
};

// ***** TFTNew.cpp *****
include "TFTNew.h"
include <TFT.h>
NewTFT::NewTFT(void)
{
  // ...
  TFT TFTscreen(10, 9, 8 );
  TFTscreen.begin();
}

void NewTFT::WriteText(char *text)
{
  TFTscreen.setTextSize(2);
  TFTscreen.stroke(0);
  TFTscreen.text(oldstr,0,0);
  TFTscreen.stroke(0xFFFF);
  TFTscreen.text(text,0,0);
  //...
}

Now the Arduino IDE compiler gives me an error message, that the TFTScreen is out of scope for the member function. The error message is as follows:
NewTFT.cpp: In member function 'void NewTFT::WriteText(char)':
NewTFT.cpp:36: error: 'TFTscreen' was not declared in this scope

How to you declare and initiate a class within a class definition?
Thanks for help.
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 601
Posts: 48543
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
How to you declare and initiate a class within a class definition?
In the constructor:
Code:
NewTFT::NewTFT(void):TFTscreen(10, 9, 8 )
{
  TFTscreen.begin();
}

You should NOT be calling the begin() method for the TFTscreen instance in the constructor of your class. You to need a begin() method.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 2
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hello again,

after the previous reply and some further reading I understand, that I should inherit the TFT class in the NewTFT class. So i modified the code as below (btw: I am using the Ardiono 1.0.5 IDE):

TFTNew.h
Code:
// ***** TFTNew.h *****
#ifndef _TFTNew_H
#define _TFTNew_H

#include <TFT.h>
class NewTFT : public TFT {    //line 35: in original file
public:
  /// constructor
  NewTFT(uint8_t CS, uint8_t RS, uint8_t RST);
  void WriteText(char *text);
private:   
  char oldstr[8];
};

#endif // _TFTNew_H
TFTNew.cpp

Code:
// ***** TFTNew.cpp *****
include "TFTNew.h"
include <TFT.h>

NewTFT::NewTFT(uint8_t CS, uint8_t RS, uint8_t RST)
  : TFT(CS, RS, RST)                                                        //line 24: in original file
{
  // ...
 
}

void NewTFT::WriteText(char *text)
{
  setTextSize(2);                                                       //line 37: in original file
  //...
}
Main sketch
Code:
#include "TFTNew.h"
include <TFT.h>

NewTFT td = NewTFT(10,9,8);
char txt[] = "Hello";

void setup()
{
// I know that the TFT.begin() method is still missing but I am still stuck with the compile errors
}

void loop()
{
td.WriteText(txt);
}

I put all files in the same directory in order to avoid the library path complexity I read about in other postings.

So when I compile check this sketch I get the following error log:
Code:
In file included from TFTNew.cpp:1:
TFTNew.h:35: error: expected class-name before '{' token
TFTNew.cpp: In constructor 'NewTFT::NewTFT(uint8_t, uint8_t, uint8_t)':
TFTNew.cpp:24: error: class 'NewTFT' does not have any field named 'TFT'
TFTNew.cpp: In member function 'void NewTFT::WriteText(char *)':
TFTNew.cpp:37: error: 'setTextsize' was not declared in this scope

I maybe blind, but I could not find anything wrong with the above code.

PaulS: Thanks for directing my, however, I am not sure which part should go into the .h or .cpp file (or even the .ino)
Thanks for your help.
Thomas
Logged

0
Offline Offline
Shannon Member
****
Karma: 200
Posts: 11694
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

C++ is complex and non-intuitive in these areas I reckon.

Best is to find an existing example of inheritance somewhere and work from that, whilst reading
up on C++ constructors and scope and so forth.  Start with the simplest class and make one change
at a time.

You actual problem can be done in two ways, either inherit/extend or delegate - if I were delegating I'd
try to make the target class passed as a reference in the constructor of the wrapper class.  Delegating
involves less assumptions about the class you are referring to, but you may have to write lots of
boilerplate.

You also have the option of not using a class which may be simpler!
Logged

[ I won't respond to messages, use the forum please ]

0
Offline Offline
Newbie
*
Karma: 0
Posts: 36
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

hello all  - i am equally interested in this topic as tlingenthal is.  Any latest guidance on his thread.  I have a similar need to address in my project (http://alibe.codeplex.com/)

thanks

nagi
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 601
Posts: 48543
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
I maybe blind, but I could not find anything wrong with the above code.
Really? Look in the TFT.h file in the TFT library. There is no class called TFT. You can't inherit from a non-existent class.
Logged

Left Coast, CA (USA)
Offline Offline
Brattain Member
*****
Karma: 361
Posts: 17262
Measurement changes behavior
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
I maybe blind, but I could not find anything wrong with the above code.
Really? Look in the TFT.h file in the TFT library. There is no class called TFT. You can't inherit from a non-existent class.

Uuu that sounds bad?  smiley-wink

I gave up going to class over 40 years ago.
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 36
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Hello all
I am trying to inherit from the "Servo" class to implement a few additional methods that address my project needs. I must also be blind, what am i missing to get this resolved.  any and all help is greatly appreciated. Thanks all in advance

The code snippets and the compilation error details are below:

Code:
// ALIBESteer.h file
#ifndef ALIBESteer_h
#define ALIBESteer_h
#include <Arduino.h>
#include <Servo.h>
#define ALIBE_STEER_SERVO_PIN 9
class ALIBESteer : public Servo {
public:
ALIBESteer();
bool turnLeft();
bool turnRight();
bool turnStraight();
private:
Servo _steer;
};
#endif


Code:
// ALIBESteer.cpp file
#include <Arduino.h>
#include <Servo.h>
#include <ALIBESteer.h>

ALIBESteer::ALIBESteer(){
// attaches the servo on pin ALIBE_STEER_SERVO_PIN to the servo object
_steer.attach(ALIBE_STEER_SERVO_PIN); 
turnStraight();
}

//public
bool ALIBESteer::turnLeft(){
_steer.write(0);              // tell servo to go to position 0d - left
delay(15);                        // waits 15ms for the servo to reach the position

}
bool ALIBESteer::turnRight(){
_steer.write(180);             // tell servo to go to position 180d - right
delay(15);                        // waits 15ms for the servo to reach the position

}
bool ALIBESteer::turnStraight(){
_steer.write(90);             // tell servo to go to position 90d - straight ahead
delay(15);                        // waits 15ms for the servo to reach the position
}

Code:
#include "ALIBESteer.h"
ALIBESteer _s;
void setup(){
delay(1000);
_s.turnLeft();
delay(1000);
_s.turnRight();
delay(1000);
_s.turnStraight();
}
void loop(){
//
}

Error message on compilation:

Code:
In file included from ALIBESteer.ino:1:
C:\Arduino\libraries\ALIBESteer/ALIBESteer.h:8: error: expected class-name before '{' token
C:\Arduino\libraries\ALIBESteer/ALIBESteer.h:15: error: 'Servo' does not name a type
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 601
Posts: 48543
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
I must also be blind, what am i missing to get this resolved. 
You are missing an include statement in your .ino file. You can NOT hide the use of the Servo library.
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 36
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

@PaulS - Than you - indeed that took care of the problem.
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 36
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

i was too quick in lighting the cigar. 

The code compiled just fine.  but, the servo does not work.  It is supposed to turn the servo on pin 9 to 0d, 90d and 180d.  But, does nothing.

just to confirm that the wiring is all good, i uploaded the "Sweep" example and that works w/o any issues whatsoever.

any guidance on what might be wrong. 

thank you in advance

Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 601
Posts: 48543
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
any guidance on what might be wrong.
Yes. Do you know when your constructor is called, relative to when the pin is ready to have a servo attached to it?

You'll undoubtedly, have noticed that there are methods like Serial.begin(), EthernetClient.begin(), EthernetServer.begin(), etc.

In the begin() method is where you do the hardware-related stuff, NOT in the constructor.
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 36
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

@PaulS - thank you yet again Paul. That fixed the problem;
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 36
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

here's the final code based on the recommendations @PaulS made (thanks again @PaulS):

Code:
// ALIBESteer.h file
#ifndef ALIBESteer_h
#define ALIBESteer_h
#include <Arduino.h>
#include <Servo.h>
#define ALIBE_STEER_SERVO_PIN 9

class ALIBESteer : public Servo {
public:
ALIBESteer();
void begin();
bool turnLeft();
bool turnRight();
bool turnStraight();
private:
Servo _steer;
};
#endif

Code:
// ALIBESteer.cpp file
#include <Arduino.h>
#include <Servo.h>
#include <ALIBESteer.h>

ALIBESteer::ALIBESteer(){
//
}

//public
void ALIBESteer::begin(){
// attaches the servo on pin ALIBE_STEER_SERVO_PIN to the servo object
_steer.attach(ALIBE_STEER_SERVO_PIN); 
turnStraight();
}

bool ALIBESteer::turnLeft(){
_steer.write(0);              // tell servo to go to position 0d - left
delay(15);                        // waits 15ms for the servo to reach the position

}
bool ALIBESteer::turnRight(){
_steer.write(180);             // tell servo to go to position 180d - right
delay(15);                        // waits 15ms for the servo to reach the position

}
bool ALIBESteer::turnStraight(){
_steer.write(90);             // tell servo to go to position 90d - straight ahead
delay(15);                        // waits 15ms for the servo to reach the position
}

Code:
#include <ALIBESteer.h>
#include <Servo.h>
ALIBESteer _s;
void setup(){
_s.begin();
}
void loop(){
delay(1000);
_s.turnLeft();
delay(1000);
_s.turnRight();
delay(1000);
_s.turnStraight();
//
}


...now onto the next few left module libs....

thanks all.

Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 36
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset


https://alibe.codeplex.com/
Logged

Pages: [1]   Go Up
Jump to: