3

I'm a little new to Arduino, but not to programming or electronics in general. I'm working on a library that will be more fleshed out later, but I'm having issues getting the basics working properly.

The following code produces the desired behavior if a servo is attached to pin 3:

#include <Servo.h>

Servo myServo;

void setup() {
  myServo.attach(3);
}

void loop() {
  myServo.write(1);
  delay(1000);
  myServo.write(45);
  delay(1000);
  myServo.write(90);
  delay(1000);
  myServo.write(135);
  delay(1000);
  myServo.write(180);
  delay(1000);
}

However, when I try to implement similar functionality in my own library the servo locks and just sort of grinds. Here's the header file:

#ifndef MotorControl_h
#define MotorControl_h

#include "Arduino.h"
#include "Servo.h"

class MotorControl
{
  public:
    MotorControl(int north, int south, int west, int east);
    void setNorth(int value);
    void setSouth(int value);
    void setWest(int value);
    void setEast(int value);
    int getNorth();
    int getSouth();
    int getWest();
    int getEast();
  private:
    Servo _north;
    Servo _south;
    Servo _west;
    Servo _east;
    int _northVal;
    int _southVal;
    int _westVal;
    int _eastVal;
};

#endif

And here's the .cpp file:

#include "Arduino.h"
#include "MotorControl.h"
#include "Servo.h"

MotorControl::MotorControl(int north, int south, int west, int east)
{
  _north.attach(north);
  _south.attach(south);
  _west.attach(west);
  _east.attach(east);
  _northVal = 0;
  _southVal = 0;
  _westVal = 0;
  _eastVal = 0;
}

void MotorControl::setNorth(int value)
{
  _north.write(value);
  _northVal = value;
}

void MotorControl::setSouth(int value)
{
  _south.write(value);
  _southVal = value;
}

void MotorControl::setWest(int value)
{
  _west.write(value);
  _westVal = value;
}

void MotorControl::setEast(int value)
{
  _east.write(value);
  _eastVal = value;
}

int MotorControl::getNorth()
{
   return _northVal;
}

int MotorControl::getSouth()
{
  return _southVal;
}

int MotorControl::getWest()
{
  return _westVal;
}

int MotorControl::getEast()
{
  return _eastVal;
}

And finally, the code using the above library which should produce the same behavior as the code up top, but does not:

#include <MotorControl.h>

MotorControl mc(3, 5, 6, 9);

void setup() {}

void loop() {
  mc.setNorth(1); 
  delay(1000);
  mc.setNorth(45);
  delay(1000);
  mc.setNorth(90);
  delay(1000);
  mc.setNorth(135);
  delay(1000);
  mc.setNorth(180);
  delay(1000);
}

I'm not sure what else to add ... this is running on an Uno R3.

Edit: This is interesting. I've tried the code from this example: How do I initialize a servo object in my own library? which works out just fine. I'm still not sure that I see what I'm doing incorrectly here. I see the differences between my code and the example, but not how they are causing problems.

If it's worth mentioning, I've also stored my library in the libraries folder. Just throwing out any random detail I can think of.

  • Hi @MattB, what is your question? – sa_leinad Nov 29 '16 at 4:53
  • Try expanding you example to have 4 servos and see if that works. I guess it won't because the Servo library uses timers and the different servos might interfere with each other. Its just my guess, and I hope I'm wrong. – Code Gorilla Nov 29 '16 at 8:03
  • In you code you could set all the servos to 3, so that its only driving one servo. The opposite of the above. – Code Gorilla Nov 29 '16 at 8:04
  • Interesting idea @Matt ... I will give that a shot. – MattB Nov 30 '16 at 0:22
  • @sa_leinad The library I've created is not driving the servo properly. The servo responds, but does not move to the appropriate positions. – MattB Nov 30 '16 at 0:22
1

In C++, when an object is declared as a member of another object, the constructor method of the inner object must be called explicity (see constructors and member initializer lists).

In your code, properties of Servo type can be constructed within the header of the MotorControl constructor:

MotorControl::MotorControl(int north, int south, int west, int east)             
    : _north(), _south(), _west(), _east()                                       
{                                                                                
  _north.attach(north);                                                          
  _south.attach(south);                                                          
  _west.attach(west);                                                            
  _east.attach(east);                                                            
  _northVal = 0;                                                                 
  _southVal = 0;                                                                 
  _westVal = 0;                                                                  
  _eastVal = 0;                                                                  
}
1

When you create your instance at global scope then you have no control over when exactly the constructor gets called. If it gets called before init() runs then your attach lines won't work out. You should have a begin method in your class that handles attaching the servos and call that method from setup.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.