Multiple files with servo motor control

Hello to everybody,

I am trying to modify the code for a servo motor loop using .h and .cpp files in order to improve code readability. I am just a hobbyist, with very few notions in programming or electronics so please be patient :slight_smile:
I am using an Arduino Uno with a PCA 9685 Controller and a MG946R servo connected through I2C. Here are some screenshot of the connections:

1 VCC
2 GND
3 SDA
4 SCL
5 Servo
6 Charger GND
7 All

I used this topic as a reference:

Using classes in tabs in the Arduino IDE?

I am controlling multiple servos, but to keep it simple I only posted the code for one single motor. Here is the original code:


#include <Wire.h>
#include <Adafruit_PWMServoDriver.h>

Adafruit_PWMServoDriver pwm =Adafruit_PWMServoDriver();

#define ServoMin 150 
#define ServoMax 510 //look for this values in the datasheet


void servowrite(int servonum, int angle){           //It moves the servo to a specific angle using setPWM
  int tick =map(angle,0,180,ServoMin,ServoMax);     //assigns the angle to the tick in the duty cycle
  pwm.setPWM(servonum,0,tick);
  }

void zeroset(){                                     //put all the servos to 90 degrees
  for(int i=0;i<6;i++){                             //Servos connected to pins 0,2,4,...,10
    servowrite(2*i,90);
    delay(100);
    }
  }

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  pwm.begin();
  pwm.setPWMFreq(60);
  delay(100);

  zeroset();                                         
  delay(1000);

}

void loop() {
     // put your main code here, to run repeatedly:

  for(int i=0; i<4; i++){           //Step 1
    servowrite(0,90-15*i);          
    delay(100);                     
    if (i<3){
      servowrite(10,90-10*i);
      delay(100);
      }
    }
    
    
    }

Here is the modified project with .h and .cpp files
walking.ino (558 Bytes)
walking.cpp (660 Bytes)
walking.h (447 Bytes)

I opened this topic for two reasons:

  • understand why the code is not working (if necessary I will post the error messages);

  • understand how to use classes and multiple files when there is a function that is calling another one (like step1 calling servowrite).

Any help would be greatly appreciated. Kind regards.

It's necessary.

Ok Idahowalker, here is the list. Given my lack of experience, it is hard for me to understand their meaning, but I really want to learn and be useful to the Arduino community.

Arduino:1.8.19 (Windows 7), Scheda:"Arduino Uno"

walking.cpp:7:70: error: 'i' is not a type

 Walking::Walking(int servnum, int angl, Adafruit_PWMServoDriver pwm, i)

                                                                      ^

walking.cpp:7:1: error: prototype for 'Walking::Walking(int, int, Adafruit_PWMServoDriver, int)' does not match any in class 'Walking'

 Walking::Walking(int servnum, int angl, Adafruit_PWMServoDriver pwm, i)

 ^~~~~~~

In file included from C:\Users\utente\Documents\Servo\walking\walking.cpp:2:0:

walking.h:7:7: error: candidates are: constexpr Walking::Walking(Walking&&)

 class Walking

       ^~~~~~~

walking.h:7:7: error:                 constexpr Walking::Walking(const Walking&)

walking.h:20:5: error:                 Walking::Walking(int, int)

     Walking(int servnum, int angl );

     ^~~~~~~

walking.cpp:7:70: error: 'int Walking::i' is private within this context

 Walking::Walking(int servnum, int angl, Adafruit_PWMServoDriver pwm, i)

                                                                      ^

In file included from C:\Users\utente\Documents\Servo\walking\walking.cpp:2:0:

C:\Users\utente\Documents\Servo\walking\walking.h:14:9: note: declared private here

     int i;

         ^

walking:11:18: error: no matching function for call to 'Walking::Walking(int, int, int)'

 Walking A(0, 0, 0);

                  ^

In file included from C:\Users\utente\Documents\Servo\walking\walking.ino:4:0:

C:\Users\utente\Documents\Servo\walking\walking.h:20:5: note: candidate: Walking::Walking(int, int)

     Walking(int servnum, int angl );

     ^~~~~~~

C:\Users\utente\Documents\Servo\walking\walking.h:20:5: note:   candidate expects 2 arguments, 3 provided

C:\Users\utente\Documents\Servo\walking\walking.h:7:7: note: candidate: constexpr Walking::Walking(const Walking&)

 class Walking

       ^~~~~~~

