Hi,
For my project I have several servo's I want be controlled by some joysticks Ive got off amazon (See link).
I have managed to control the servos by simply mapping the analogue output from the x and y of the sticks to the pwm value sent to the servo's but what I really want is for the sticks to control the increment of the servo position.
For example, pushing the stick up will increase the position of the servo, then, upon letting the stick return to it neutral position, the servo stays where it is. Then moving the stick down, will decrease the position of the servo.
I have 8 servo's to control, and 4 joysticks.
Ideally it would be nice if the further I push the stick, the greater the rate of increase in the servo's position, though this is not necessary.
Any ideas on how to achieve this? I assume some for loop where once the analogueRead of the stick is over a certain value the pwm value sent to the servo is incremented upwards.
For example, pushing the stick up will increase the position of the servo, then, upon letting the stick return to it neutral position, the servo stays where it is. Then moving the stick down, will decrease the position of the servo.
How is the Arduino supposed to know when YOU are moving the joystick down, vs. the return spring moving the joystick down?
When you can answer that, you can see that doing what you want is trivial.
You are currently mapping the joystick reading to a servo position.
Instead, map the joystick reading to a joystick adjustment factor.
That can be added to a variable that holds the servo position and then used to command the servo to move to that position.
You will want to test the bounds to prevent allowing the servo position from getting too large or too small.
You will want some timing delay (millis or delay) to keep the values from moving up or down too fast.
Basically it reads the analogue input of the sticks, maps it to the min and max positions of my servos, then sends it down the serial line to 3 other boards (Adafruit trinket m0s) which listen out for their 'module' number (1, 2 or 3 at the moment), and log the next two numbers as the servo positions for the two servos they each control.
const int module_id = 0; //Define this module as node 0. Due to 1 byte limit max number of modules is 225
int d = 10;
int v1 = 90;
int h1 = 90;
int v2 = 90;
int h2 = 90;
int v3 = 90;
int h3 = 90; //Initialise h and v as the horiz and vert servo position values
int x_pos1 = 512;
int y_pos1 = 512;
int x_pos2 = 512;
int y_pos2 = 512;
int x_pos3 = 512;
int y_pos3 = 512; //Int x and y stick position values
int x_pin1 = 0;
int y_pin1 = 1;
int x_pin2 = 2;
int y_pin2 = 3;
int x_pin3 = 4;
int y_pin3 = 5; //Int x and y analogue pin numbers
void setup() {
Serial.begin(19200); //Initialise Serial Comunications
}
void loop() {
x_pos1 = analogRead(x_pin1);
y_pos1 = analogRead(y_pin1);
x_pos2 = analogRead(x_pin2);
y_pos2 = analogRead(y_pin2);
x_pos3 = analogRead(x_pin3);
y_pos3 = analogRead(y_pin3);
h1 = map(x_pos1, 0, 1023, 30, 150);
v1 = map(y_pos1, 1023, 0, 30, 150);
h2 = map(x_pos2, 0, 1023, 30, 150);
v2 = map(y_pos2, 1023, 0, 30, 150);
h3 = map(x_pos3, 0, 1023, 30, 150);
v3 = map(y_pos3, 1023, 0, 30, 150);
send(1, v1, h1);
delay(d);
send(2, v2, h2);
delay(d);
send(3, v3, h3);
delay(d);
}
void send (int id, int horiz, int vert){
Serial.print(id);Serial.print(" ");
Serial.print(horiz);Serial.print(" ");
Serial.print(vert);Serial.print(" ");
}
I was able to replicate this exact question with a tutorial that I wrote. The servos I'm using are the MG90S kind, and standard joysticks. I've reduced the jitter by reducing the response to small movements in the joystick. Ive also been able to return the joystick to neutral and have almost no movement in the servos. This is somewhat difficult, but essentially if the movement of the servo only responds to movements in the 0-180 degrees, then this isn't so bad.
Here's a link to the tutorial if you're interested: