roniloapin

Self Balancing Stick

Mar 5th, 2017
302
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // Library Inclusions
  2.  
  3. #include <I2Cdev.h>                             // IMU IC2 Communication
  4. #include <Wire.h>                               // IMU IC2 Communication
  5. #include <MPU6050_6Axis_MotionApps20_mod_1.h>   // IMU,  changed value in line 305 to 1 to change update speed from every 15ms to every 10ms
  6. #include <PinChangeInt.h>                       // Pin Change Interrupt
  7. #include <digitalWriteFast.h>                   // Fast Digital Readings
  8.  
  9.  
  10.  
  11. // Pin Assignments
  12.  
  13. #define   pin_left_PMW          9
  14. #define   pin_left_EncoderA     2
  15. #define   pin_left_EncoderB     A2
  16.  
  17. #define   pin_right_PMW         10
  18. #define   pin_right_EncoderA    3  
  19. #define   pin_right_EncoderB    4
  20.  
  21. #define   pin_IN1               5
  22. #define   pin_IN2               6
  23. #define   pin_IN3               7
  24. #define   pin_IN4               8
  25.  
  26. #define   pin_left_Current      A0
  27. #define   pin_right_Current     A1
  28.  
  29. #define   pin_IMU_Interrupt     12
  30. #define   pin_IMU_SDA           A4
  31. #define   pin_IMU_SCL           A5
  32.  
  33. #define   pin_Pot               A3
  34. #define   pin_Pot_kp            //
  35. #define   pin_Pot_ki            //
  36. #define   pin_Pot_kd            //
  37.  
  38.  
  39.  
  40. // Interrupt Assignment
  41.  
  42. #define   interruptPin_left_Encoder    0
  43. #define   interruptPin_right_Encoder   1
  44.  
  45.  
  46. // User Variable Definitions
  47.  
  48. #define   encoder_Tick_Resolution   10                    // Defines how many ticks to 'wait' until calculating encoder positions and time measurments. Higher values lead to decreased ISR times, but decreased encoder accuracy.
  49. #define   pmw_Length                256                   // Defines wavelength of PMW signals by modifying divisor, [ 1, 8, 64(default), 256, 1024].  Base Freq.: 31250 Hz. Lower values lead to smoother motors, but worse current readings (or better, not sure).
  50. #define   encoder_Speed_Time_Limit  100                   // Defines how long to wait for a new tick before assuming wheel is stopped [ms]
  51. #define   motor_Current_Sample_Size 400 //50              // Defines the number of current samples to take, should be atleast 255, [20us*400 = 8000us = PMW Length@Divisor=256]
  52. #define   motor_Current_Sample_Delay 0                    // Delay between samples [us]
  53. #define   time_Delay                1                     // Defines amount of time program pauses
  54. #define   voltage_Offset            0                     // Defines amount of volateg added to compensate for motor sticktion, [0 - 255].
  55. #define   twbr_Value                24                    // Defines clocck speed of I2C, higher value leads to slower speeds and more robust comms 'aledgledy', [1-255, 24(default)].
  56. #define   angle_Rounding_Value      1000.                   // Defines what value to multiple by before round theta and omega. Cuts down on noise, [10 = x.1,  100 = x.x1 , 1(Default)]
  57. //Line 305 of MPU6050_6Axis_MotionApps20.h  = 1[10ms]    // Defines frequency of FIFO, higher value leads to less frequent updates, (200Hz /(1+value)), [0x02 (default)].
  58.  
  59.  
  60. #define   theta_Filter              0.7
  61. #define   theta_Speed_Filter        0.7
  62. #define   theta_Integral_Max        3.0
  63. #define   left_Speed_Filter         0.8
  64.  
  65. #define   omega_Filter              0.7
  66. #define   omega_Speed_Filter        0.7
  67. #define   omega_Integral_Max        3.0
  68. #define   right_Speed_Filter        0.8
  69.  
  70.  
  71.    
  72. float     angle_Average_Filter  = 0.970;
  73. float     theta_Zero_Filter     = 0.995;
  74. float     omega_Zero_Filter     = 0.986;
  75. float     angle_Smoothed_Filter = 0.997;
  76. float     friction_Value        = 10;
  77.  
  78. // Definitions
  79.  
  80. #define   encoder_PPR               334.                   // Encoder pulse per revolution
  81. #define   serial_Frequency          250000 //230400               // Frequency of serial interface
  82.  
  83.  
  84. // Motor Global Variables
  85.  
  86. volatile unsigned int   left_Rel_Tick_Count = 0;          // Encoder ticks untill resolution
  87. volatile long           left_Abs_Tick_Count = 0;          // Absolute total of encoder ticks
  88. volatile long           left_Abs_Tick_Count_Prev = 0;     // Previous Absolute total of encoder ticks
  89. volatile int            left_Encoder_Direction = 0;       // Encoder measured direction, [-1 or 1]
  90. volatile int            left_Encoder_Direction_Prev = 0;  // Encoder measured direction, [-1 or 1]
  91. volatile int            left_Encoder_Direction_Now = 0;   // Encoder measured direction, [-1 or 1]
  92. volatile int            left_Encoder_Direction_Debug = 0;   // Encoder measured direction, [-1 or 1]
  93. volatile unsigned long  left_Time_Prev = 0;               // Time at previous absolute tick change, [us]
  94. volatile unsigned long  left_Time_Now = 0;                // Time at current absolute tick change, [us]
  95. volatile unsigned long  left_Time_Dif = 0;            
  96. volatile unsigned long  left_Time_Acc_Prev = 0;           // Time at previous absolute tick change, [us]
  97. volatile unsigned long  left_Time_Acc_Now = 0;            // Time at current absolute tick change, [us]
  98.          unsigned long  left_Time_Age = 0;                // Time at current absolute tick change, [us]
  99.          unsigned long  left_Time_Saved = 0;              // Time at current absolute tick change, [us]
  100.  
  101. volatile unsigned int   right_Rel_Tick_Count = 0;          // Encoder ticks untill resolution
  102. volatile long           right_Abs_Tick_Count = 0;          // Absolute total of encoder ticks
  103. volatile int            right_Encoder_Direction = 0;       // Encoder measured direction, [-1 or 1]
  104. volatile int            right_Encoder_Direction_Prev = 0;  // Encoder measured direction, [-1 or 1]
  105. volatile int            right_Encoder_Direction_Now = 0;   // Encoder measured direction, [-1 or 1]
  106. volatile unsigned long  right_Time_Prev = 0;               // Time at previous absolute tick change, [us]
  107. volatile unsigned long  right_Time_Now = 0;                // Time at current absolute tick change, [us]
  108. volatile unsigned long  right_Time_Dif = 0;            
  109. volatile unsigned long  right_Time_Acc_Prev = 0;           // Time at previous absolute tick change, [us]
  110. volatile unsigned long  right_Time_Acc_Now = 0;            // Time at current absolute tick change, [us]
  111.          unsigned long  right_Time_Age = 0;                // Time at current absolute tick change, [us]
  112.          unsigned long  right_Time_Saved = 0;              // Time at current absolute tick change, [us]
  113.          
  114. float   left_Speed_RPM = 0;
  115. float   left_Speed_RPM_Unfiltered = 0;
  116. float   left_Speed_RPM_Prev = 0;
  117. float   left_Speed_RPM_Alt = 0;
  118. float   left_Speed_RPM_Alt_Prev = 0;
  119. float   left_Acceleration = 0;                    
  120. int     left_Current_Max = 0;
  121. int     left_Current_Avg = 0;
  122. long    left_Current_Total = 0;
  123. int     left_Current;
  124. int     left_Voltage = 0;
  125.  
  126. float   right_Speed_RPM = 0;
  127. float   right_Speed_RPM_Prev = 0;
  128. float   right_Acceleration = 0;                    
  129. int     right_Current_Max = 0;
  130. int     right_Current_Avg = 0;
  131. long    right_Current_Total = 0;
  132. int     right_Current;
  133. int     right_Voltage = 0;
  134.  
  135.  
  136. float   encoder_Resolution_Size;                          // Encoder Revolution per each encrment in resolution * 100000, calculated in setup
  137.  
  138.  
  139.  
  140.  
  141. //  Controller Variables
  142.  
  143. unsigned long   imu_Time_Now = 0;
  144. unsigned long   imu_Time_Prev = 0;
  145.  
  146.  
  147. float           left_Speed_Const = 0;                     // Relates Voltage to Speed.  Determines how much extra voltage is added to PID Voltage.
  148. int             left_PID_Voltage = 0;
  149. float           left_PID_Accel = 0;
  150. float           left_P_Accel = 0;
  151. float           left_I_Accel = 0;
  152. float           left_D_Accel = 0;
  153. float           left_S_Accel = 0;
  154.  
  155. float           right_Speed_Const = 0;                     // Relates Voltage to Speed.  Determines how much extra voltage is added to PID Voltage.
  156. int             right_PID_Voltage = 0;
  157. float           right_PID_Accel = 0;
  158. float           right_P_Accel = 0;
  159. float           right_I_Accel = 0;
  160. float           right_D_Accel = 0;
  161. float           right_S_Accel = 0;
  162.  
  163. float           theta_Kp = 1200;
  164. float           theta_Ki = 0;
  165. float           theta_Kd = 130;
  166. float           theta_Ks = -25;
  167. float           theta_Kt = 0.6;
  168. float           theta_Ktd = 0;
  169. float           theta_Zero = 0;
  170. float           theta_Zero_Initial = 0;
  171. float           theta_Zero_Prev = 0;
  172. float           theta_Zero_Unfiltered = 0;
  173. float           theta_Error = 0;
  174. float           theta_Error_Prev = 0;
  175. float           theta_Error_Unfiltered = 0;
  176. float           theta_Now = 0;
  177. float           theta_Now_Unfiltered = 0;
  178. float           theta_Prev = 0;
  179. float           theta_Average = 0;
  180. float           theta_Average_Prev = 0;
  181. float           theta_Speed_Now = 0;
  182. float           theta_Speed_Prev = 0;
  183. float           theta_Speed_Unfiltered = 0;
  184. float           theta_Integral = 0;
  185. float           theta_Smoothed = 0;
  186. float           theta_Smoothed_Prev = 0;
  187. float           theta_Smoothed_Speed = 0;
  188.  
  189.  
  190. float           omega_Kp = 1600;
  191. float           omega_Ki = 0;
  192. float           omega_Kd = 130;
  193. float           omega_Ks = -25;
  194. float           omega_Kt = 0.6;
  195. float           omega_Ktd = 1.0;
  196. float           omega_Zero = 0;
  197. float           omega_Zero_Initial = 0;
  198. float           omega_Zero_Prev = 0;
  199. float           omega_Zero_Unfiltered = 0;
  200. float           omega_Error = 0;
  201. float           omega_Error_Prev = 0;
  202. float           omega_Now = 0;
  203. float           omega_Now_Unfiltered = 0;
  204. float           omega_Average = 0;
  205. float           omega_Average_Prev = 0;
  206. float           omega_Prev = 0;
  207. float           omega_Speed_Now = 0;
  208. float           omega_Speed_Prev = 0;
  209. float           omega_Speed_Error = 0;
  210. float           omega_Integral = 0;
  211. float           omega_Smoothed = 0;
  212. float           omega_Smoothed_Prev = 0;
  213. float           omega_Smoothed_Speed = 0;
  214.  
  215.  
  216. // OTHERS
  217. int     pot_Value = 0;
  218. long    time_Now = 0;
  219. long    time_Prev = 0;
  220. float   hertz = 0;
  221. int     stat = 0;                                       // Brings you to Change theta_zero mode
  222.  
  223. int     voltage_Max = 0;
  224. String  package;
  225.  
  226.  
  227. // DEBUG
  228. volatile long l = 0;
  229. int     m = 0;
  230. long    o = 0;
  231. int     p = 0;
  232. int     p_Prev = 0;
  233.  
  234. long    time_IMU_Prev = 0;
  235. long    time_IMU_Now = 0;
  236. long    time_IMU_Dif = 0;
  237.  
  238. long    time_Probe_Prev = 0;
  239. long    time_Probe_Now = 0;
  240. long    time_Probe_Dif = 0;
  241.  
  242. // TestBed_Accleration
  243. int left_Target_Voltage = 0;
  244. int right_Target_Voltage = 0;
  245.  
  246.  
  247.  
  248. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  249.  
  250.  
  251.  
  252.  
  253. // IMU Global Variables
  254.  
  255. bool          blinkState = false;
  256. bool          dmpReady = false;     // set true if DMP init was successful
  257. uint8_t       mpuIntStatus;         // holds actual interrupt status byte from MPU
  258. uint8_t       devStatus;            // return status after each device operation (0 = success, !0 = error)
  259. uint16_t      packetSize;           // expected DMP packet size (default is 42 bytes)
  260. uint16_t      fifoCount;            // count of all bytes currently in FIFO
  261. uint8_t       fifoBuffer[64];       // FIFO storage buffer
  262. float         euler[3];             // [psi, theta, phi]    Euler angle container
  263. float         ypr[3];               // [yaw, pitch, roll]   yaw/pitch/roll container and gravity vector
  264. MPU6050       mpu;                  // Creating object 'mpu', I think
  265. Quaternion    q;                    // [w, x, y, z]         quaternion container
  266. VectorInt16   aa;                   // [x, y, z]            accel sensor measurements
  267. VectorInt16   aaReal;               // [x, y, z]            gravity-free accel sensor measurements
  268. VectorInt16   aaWorld;              // [x, y, z]            world-frame accel sensor measurements
  269. VectorFloat   gravity;              // [x, y, z]            gravity vector
  270.  
  271. uint8_t       teapotPacket[14] = { '$', 0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0x00, 0x00, '\r', '\n' };     // packet structure for InvenSense teapot demo
  272. volatile bool mpuInterrupt = false;                                                                 // indicates whether MPU interrupt pin has gone high
  273.  
  274. void setup() {
  275.  
  276.   //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  277.  
  278.   // Serial
  279.   Serial.begin(serial_Frequency);
  280.   //package.reserve(500);
  281.  
  282.   //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  283.  
  284.   // Pin Modes
  285.   pinMode(pin_IMU_Interrupt, INPUT);
  286.   pinMode(pin_left_PMW, OUTPUT);
  287.   pinMode(pin_right_PMW, OUTPUT);
  288.   pinMode(pin_IN1, OUTPUT);
  289.   pinMode(pin_IN2, OUTPUT);
  290.   pinMode(pin_IN3, OUTPUT);
  291.   pinMode(pin_IN4, OUTPUT);
  292.  
  293.   //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  294.  
  295.   // Pull Ups
  296.   digitalWrite(pin_IMU_Interrupt, HIGH);
  297.  
  298.   //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  299.  
  300.   // Interrupts
  301.   PCintPort::attachInterrupt(pin_IMU_Interrupt, dmpDataReady, RISING);
  302.   attachInterrupt(interruptPin_left_Encoder, ISR_left_Encoder, RISING);
  303.   attachInterrupt(interruptPin_right_Encoder, ISR_right_Encoder, RISING);
  304.  
  305.   //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  306.  
  307.   // Setting PMW Wavelength
  308.   byte mode;
  309.   switch (pmw_Length) {
  310.     case 1: mode = 0x01; break;
  311.     case 8: mode = 0x02; break;
  312.     case 64: mode = 0x03; break;
  313.     case 256: mode = 0x04; break;
  314.     case 1024: mode = 0x05; break;
  315.     default:  ;                        // Code that is executed when pmw_Length does not match a case
  316.   }
  317.   TCCR1B = TCCR1B & 0b11111000 | mode;
  318.  
  319.  //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  320.  
  321.   // Initializing Other Calculations
  322.   encoder_Resolution_Size = (encoder_Tick_Resolution * 1000000. / encoder_PPR);
  323.   voltage_Max = 255 - voltage_Offset;
  324.  
  325.   //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  326.  
  327.   // IMU Setup
  328.   Wire.begin();       // Join I2C bus
  329.   TWBR = twbr_Value;  // 12 = 400kHz I2C clock (200kHz if CPU is 8MHz)
  330.   mpu.initialize();   // Initialize IMU
  331.  
  332.   Serial.println(mpu.testConnection() ? F("MPU6050 connection successful") : F("MPU6050 connection failed")); // verify connection
  333. //  Serial.println(F("\nSend any character to begin: "));                           // wait for ready
  334. //  while (Serial.available() && Serial.read());                                    // empty buffer
  335. //  while (!Serial.available());                                                    // wait for data
  336. //  while (Serial.available() && Serial.read());                                    // empty buffer again
  337.   devStatus = mpu.dmpInitialize();                                                // load and configure the DMP
  338.  
  339.   // supply your own gyro offsets here, scaled for min sensitivity
  340.   mpu.setXGyroOffset(220);
  341.   mpu.setYGyroOffset(76);
  342.   mpu.setZGyroOffset(-85);
  343.   mpu.setZAccelOffset(1788);                  // 1688 factory default for my test chip
  344.  
  345.   if (devStatus == 0) {                       // make sure it worked (devStatus returns 0 if so)
  346.     mpu.setDMPEnabled(true);                  // turn on the DMP, now that it's ready
  347.     mpuIntStatus = mpu.getIntStatus();        // enable Arduino interrupt detection (Remove attachInterrupt function here)
  348.     dmpReady = true;                          // set our DMP Ready flag so the main loop() function knows it's okay to use it
  349.     packetSize = mpu.dmpGetFIFOPacketSize();  // get expected DMP packet size for later comparison
  350.   } else {
  351.     // ERROR!
  352.     // 1 = initial memory load failed
  353.     // 2 = DMP configuration updates failed
  354.     // (if it's going to break, usually the code will be 1)
  355.     Serial.print(F("DMP Initialization failed (code "));
  356.     Serial.print(devStatus);
  357.     Serial.println(F(")"));
  358.   }
  359.  
  360.  
  361.   //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  362.  
  363.   Serial.println(F("Setup Complete"));
  364. Serial.println(F("\n\n"));
  365.   while (Serial.available() && Serial.read());                                    // empty buffer
  366.   while (!Serial.available());                                                    // wait for data
  367.   while (Serial.available() && Serial.read());                                    // empty buffer again
  368. //  delay(1000);
  369. mpu.resetFIFO();  
  370.  
  371. }
  372.  
  373.  
  374. void setup() {
  375.  
  376.   //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  377.  
  378.   // Serial
  379.   Serial.begin(serial_Frequency);
  380.   //package.reserve(500);
  381.  
  382.   //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  383.  
  384.   // Pin Modes
  385.   pinMode(pin_IMU_Interrupt, INPUT);
  386.   pinMode(pin_left_PMW, OUTPUT);
  387.   pinMode(pin_right_PMW, OUTPUT);
  388.   pinMode(pin_IN1, OUTPUT);
  389.   pinMode(pin_IN2, OUTPUT);
  390.   pinMode(pin_IN3, OUTPUT);
  391.   pinMode(pin_IN4, OUTPUT);
  392.  
  393.   //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  394.  
  395.   // Pull Ups
  396.   digitalWrite(pin_IMU_Interrupt, HIGH);
  397.  
  398.   //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  399.  
  400.   // Interrupts
  401.   PCintPort::attachInterrupt(pin_IMU_Interrupt, dmpDataReady, RISING);
  402.   attachInterrupt(interruptPin_left_Encoder, ISR_left_Encoder, RISING);
  403.   attachInterrupt(interruptPin_right_Encoder, ISR_right_Encoder, RISING);
  404.  
  405.   //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  406.  
  407.   // Setting PMW Wavelength
  408.   byte mode;
  409.   switch (pmw_Length) {
  410.     case 1: mode = 0x01; break;
  411.     case 8: mode = 0x02; break;
  412.     case 64: mode = 0x03; break;
  413.     case 256: mode = 0x04; break;
  414.     case 1024: mode = 0x05; break;
  415.     default:  ;                        // Code that is executed when pmw_Length does not match a case
  416.   }
  417.   TCCR1B = TCCR1B & 0b11111000 | mode;
  418.  
  419.  //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  420.  
  421.   // Initializing Other Calculations
  422.   encoder_Resolution_Size = (encoder_Tick_Resolution * 1000000. / encoder_PPR);
  423.   voltage_Max = 255 - voltage_Offset;
  424.  
  425.   //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  426.  
  427.   // IMU Setup
  428.   Wire.begin();       // Join I2C bus
  429.   TWBR = twbr_Value;  // 12 = 400kHz I2C clock (200kHz if CPU is 8MHz)
  430.   mpu.initialize();   // Initialize IMU
  431.  
  432.   Serial.println(mpu.testConnection() ? F("MPU6050 connection successful") : F("MPU6050 connection failed")); // verify connection
  433. //  Serial.println(F("\nSend any character to begin: "));                           // wait for ready
  434. //  while (Serial.available() && Serial.read());                                    // empty buffer
  435. //  while (!Serial.available());                                                    // wait for data
  436. //  while (Serial.available() && Serial.read());                                    // empty buffer again
  437.   devStatus = mpu.dmpInitialize();                                                // load and configure the DMP
  438.  
  439.   // supply your own gyro offsets here, scaled for min sensitivity
  440.   mpu.setXGyroOffset(220);
  441.   mpu.setYGyroOffset(76);
  442.   mpu.setZGyroOffset(-85);
  443.   mpu.setZAccelOffset(1788);                  // 1688 factory default for my test chip
  444.  
  445.   if (devStatus == 0) {                       // make sure it worked (devStatus returns 0 if so)
  446.     mpu.setDMPEnabled(true);                  // turn on the DMP, now that it's ready
  447.     mpuIntStatus = mpu.getIntStatus();        // enable Arduino interrupt detection (Remove attachInterrupt function here)
  448.     dmpReady = true;                          // set our DMP Ready flag so the main loop() function knows it's okay to use it
  449.     packetSize = mpu.dmpGetFIFOPacketSize();  // get expected DMP packet size for later comparison
  450.   } else {
  451.     // ERROR!
  452.     // 1 = initial memory load failed
  453.     // 2 = DMP configuration updates failed
  454.     // (if it's going to break, usually the code will be 1)
  455.     Serial.print(F("DMP Initialization failed (code "));
  456.     Serial.print(devStatus);
  457.     Serial.println(F(")"));
  458.   }
  459.  
  460.  
  461.   //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  462.  
  463.   Serial.println(F("Setup Complete"));
  464. Serial.println(F("\n\n"));
  465.   while (Serial.available() && Serial.read());                                    // empty buffer
  466.   while (!Serial.available());                                                    // wait for data
  467.   while (Serial.available() && Serial.read());                                    // empty buffer again
  468. //  delay(1000);
  469. mpu.resetFIFO();  
  470.  
  471. }
  472.  
  473.  
  474. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  475. ////////////////////////////////////////////////////// IMU ////////////////////////////////////////////////////////////////////////////
  476. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  477.  
  478.  
  479.  
  480. void get_IMU_Values() {
  481.  
  482. ///////////////////////////////////////////////////// IMU Comms ////////////////////////////////////////////////////////////////////////
  483.   if (!dmpReady) {
  484.     Serial.println("Shit failed yo");
  485.     return;                                               // if programming failed, don't try to do anything
  486.   }
  487.  
  488.   time_IMU_Prev = micros();
  489.  
  490.   while (!mpuInterrupt) { // && fifoCount < packetSize) {       // wait for MPU interrupt or extra packet(s) available
  491.     // other program behavior stuff here
  492.     // if you are really paranoid you can frequently test in between other
  493.     // stuff to see if mpuInterrupt is true, and if so, "break;" from the
  494.     // while() loop to immediately process the MPU data
  495.     //Serial.println("Waiting in IMU function");
  496.  
  497.   }
  498.  
  499.   time_IMU_Dif = micros() - time_IMU_Prev;
  500.  
  501.  
  502.   mpuInterrupt = false;                                             // reset interrupt flag
  503.   mpuIntStatus = mpu.getIntStatus();                                // get INT_STATUS byte
  504.   fifoCount = mpu.getFIFOCount();                                   // get current FIFO count
  505.  
  506.   if ((mpuIntStatus & 0x10) || fifoCount >= 1024) {                 // check for overflow (this should never happen unless our code is too inefficient)
  507.     mpu.resetFIFO();                                                // reset so we can continue cleanly
  508.     Serial.println(F("FIFO overflow!"));
  509.   }
  510.  
  511.  
  512.   else if (mpuIntStatus & 0x02) {                                   // otherwise, check for DMP data ready interrupt (this should happen frequently)
  513.     while (fifoCount < packetSize) {
  514.       delay(1);  // wait for correct available data length, should be a VERY short wait
  515.       fifoCount = mpu.getFIFOCount();
  516.       mpuIntStatus = mpu.getIntStatus();
  517.     }
  518.     mpu.getFIFOBytes(fifoBuffer, packetSize);                       // read a packet from FIFO
  519.     fifoCount -= packetSize;                                        // track FIFO count here in case there is > 1 packet available (this lets us immediately read more without waiting for an interrupt)
  520.     mpu.dmpGetQuaternion(&q, fifoBuffer);                           // display YPR angles in degrees
  521.     mpu.dmpGetGravity(&gravity, &q);
  522.     mpu.dmpGetYawPitchRoll(ypr, &q, &gravity);
  523.   }
  524.  
  525.   mpu.resetFIFO();      // ADDED BY ME!!!!!!!!!!!
  526.  
  527.  
  528.  
  529.  
  530.  
  531.   if (p == 1 && p_Prev == 0) {        // Resets integral when balancing mode is started to avoid wide up while holding
  532.     theta_Integral = 0;
  533.     omega_Integral = 0;
  534.     theta_Error = 0;
  535.     omega_Error = 0;
  536.     theta_Smoothed = theta_Now;
  537.     omega_Smoothed = omega_Now;
  538.     theta_Smoothed_Speed = 0;
  539.     omega_Smoothed_Speed - 0;
  540.   }
  541.  
  542.   p_Prev = p;
  543.   imu_Time_Prev = imu_Time_Now;
  544.   imu_Time_Now = micros();
  545.  
  546.  
  547.  
  548.   ////////////////////////////////////////////////////////// Theta Calcs//////////////////////////////////////////////////////////////////////////////////////////
  549.  
  550.   theta_Prev = theta_Now;
  551.   theta_Now_Unfiltered = round((ypr[2] * 180 / M_PI) * angle_Rounding_Value) / angle_Rounding_Value;    //undo
  552.   theta_Now = (1 - theta_Filter) * (theta_Now_Unfiltered) + (theta_Filter * theta_Prev); //undo
  553.  
  554.  
  555.   theta_Error = theta_Now - theta_Zero;
  556.  
  557.   theta_Integral += theta_Error * (imu_Time_Now - imu_Time_Prev) / 1000000.0;
  558.   if (theta_Integral > theta_Integral_Max) {
  559.     theta_Integral = theta_Integral_Max;
  560.   } else if (theta_Integral < -theta_Integral_Max) {
  561.     theta_Integral = - theta_Integral_Max;
  562.   }
  563.  
  564.  
  565.   theta_Speed_Prev = theta_Speed_Now;
  566.   theta_Speed_Now = ((1 - theta_Speed_Filter) * (theta_Now - theta_Prev) / (imu_Time_Now - imu_Time_Prev) * 1000000.) + theta_Speed_Filter * theta_Speed_Prev; // Relative to absolute zero
  567.   theta_Average_Prev = theta_Average;
  568.   theta_Average = (1 - angle_Average_Filter) * (theta_Now) + (angle_Average_Filter * theta_Average_Prev);
  569.  
  570.   theta_Smoothed_Prev = theta_Smoothed;
  571.   theta_Smoothed = (1 - angle_Smoothed_Filter) * theta_Now + angle_Smoothed_Filter * theta_Smoothed_Prev;
  572.   theta_Smoothed_Speed = (theta_Smoothed - theta_Smoothed_Prev) / (imu_Time_Now - imu_Time_Prev) * 1000000.;
  573.  
  574.   theta_Zero_Prev = theta_Zero;
  575.   if ( p == 1) {                                                                                                        // Automatic setpoint adjustment
  576.     theta_Zero_Unfiltered = theta_Zero - theta_Kt * theta_Error - theta_Ktd * theta_Smoothed_Speed;
  577.     theta_Zero = (1 - theta_Zero_Filter) * theta_Zero_Unfiltered + theta_Zero_Filter * theta_Zero_Prev;
  578.   } else {
  579.     theta_Zero = theta_Average;
  580.   }
  581.  
  582.  
  583.  
  584.  
  585.   //////////////////////////////////////////////////////////////// Omega Calcs//////////////////////////////////////////////////////////////////////////////////////
  586.   omega_Prev = omega_Now;
  587.   omega_Now_Unfiltered = round((-ypr[1] * 180 / M_PI) * angle_Rounding_Value) / angle_Rounding_Value;    //undo
  588.   omega_Now = (1 - omega_Filter) * (omega_Now_Unfiltered) + omega_Filter * (omega_Prev); //undo
  589.   omega_Error = omega_Now - omega_Zero;
  590.  
  591.  
  592.   omega_Error = omega_Now - omega_Zero;
  593.  
  594.   omega_Integral += omega_Error * (imu_Time_Now - imu_Time_Prev) / 1000000.0;
  595.   if (omega_Integral > omega_Integral_Max) {
  596.     omega_Integral = omega_Integral_Max;
  597.   } else if (omega_Integral < -omega_Integral_Max) {
  598.     omega_Integral = - omega_Integral_Max;
  599.   }
  600.  
  601.  
  602.   omega_Speed_Prev = omega_Speed_Now;
  603.   omega_Speed_Now = ((1 - omega_Speed_Filter) * (omega_Now - omega_Prev) / (imu_Time_Now - imu_Time_Prev) * 1000000.) + omega_Speed_Filter * omega_Speed_Prev; // Relative to absolute zero
  604.   omega_Average_Prev = omega_Average;
  605.   omega_Average = (1 - angle_Average_Filter) * (omega_Now) + (angle_Average_Filter * omega_Average_Prev);
  606.  
  607.   omega_Smoothed_Prev = omega_Smoothed;
  608.   omega_Smoothed = (1 - angle_Smoothed_Filter) * omega_Now + angle_Smoothed_Filter * omega_Smoothed_Prev;
  609.   omega_Smoothed_Speed = (omega_Smoothed - omega_Smoothed_Prev) / (imu_Time_Now - imu_Time_Prev) * 1000000.;
  610.  
  611.   omega_Zero_Prev = omega_Zero;
  612.   if ( p == 1) {                                                                                                     // Automatic setpoint adjustment
  613.     omega_Zero_Unfiltered = omega_Zero - omega_Kt * omega_Error - omega_Ktd * omega_Smoothed_Speed;
  614.     omega_Zero = (1 - omega_Zero_Filter) * omega_Zero_Unfiltered + omega_Zero_Filter * omega_Zero_Prev;
  615.   } else {
  616.     omega_Zero = omega_Average;
  617.   }
  618.  
  619. }
  620.  
  621.  
  622.  
  623.  
  624. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  625. //////////////////////////////////////////////////  SPEED  ////////////////////////////////////////////////////////////////////////
  626. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  627.  
  628.  
  629.  
  630. void get_left_Encoder_Speeds() {
  631.   left_Speed_RPM_Prev = left_Speed_RPM;
  632.   //left_Speed_RPM_Alt_Prev = left_Speed_RPM_Alt;
  633.  
  634.   left_Time_Saved = left_Time_Now;
  635.   left_Time_Age = micros();
  636.  
  637.   left_Encoder_Direction_Debug = left_Encoder_Direction;
  638.  
  639.   left_Time_Acc_Prev = left_Time_Acc_Now;
  640.   left_Time_Acc_Now = micros();
  641.  
  642.   if ( (left_Time_Age - left_Time_Saved) > (encoder_Speed_Time_Limit * 1000L)) {                                                 // If last time measurment was taken too long ago, it means wheel has stopped
  643.     left_Speed_RPM = 0;
  644.     left_Speed_RPM_Unfiltered = 0;
  645.    } else {
  646.     left_Speed_RPM_Unfiltered = encoder_Resolution_Size / left_Time_Dif * 60 * left_Encoder_Direction_Debug;    // Speed measurement
  647.       }
  648.  
  649.   left_Abs_Tick_Count_Prev = left_Abs_Tick_Count;
  650.   left_Speed_RPM = ((1 - left_Speed_Filter) * left_Speed_RPM_Unfiltered) + (left_Speed_Filter * left_Speed_RPM_Prev);
  651.   left_Acceleration = (left_Speed_RPM - left_Speed_RPM_Prev) / (left_Time_Acc_Now - left_Time_Acc_Prev) * 1000000;
  652. }
  653.  
  654.  
  655. void get_right_Encoder_Speeds() {
  656.   right_Speed_RPM_Prev = right_Speed_RPM;
  657.   right_Time_Acc_Prev = right_Time_Acc_Now;
  658.   right_Time_Acc_Now = micros();
  659.  
  660.   right_Time_Saved = right_Time_Now;
  661.   right_Time_Age = micros();
  662.  
  663.  
  664.   if ( (right_Time_Age - right_Time_Saved) > (encoder_Speed_Time_Limit * 1000L)) {                                                 // If last time measurment was taken too long ago, it means wheel has stopped
  665.     right_Speed_RPM = 0;
  666.       } else {
  667.     right_Speed_RPM = encoder_Resolution_Size / right_Time_Dif * 60 * right_Encoder_Direction;    // Speed measurement
  668.    
  669.   }
  670.  
  671.   right_Speed_RPM = ((1 - right_Speed_Filter) * right_Speed_RPM) + (right_Speed_Filter * right_Speed_RPM_Prev);
  672.   right_Acceleration = (right_Speed_RPM - right_Speed_RPM_Prev) / (right_Time_Acc_Now - right_Time_Acc_Prev) * 1000000;
  673. }
  674.  
  675.  
  676.  
  677.  
  678. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  679. ///////////////////////////////////////////////////////SET VOLTAGE /////////////////////////////////////////////////////////////////
  680. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  681.  
  682. void set_left_Motor_Voltage() {         // Switched directions (0's and 1's) from originial
  683.   if (left_Voltage == 0) {
  684.     analogWrite(pin_left_PMW, 0);
  685.   }
  686.   else {
  687.     if (left_Voltage < 0) {
  688.       digitalWrite(pin_IN1, 1);
  689.       digitalWrite(pin_IN2, 0);
  690.     } else {
  691.       digitalWrite(pin_IN1, 0);
  692.       digitalWrite(pin_IN2, 1);
  693.     }
  694.     analogWrite(pin_left_PMW, abs(left_Voltage) + voltage_Offset);
  695.   }
  696. }
  697.  
  698.  
  699. void set_right_Motor_Voltage() {         // Switched directions (0's and 1's) from originial
  700.   if (right_Voltage == 0) {
  701.     analogWrite(pin_right_PMW, 0);
  702.   }
  703.   else {
  704.     if (right_Voltage < 0) {
  705.       digitalWrite(pin_IN3, 1);
  706.       digitalWrite(pin_IN4, 0);
  707.     } else {
  708.       digitalWrite(pin_IN3, 0);
  709.       digitalWrite(pin_IN4, 1);
  710.     }
  711.     analogWrite(pin_right_PMW, abs(right_Voltage) + voltage_Offset);
  712.   }
  713. }
  714.  
  715.  
  716.  
  717. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  718. ///////////////////////////////////////////////////////// UPDATE VALUE USING SERIAL CONSOLE //////////////////////////////////////////
  719. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  720.  
  721. float update_Value(float x) {
  722.   analogWrite(pin_left_PMW, 0);
  723.   analogWrite(pin_right_PMW, 0);
  724.   Serial.print(F("\n\n"));
  725.   Serial.print(F("Current Value:\t"));
  726.   Serial.println(x, 4);
  727.   Serial.println(F("Input New Value:"));
  728.   x = get_Serial();
  729.   Serial.print(F("Value changed to:\t"));
  730.   Serial.println(x, 4);
  731.   delay(100);
  732.   mpu.resetFIFO();
  733.   delay(5);
  734.   stat = 0;
  735.   return x;
  736. }
  737.  
  738. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  739. /////////////////////////////////////////////////////////GET SERIAL INPUT FROM CONSOLE//////////////////////////////////////////////////////////////////
  740. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  741.  
  742.  
  743. float get_Serial() {
  744.  
  745.   String inString = "";
  746.   //  Serial.println("Input New Value:");
  747.   while (Serial.available() && Serial.read()); // empty buffer
  748.   while (!Serial.available());                 // wait for data
  749.  
  750.  
  751.   delay(1);
  752.  
  753.   while (Serial.available() > 0 ) {
  754.     inString += (char)Serial.read();
  755.   }
  756.  
  757.   return inString.toFloat();
  758. }
  759.  
  760. // Interrupts Service Routines for Encoders
  761. // Only trigger when signal A rises.  
  762.  
  763. void ISR_left_Encoder() {
  764.  
  765.   left_Rel_Tick_Count++;
  766.   if (left_Rel_Tick_Count >= encoder_Tick_Resolution) {
  767.  
  768.     left_Encoder_Direction_Now = digitalReadFast (pin_left_EncoderB) ? -1 : +1;
  769.  
  770.     if (left_Encoder_Direction_Now == left_Encoder_Direction_Prev) {                     // Needs to register to ticks in the same directions. Sometimes the encoder will incorretly read wrong direction for one tick.    
  771.       left_Encoder_Direction = left_Encoder_Direction_Now;
  772.     }
  773.  
  774.     left_Encoder_Direction_Prev = left_Encoder_Direction_Now;
  775.     left_Abs_Tick_Count += left_Encoder_Direction;
  776.  
  777.     left_Time_Prev = left_Time_Now;
  778.     left_Time_Now = micros();
  779.     left_Time_Dif = left_Time_Now - left_Time_Prev;
  780.    
  781.     left_Rel_Tick_Count = 0;
  782.   }
  783. }
  784.  
  785.  
  786. void ISR_right_Encoder() {
  787.  
  788.   right_Rel_Tick_Count++;
  789.   if (right_Rel_Tick_Count >= encoder_Tick_Resolution) {
  790.  
  791.     right_Encoder_Direction_Now = digitalReadFast (pin_right_EncoderB) ? -1 : +1;
  792.  
  793.     if (right_Encoder_Direction_Now == right_Encoder_Direction_Prev) {                // Needs to register to ticks in the same directions. Sometimes the encoder will incorretly read wrong direction for one tick.  
  794.       right_Encoder_Direction = right_Encoder_Direction_Now;
  795.     }
  796.  
  797.     right_Encoder_Direction_Prev = right_Encoder_Direction_Now;
  798.     right_Abs_Tick_Count += right_Encoder_Direction;
  799.  
  800.     right_Time_Prev = right_Time_Now;
  801.     right_Time_Now = micros();
  802.     right_Time_Dif = right_Time_Now - right_Time_Prev;
  803.    
  804.     right_Rel_Tick_Count = 0;
  805.   }
  806. }
  807.  
  808.  
  809.  
  810. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  811. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  812.  
  813.  
  814. void dmpDataReady() {
  815.   //l++;
  816.   if (PCintPort::arduinoPin == pin_IMU_Interrupt) {
  817.     mpuInterrupt = true;
  818.  
  819.   }
  820. }
  821.  
  822. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  823. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  824.  
  825.  
  826.  
  827.  
  828.  
  829. void get_left_PID_Voltage_Value() {
  830.  
  831.   left_P_Accel = theta_Kp * (theta_Now - theta_Zero);
  832.   left_I_Accel = theta_Ki * theta_Integral;
  833.   left_D_Accel = theta_Kd * theta_Speed_Now;
  834.   left_S_Accel = theta_Ks * left_Speed_RPM / 1000.;
  835.   left_PID_Accel = left_P_Accel + left_I_Accel + left_D_Accel + left_S_Accel;
  836.  
  837.   float friction = 0;
  838.   if (left_Speed_RPM > 0.5) {
  839.     friction = friction_Value;
  840.   } else if (left_Speed_RPM < -0.5) {
  841.     friction = -friction_Value;
  842.   }
  843.  
  844.   float voltage = (left_PID_Accel + 0.303 * left_Speed_RPM + friction) / 9.4;     // Equation measured from Acceleration Motor Tests
  845.  
  846.   left_PID_Voltage = round(constrain(voltage, -voltage_Max, voltage_Max));
  847. }
  848.  
  849.  
  850.  
  851.  
  852. void get_right_PID_Voltage_Value() {
  853.  
  854.   right_P_Accel = omega_Kp * (omega_Now - omega_Zero);
  855.   right_I_Accel = omega_Ki * omega_Integral;
  856.   right_D_Accel = omega_Kd * omega_Speed_Now;
  857.   right_S_Accel = omega_Ks * right_Speed_RPM / 1000.;
  858.   right_PID_Accel = right_P_Accel + right_I_Accel + right_D_Accel + right_S_Accel;
  859.  
  860.   float friction = 0;
  861.   if (right_Speed_RPM > 0.5) {
  862.     friction = friction_Value;
  863.   } else if (right_Speed_RPM < -0.5) {
  864.     friction = -friction_Value;
  865.   }
  866.  
  867.   float voltage = (right_PID_Accel + 0.295 * right_Speed_RPM + friction) / 9.4;      // Equation measured from Acceleration Motor Tests
  868.  
  869.  
  870.   right_PID_Voltage = round(constrain(voltage, -voltage_Max, voltage_Max));
  871. }
Add Comment
Please, Sign In to add comment