C:\Users\utente\Documents\Servo\walking\walking.h:7:7: note:   candidate expects 1 argument, 3 provided

C:\Users\utente\Documents\Servo\walking\walking.h:7:7: note: candidate: constexpr Walking::Walking(Walking&&)

C:\Users\utente\Documents\Servo\walking\walking.h:7:7: note:   candidate expects 1 argument, 3 provided

C:\Users\utente\Documents\Servo\walking\walking.ino: In function 'void zeroset()':

walking:16:5: error: 'servowrite' was not declared in this scope

     servowrite(2 * i, 90);

     ^~~~~~~~~~

C:\Users\utente\Documents\Servo\walking\walking.ino:16:5: note: suggested alternative: 'fwrite'

     servowrite(2 * i, 90);

     ^~~~~~~~~~

     fwrite

C:\Users\utente\Documents\Servo\walking\walking.cpp: In member function 'void Walking::step1()':

walking.cpp:29:30: error: no matching function for call to 'Walking::servowrite(int, int)'

     servowrite(0, 90 - 15 * i);

                              ^

C:\Users\utente\Documents\Servo\walking\walking.cpp:20:6: note: candidate: void Walking::servowrite()

 void Walking::servowrite()

      ^~~~~~~

C:\Users\utente\Documents\Servo\walking\walking.cpp:20:6: note:   candidate expects 0 arguments, 2 provided

walking.cpp:32:33: error: no matching function for call to 'Walking::servowrite(int, int)'

       servowrite(10, 90 - 10 * i);

                                 ^

C:\Users\utente\Documents\Servo\walking\walking.cpp:20:6: note: candidate: void Walking::servowrite()

 void Walking::servowrite()

      ^~~~~~~

C:\Users\utente\Documents\Servo\walking\walking.cpp:20:6: note:   candidate expects 0 arguments, 2 provided

exit status 1

'i' is not a type

Post all of those files inline in this thread. Why make us download them?

Here are some guidelines for having multiple .h / .cpp files:

I have no idea what that line of code is or where it would be placed.

But anyone can see that the other three parameters, if that is what they are, have a type preceding an identifier, int, int and Adafruit_PWMServoDriver.

i does not. Compiler complains. Is it the problem? IDK. Is it a problem? IDK, but maybe.

a7

You can load the three file files into the Wokwi simulator and folks could see the files and the error messages more easily than downloading them and loading them into a sketch.

Does the class work when in a single file?

looking into walking.cpp I find,

Walking::Walking(int servnum, int angl, Adafruit_PWMServoDriver pwm, i)

perhaps you meant to type the variable i as a an int which would be

Walking::Walking(int servnum, int angl, Adafruit_PWMServoDriver pwm, int i)

It's best to post all the code instead of making people download a thing we don't really want. Also, posting the error message right off the bat would have saved a few.

1 Like

Sorry Idahowalker, I did not post all the code because some people might get bored reading long threads. Now I wrote "int i" both in walking.cpp and walking.h.

walking.ino


#include <Wire.h>
#include "walking.h"
#include <Adafruit_PWMServoDriver.h>
Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();


int flag = 0;

Walking A(0, 0, 0);


void zeroset() {
  for (int i = 0; i < 6; i++) {
    servowrite(2 * i, 90);
    delay(100);
  }
}


void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  pwm.begin();
  pwm.setPWMFreq(60);
  delay(100);

  zeroset();
  delay(1000);

}

void loop() {
  // put your main code here, to run repeatedly:
  A.step1();

}

walking.cpp


#include "walking.h"
#include "Arduino.h"
#include <Wire.h>
#include <Adafruit_PWMServoDriver.h>

Walking::Walking(int servnum, int angl, Adafruit_PWMServoDriver pwm, int i)
{
  servonum = servnum;
  angle = angl;
  ServoMin = 150;
  ServoMax = 510;
  i = 0;
  tick = 0;
  pwm = pwm;
  pwm = Adafruit_PWMServoDriver();

}

void Walking::servowrite()
{
  int tick = map(angle, 0, 180, ServoMin, ServoMax);
  pwm.setPWM(servonum, 0, tick);
}

void Walking::step1()
{
  for (int i = 0; i < 4; i++) {
    servowrite(0, 90 - 15 * i);
    delay(100);
    if (i < 3) {
      servowrite(10, 90 - 10 * i);
      delay(100);
    }
  }
}

walking.h


#ifndef WALKING_H
#define WALKING_H
#include <Wire.h>
#include <Adafruit_PWMServoDriver.h>

class Walking
{
  private:
    int servonum;
    int angle;
    int ServoMin;
    int ServoMax;
    int i;
    int tick;
    Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();

  public:
    //constructor
    Walking(int servnum, int angl, Adafruit_PWMServoDriver pwm, int i);

    //member function
    void servowrite();
    void step1();

};

#endif

Error messages

C:\Users\utente\Documents\Servo\walking\walking.cpp: In member function 'void Walking::step1()':

walking.cpp:29:30: error: no matching function for call to 'Walking::servowrite(int, int)'

     servowrite(0, 90 - 15 * i);

                              ^

C:\Users\utente\Documents\Servo\walking\walking.cpp:20:6: note: candidate: void Walking::servowrite()

 void Walking::servowrite()

      ^~~~~~~

C:\Users\utente\Documents\Servo\walking\walking.cpp:20:6: note:   candidate expects 0 arguments, 2 provided

walking.cpp:32:33: error: no matching function for call to 'Walking::servowrite(int, int)'

       servowrite(10, 90 - 10 * i);

                                 ^

C:\Users\utente\Documents\Servo\walking\walking.cpp:20:6: note: candidate: void Walking::servowrite()

 void Walking::servowrite()

      ^~~~~~~

C:\Users\utente\Documents\Servo\walking\walking.cpp:20:6: note:   candidate expects 0 arguments, 2 provided

walking:11:18: error: no matching function for call to 'Walking::Walking(int, int, int)'

 Walking A(0, 0, 0);

                  ^

In file included from C:\Users\utente\Documents\Servo\walking\walking.ino:4:0:

C:\Users\utente\Documents\Servo\walking\walking.h:20:5: note: candidate: Walking::Walking(int, int, Adafruit_PWMServoDriver, int)

     Walking(int servnum, int angl, Adafruit_PWMServoDriver pwm, int i);

     ^~~~~~~

C:\Users\utente\Documents\Servo\walking\walking.h:20:5: note:   candidate expects 4 arguments, 3 provided

C:\Users\utente\Documents\Servo\walking\walking.h:7:7: note: candidate: constexpr Walking::Walking(const Walking&)

 class Walking

       ^~~~~~~

C:\Users\utente\Documents\Servo\walking\walking.h:7:7: note:   candidate expects 1 argument, 3 provided

C:\Users\utente\Documents\Servo\walking\walking.h:7:7: note: candidate: constexpr Walking::Walking(Walking&&)

C:\Users\utente\Documents\Servo\walking\walking.h:7:7: note:   candidate expects 1 argument, 3 provided

C:\Users\utente\Documents\Servo\walking\walking.ino: In function 'void zeroset()':

walking:16:5: error: 'servowrite' was not declared in this scope

     servowrite(2 * i, 90);

     ^~~~~~~~~~

C:\Users\utente\Documents\Servo\walking\walking.ino:16:5: note: suggested alternative: 'fwrite'

     servowrite(2 * i, 90);

     ^~~~~~~~~~

     fwrite

exit status 1

no matching function for call to 'Walking::servowrite(int, int)'

gfvalvo, thank you for the link. Following your suggestion and a classy solution I started creating the class for the simplest function in the code: servowrite

#include <Adafruit_PWMServoDriver.h>

class servowrite
{
    // Class Member Variables - These are initialized at startup
    int servonum;
    int angle;
    int ServoMin;
    int ServoMax;
    Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();

    // Constructor - initializes the member variables and state
  public:
    servowrite(int serv_n, int ang, int SMin, int SMax, Adafruit_PWMServoDriver p_w_m)
    {
      servonum = serv_n;
      angle = ang;
      ServoMin = SMin;
      ServoMax = SMax;
      pwm = p_w_m;
    }

    //Member function
    void servowrite(int servonum, int angle)
    {
      int tick = map(angle, 0, 180, ServoMin, ServoMax);
      pwm.setPWM(servonum, 0, tick);
    }

};

void setup()
{
}

void loop()
{
}

Error messages

Class_Servowrite:23:42: error: return type specification for constructor invalid

   void servowrite(int servonum, int angle){
                                          ^
exit status 1

return type specification for constructor invalid

Two problems I see right away:

  • You have a member function with the same name as the class.

  • Instead of this:

Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();

Do This:

Adafruit_PWMServoDriver pwm;

I think you are going to have a problem with each Walking having a separate copy of the Adafruit_PWMServoDriver object. I would recommend you define a separate class for the servos.

class PWMServo
{
 public:
    PWMServo(Adafruit_PWMServoDriver *_driver, int _index, int _min = 150, int _max = 510)
    {
       PWMDriver = _driver;
       index = _index;
       ticksMinimum = _min;
       ticksMaximum = _max;
    }

   void write(int angle)
   {
      int ticks = map(angle, 0, 180, ticksMinimum, ticksMaximum);
      PWMdriver->setPWM(index, 0, ticks);
   }

 private:
    Adafruit_PWMServoDriver *PWMdriver;
    int index;
    int ticksMinimum;
    int ticksMaximum;
};

Then you can create the PWMServo objects in your main sketch and pass them to the Walking object so it doesn't need to know about what an Adafruit_PWMServoDriver is.

#include <Adafruit_PWMServoDriver.h>
Adafruit_PWMServoDriver pwm;

PWMServo s0(pwm, 0);
PWMServo s1(pwm, 1);
PWMServo s2(pwm, 2);
PWMServo s3(pwm, 3);

Walking  A(s0);
Walking  B(s1);

void setup() 
{
  // put your setup code here, to run once:
  Serial.begin(9600);
  pwm.begin();
  pwm.setPWMFreq(60);
}

void loop()
{
  A.step1();
}

In Walking you would use the PWMServo object that got passed in just as you would any servo:

servo.write(90 - 15 * i);

The PWMServo object knows what Adafruit_PWMServoDriver to use and knows its index among the 16 servos so all it needs is an angle.

This code is passing a COPY of the Adafruit_PWMServoDriver object to the PWMServo constructor:

This constructor is expecting to be passed a pointer to a Adafruit_PWMServoDriver object:

Fixing the relevant parts:

class PWMServo {
  public:
    PWMServo(Adafruit_PWMServoDriver &_driver, int _index, int _min = 150, int _max = 510) : PWMdriver(_driver) {

    }

  private:
    Adafruit_PWMServoDriver &PWMdriver;
};

Also, the constructor for the Walking class should be modified to be passed a Reference to a PWMServo object for the same reason.

Sorry, I meant to pass the address:

PWMServo s0(&pwm, 0);
PWMServo s1(&pwm, 1);
PWMServo s2(&pwm, 2);
PWMServo s3(&pwm, 3);

johnwasser, gfvalvo, you're very helpful and skilled. I need some time to understand your codes. I will be back to you once I have good questions and after a compilation attempt.

//Class_Servowrite.ino
#include <Adafruit_PWMServoDriver.h>

class servowrite
{
    // Class Member Variables - These are initialized at startup
    int servonum;
    int angle;
    int ServoMin;
    int ServoMax;
    Adafruit_PWMServoDriver pwm;

    // Constructor - initializes the member variables and state
  public:
    void servo_move(int serv_n, int ang, int SMin, int SMax, Adafruit_PWMServoDriver p_w_m)
    {
      servonum = serv_n;
      angle = ang;
      ServoMin = SMin;
      ServoMax = SMax;
      pwm = p_w_m;
    }

    //Member function
    void servo_move(int servonum, int angle)
    {
      int tick = map(angle, 0, 180, ServoMin, ServoMax);
      pwm.setPWM(servonum, 0, tick);
    }

};

void setup()
{
}

void loop()
{
}

I applied your corrections and put the "void" type before the functions, I had zero errors during the compilation but I will johnwasser's file instead of mine.

Walking_immagine_esplicativa

This is what I understood so far. The write() function is needed for zeroset() and step().

-zeroset() puts every servo to 90 degrees
-step1() puts every servo from 90 to 45 degrees

As you can see below, I modified them putting johnwasser's code in the loop

PWMServo si(pwm, i);

These two functions are defined in walking.cpp and declared in walking.h. The .ino file need the .cpp and .h files in order to run. I included the files with "#include" according to the diagram that I uploaded. Here are the codes and errors.

//Test_h_cpp.ino

#include "Arduino.h"
#include <Wire.h>
#include "walking.h"
#include "walking.cpp"
#include "PWMServo.h"
#include <Adafruit_PWMServoDriver.h>


void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  pwm.begin();
  pwm.setPWMFreq(60);
  delay(100);

  walking::zeroset();
  delay(1000);

}

void loop() {
  walking::step1();

}
//PWMServo.h

#include "Arduino.h"
#include <Adafruit_PWMServoDriver.h>

class PWMServo
{
  public:
    PWMServo(Adafruit_PWMServoDriver &_driver, int _index, int _min = 150, int _max = 510) : PWMdriver(_driver)
    {
      PWMDriver = _driver;
      index = _index;
      ticksMinimum = _min;
      ticksMaximum = _max;
    }

    void write(int angle)
    {
      int ticks = map(angle, 0, 180, ticksMinimum, ticksMaximum);
      PWMdriver->setPWM(index, 0, ticks);
    }

  private:
    Adafruit_PWMServoDriver &PWMdriver;
    int index;
    int ticksMinimum;
    int ticksMaximum;
};
// File: walking.cpp

#include "PWMServo.h"

walking::zeroset()
{
  for (int i = 0; i < 6; i++) {     
    PWMServo si(90, i);
    delay(100);
  }

}

walking::step1()
{

  for (int i = 0; i < 4; i++) {     //Step 1
    PWMServo si(90 - 15 * i);;
    delay(100);
    if (i < 3) {
      PWMServo si(90 - 10 * i);
      delay(100);
    }

  }

}
//walking.h

#ifndef walking_h
#define walking_h

#include "walking.cpp"


class walking
{
  public:
    // One or more constructors (two in this example)
    zeroset();
    step1();

  private:

};

#endif
//Errors
In file included from C:\Users\utente\Documents\Arduino\Prova_H_CPP\Test_h_cpp.ino\walking.cpp:3:0,

                 from C:\Users\utente\Documents\Arduino\Prova_H_CPP\Test_h_cpp.ino\walking.h:6,

                 from C:\Users\utente\Documents\Arduino\Prova_H_CPP\Test_h_cpp.ino\Test_h_cpp.ino.ino:5:

C:\Users\utente\Documents\Arduino\Prova_H_CPP\Test_h_cpp.ino\PWMServo.h: In constructor 'PWMServo::PWMServo(Adafruit_PWMServoDriver&, int, int, int)':

PWMServo.h:11:7: error: 'PWMDriver' was not declared in this scope

       PWMDriver = _driver;

       ^~~~~~~~~

C:\Users\utente\Documents\Arduino\Prova_H_CPP\Test_h_cpp.ino\PWMServo.h:11:7: note: suggested alternative: 'PWMdriver'

       PWMDriver = _driver;

       ^~~~~~~~~

       PWMdriver

C:\Users\utente\Documents\Arduino\Prova_H_CPP\Test_h_cpp.ino\PWMServo.h: In member function 'void PWMServo::write(int)':

PWMServo.h:20:16: error: base operand of '->' has non-pointer type 'Adafruit_PWMServoDriver'

       PWMdriver->setPWM(index, 0, ticks);

                ^~

In file included from C:\Users\utente\Documents\Arduino\Prova_H_CPP\Test_h_cpp.ino\walking.h:6:0,

                 from C:\Users\utente\Documents\Arduino\Prova_H_CPP\Test_h_cpp.ino\Test_h_cpp.ino.ino:5:

C:\Users\utente\Documents\Arduino\Prova_H_CPP\Test_h_cpp.ino\walking.cpp: At global scope:

walking.cpp:5:1: error: 'walking' does not name a type; did you mean 'walking_h'?

 walking::zeroset()

 ^~~~~~~

 walking_h

walking.cpp:14:1: error: 'walking' does not name a type; did you mean 'walking_h'?

 walking::step1()

 ^~~~~~~

 walking_h

In file included from C:\Users\utente\Documents\Arduino\Prova_H_CPP\Test_h_cpp.ino\Test_h_cpp.ino.ino:5:0:

C:\Users\utente\Documents\Arduino\Prova_H_CPP\Test_h_cpp.ino\walking.h:13:13: warning: ISO C++ forbids declaration of 'zeroset' with no type [-fpermissive]

     zeroset();

             ^

C:\Users\utente\Documents\Arduino\Prova_H_CPP\Test_h_cpp.ino\walking.h:14:11: warning: ISO C++ forbids declaration of 'step1' with no type [-fpermissive]

     step1();

           ^

In file included from C:\Users\utente\Documents\Arduino\Prova_H_CPP\Test_h_cpp.ino\walking.cpp:3:0,

                 from C:\Users\utente\Documents\Arduino\Prova_H_CPP\Test_h_cpp.ino\Test_h_cpp.ino.ino:6:

PWMServo.h:6:7: error: redefinition of 'class PWMServo'

 class PWMServo

       ^~~~~~~~

In file included from C:\Users\utente\Documents\Arduino\Prova_H_CPP\Test_h_cpp.ino\walking.cpp:3:0,

                 from C:\Users\utente\Documents\Arduino\Prova_H_CPP\Test_h_cpp.ino\walking.h:6,

                 from C:\Users\utente\Documents\Arduino\Prova_H_CPP\Test_h_cpp.ino\Test_h_cpp.ino.ino:5:

C:\Users\utente\Documents\Arduino\Prova_H_CPP\Test_h_cpp.ino\PWMServo.h:6:7: note: previous definition of 'class PWMServo'

 class PWMServo

       ^~~~~~~~

In file included from C:\Users\utente\Documents\Arduino\Prova_H_CPP\Test_h_cpp.ino\Test_h_cpp.ino.ino:6:0:

C:\Users\utente\Documents\Arduino\Prova_H_CPP\Test_h_cpp.ino\walking.cpp:5:18: warning: ISO C++ forbids declaration of 'zeroset' with no type [-fpermissive]

 walking::zeroset()

                  ^

C:\Users\utente\Documents\Arduino\Prova_H_CPP\Test_h_cpp.ino\walking.cpp: In member function 'int walking::zeroset()':

walking.cpp:8:22: error: cannot bind non-const lvalue reference of type 'Adafruit_PWMServoDriver&' to an rvalue of type 'Adafruit_PWMServoDriver'

     PWMServo si(90, i);

                      ^

In file included from C:\Users\utente\Documents\Arduino\Prova_H_CPP\Test_h_cpp.ino\PWMServo.h:4:0,

                 from C:\Users\utente\Documents\Arduino\Prova_H_CPP\Test_h_cpp.ino\walking.cpp:3,

                 from C:\Users\utente\Documents\Arduino\Prova_H_CPP\Test_h_cpp.ino\walking.h:6,

                 from C:\Users\utente\Documents\Arduino\Prova_H_CPP\Test_h_cpp.ino\Test_h_cpp.ino.ino:5:

C:\Users\utente\Documents\Arduino\libraries\Adafruit_PWM_Servo_Driver_Library/Adafruit_PWMServoDriver.h:78:3: note:   after user-defined conversion: Adafruit_PWMServoDriver::Adafruit_PWMServoDriver(uint8_t)

   Adafruit_PWMServoDriver(const uint8_t addr);

   ^~~~~~~~~~~~~~~~~~~~~~~

In file included from C:\Users\utente\Documents\Arduino\Prova_H_CPP\Test_h_cpp.ino\walking.cpp:3:0:

C:\Users\utente\Documents\Arduino\Prova_H_CPP\Test_h_cpp.ino\PWMServo.h: In constructor 'PWMServo::PWMServo(Adafruit_PWMServoDriver&, int, int, int)':

PWMServo.h:11:7: error: 'PWMDriver' was not declared in this scope

       PWMDriver = _driver;

       ^~~~~~~~~

In file included from C:\Users\utente\Documents\Arduino\Prova_H_CPP\Test_h_cpp.ino\walking.cpp:3:0,

                 from C:\Users\utente\Documents\Arduino\Prova_H_CPP\Test_h_cpp.ino\walking.h:6,

                 from C:\Users\utente\Documents\Arduino\Prova_H_CPP\Test_h_cpp.ino\Test_h_cpp.ino.ino:5:

C:\Users\utente\Documents\Arduino\Prova_H_CPP\Test_h_cpp.ino\PWMServo.h:9:5: note:   initializing argument 1 of 'PWMServo::PWMServo(Adafruit_PWMServoDriver&, int, int, int)'

     PWMServo(Adafruit_PWMServoDriver &_driver, int _index, int _min = 150, int _max = 510) : PWMdriver(_driver)

     ^~~~~~~~

In file included from C:\Users\utente\Documents\Arduino\Prova_H_CPP\Test_h_cpp.ino\Test_h_cpp.ino.ino:6:0:

C:\Users\utente\Documents\Arduino\Prova_H_CPP\Test_h_cpp.ino\walking.cpp: At global scope:

C:\Users\utente\Documents\Arduino\Prova_H_CPP\Test_h_cpp.ino\walking.cpp:14:16: warning: ISO C++ forbids declaration of 'step1' with no type [-fpermissive]

 walking::step1()

                ^

C:\Users\utente\Documents\Arduino\Prova_H_CPP\Test_h_cpp.ino\PWMServo.h:11:7: note: suggested alternative: 'PWMdriver'

       PWMDriver = _driver;

       ^~~~~~~~~

       PWMdriver

C:\Users\utente\Documents\Arduino\Prova_H_CPP\Test_h_cpp.ino\walking.cpp: In member function 'int walking::step1()':

walking.cpp:18:28: error: no matching function for call to 'PWMServo::PWMServo(int)'

     PWMServo si(90 - 15 * i);;

                            ^

In file included from C:\Users\utente\Documents\Arduino\Prova_H_CPP\Test_h_cpp.ino\walking.cpp:3:0,

                 from C:\Users\utente\Documents\Arduino\Prova_H_CPP\Test_h_cpp.ino\walking.h:6,

                 from C:\Users\utente\Documents\Arduino\Prova_H_CPP\Test_h_cpp.ino\Test_h_cpp.ino.ino:5:

C:\Users\utente\Documents\Arduino\Prova_H_CPP\Test_h_cpp.ino\PWMServo.h:9:5: note: candidate: PWMServo::PWMServo(Adafruit_PWMServoDriver&, int, int, int)

     PWMServo(Adafruit_PWMServoDriver &_driver, int _index, int _min = 150, int _max = 510) : PWMdriver(_driver)

     ^~~~~~~~

C:\Users\utente\Documents\Arduino\Prova_H_CPP\Test_h_cpp.ino\PWMServo.h:9:5: note:   candidate expects 4 arguments, 1 provided

C:\Users\utente\Documents\Arduino\Prova_H_CPP\Test_h_cpp.ino\PWMServo.h:6:7: note: candidate: constexpr PWMServo::PWMServo(const PWMServo&)

 class PWMServo

       ^~~~~~~~

C:\Users\utente\Documents\Arduino\Prova_H_CPP\Test_h_cpp.ino\PWMServo.h:6:7: note:   no known conversion for argument 1 from 'int' to 'const PWMServo&'

C:\Users\utente\Documents\Arduino\Prova_H_CPP\Test_h_cpp.ino\PWMServo.h: In member function 'void PWMServo::write(int)':

PWMServo.h:20:16: error: base operand of '->' has non-pointer type 'Adafruit_PWMServoDriver'

       PWMdriver->setPWM(index, 0, ticks);

                ^~

C:\Users\utente\Documents\Arduino\Prova_H_CPP\Test_h_cpp.ino\PWMServo.h:6:7: note: candidate: constexpr PWMServo::PWMServo(PWMServo&&)

C:\Users\utente\Documents\Arduino\Prova_H_CPP\Test_h_cpp.ino\PWMServo.h:6:7: note:   no known conversion for argument 1 from 'int' to 'PWMServo&&'

In file included from C:\Users\utente\Documents\Arduino\Prova_H_CPP\Test_h_cpp.ino\Test_h_cpp.ino.ino:6:0:

walking.cpp:21:30: error: no matching function for call to 'PWMServo::PWMServo(int)'

       PWMServo si(90 - 10 * i);

                              ^

In file included from C:\Users\utente\Documents\Arduino\Prova_H_CPP\Test_h_cpp.ino\walking.cpp:3:0,

                 from C:\Users\utente\Documents\Arduino\Prova_H_CPP\Test_h_cpp.ino\walking.h:6,

                 from C:\Users\utente\Documents\Arduino\Prova_H_CPP\Test_h_cpp.ino\Test_h_cpp.ino.ino:5:

C:\Users\utente\Documents\Arduino\Prova_H_CPP\Test_h_cpp.ino\PWMServo.h:9:5: note: candidate: PWMServo::PWMServo(Adafruit_PWMServoDriver&, int, int, int)

     PWMServo(Adafruit_PWMServoDriver &_driver, int _index, int _min = 150, int _max = 510) : PWMdriver(_driver)

     ^~~~~~~~

C:\Users\utente\Documents\Arduino\Prova_H_CPP\Test_h_cpp.ino\PWMServo.h:9:5: note:   candidate expects 4 arguments, 1 provided

C:\Users\utente\Documents\Arduino\Prova_H_CPP\Test_h_cpp.ino\PWMServo.h:6:7: note: candidate: constexpr PWMServo::PWMServo(const PWMServo&)

 class PWMServo

       ^~~~~~~~

C:\Users\utente\Documents\Arduino\Prova_H_CPP\Test_h_cpp.ino\PWMServo.h:6:7: note:   no known conversion for argument 1 from 'int' to 'const PWMServo&'

C:\Users\utente\Documents\Arduino\Prova_H_CPP\Test_h_cpp.ino\PWMServo.h:6:7: note: candidate: constexpr PWMServo::PWMServo(PWMServo&&)

C:\Users\utente\Documents\Arduino\Prova_H_CPP\Test_h_cpp.ino\PWMServo.h:6:7: note:   no known conversion for argument 1 from 'int' to 'PWMServo&&'

In file included from C:\Users\utente\Documents\Arduino\Prova_H_CPP\Test_h_cpp.ino\Test_h_cpp.ino.ino:7:0:

C:\Users\utente\Documents\Arduino\Prova_H_CPP\Test_h_cpp.ino\PWMServo.h: At global scope:

PWMServo.h:6:7: error: redefinition of 'class PWMServo'

 class PWMServo

       ^~~~~~~~

C:\Users\utente\Documents\Arduino\Prova_H_CPP\Test_h_cpp.ino\walking.cpp: At global scope:

walking.cpp:5:1: error: 'walking' does not name a type

 walking::zeroset()

 ^~~~~~~

In file included from C:\Users\utente\Documents\Arduino\Prova_H_CPP\Test_h_cpp.ino\walking.cpp:3:0,

                 from C:\Users\utente\Documents\Arduino\Prova_H_CPP\Test_h_cpp.ino\walking.h:6,

                 from C:\Users\utente\Documents\Arduino\Prova_H_CPP\Test_h_cpp.ino\Test_h_cpp.ino.ino:5:

C:\Users\utente\Documents\Arduino\Prova_H_CPP\Test_h_cpp.ino\PWMServo.h:6:7: note: previous definition of 'class PWMServo'

 class PWMServo

       ^~~~~~~~

C:\Users\utente\Documents\Arduino\Prova_H_CPP\Test_h_cpp.ino\Test_h_cpp.ino.ino: In function 'void setup()':

Test_h_cpp.ino:14:3: error: 'pwm' was not declared in this scope

   pwm.begin();

   ^~~

Test_h_cpp.ino:18:20: error: cannot call member function 'int walking::zeroset()' without object

   walking::zeroset();
                    ^
C:\Users\utente\Documents\Arduino\Prova_H_CPP\Test_h_cpp.ino\Test_h_cpp.ino.ino: In function 'void loop()':

Test_h_cpp.ino:24:18: error: cannot call member function 'int walking::step1()' without object

   walking::step1();
                  ^
walking.cpp:14:1: error: 'walking' does not name a type

 walking::step1()

 ^~~~~~~

exit status 1

'PWMDriver' was not declared in this scope

There are several errors because I do not know how to call the functions in the main .ino file using:

A.step1();

and because this is my first multiple file project. Please help me to correct the mistakes. Thank you for your support so far.

Hello, today I succesfully modified the code with no compilation errors. I tried it on my servos and everything works fine.

//main.ino

#include <Wire.h>
#include "functions.h"


void setup() {
  // put your setup code here, to run once:

  Serial.begin(9600);
  setpwm();
  delay(100);
  zeroset();                                         //Chiamata della funzione zeroset
  delay(1000);

}

void loop() {
  // put your main code here, to run repeatedly:

}
//functions.cpp

#include <Wire.h>
#include <Adafruit_PWMServoDriver.h>
#include "functions.h"


Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();

#define ServoMin 150
#define ServoMax 510 //Cerca questi due valori nel datasheet del motore oppure sperimenta


void setpwm() {
  pwm.begin();
  pwm.setPWMFreq(60);
}


void zeroset() {                                    //Funzione per mettere tutti i servo a 90°(settaggio zero) chiamando la funzione servowrite
  for (int i = 0; i < 6; i++) {                     //Per semplicità servo sono connessi ai pin 0,2,4,...,10 della shield
    servowrite(2 * i, 90);
    delay(100);
  }
}

void servowrite(int servonum, int angle) {          //Funzione per pilotare il servo ad un angolo direttamente usando la funzione setPWM
  int tick = map(angle, 0, 180, ServoMin, ServoMax); //assegna l'angolo al tick nel duty cycle
  pwm.setPWM(servonum, 0, tick);
}
//functions.h

#ifndef FUNCTIONS_H_
#define FUNCTIONS_H_

void zeroset();
void setpwm();
void servowrite(int servonum, int angle);

#endif

Could someone help me to complete the conversion of functions into classes, using johnwasser's code and my new modifications? I still have the same doubts since the last post. Kind regards.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.