A "continuous revolution" 'servo' has the feedback loop removed, thus reducing it to a gear motor with ESC (Electronic Speed Control). You will need to experimentally determine the middle of the ESC 'dead' zone to get them to stop. It will probably be different for each servo. Then you need to tune the speed values to match the speeds closely. You mat want to switch from .write(0 through 180) to .writeMicroseconds(1000 through 2000) to get more precise control.
You could add rotation feedback on the wheels to get more precise control.
The servos aren't even. They often drift when it's sitting.
You will probably get more control of the servos using writeMicroseconds. If you made your own continuous rotation servos, you might send the servos a 1500us signal, then tweak the pot (if available) such that the servo will not rotate. If drift continues to be a problem, you probably can use the servo detach function to stop the servo rotation. Below is some servo test code that includes the detach function.
// zoomkat 12-25-13 serial servo test
// type servo position 0 to 180 in serial monitor
// or for writeMicroseconds, use a value like 1500
// Send an a to attach servo or d to detach servo
// for IDE 1.0.5 and later
// Powering a servo from the arduino usually *DOES NOT WORK*.
#include <Servo.h>
String readString; //String captured from serial port
Servo myservo; // create servo object to control a servo
int n; //value to write to servo
void setup() {
Serial.begin(9600);
myservo.writeMicroseconds(1500); //set initial servo position if desired
myservo.attach(7, 500, 2500); //the pin for the servo control, and range if desired
Serial.println("servo all-in-one test code 12-25-13"); // so I can keep track of what is loaded
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) {
Serial.println(readString); //so you can see the captured string
// attach or detach servo if desired
if (readString == "d") {
myservo.detach(); //detach servo
Serial.println("servo detached");
goto bailout; //jump over writing to servo
}
if (readString == "a") {
myservo.attach(7); //reattach servo to pin 7
Serial.println("servo attached");
goto bailout;
}
n = readString.toInt(); //convert readString into a number
// auto select appropriate value
if(n >= 500)
{
Serial.print("writing Microseconds: ");
Serial.println(n);
myservo.writeMicroseconds(n);
}
else
{
Serial.print("writing Angle: ");
Serial.println(n);
myservo.write(n);
}
bailout: //reenter code loop
Serial.print("Last servo command position: ");
Serial.println(myservo.read());
Serial.println();
readString=""; //empty for next input
}
}
Thanks! I think the detach() method will cure the drift...
What I did:
remove servoRight.attach(9); and servoLeft.attach(10); from void.setup()
Put servoRight.attach(9); and servoLeft.attach(10); in all movement commands.
Put servoRight.detach(); and servoLeft.detach(); in the stop command.
Works like a charm.
@inventorArtist;
I will post them and the code when i tidy up the wiring a bit and mount the boards and battery properly.
I have the accelerator working, Had to change speed to only + numbers and use direction to turn and reverse.
Also using microseconds for speed = stop 1500 ~ 1620 fast.
It has 6" wheels and the frame is 1.5 x 6.5" so a 7.2V RC battery will fit. All of 1/8" plywood.
It's using a Arduino Pro Mini and a home made breakout board for standard servos and power supply.
Here is the code, subject to change.
/* Rolly_Robot Pro Mini 18 July 2014 JDS
IR Codes for DVR Remote
16720350 MULT
16763190 POWER
16716270 SEARCH
16714230 |<
16718310 ||<
16724430 |>
16728510 >||
16726470 >>
16761150 >|
16771350 ADD
16746870 FN
16742790 MENU
16767270 LEFT
16750950 RIGHT
16755030 UP
16734630 DOWN
16769310 1
16736670 2
16752990 3
16765230 4
16732590 5
16748910 6
16773390 7
16740750 8
16757070 9
16730550 0
16738710 ESC
16722390 -/--
Repeat 4294967295
Left servo pin 10
Right servo pin 11
IR is on pin 12
The IR sensor's pins to Arduino like so:
Pin 1 to Vout (pin 12 on Arduino)
Pin 2 to GND
Pin 3 to Vcc (+5v from Arduino)
*/
#include <IRremote.h>
#include <Servo.h>
int IRpin = 12; // pin for the IR sensor
int LED = 13; // LED pin
IRrecv irrecv(IRpin);
decode_results results;
unsigned long PrevResult;
Servo servoRight;
int servoRightZero = 1500;
int servoRightDirection = -1;
Servo servoLeft;
int servoLeftZero = 1500;
int servoLeftDirection = 1;
int Speed = 50;
int rightSpeed = 0;
int leftSpeed = 0;
void setup() {
irrecv.enableIRIn(); // Start the receiver
Serial.begin(9600);
}
void loop() {
digitalWrite(LED, LOW);
if (irrecv.decode(&results))
{ Serial.println(PrevResult);
digitalWrite(LED, HIGH);
switch (results.value)
{
case 16755030://forward
PrevResult = 16755030;
servoRight.attach(11);
servoLeft.attach(10);
Serial.println("Forward");
servoRightDirection = -1;
servoLeftDirection = 1;
rightSpeed = Speed;
leftSpeed = Speed;
break;
case 16742790://stop
PrevResult = 16742790;
Serial.println("Stop");
//rightSpeed = 0;
//leftSpeed = 0;
servoRight.detach();
servoLeft.detach();
break;
case 16734630://backward
PrevResult = 16734630;
servoRight.attach(11);
servoLeft.attach(10);
Serial.println("Backward");
servoRightDirection = 1;
servoLeftDirection = -1;
rightSpeed = Speed;
leftSpeed = Speed;
break;
case 16767270://left
PrevResult = 16767270;
servoRight.attach(11);
servoLeft.attach(10);
Serial.println("Left turn");
rightSpeed = Speed;
leftSpeed = Speed / 2;
break;
case 16750950://right
PrevResult = 16750950;
servoRight.attach(11);
servoLeft.attach(10);
Serial.println("Right turn");
rightSpeed = Speed / 2;
leftSpeed = Speed;
break;
case 16771350://ADD
PrevResult = 16771350;
servoRight.attach(11);
servoLeft.attach(10);
Serial.println("Left Dime");
servoRightDirection = -1;
servoLeftDirection = -1;
rightSpeed = Speed;
leftSpeed = Speed;
break;
case 16746870://FN
PrevResult = 16746870;
servoRight.attach(11);
servoLeft.attach(10);
Serial.println("Right Dime");
servoRightDirection = 1;
servoLeftDirection = 1;
rightSpeed = Speed;
leftSpeed = Speed;
break;
case 16718310://||< Slower
PrevResult = 16718310;
Serial.print("Slower ");
if (Speed >= 10)
{
Speed = Speed - 10;
}
rightSpeed = Speed;
leftSpeed = Speed;
Serial.println(Speed);
break;
case 16726470://>> Faster
PrevResult = 16726470;
Serial.print("Faster ");
if (Speed < 120)
{
Speed = Speed + 10;
}
rightSpeed = Speed;
leftSpeed = Speed;
Serial.println(Speed);
break;
case 4294967295:// repeat
if (PrevResult == 16718310) //slower
{
if (Speed >= 10)
{
Speed = Speed - 10;
delay(250);//blocking delay to slow speed change
}
rightSpeed = Speed;
leftSpeed = Speed;
}
if (PrevResult == 16726470) //faster
{
if (Speed < 120)
{
Speed = Speed + 10;
delay(250);//blocking delay to slow speed change
}
rightSpeed = Speed;
leftSpeed = Speed;
}
break;
}
servoLeft.writeMicroseconds(servoLeftZero + leftSpeed * servoLeftDirection);
servoRight.writeMicroseconds(servoRightZero + rightSpeed * servoRightDirection);
irrecv.resume();
}
}
Cool.
I made another one. It's a Flatpack, 4 leg walker. The dog gos nuts when it's walking around on the floor.
I guess it's the noise it makes walking, kinda loud.