Motor Seizure, Continuous Rotation Servo Help- Arduino Uno R3

Hi all!,
I uploaded a code with voice recognition and three commands.
For the motors that move the robot, I used Parallax Continuous Rotation Servos and adjusted the pentameter to stay still at 90 and to move clockwise and counter clockwise at 180 and 0.
When I uploaded my code into my Arduino, both motors started moving, little by little.
I’m not sure where I went wrong.

#include <Servo.h>
const int RForward = 0; 
const int RBackward = 180; 
const int LForward = 0; 
const int LBackward = 180; 
const int RNeutral = 90; 
const int LNeutral = 90; //constants for motor speed 
const int trigpin = 7; 
const int echopin = 3; 
const int dangerThresh = 10; //threshold for obstacles (in cm) 
int leftDistance, rightDistance; //distances on either side 
Servo panMotor; 
Servo leftMotor; 
Servo rightMotor; //declare motors 
long duration; //time it takes to recieve PING))) signal 
byte com = 0;

void setup (){
  Serial.begin(9600);
  delay(2000);
  Serial.write(0xAA);
  Serial.write(0x37);
  delay(1000);
  Serial.write(0xAA);
  Serial.write(0x21);
  rightMotor.attach(11);
  rightMotor.write(90);
  leftMotor.write(90);
  leftMotor.attach(10);
  panMotor.attach(6);
  panMotor.write(90);
}
void loop ()
{
  while(Serial.available())
{
  com = Serial.read();
  switch(com)
{
  case 0x11:
  {
    int distanceFwd = ping(); 
    if (distanceFwd>dangerThresh) //if path is clear 
    { 
      leftMotor.write(LForward); 
      rightMotor.write(RForward); //move forward 
    } 
    else //if path is blocked 
    { 
      leftMotor.write(LNeutral); 
      rightMotor.write(RNeutral); 
      panMotor.write(0); 
      delay(500); 
      rightDistance = ping(); //scan to the right 
      delay(500); 
      panMotor.write(180); 
      delay(700); 
      leftDistance = ping(); //scan to the left 
      delay(500); 
      panMotor.write(90); //return to center 
      delay(100); 
      compareDistance(); 
    }
  } 
  break;
  case 0x12:
  {
    panMotor.write(180);              
    delay(1000);                                               
    panMotor.write(0);              
    delay(1000);                        
    panMotor.write(90);
    delay(1000);
  }
  break;
  case 0x13:
  {
    panMotor.write(90);
    leftMotor.write(LNeutral);
    rightMotor.write(RNeutral);
  }
  break;
}
}
}

void compareDistance()
{
  if (leftDistance>rightDistance) //if left is less obstructed 
  { 
    leftMotor.write(LBackward); 
    rightMotor.write(RForward); //turn left 
    delay(500); 
  } 
  else if (rightDistance>leftDistance) //if right is less obstructed 
  { 
    leftMotor.write(LForward); 
    rightMotor.write(RBackward); //turn right 
    delay(500); 
  } 
  else //if they are equally obstructed 
  { 
    leftMotor.write(LForward); 
    rightMotor.write(RBackward); //turn 180 degrees 
    delay(1000); 
  } 
}

long ping()
{
  // Send out PING))) signal pulse 
  pinMode(trigpin, OUTPUT); 
  pinMode(echopin,INPUT); 
  digitalWrite(trigpin, LOW); 
  delayMicroseconds(2); 
  digitalWrite(trigpin, HIGH); 
  delayMicroseconds(10); 
  digitalWrite(trigpin, LOW); 
 //Get duration it takes to receive echo 
duration = pulseIn(echopin, HIGH); 
//Convert duration into distance 
return duration / 29 / 2; 
}

You may want to use microsecond commands instead of degree values. Below is some servo test code that might be of use.

// zoomkat 3-28-14 serial servo incremental test code
// using serial monitor type a character (s to increase or a 
// to decrease) and enter to change servo position 
// (two hands required, one for letter entry and one for enter key)
// use strings like 90x or 1500x for new servo position 
// for IDE 1.0.5 and later
// Powering a servo from the arduino usually *DOES NOT WORK*.

