Advertisement
MrLunk

Balancing robot Arduino + MPU 6050 - GY 521 + L293D deek-robot motor driver

Mar 21st, 2021 (edited)
108
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.90 KB | None | 0 0
  1. /*Arduino Self Balancing Robot
  2. * Code by: B.Aswinth Raj
  3. * Build on top of Lib: https://github.com/jrowberg/i2cdevlib/tree/master/Arduino/MPU6050
  4. * Website: circuitdigest.com
  5.  
  6. Code source credits to this man above !!!
  7. Here is the exact page: https://circuitdigest.com/microcontroller-projects/arduino-based-self-balancing-robot
  8. Sincerely Peter Lunk
  9. Video of my version running this code: https://www.youtube.com/watch?v=4iKDf0UMjdc <-----------------------------
  10.  
  11. */
  12.  
  13. #include "I2Cdev.h"
  14. #include <PID_v1.h> //From https://github.com/br3ttb/Arduino-PID-Library/blob/master/PID_v1.h
  15. #include "MPU6050_6Axis_MotionApps20.h" //https://github.com/jrowberg/i2cdevlib/tree/master/Arduino/MPU6050
  16.  
  17. MPU6050 mpu;
  18.  
  19. // MPU control/status vars
  20. bool dmpReady = true; // set true if DMP init was successful
  21. uint8_t mpuIntStatus; // holds actual interrupt status byte from MPU
  22. uint8_t devStatus; // return status after each device operation (0 = success, !0 = error)
  23. uint16_t packetSize; // expected DMP packet size (default is 42 bytes)
  24. uint16_t fifoCount; // count of all bytes currently in FIFO
  25. uint8_t fifoBuffer[64]; // FIFO storage buffer
  26.  
  27. // orientation/motion vars
  28. Quaternion q; // [w, x, y, z] quaternion container
  29. VectorFloat gravity; // [x, y, z] gravity vector
  30. float ypr[3]; // [yaw, pitch, roll] yaw/pitch/roll container and gravity vector
  31.  
  32. /*********Tune these 4 values for your BOT*********/
  33. double setpoint= 179; //set the value when the bot is perpendicular to ground using serial monitor. was 176
  34. //Read the project documentation on circuitdigest.com to learn how to set these values
  35. double Kp = 21; //Set this first was 21
  36. double Kd = 0.8; //Set this secound was 0.8
  37. double Ki = 140; //Finally set this was 140
  38. /******End of values setting*********/
  39.  
  40. double input, output;
  41. PID pid(&input, &output, &setpoint, Kp, Ki, Kd, DIRECT);
  42.  
  43. volatile bool mpuInterrupt = false; // indicates whether MPU interrupt pin has gone high
  44. void dmpDataReady()
  45. {
  46. mpuInterrupt = true;
  47. }
  48.  
  49. void setup() {
  50. Serial.begin(115200);
  51.  
  52. // initialize device
  53. Serial.println(F("Initializing I2C devices..."));
  54. mpu.initialize();
  55.  
  56. // verify connection
  57. Serial.println(F("Testing device connections..."));
  58. Serial.println(mpu.testConnection() ? F("MPU6050 connection successful") : F("MPU6050 connection failed"));
  59.  
  60. // load and configure the DMP
  61. devStatus = mpu.dmpInitialize();
  62.  
  63.  
  64. // supply your own gyro offsets here, scaled for min sensitivity
  65. mpu.setXGyroOffset(130);
  66. mpu.setYGyroOffset(8);
  67. mpu.setZGyroOffset(22);
  68. mpu.setZAccelOffset(930);
  69.  
  70. // make sure it worked (returns 0 if so)
  71. if (devStatus == 0)
  72. {
  73. // turn on the DMP, now that it's ready
  74. Serial.println(F("Enabling DMP..."));
  75. mpu.setDMPEnabled(true);
  76.  
  77. // enable Arduino interrupt detection
  78. Serial.println(F("Enabling interrupt detection (Arduino external interrupt 0)..."));
  79. attachInterrupt(0, dmpDataReady, RISING);
  80. mpuIntStatus = mpu.getIntStatus();
  81.  
  82. // set our DMP Ready flag so the main loop() function knows it's okay to use it
  83. Serial.println(F("DMP ready! Waiting for first interrupt..."));
  84. dmpReady = true;
  85.  
  86. // get expected DMP packet size for later comparison
  87. packetSize = mpu.dmpGetFIFOPacketSize();
  88.  
  89. //setup PID
  90. pid.SetMode(AUTOMATIC);
  91. pid.SetSampleTime(10); // was 10 LUNK adjust testing
  92. pid.SetOutputLimits(-210, 210); // was -255, 255 LUNK testing
  93. }
  94. else
  95. {
  96. // ERROR!
  97. // 1 = initial memory load failed
  98. // 2 = DMP configuration updates failed
  99. // (if it's going to break, usually the code will be 1)
  100. Serial.print(F("DMP Initialization failed (code "));
  101. Serial.print(devStatus);
  102. Serial.println(F(")"));
  103. }
  104.  
  105. //Initialise the Motor outpu pins
  106. pinMode (6, OUTPUT);
  107. pinMode (9, OUTPUT);
  108. pinMode (10, OUTPUT);
  109. pinMode (11, OUTPUT);
  110.  
  111. //By default turn off both the motors
  112. analogWrite(6,LOW);
  113. analogWrite(9,LOW);
  114. analogWrite(10,LOW);
  115. analogWrite(11,LOW);
  116. }
  117.  
  118. void loop() {
  119.  
  120. // if programming failed, don't try to do anything
  121. if (!dmpReady) return;
  122.  
  123. // wait for MPU interrupt or extra packet(s) available
  124. while (!mpuInterrupt && fifoCount < packetSize)
  125. {
  126. //no mpu data - performing PID calculations and output to motors
  127. pid.Compute();
  128.  
  129. //Print the value of Input and Output on serial monitor to check how it is working.
  130. Serial.print(input); Serial.print(" =>"); Serial.println(output);
  131.  
  132. if (input>150 && input<200){//If the Bot is falling
  133.  
  134. if (output>0) //Falling towards front
  135. Forward(); //Rotate the wheels forward
  136. else if (output<0) //Falling towards back
  137. Reverse(); //Rotate the wheels backward
  138. }
  139. else //If Bot not falling
  140. Stop(); //Hold the wheels still
  141.  
  142. }
  143.  
  144. // reset interrupt flag and get INT_STATUS byte
  145. mpuInterrupt = false;
  146. mpuIntStatus = mpu.getIntStatus();
  147.  
  148. // get current FIFO count
  149. fifoCount = mpu.getFIFOCount();
  150.  
  151. // check for overflow (this should never happen unless our code is too inefficient)
  152. if ((mpuIntStatus & 0x10) || fifoCount == 1024)
  153. {
  154. // reset so we can continue cleanly
  155. mpu.resetFIFO();
  156. Serial.println(F("FIFO overflow!"));
  157.  
  158. // otherwise, check for DMP data ready interrupt (this should happen frequently)
  159. }
  160. else if (mpuIntStatus & 0x02)
  161. {
  162. // wait for correct available data length, should be a VERY short wait
  163. while (fifoCount < packetSize) fifoCount = mpu.getFIFOCount();
  164.  
  165. // read a packet from FIFO
  166. mpu.getFIFOBytes(fifoBuffer, packetSize);
  167.  
  168. // track FIFO count here in case there is > 1 packet available
  169. // (this lets us immediately read more without waiting for an interrupt)
  170. fifoCount -= packetSize;
  171.  
  172. mpu.dmpGetQuaternion(&q, fifoBuffer); //get value for q
  173. mpu.dmpGetGravity(&gravity, &q); //get value for gravity
  174. mpu.dmpGetYawPitchRoll(ypr, &q, &gravity); //get value for ypr
  175.  
  176. input = ypr[1] * 180/M_PI + 180;
  177.  
  178. }
  179. }
  180.  
  181. void Forward() //Code to rotate the wheel forward
  182. {
  183. analogWrite(6,output);
  184. analogWrite(9,0);
  185. analogWrite(10,output);
  186. analogWrite(11,0);
  187. Serial.print("F"); //Debugging information
  188. }
  189.  
  190. void Reverse() //Code to rotate the wheel Backward
  191. {
  192. analogWrite(6,0);
  193. analogWrite(9,output*-1);
  194. analogWrite(10,0);
  195. analogWrite(11,output*-1);
  196. Serial.print("R");
  197. }
  198.  
  199. void Stop() //Code to stop both the wheels
  200. {
  201. analogWrite(6,0);
  202. analogWrite(9,0);
  203. analogWrite(10,0);
  204. analogWrite(11,0);
  205. Serial.print("S");
  206. }
  207.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement