Class, Constructor & Variable Scope help!

Cannibalising the sketch from Adafruit’s multitasking tutorial (A classy solution | Multi-tasking the Arduino - Part 1 | Adafruit Learning System) I have been trying to write a sketch where I can control the speed of a servo using the same technique. But there are a few things I still don’t understand

// Using one pot to independently control the speed of one servo - no longer in the loop
// Next step - add another servo with independent speed control

#include <Servo.h>
const int potPin = A0;
int potVal;
int servoInterval;
int pos; // current servo position
int increment = 1 ; // increment to move for each interval
unsigned long lastUpdate; // last update of position
Servo servo; // the servo

class Sweeper
{
  public:
    Sweeper(int pointless) { // WHAT DO I DO HERE???
    }

    void Attach(int servoPin) {
      servo.attach(servoPin);
    }

    void Detach() {
      servo.detach();
    }

    void Update() {
      potVal = analogRead(potPin);
      //map analog values to milliseconds
      servoInterval = map(potVal, 0, 1023, 100, 3);
      if ((millis() - lastUpdate) >  servoInterval) // time to update
      { lastUpdate = millis();
        pos += increment; // pos = pos + increment
        servo.write(pos); // tell the servo to move to pos
        if ((pos >= 171) || (pos <= 0)) //end of sweep.  "||" means OR
        {
          // reverse direction
          increment = -increment; // assign negative value to variable increment
        }
      }
    }
};

Sweeper servo1(0); // What is being addressed here??? I am declaring the servos but do I need the ()???
Sweeper servo2(0);

void setup()
{
  // assign pins to servos
  servo1.Attach(9); //servo1 isn't attaching...
  servo2.Attach(10);
  Serial.begin(250000); //High baud rate due to low interval value on servo.
}

void loop() {
  servo1.Update();
  servo2.Update(); //if this is commented out it makes no difference
  Serial.print("potVal: ");
  Serial.print(potVal);
  Serial.print(", servoInterval: ");
  Serial.println(servoInterval);
}

Before I can go onto my next task I obviously need to get this working, but more importantly understand what’s going on. The Arduino library tutorial (Arduino - LibraryTutorial) is pretty good but it doesn’t really answer my queries.

There are two problems I am having:
A) I cannot get servo1 and servo2 to run at the same time - no matter what PWM pins I assign them and what number I give them (could be servox & servoy even) it only ever runs one servo. Not only that but I can comment out "servo2.Update() and it will still run a servo off pin10 albeit slightly slower (is that useful to know…? Is the Update function running twice through one pin?) I cannot source the problem for this. As the Adafruit sketch works fine on the same circuit!

B) Class & Constructor syntax - you may notice at the top of the class:

public:
    Sweeper(int pointless) { // WHAT DO I DO HERE???
    }

and then later on:

Sweeper servo1(0); // What is being addressed here??? I am declaring the servos but do I need the ()???

The only reason these are here is to get everything else to work. This is clearly wrong but I do not know how to create the constructor without creating a useless int variable after the class - can someone help me out here?

Much appreciated - I am somewhat at a loss.

Delete the constructor:

    Sweeper(int pointless) { // WHAT DO I DO HERE???
    }

Just get rid of that.

Now create instances without an argument:

Sweeper servo1; 
Sweeper servo2;

That compiles.

You don't have to throw in integers you don't need.

You don't have to throw in integers you don't need.

However, if you want the class to deal with the pin, instead of having an Attach() method, you could pass the pin number to the (now necessary) constructor.

no matter what PWM pins I assign them

SERVOS DO NOT NEED PWM PINS!

Well that's easy enough, thank you! Unfortunately the pin output weirdness is still going on :-S

SERVOS DO NOT NEED PWM PINS!

Good to know!

Okay - so worked out what was causing the pin weirdness. It was because

Servo servo;

was declared as a global variable rather than in the Class scope. So now both pins work - not entirely sure why however. Is it because I am assigning different pins to servos outside of this scope?

Right, now I need to work out why my servo is now whimpering and sticking. Two steps forward, one step back as always!

Edit - the sticking was low battery power. All that testing seems to have drained the poor thing!

PaulS:
However, if you want the class to deal with the pin, instead of having an Attach() method, you could pass the pin number to the (now necessary) constructor.

Thanks Paul,

The next step is to add independant speed control with another pot - I guess this would be the way to do it?
Something like

Sweeper (int servoPin, int potPin)

now when the constructor is addressed, I can map the servo to its relative pot. I'm sure they'll be more to it than that but I hope this is a start. I will try it tomorrow.

(sorry if my terminology is a bit off)

Okay,

So I have tried to apply what has been said to control two servos now with independent speed control. It is not going as well as I hoped. Here is my code:

// Using two pots to independently control the speed of two servos

#include <Servo.h>

class Sweeper
{
    Servo myServo; // the servo
    int potVal;
    int servoInterval;
    int pos; // current servo position
    int increment = 1 ; // increment to move for each interval
    unsigned long lastUpdate; // last update of position

  public:
    Sweeper(int potPin, int servoPin) {
      myServo.attach(servoPin);
      potVal = analogRead(potPin);
      servoInterval = map(potVal, 0, 1023, 10, 3);
    }

    void Detach() {
      myServo.detach();
    }

    void Update() {
      if ((millis() - lastUpdate) >  servoInterval) // time to update
      { lastUpdate = millis();
        pos += increment; // pos = pos + increment
        myServo.write(pos); // tell the servo to move to pos
        if ((pos >= 171) || (pos <= 0)) //end of sweep.  "||" means OR
        {
          // reverse direction
          increment = -increment; // assign negative value to variable increment
        }
      }
    }

};
Sweeper servo1(A1, 9);
Sweeper servo2(A0, 10);

void setup()
{
}

void loop() {
  servo1.Update();
  servo2.Update();
}

The arduino has acknowledged that pins 9 & 10 are servo outputs as there is some behaviour - but the servos don’t know whether they are coming or going - very jiterry. Also if lines

Sweeper servo2(A0, 10);
...
  servo2.Update();

are commented out then the active servo almost breaks itself by swinging to about -5° until it reaches its mechanical stop, which I have not seen before. Also any kind of serial monitor does not show any life coming from the pots.

All comments welcome - as usual I am very grateful for everyone’s input.

PS sorry for all the bumps - hopefully other people may find this thread useful in the future.

http://www.gammon.com.au/tips#trap20