Request for member is of non-class type error

Hi,

I am programming uno for a motor controller. Below is the code I have used. It shows be errors as given below in two different usages.

//motor.h file
class Motor
{
public:
  Motor(int dir1, int dir2, int pwm);
  void setForward();
private:
  int _dir1, _dir2, _pwm;
};

//motor.cpp file
Motor::Motor(int dir1, int dir2, int pwm)
{
  _dir1 = dir1;
  _dir2 = dir2;
  _pwm = pwm;
  pinMode(_dir1, OUTPUT);
  pinMode(_dir2, OUTPUT);
  pinMode(_pwm, OUTPUT);
}

// sets the motor's direction to forward
void Motor::setForward(int level)
{
  analogWrite(_pwm, level);	
  digitalWrite(_dir1, HIGH);
  digitalWrite(_dir2, LOW);
}

//usage 1
Motor M0(m0APin, m0BPin, m0PwmPin);

Error Message:
MotorControl:6: error: ‘m0APin’ was not declared in this scope Motor M0(m0APin, m0BPin, m0PwmPin);

//usage 2
Motor M0 (int m0APin, int m0BPin, int m0PwmPin);

M0.setForward (100);

Error Message:
MotorControl:31: error: request for member ‘setForward’ in ‘M0’, which is of non-class type ‘Motor(int, int, int)’

Can someone please help? I am not sure where the error is.

I am not sure where the error is.

It's in the code you didn't post. We need to see the source file for the Motor class and the sketch that tries to use the Motor class.

you define a method

void Motor::setForward(int level)

with a single int parameter but the declaration of the motor class does not contain a prototype for that method
add the prototype

class Motor
{
public:
  Motor(int dir1, int dir2, int pwm);
  void setForward();
  void setForward(int level);     // <<< add prototype
private:
  int _dir1, _dir2, _pwm;
};

// sets the motor's direction to forward
void Motor::setForward(int level)
{
  analogWrite(_pwm, level);  
  digitalWrite(_dir1, HIGH);
  digitalWrite(_dir2, LOW);
}

it should then compile

Thanks for the responses. Please find below complete code attached. The errors still remain the same

/*VEEMotor.h*/

#ifndef VEEMotor_h
#define VEEMotor_h

#include "Arduino.h"

class Motor
{
public:
  Motor(int dir1, int dir2, int pwm);
  void setForward();
  void setForward(int pwm);
private:
  int _dir1, _dir2, _pwm;
};

#endif
/*VEEMotor.cpp*/

#include "Arduino.h"
#include "VEEMotor.h"

Motor::Motor(int dir1, int dir2, int pwm)
{
  _dir1 = dir1;
  _dir2 = dir2;
  _pwm = pwm;
  pinMode(_dir1, OUTPUT);
  pinMode(_dir2, OUTPUT);
  pinMode(_pwm, OUTPUT);
}

// sets the motor's direction to forward
void Motor::setForward()
{
  digitalWrite(_dir1, HIGH);
  digitalWrite(_dir2, LOW);
}

// sets the motor's direction to forward
void Motor::setForward(int level)
{
  analogWrite(_pwm, level);	
  digitalWrite(_dir1, HIGH);
  digitalWrite(_dir2, LOW);
}

void Motor::setPWM(int level)
{
  analogWrite(_pwm, level);
}
/* main.ino */
#include "VEEMotor.h"

#define m0APin      7   //  A Pin - Motor 0
#define m0BPin      8   //  B Pin - Motor 0
#define m0PwmPin      5   //  PWM Pin - Motor 0

#define m1APin      4   //  A Pin - Motor 1
#define m1BPin      9   //  B Pin - Motor 1
#define m1PwmPin      6   //  PWM Pin - Motor 1

Motor M0 (int m0APin, int m0BPin, int m0PwmPin);
Motor M1 (int m1APin, int m1BPin, int m1PwmPin);

