Advertisement
Cai_B

PID Line Following Solution

Feb 13th, 2024 (edited)
95
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 3.61 KB | None | 0 0
  1. //  Code for a PID line Following solution for EEE Bot
  2. //  To calibrate the sensors replace values in constrain and map functions
  3.  
  4.  
  5.  
  6. #include <Wire.h>
  7. #define I2C_SLAVE_ADDR 0x04 // 4 in hexadecimal
  8.  
  9. //Function to send Data from Master to Slave
  10. //Parameters
  11. //        - Left motor Speed
  12. //        - Right motor Speed
  13. //        - Servo angle
  14. // Does not return a value
  15. void carmovement(int16_t leftmotor, int16_t rightmotor, int16_t servoangle)
  16. {
  17.   Wire.beginTransmission(I2C_SLAVE_ADDR);
  18.   Wire.write((byte)((leftmotor & 0x0000FF00) >> 8));    // first byte of x, containing bits 16 to 9
  19.   Wire.write((byte)(leftmotor & 0x000000FF));           // second byte of x, containing the 8 LSB - bits 8 to 1
  20.   Wire.write((byte)((rightmotor & 0x0000FF00) >> 8));    // first byte of y, containing bits 16 to 9
  21.   Wire.write((byte)(rightmotor & 0x000000FF));           // second byte of y, containing the 8 LSB - bits 8 to 1
  22.   Wire.write((byte)((servoangle & 0x0000FF00) >> 8));    // first byte of y, containing bits 16 to 9
  23.   Wire.write((byte)(servoangle & 0x000000FF));           // second byte of y, containing the 8 LSB - bits 8 to 1
  24.   Wire.endTransmission();   // stop transmitting
  25. }
  26.  
  27.  
  28. //Initalising Variables
  29.  
  30. int motorleft = 0;
  31. int motorright = 0;
  32. int servoangle = 90;
  33. int centreangle=80;
  34. int speedintial= 150;
  35. float k=0.6; // K needs to be less than 1 change appropiately
  36.  
  37. float setpoint=0;
  38. float error=0;
  39. float previouserror=0;
  40. float totalerror=0;
  41. float weightedaverage=0;
  42. float u=0;
  43.  
  44.  
  45. /* Change pin numbers dependent on EEE Bot
  46.  If want to use Node-RED to alter PID constants connect them to ADC1 pins on ESP32 the pins
  47.  These pins are shown on the flowchart as 25,33,34,39,36 and are used to alter Kp,Ki and Kd values in real time*/
  48. const int photodiode1=26;
  49. const int photodiode2=25;
  50. const int photodiode3=33;
  51. const int photodiode4=15;
  52. const int photodiode5=35;
  53.  
  54.  
  55. // Constants for PID calulation, can be changed dependent upon EEE Bot
  56. float kp=139;
  57. float ki=1.2;
  58. float kd=1.3;
  59.  
  60.  
  61.  
  62. void setup()
  63. {
  64.   Serial.begin(9600);
  65.   Wire.begin();  
  66.  
  67.  
  68. }
  69.  
  70.  
  71. void loop()
  72. {
  73.    /*Reads values from Photodiodes on the ESP32 and assigns them to a variable that is later used in weighted average       calulation*/
  74.   float IR1 = analogRead(photodiode1);
  75.   float IR2 = analogRead(photodiode2);
  76.   float IR3 = analogRead(photodiode3);
  77.   float IR4 = analogRead(photodiode4);
  78.   float IR5 = analogRead(photodiode5);
  79.  
  80.  
  81.  
  82.   // The following lines of code are used for sensor calibration and so are commented out as they will
  83.   //change dependent on surrounds. They can be uncommented if need be.  
  84.   /*
  85.   IR1= constrain(IR1,252,3378);
  86.   IR2= constrain(IR2,245,3636);
  87.   IR3= constrain(IR3,112,3701);
  88.   IR4= constrain(IR4,158,3378);
  89.   IR5= constrain(IR5,112,3749);
  90.  
  91.   IR1=map(IR1,252,3378,0,10);
  92.   IR2=map(IR2,245,3636,0,10);
  93.   IR3=map(IR3,112,3701,0,10);
  94.   IR4=map(IR4,158,3378,0,10);
  95.   IR5=map(IR5,112,3749,0,10);*/
  96.  
  97.  
  98.  
  99.   weightedaverage=((IR1*2)+(IR2*1)+(IR3*0)+(IR4*-1)+(IR5*-2))/(IR1+IR2+IR3+IR4+IR5);
  100.   previouserror=error;
  101.   error = setpoint - weightedaverage;  // finds error
  102.   totalerror =totalerror+ error; // en to times by ki
  103.  
  104.   u=(kp*error)+(ki*totalerror)+(kd*(error-previouserror));
  105.  
  106.  
  107.   /* If you flipped the weights assigned in weighted average and made IR1 =-2 and IR2=-1 and IR4 =1 and IR5=2
  108.    the formula would then need to be changed to 'servoangle=centreangle-u'*/
  109.   servoangle = centreangle+u;
  110.  
  111.   motorleft=speedintial+(k*u);
  112.   motorright=speedintial-(k*u);
  113.  
  114.   carmovement(motorleft,motorright,servoangle);// change motor speed if needed
  115.  
  116.  
  117. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement