Advertisement
kr0k0f4nt

Arduino Nano - Bayangtoys X21 Gimbal Control - Version 1.2

Oct 21st, 2017
936
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 7.80 KB | None | 0 0
  1. /*  
  2.  *  Bayangtoys X21 BGC Gimbal Control for Ardunio
  3.  *  by kr0k0f4nt (2017) - Version 1.2
  4.  *  
  5.  *  Version 1.2 (2017-10-21)
  6.  *  - Changed MODE 2 control to Start/Stop on each press on Photo/Video (Up/Down)
  7.  *    Also reaching the MAX/MIN Angle will stop the movement
  8.  *  - Changed default Value for SPEED to 2, to allow smooth Pans with the Gimbal
  9.  *  - Remove STEPS Settings, as it is not longer required
  10.  *  
  11.  *  Version 1.1 (2017-09-20)
  12.  *  - Added SPEED to SETTINGS to Control MODE 1
  13.  *  - Pressing the Video Button will now always set next Movement on Photo Button to upwards
  14.  *  
  15.  *  Version 1.0 (2017-09-19)
  16.  *  - Initial Release
  17.  *  
  18.  *  PPM Processing based on Code by Sijjim (https://forum.arduino.cc/index.php?topic=182681.0)
  19.  *  Inspired by Muhammad Imam Zulkarnaen (https://www.youtube.com/watch?v=pYitT60Frjc)
  20.  */
  21.  
  22. // *********************** SETTINGS ****************************
  23. /*
  24.  * Angle can be 0-2000, but only Values between 1500-2000 make sense
  25.  * 1000 = Camera looks straight up to the drone body, lower values make it look backwards
  26.  * 1500 = Neutal Setting looking straight forward
  27.  * 2000 = Cameras looks straight down
  28.  */
  29. #define MAX           2000     // Max Angle
  30. #define STD           1650     // Standard Angle for MODE 1
  31. #define MIN           1500     // Min Angle
  32. #define SPEED         2        // Speed for MODE 2 (or MODE 1 when pressing Photo Button), 1 is slowest to 10 fastest
  33.  
  34. /*
  35.  * Interrputs are not available on all Pins, for the Nano only on 2 & 3
  36.  */
  37. #define PPM_PIN       2        // PIN with X21 Signal
  38.  
  39. /*
  40.  * This only needs to be a Pin that is capable of PWM, for the Nano this is 3,5-6,9-11
  41.  */
  42. #define GIMBAL_PIN    6       // PIN with Gimbal Signal
  43.  
  44. /*
  45.  * Setting Up Pin Pair for MODE Control
  46.  */
  47. #define MODE_PIN_OUT  7        // MODE Pin Output
  48. #define MODE_PIN_IN   8        // MODE Pin Input
  49. #define MODE_1_FIXED  1        // Mode for fixed Angles on Video Button
  50. #define MODE_2_STEP   2        // Mode for Stepping Angles video Video (Down) and Photo Up
  51.  
  52. /*
  53.  * This will set the number of channels in the PPM signal
  54.  */
  55.  
  56. #define CHANNELS        3         // X21 works with 3 Channels
  57. #define CHANNEL_SIGNAL  3         // X21 Signal is on Channel 3
  58.  
  59. /*
  60.  * These are the Signal average Values for the Channel 3, which varies on the Video/Photo Buttons being pressed
  61.  */
  62.  
  63. #define SIGNAL_BASE    500
  64. #define SIGNAL_PHOTO   1100
  65. #define SIGNAL_VIDEO   1600
  66.  
  67. // ****************** GLOBAL VARIABLES ******************
  68.  
  69. #include <Servo.h>
  70. Servo Gimbal;
  71.  
  72. // State Variables for handling Signal toggles
  73. boolean VideoMode = false;
  74. int LastSignal = SIGNAL_BASE;
  75.  
  76. int GimbalMode = 0;
  77. int GimbalState = STD;
  78.  
  79. // Variables for MODE 1 Control by Photo Button
  80. int GimbalSteps = 0;
  81. int GimbalLastSteps = SPEED;
  82.  
  83. // Variables for PPM Processing
  84. volatile int Values[CHANNELS + 1] = {0};
  85.  
  86. // *****************************************************
  87.  
  88. void setup() {
  89.   // Serial Communcication Output
  90.   Serial.begin(115200);
  91.  
  92.   // Settings up MODE pins
  93.   pinMode(PPM_PIN, INPUT);
  94.   pinMode(MODE_PIN_OUT, OUTPUT);
  95.   pinMode(MODE_PIN_IN, INPUT_PULLUP);
  96.   digitalWrite(MODE_PIN_OUT, LOW);
  97.  
  98.   // Setting up Gimbal
  99.   Gimbal.attach(GIMBAL_PIN);
  100.   Gimbal.writeMicroseconds(GimbalState);
  101. }
  102.  
  103. void loop(){
  104.  
  105.   // MODE Selection
  106.   if (digitalRead(MODE_PIN_IN) == HIGH) {
  107.     if (GimbalMode != MODE_1_FIXED) {
  108.       GimbalMode = MODE_1_FIXED;
  109.       Serial.println("MODE 1 - Fixed Angles");
  110.     }
  111.   } else {
  112.     if (GimbalMode != MODE_2_STEP) {
  113.       GimbalMode = MODE_2_STEP;
  114.       Serial.println("MODE 2 - Stepping Angles");
  115.     }
  116.   }
  117.  
  118.   // Wait for Sync on Signal
  119.   while(pulseIn(PPM_PIN, HIGH) < 2500){}
  120.  
  121.   // Processing PPM Signal
  122.   for (int Channel = 1; Channel <= CHANNELS; Channel++) {
  123.     Values[Channel] = pulseIn(PPM_PIN, HIGH);
  124.   }
  125.  
  126.   // Determinig the Sigal for easier handling
  127.   int Signal = Values[CHANNEL_SIGNAL];
  128.   if (Signal <= 1800 && Signal >= 1500) {
  129.     Signal = SIGNAL_VIDEO;
  130.   } else if (Signal <= 1200 && Signal >= 900) {
  131.     Signal = SIGNAL_PHOTO;
  132.   } else {
  133.     Signal = SIGNAL_BASE;
  134.   }
  135.  
  136.  
  137.   // Only do something whenever Signal changes
  138.   if (LastSignal != Signal) {
  139.    
  140.     /*
  141.      *  Figuring out which Key was actually pressed ...
  142.      *  This is a bit tricky as there are only 3 Signal States and the SIGNAL_BASE is shared by both Buttons
  143.      *  To solve this we need to maintain the State of the VideoMode as well as the LastSignal.
  144.     */
  145.    
  146.     int KeyPressed;
  147.    
  148.     switch(Signal) {
  149.       case SIGNAL_VIDEO:
  150.         if (VideoMode) {
  151.           VideoMode = false;
  152.           KeyPressed = SIGNAL_VIDEO;
  153.         } else {
  154.           VideoMode = true;
  155.           KeyPressed = SIGNAL_VIDEO;  
  156.         }
  157.         break;
  158.       case SIGNAL_PHOTO:
  159.         KeyPressed = SIGNAL_PHOTO;
  160.         break;
  161.       case SIGNAL_BASE:
  162.         if (VideoMode == true && LastSignal == SIGNAL_VIDEO) {
  163.           VideoMode = false;
  164.           KeyPressed = SIGNAL_VIDEO;
  165.         } else if (VideoMode == false && LastSignal == SIGNAL_VIDEO) {
  166.           VideoMode = true;
  167.           KeyPressed = SIGNAL_VIDEO;
  168.         } else {
  169.           KeyPressed = SIGNAL_PHOTO;
  170.         }
  171.         break;
  172.     }
  173.  
  174.     DebugPrintStates(KeyPressed, Signal, VideoMode);
  175.  
  176.     if (GimbalMode == MODE_1_FIXED) {
  177.       // MODE 1 - Using Fixed Values on Video Button / Toggle Control on Photo
  178.  
  179.       // Toggle between Standard and Maximum Angle with Video Mode
  180.       if (KeyPressed == SIGNAL_VIDEO) {
  181.         // Stop current movement and set next direction to upwards
  182.         GimbalSteps = 0;
  183.         GimbalLastSteps = SPEED;
  184.         // Video Mode represents the Angles on the Remote, it toggels between MAX and STD Settings
  185.         if (VideoMode) {
  186.           GimbalState = MAX;
  187.         } else {            
  188.           GimbalState = STD;
  189.         }
  190.       } else {
  191.         // Photo Button controls the Gimbal by starting or stopping the motion and cycle direction each time
  192.         if (GimbalSteps != 0) {
  193.           // Gimbal is currently moving ... Stop now!
  194.           GimbalSteps = 0;
  195.         } else {
  196.           // Gimbal is stopped ... Start moving and switch direction!
  197.           GimbalSteps = GimbalLastSteps * (-1);
  198.           GimbalLastSteps = GimbalSteps;
  199.         }
  200.       }
  201.      
  202.     } else {
  203.       // MODE 2 - Using Photo Button for Step Up / Video Button for Down
  204.  
  205.       if (KeyPressed == SIGNAL_VIDEO) {
  206.         // Moving the Gimbal downwards ...
  207.         if (GimbalSteps != 0) {
  208.           // Gimbal is currently moving ... Stop now!
  209.           GimbalSteps = 0;
  210.         } else {
  211.           // Gimbal is stopped ... Start moving downwards ...
  212.           GimbalSteps = SPEED;
  213.         }
  214.       } else {
  215.         // Moving the Gimbal upwards ...
  216.         if (GimbalSteps != 0) {
  217.           // Gimbal is currently moving ... Stop now!
  218.           GimbalSteps = 0;
  219.         } else {
  220.           // Gimbal is stopped ... Start moving upwards ...
  221.           GimbalSteps = -SPEED;
  222.         }
  223.       }
  224.        
  225.     }
  226.  
  227.     // Overwrite Last Signal
  228.     LastSignal = Signal;
  229.    
  230.   }
  231.  
  232.   // Write GimbalState but maintain MIN/MAX Angles and stop movment if exceeded
  233.   if (GimbalState + GimbalSteps > MAX) {
  234.     GimbalState = MAX;
  235.     GimbalSteps = 0;
  236.   } else if (GimbalState + GimbalSteps < MIN) {
  237.     GimbalState = MIN;
  238.     GimbalSteps = 0;
  239.   } else {
  240.     Gimbal.writeMicroseconds(GimbalState += GimbalSteps);
  241.   }
  242.  
  243. }
  244.  
  245. void DebugPrintStates(int KeyPressed, int Signal, boolean VideoMode) {
  246.     Serial.print("Key pressed: ");
  247.     if (KeyPressed == SIGNAL_VIDEO) {
  248.       Serial.print("VIDEO - ");
  249.       Serial.println(Signal);
  250.     } else {
  251.       Serial.print("PHOTO - ");
  252.       Serial.println(Signal);
  253.     }
  254.     Serial.print("Video Mode: ");
  255.     if (VideoMode) {
  256.       Serial.println("ON");
  257.     } else {
  258.       Serial.println("OFF");
  259.     }  
  260. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement