I've been searching on the web a lot but I didn't find anything that match what I need, I'm really new to all these and trying to make my own code for these project is quite difficult. I "just" need variable speed with a joystick on a modify continuous rotation servo. I already have the modify servo working, but when I push the joystick the servo reach its max. speed with a little impute (or pushing all degrees), I need it to be exponential (from 0 to 100, lets say), like the wheels of a car toy.
I was trying with the VarSpeedServo.h Arduino library, but not results so far (mostly I spouse because of my poor knowledge).
Perhaps if you showed your code it would be a minor change.
My first guess at a solution would look something like this:
const int INPUT_PIN = A0;
const int ZERO_POINT = 33; // An adjustment to get the servo to stop when stick is centered.
void loop() {
int speed = analogRead(INPUT_PIN) - 512; // -512 to +511
long expo = speed * abs(speed); // -262144L to +261121L
servo.writeMicroseconds(map(expo, -262144L, 261121L, 1000, 2000) - ZERO_POINT);
}
Hi, johnwasser, at int speed = analogRead(INPUT_PIN)-512 with tiny input the servo moves slow, then faster (slow tough, not reach its max peed), and then ultra slow. I played with that numbers from -512 to +511, but not results
zoomkat, it's almost there. I get an exponential servo moving (with a potVal=150) but with in a 1/3 of the joystick range, the rest is full speed. what do you mean when you say "put your main code here, to run repeatedly".
hi Tom, its a futaba s3004, I didn't remove the potentiometer, I drilled a biger hole in the main gear so that the potentiometer would not move. I did these so I could adjust the potenciometer to "0", I mean, so it stops spinning.
While you had the servo apart, did you send the servo a 90 deg. (1500us) command and then carefully adjust the pot such that the motor stopped moving?
zoomkat, it's almost there. I get an exponential servo moving (with a potVal=150) but with in a 1/3 of the joystick range, the rest is full speed. what do you mean when you say "put your main code here, to run repeatedly".
sin2numeros:
if it's myservo.write(90); in void setup... it's done. But I'm having the same problems
You need to clearly explain what your current problems are. You can change the mapping like below. Bottom is servo test code to see how the command values change the servo rotation speed.
// 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
}
You need to clearly explain what your current problems are. You can change the mapping like below. Bottom is servo test code to see how the command values change the servo rotation speed.
I made a video showing the problem I have (Hope would be more clear). I've been playing with the mapping numbers, but no succeed. It slowly gain speed but with in the halph of the joystick range, then it's all constant speed.
I had problems with the code, I enter the values for the servo position but nothing happens. here is the code, there might be something I did wrong. (I used this code in the video. thanks Tom for the tip!):
#include <Servo.h>
String readString;
Servo myservo;
int pos=1500;
int potPin=0;
int potVal=150;
void setup() {
myservo.attach(9,400,2600); // put your setup code here, to run once:
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
potVal = analogRead(potPin); // read pan joystick position
potVal = map(potVal, 0, 1023, 1300, 1700); // scale reading to servo
myservo.writeMicroseconds(potVal); //move servo to required position// put your main code here, to run repeatedly:
}
Use this sketch to control the servo and note the microsecond values for maximum speed forward, stop, and maximum speed reverse. Report back with those values. That data will be handy for designing your final sketch.
#include <Servo.h>
Servo myservo;
const int potPin = A0;
void setup() {
myservo.attach(9); // put your setup code here, to run once:
Serial.begin(9600);
}
void loop() {
int potVal = analogRead(potPin);
int microseconds = map(potVal, 0, 1023, 1000, 2000);
myservo.writeMicroseconds(microseconds);
Serial.println(microseconds);
delay(500);
}
and should be: (backward) 987654321-0-123456789 (forward)
Did you try reducing the mapped servo control range like I suggested to 1400-1600? The code below has the reduced range which should give wider stick speed control.
//continuous rotation servo joystick
#include <Servo.h>
Servo myservo; //declare servo
int potPin = 0; //analog input pin A0
int potVal=1500; //~neutral value for continous rotation servo
void setup()
{
myservo.attach(9); // use pin 9 for servo control
}
void loop ()
{
potVal = analogRead(potPin); // read pan joystick position
potVal = map(potVal, 0, 1023, 1400, 1600); // scale reading to servo
myservo.writeMicroseconds(potVal); //move servo to required position
}
Use this sketch to control the servo and note the microsecond values for maximum speed forward, stop, and maximum speed reverse. Report back with those values. That data will be handy for designing your final sketch.
I just upload the code and read it in the serial monitor, is that right? my doubt is because of the obvious numbers.
Did you try reducing the mapped servo control range like I suggested to 1400-1600? The code below has the reduced range which should give wider stick speed control.
Yes I did, but 1300-1700 was the best range. Now I have check it again and notice the potVal was 150 instead of 1500. With this correction and the 1400-1600 range, the servo works better. It's a softer curve but not quite yet where I need it to be. It allows me more control because it's slower now...
I found a video that shows the exact same problem (although the solution it's not for me...)
Please jump to the minute 5:45 (you only need to watch 2 minutes from there)