Hi! I'm trying to control a DJI Ronin S gimbal with this hall effect joystick using an Arduino Uno.
The Ronin S can be controlled with the Futaba S-bus-system. To make this work, I'm using the servo library, and to translate the 'servo commands' to S-bus, I'm running the signal through a PWM/PPM to S-bus-converter, like this one.
This works, and I'm able to control the pan and tilt axis of the gimbal.
However, the program/gimbal seems unable to change directions or speed without first centering the joystick, if I've initiated a move involving more than one axis.
If I, for example, push the joystick up and to the right, the camera moves down and to the right, which is correct. However, if I keep the joystick pushed upwards, but move it to the left, the gimbal still keeps going right. If I then pull the joystick towards me, while still keeping it to the left, the gimbal keeps going right and the camera down. In other words it doesn't seem to want to change a move that has already started.
Once I recenter the joystick and pulls it towards me and to the left the gimbal will move in the right directions again.
Similarly, if I move the joystick to the left, and then initiate a camera down-movement by pushing the joystick forwards, the gimbal will only move to the left, but not start tilting down at all.
Using the joystick in just one axis at a time works as it should, and I'm able to do a two axes move if I'm careful and move the joystick so that movement in each axis (x, y) starts at the same time.
In other words: starting a move in two axes works, but correcting the move or changing directions does not work without first centering the joystick. Starting a one axis move and trying to start a second axis does not work.
The analogue values from the joystick as presented in the serial monitor all seems stable and valid to me, and they do change value when I move the joystick, but the gimbal doesn't seem to respond.
Does anyone have a suggestion as to what I'm doing wrong?
/* This program controls one or more DJI Ronin S gimbals using a hall effect joystick.
Revised 14 January 2020
*/
#include <Servo.h>
#define xaxis (A1) //Puts X-axis of joystick to input A1
#define yaxis (A3) //Puts Y-axis of joystick on input A2
#define zaxis (A5) //Puts Z-axis of joystick on input A3
Servo xmotor; //Names the 'servos': outputs for controlling the s.bus-converter
Servo ymotor;
Servo zmotor;
int xDJI; //Defines a value called xDJI for the variable speed of the x-axis
int yDJI; //Defines a value called yDJI for the variable speed of the y-axis
int zDJI; //Defines a value called zDJI for the variable speed of the z-axis
int cmdRepeatCount; //Defines a value called cmdRepeatCount, to repeat commands more easily
void setup() {
Serial.begin(9600);
Serial.println("Starting up ...");
pinMode(LED_BUILTIN, OUTPUT);
pinMode(xaxis, INPUT); //defines input-pins from joystick as inputs
pinMode(yaxis, INPUT);
pinMode(zaxis, INPUT);
Serial.println("Attaching servo x-axis");
xmotor.attach(3); //Sets output pin for for xmotor: pan, S.BUS channel 0 (PPM-PPS-SBUS-board CH 1)
delay(200);
Serial.println("Attaching servo y-axis");
ymotor.attach(5); //Sets output pin for for ymotor: tilt, S.BUS channel 1 (PPM-PPS-SBUS-board CH 2)
delay(200);
Serial.println("Attaching servo z-axis");
zmotor.attach(6); //Sets output pin for for zmotor: roll, S.BUS channel 3 (PPM-PPS-SBUS-board CH 4)
delay(200);
while (cmdRepeatCount < 5) { //repeats this command x times
digitalWrite(LED_BUILTIN, HIGH);
delay(200);
digitalWrite(LED_BUILTIN, LOW); //flash builtin LED once
delay(200);
cmdRepeatCount++; //increase repeat count +1
}
Serial.println("Startup complete");
}
void loop() {
int xvalue = analogRead(xaxis); //reading values from joystick axis
int yvalue = analogRead(yaxis);
int zvalue = analogRead(zaxis);
Serial.print("\t xvalue: "); //printing values from joystick axis
Serial.print(xvalue);
Serial.print("\t yvalue: ");
Serial.print(yvalue);
Serial.print("\t zvalue: ");
Serial.print(zvalue);
Serial.println(" ");
xDJI = xvalue; //Link xvalue to xDJI
yDJI = yvalue; //Link yvalue to yDJI
xDJI = map(xDJI, 57, 950, 0, 180); //maps xDJI values to servo-values: min value from joystick, max, degrees min, degrees max
yDJI = map(yDJI, 57, 950, 0, 180); //maps yDJI values to servo-values: min value from joystick, max, degrees min, degrees max
if (xDJI > 480 && xDJI < 505){xDJI = 510;} //sets range of deadband low and high, and gives a replacement value.
if (yDJI > 480 && yDJI < 505){yDJI = 510;} //sets range of deadband low and high, and gives a replacement value.
if (xDJI != 510) {
xmotor.write(xDJI);}
if (yDJI != 510) {
ymotor.write(yDJI);}
}