// Global variables across all modes
int m0Value = 100;
int m1Value = 100;      // these two variables used across the program to store motor control value

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

/**/
void loop() {
M0.setForward(m0Value);
M1.setForward(m1Value);
}

for a start you don’t appear to have declared setPWM(int level) in the VEEmotor.h file

/*VEEMotor.h*/

#ifndef VEEMotor_h
#define VEEMotor_h

#include "Arduino.h"

class Motor
{
public:
  Motor(int dir1, int dir2, int pwm);
  void setForward();
  void setForward(int pwm);
  void setPWM(int level);  // <<< add
private:
  int _dir1, _dir2, _pwm;
};

#endif

also in main.ino remove the ints from declarations

Motor M0 (m0APin, m0BPin, m0PwmPin);   // remove ints
Motor M1 (m1APin, m1BPin, m1PwmPin);

horace:
for a start you don’t appear to have declared setPWM(int level) in the VEEmotor.h file

/*VEEMotor.h*/

#ifndef VEEMotor_h
#define VEEMotor_h

#include “Arduino.h”

class Motor
{
public:
  Motor(int dir1, int dir2, int pwm);
  void setForward();
  void setForward(int pwm);
  void setPWM(int level);  // <<< add
private:
  int _dir1, _dir2, _pwm;
};

#endif

horace:
for a start you don’t appear to have declared setPWM(int level) in the VEEmotor.h file

/*VEEMotor.h*/

#ifndef VEEMotor_h
#define VEEMotor_h

#include “Arduino.h”

class Motor
{
public:
  Motor(int dir1, int dir2, int pwm);
  void setForward();
  void setForward(int pwm);
  void setPWM(int level);  // <<< add
private:
  int _dir1, _dir2, _pwm;
};

#endif

Its added now. However, the issue with …which is of non-class type… is still existing.

in main.ino remove the ints from declarations

Motor M0 (m0APin, m0BPin, m0PwmPin);   // remove ints
Motor M1 (m1APin, m1BPin, m1PwmPin);

By convention, the name of the class in the file is the same as the name of the file. Why don't your files/class name follow that convention?

horace:
in main.ino remove the ints from declarations

Motor M0 (m0APin, m0BPin, m0PwmPin);   // remove ints

Motor M1 (m1APin, m1BPin, m1PwmPin);

As mentioned in my first post, I get an error when removing “int” as

MotorControl:6: error: ‘m0APin’ was not declared in this scope

Motor M0 (m0APin, m0BPin, m0PwmPin);

Renamed the .cpp and .h files to Motor.cpp and Motor.h. The issue remains the same.

After removing the int keyword from your constructor calls, I get:

Arduino: 1.8.2 (Windows 7), TD: 1.36, Board: "Arduino/Genuino Uno"

Motor.cpp:29: error: no 'void Motor::setPWM(int)' member function declared in class 'Motor'

 void Motor::setPWM(int level)

                             ^

exit status 1
no 'void Motor::setPWM(int)' member function declared in class 'Motor'

This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.

NOTHING about issues with m0APin, etc.

The issue got resolved.

  1. The #define shown in the main program was in a different ino file by name “IOconfig.ino”. After moving the constants to main program, it compiled.
  2. I have removed the “ints” as mentioned in the previous reply and that helped.
    Motor M0 (m0APin, m0BPin, m0PwmPin); // remove ints

Now the last question is, how does arduino compile? Does it not pull all the files into a single file before compilation of main.ino? If yes, how do I declare constants in a different file so that everything is pulled before Motor M0 (m0APin, m0BPin, m0PwmPin); is executed?

Thanks for your time.

Now the last question is, how does arduino compile? Does it not pull all the files into a single file before compilation of main.ino?

No. The .ino file is converted to a .cpp file, which gets compiled. The Motor.cpp file also gets compiled, separately.

The linker is what connects them together.

how do I declare constants in a different file so that everything is pulled before Motor M0 (m0APin, m0BPin, m0PwmPin); is executed?

The code is EXECUTED at run time. That happens WAY after compilation time.

You are wasting our time by not posting your real code. Quit that.

also,

you should not be putting hardware setup in the constructor like this:

Motor::Motor(int dir1, int dir2, int pwm)
{
  _dir1 = dir1;
  _dir2 = dir2;
  _pwm = pwm;
  pinMode(_dir1, OUTPUT);
  pinMode(_dir2, OUTPUT);
  pinMode(_pwm, OUTPUT);
}

the hardware is not guaranteed to be ready until setup(), so you may want to move those pinMode calls into a (i.e. begin()) method which you call in setup().

The code is EXECUTED at run time. That happens WAY after compilation time.

You are wasting our time by not posting your real code. Quit that.

Thanks for the response and apologies for not posting the code as it was. I just wanted to make it simpler for guys who take time to answer me. Hence I pulled out the code and pasted it here.

Will make sure I will attach files in future rather than pasting code here.

Since I understand that it is executed at run time, I suppose there is no way to get the #define’s in a different file. That should be OK for me. I will add those constants in the main file.

Apologies again if I have wasted your time. I always try to make sure the questions are asked in a way that it is easier for others to follow, but finally mess up. >:(

BulldogLowell:
also,

you should not be putting hardware setup in the constructor like this:

Motor::Motor(int dir1, int dir2, int pwm)

{
 _dir1 = dir1;
 _dir2 = dir2;
 _pwm = pwm;
 pinMode(_dir1, OUTPUT);
 pinMode(_dir2, OUTPUT);
 pinMode(_pwm, OUTPUT);
}




the hardware is not guaranteed to be ready until **setup()**, so you may want to move those pinMode calls into a (i.e. **begin()**) method which you call in **setup()**.

Thanks for the tip. I have added the below code as a separate function and calling M0.begin; in setup()

void Motor::begin()
{
 pinMode(_dir1, OUTPUT);
 pinMode(_dir2, OUTPUT);
 pinMode(_pwm, OUTPUT);
}

praveen_khm:
Thanks for the tip.

Another tip would be not to use the #define directive for simple literals. You can debug easier if you use:

const uint8_t m1APin  = 4;   //  A Pin - Motor 1

or even better, 'cuz this is C++

constexpr uint8_t m1APin = 4;   //  A Pin - Motor 1

Thanks. Apart from easy debugging, is there any additional advantage like quicker processing, or lesser memory usage?

praveen_khm:
Thanks. Apart from easy debugging...

that's not reason enough?

There are a bunch, but you may read some pros and cons here... paying particular attention to what God says here.

Most of the advantages will come later (if you are new to this) so it is good to start off on the right foot.

You can tell by usage like this (or typedef keyword as another example) that there are a bunch of people on the forum that grew up with plain C, so you see a lot of that paradigm here. It in't harmful, but why not use the richer benefits of C++????

is there any additional advantage like quicker processing, or lesser memory usage?

During compilation/linking? Or, at run time?

Anyway, the answers are yes and no. But, the additional time that the preprocessor takes to perform name resolution is negligible.

The real advantage is type checking at compile time.

You CAN put code, preprocessor directives, etc. in a separate file. After all, that's what you do when you put the class definition in a .h file.

If you post the real code, with the separate header file for the declarations, it is quite possible that we can explain why what you have done is wrong, why, and how to fix it. Because it SHOULD work.

@BulldogLowell

There are a bunch, but you may read some pros and cons here... paying particular attention to what God says here.

That is a lot of information. Studying it. Thanks a ton for the link.

@PaulS

You CAN put code, preprocessor directives, etc. in a separate file. After all, that's what you do when you put the class definition in a .h file.

I have put it in a separate header file and calling it in the main function. It works. Only that when I use a .ino file, it does not work. After your explanation of linking all files, I understand why it does not work. Thank you.