Controlling continuous rotation servo speed w/ POT

Hello All,
I'm new to Arduino and this is my first post. In the below sketch I'm trying to control the direction of a continuous rotation servo using a button switch (works) and its speed using a POT (doesn't work as I'd like). Problem is the program reads the POT in LOOP but when runs the function to operate the servo it runs it once and leaves causing the servo to run at speed the POT was at when it read it last. Is there a way to update the POT and have real time control over the servos speed?

 int redLed = 10;
int greenLed = 11;
int yellowLed = 12;
int switchPin = 19;
int count = 0;
const int potPin = A0;
boolean lastButton;
boolean currentButton = false;
boolean ledOn = false;
#include <Servo.h>
Servo myServo;
int potIn;
int servoCW;
int servoCCW;



void setup() {
// sets pin modes, attaches servo to pin3, starts the serial monitor and initializes count to zero
  pinMode(switchPin, INPUT_PULLUP);
  pinMode(redLed, OUTPUT);
  pinMode(greenLed, OUTPUT);
  pinMode(yellowLed, OUTPUT);
  myServo.attach(3);
  Serial.begin(9600);
  count = 0;
}
//debounce function to stabilise the button
boolean debounce(boolean last) {
  boolean current = digitalRead(switchPin);
  if (last != current) {
    delay(5);
    current = digitalRead(switchPin);
  }
  return current;
}
void loop() {
  potIn = analogRead(potPin);            // reads the POT and maps values to clockwise and counter clockwise int. 
  servoCW = map(potIn, 0, 1023, 0, 90);
  servoCCW = map(potIn, 0, 1023, 90, 180);


  lastButton = currentButton;
  currentButton = debounce(lastButton);
  if (lastButton == false && currentButton == true) {
    if (count == 0) {
      count++;
      digitalWrite(redLed, LOW);         // ensures sketch starts w/ leds off
      digitalWrite(greenLed, LOW);
   }  else if (count == 1) {
      count++;
      digitalWrite(redLed, HIGH);    // turns on red LED and calls servo cw rotation function
      digitalWrite(greenLed, LOW);
      servoCWout();
    } else if (count == 2) {
      count++;
      digitalWrite(redLed, LOW);       // turns off red LED, turns on the green LED and calls the counter clockwise rotation function
      digitalWrite(greenLed, HIGH);
      servoCCWout();
    } else if (count == 3) {
      count = 0;
      digitalWrite(redLed, LOW);      // turns of the LEDs and the servo
      digitalWrite(greenLed, LOW);
      myServo.write(90);
    }
  }
}

void servoCCWout() {
  myServo.write(servoCCW);
  Serial.println(servoCCW);    // runs the servo counter clockwise and prints the map and POT values to the serial monitor
  Serial.println(potIn);
}
void servoCWout() {
  myServo.write(servoCW);
  Serial.println(servoCW);
  Serial.println(potIn);     // runs the servo clockwise and prints the map  and POT values to the serial monitor
}

You are trying to do too much all at once. Just concentrate on one thing, and that is getting the servo to run at the speed and direction given by the pot. Forget for the moment about switches and LEDs.

Simply read the pot, map the reading to the range of values of the pot and apply that number to the servo. Do not do like your code currently does is use two mappings. Put this in the loop function, get it working first.

These two lines look like they are trying to control 1/4 of a rotation with the pot. I think too many things were combined.

  1. Make a setup and sketch that changes servo direction with a button press.

  2. Make a setup and sketch that increases and decreases a motor speed with a pot.

  3. Combine.

Thanks for the fast replies. Ill attempt to address both recommendations. The included sketch is in fact the merger of two projects/ideas. I am able to control the speed and direction of the servo using just a POT and one 0-180 MAP. 0-90 CW and 90-180 CCW. 88-92 or so turns the servo off. And I am able to change its direction w/ a push button in separate sketches. xfpd, changing the 0 and 90 around in the first map does fix the problem of the servo changing speeds when going from CW to CCW. If I attempt to put the map for both directions in the LOOP the servo ratchets back and forth as the program executes opposite instructions. The speed can be controlled inside a while loop but that comes w/ its own set of problems. I think what I need is a way to periodically check the MAP value and rewrite it to the servo (re-call the function?) ??

I fixed it! By adding two variables to store the servo CW/CCW rotation state and two IF statements to check those states, then if true...recalls the servoCW/CCWout functions. Works flawlessly.
Thank you for your help, just needed that little extra push

int redLed = 10;
int greenLed = 11;
int yellowLed = 12;
int switchPin = 19;
int count = 0;
const int potPin = A0;
boolean lastButton;
boolean currentButton = false;
boolean ledOn = false;
#include <Servo.h>
Servo myServo;
int potIn;
int servoCW;
int servoCCW;
int servoCCWrun = 0; //variable for servo run state
int servoCWrun = 0;



void setup() {
// sets pin modes, attaches servo to pin3, starts the serial monitor and initializes count to zero
  pinMode(switchPin, INPUT_PULLUP);
  pinMode(redLed, OUTPUT);
  pinMode(greenLed, OUTPUT);
  pinMode(yellowLed, OUTPUT);
  myServo.attach(3);
  Serial.begin(9600);
  count = 0;
}
//debounce function to stabilise the button
boolean debounce(boolean last) {
  boolean current = digitalRead(switchPin);
  if (last != current) {
    delay(5);
    current = digitalRead(switchPin);
  }
  return current;
}
void loop() {
  potIn = analogRead(potPin);            // reads the POT and maps values to clockwise and counter clockwise int. 
  servoCW = map(potIn, 0, 1023, 90, 0);
  servoCCW = map(potIn, 0, 1023, 90, 180);


  lastButton = currentButton;
  currentButton = debounce(lastButton);
  if (lastButton == false && currentButton == true) {
    if (count == 0) {
      count++;
      digitalWrite(redLed, LOW);         // ensures sketch starts w/ leds off
      digitalWrite(greenLed, LOW);
   }  else if (count == 1) {
      count++;
      digitalWrite(redLed, HIGH);    // turns on red LED and calls servo cw rotation function
      digitalWrite(greenLed, LOW);
      servoCWout();
      servoCWrun = 1;
      servoCCWrun = 0;
    } else if (count == 2) {
      count++;
      digitalWrite(redLed, LOW);       // turns off red LED, turns on the green LED and calls the counter clockwise rotation function
      digitalWrite(greenLed, HIGH);
      servoCCWout();
      servoCCWrun = 1; // sets the variable for servo run state to 1
      servoCWrun = 0;
    } else if (count == 3) {
      count = 0;
      digitalWrite(redLed, LOW);      // turns of the LEDs and the servo
      digitalWrite(greenLed, LOW);
      myServo.write(90);
      servoCCWrun = 0;
      servoCWrun = 0;
    }
  }
if (servoCWrun == 1){ //checks the servo run state and re-calls servoCWout function
  servoCWout();
}
if (servoCCWrun == 1){
  servoCCWout();
}
}

void servoCCWout() {
  myServo.write(servoCCW);
  Serial.println(servoCCW);    // runs the servo counter clockwise and prints the map and POT values to the serial monitor
  Serial.println(potIn);
}
void servoCWout() {
  myServo.write(servoCW);
  Serial.println(servoCW);
  Serial.println(potIn);     // runs the servo clockwise and prints the map  and POT values to the serial monitor
}

1 Like

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