#include<Servo.h>
String readString;
Servo myservo;
int pos=1500; //~neutral value for continous rotation servo
//int pos=90;

void setup()
{
  myservo.attach(7, 400, 2600); //servo control pin, and range if desired
  Serial.begin(9600);
  Serial.println("serial servo incremental test code");
  Serial.println("type a character (s to increase or a to decrease)");
  Serial.println("and enter to change servo position");
  Serial.println("use strings like 90x or 1500x for new servo position");
  Serial.println();
}

void loop()
{
  while (Serial.available()) {
    char c = Serial.read();  //gets one byte from serial buffer
    readString += c; //makes the string readString
    delay(2);  //slow looping to allow buffer to fill with next character
  }
  if (readString.length() >0) {
    if(readString.indexOf('x') >0) { 
      pos = readString.toInt();
    }

    if(readString =="a"){
      (pos=pos-1); //use larger numbers for larger increments
      if(pos<0) (pos=0); //prevent negative number
    }
    if (readString =="s"){
      (pos=pos+1);
    }

    if(pos >= 400) //determine servo write method
    {
      Serial.println(pos);
      myservo.writeMicroseconds(pos);
    }
    else
    {   
      Serial.println(pos);
      myservo.write(pos); 
    }
  }
  readString=""; //empty for next input
}

That does not help solve the problem, but thank you.
Using microsecond intervals instead of degrees is smart, but this is a continuous rotation servo mind you.
I need him to keep driving, which I can’t do in microseconds.

Still confused as to why the motors are spinning slowly in opposite directions…
code reuploaded:
Oh and all that I plugged in was the motors themselves.

#include <Servo.h>
const int RForward = 0; 
const int RBackward = 180; 
const int LForward = 0; 
const int LBackward = 180; 
const int RNeutral = 90; 
const int LNeutral = 90; //constants for motor speed 
const int trigpin = 7; 
const int echopin = 3; 
const int dangerThresh = 10; //threshold for obstacles (in cm) 
int leftDistance, rightDistance; //distances on either side 
Servo panMotor; 
Servo leftMotor; 
Servo rightMotor; //declare motors 
long duration; //time it takes to recieve PING))) signal 
byte com = 0;

void setup (){
  Serial.begin(9600);
  delay(2000);
  Serial.write(0xAA);
  Serial.write(0x37);
  delay(1000);
  Serial.write(0xAA);
  Serial.write(0x21);
  rightMotor.attach(11);
  rightMotor.write(90);
  leftMotor.write(90);
  leftMotor.attach(10);
  panMotor.attach(6);
  panMotor.write(90);
}
void loop ()
{
  while(Serial.available())
{
  com = Serial.read();
  switch(com)
{
  case 0x11:
  {
    int distanceFwd = ping(); 
    if (distanceFwd>dangerThresh) //if path is clear 
    { 
      leftMotor.write(LForward); 
      rightMotor.write(RForward); //move forward 
    } 
    else //if path is blocked 
    { 
      leftMotor.write(LNeutral); 
      rightMotor.write(RNeutral); 
      panMotor.write(0); 
      delay(500); 
      rightDistance = ping(); //scan to the right 
      delay(500); 
      panMotor.write(180); 
      delay(700); 
      leftDistance = ping(); //scan to the left 
      delay(500); 
      panMotor.write(90); //return to center 
      delay(100); 
      compareDistance(); 
    }
  } 
  break;
  case 0x12:
  {
    panMotor.write(180);              
    delay(1000);                                               
    panMotor.write(0);              
    delay(1000);                        
    panMotor.write(90);
    delay(1000);
  }
  break;
  case 0x13:
  {
    panMotor.write(90);
    leftMotor.write(LNeutral);
    rightMotor.write(RNeutral);
  }
  break;
}
}
}

void compareDistance()
{
  if (leftDistance>rightDistance) //if left is less obstructed 
  { 
    leftMotor.write(LBackward); 
    rightMotor.write(RForward); //turn left 
    delay(500); 
  } 
  else if (rightDistance>leftDistance) //if right is less obstructed 
  { 
    leftMotor.write(LForward); 
    rightMotor.write(RBackward); //turn right 
    delay(500); 
  } 
  else //if they are equally obstructed 
  { 
    leftMotor.write(LForward); 
    rightMotor.write(RBackward); //turn 180 degrees 
    delay(1000); 
  } 
}

long ping()
{
  // Send out PING))) signal pulse 
  pinMode(trigpin, OUTPUT); 
  pinMode(echopin,INPUT); 
  digitalWrite(trigpin, LOW); 
  delayMicroseconds(2); 
  digitalWrite(trigpin, HIGH); 
  delayMicroseconds(10); 
  digitalWrite(trigpin, LOW); 
 //Get duration it takes to receive echo 
duration = pulseIn(echopin, HIGH); 
//Convert duration into distance 
return duration / 29 / 2; 
}

I also noticed something about powering the motors separately.
I was using a 9V battery to power the Arduino.
Should I use a 9V instead to power the motors and 4 AA for the Arduino instead?

Hi,
have you written a sketch, just to send commands to the servos, nothing else a simple little sketch.
Send 90 and see if they creep, if so then send 89 or 91 until the creep stops.

Your continuous servos are basically normal 0 to 180 servo with the feedback pot disconnected from the output shaft and positioned at 90deg.

There will be some errors with the fixing of this 90, so you will have to play with the output to find the zero sweet spot.

The suggestion to use micro seconds by zoomkat is so you have finer control, you only have 0 to 180 steps using servo, however using micro the steps are much finer so tuning much better.

Tom.... :slight_smile:

TrollNyan:
I need him to keep driving, which I can't do in microseconds.

You can do anything with writeMicroseconds() that can be done with write(), it just gives you finer control.

I also noticed something about powering the motors separately.
I was using a 9V battery to power the Arduino.
Should I use a 9V instead to power the motors and 4 AA for the Arduino instead?

Do you mean a PP3 type of 9v battery? That is quite unsuitable for the Arduino and for the servos. They cannot produce enough current (amps).

Use a pack of 6 AA NiMh cells to drive the Arduino and a separate pack of 4 AA NiMh batteries to power the servos. NEVER power the servos from the Arduino. Make sure that the servo GND is connected to the Arduino GND.

...R

Thanks for the replies,
So using microseconds I'd be able to disregard the pentameter and just make it turn clockwise or counterclockwise?
That's cool.
So I replace in my code, 180 with 2000, 0 with 1000, and 90 with 1500.

I don't really have the time to order NiMH batteries at the moment, as the robot itself is due at the end of spring break along with many other things, so would it be recommended to use normal AAs instead of the 9V PP3?
6 for the servos and 4 for the Arduino?
Or should I use Li-Ions?

Hi all,
I have almost finished the assembly but I have run across a problem. When I connected the ground of the servos and the rest of the components to the Arduino, separately powered by 4 AA’s, my voice recognition module stops working. When I don’t connect the ground, the voice recognition module is just stuck in serial mode, which means it’s waiting for the commands from the arduino. I have plugged the Tx to the Rx and the Rx to the Tx

This is a geeetech high sensitivity voice recognition if anyone needed to know.
Have a nice day.

TrollNyan:
When I don't connect the ground, the voice recognition module is just stuck in serial mode,

Without seeing a wiring diagram how can we comment?

Make a pencil drawing showing ALL the connections and post a photo of the drawing.
Do NOT post a photo of your hardware.

And be careful you are not connecting something in a way that can cause damage.

...R

The x means it’s not plugged in while the check means it is.

Any comments?

Two comments.

It is not very polite to bump your post after 1 hour. After 48 hours, OK

That is not a wiring diagram.

...R

Hi all,
Sorry about the bump, I just have a limited amount of time.
Anyways, I tried to recreate a wiring diagram as I could, I hope this will do.

TrollNyan:
Sorry about the bump, I just have a limited amount of time.

So have we all.

Anyways, I tried to recreate a wiring diagram as I could, I hope this will do.

If you had read Reply #7 we might neither of us be wasting our time.

Make a PENCIL drawing.
I won't even try to decipher that quasi photograph in case I misunderstand something.

...R