Advertisement
Guest User

Untitled

a guest
Dec 17th, 2018
64
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #define LED_RED 13
  2. #define MOTOR_DIR_PIN 4
  3. #define MOTOR_SPEED_PIN 5
  4. #define ENCODER_A_PIN 2
  5. #define ENCODER_B_PIN 3
  6. #define COUNTER_PER_MM 10.
  7. #define dt 50
  8.  
  9.  
  10.  
  11. /* ------ Vars ------ */
  12. // Turns by default 3000mm
  13. float finalOrder = 3000; // mm
  14. float order = 0;
  15. float previousOrder = 0;
  16.  
  17. // PID parameters
  18. const float paramP = 2;
  19. const float paramI = 0.012;
  20. const float paramD = 0.01;
  21.  
  22. unsigned long time = 0;
  23. unsigned long orderTime = 0;
  24. float tpP = 0;
  25. long counter = 0;
  26.  
  27. float error = 0;
  28. float error2 = 0;
  29. float error3 = 0;
  30. float error4 = 0;
  31.  
  32. float integrate = 0;
  33. float derivate = 0;
  34.  
  35. // Time to get the order to the final order
  36. float period = 10000; // ms
  37.  
  38. char chanAState = 0;
  39. char chanBState = 0;
  40.  
  41. int dir = 0;
  42. int power;
  43. bool disable = false;
  44.  
  45. // Type of curve followed for a new order
  46. // 0 : step, 1 : ramp, 2 : smooth
  47. int type = 1;
  48.  
  49. void setup() {
  50.   pinMode(MOTOR_DIR_PIN, OUTPUT);
  51.   pinMode(MOTOR_SPEED_PIN, OUTPUT);
  52.  
  53.   // Enable serial
  54.   Serial.begin(9600);
  55.  
  56.   time = millis()+dt;
  57.  
  58.   // Interrupts for the encoder
  59.   attachInterrupt(digitalPinToInterrupt(ENCODER_A_PIN), channelAChange, CHANGE);
  60.   attachInterrupt(digitalPinToInterrupt(ENCODER_B_PIN), channelBChange, CHANGE);
  61.   orderTime = millis();
  62. }
  63.  
  64. void loop() {
  65.   // Check if the user wrote someting in serial
  66.   if(Serial.available() > 0) {
  67.     float tmp = Serial.parseFloat();
  68.     Serial.parseInt();
  69.     if(tmp == 0) { // 0 is to disable the motor
  70.       disable = true;
  71.       analogWrite(MOTOR_SPEED_PIN, 0);
  72.       return;
  73.     }
  74.     disable = false;
  75.     // Store the order in finalOrder and the loop will decide if it is a ramp or something else
  76.     previousOrder = order;
  77.     finalOrder = tmp;
  78.     orderTime = millis();
  79.   }
  80.   // Control the power to the motor every dt
  81.   if(time < millis()) {
  82.     controlPower();
  83.     time = millis()+dt;
  84.   }
  85. }
  86.  
  87. void controlPower() {
  88.   if(disable) {
  89.     analogWrite(MOTOR_SPEED_PIN, 0);
  90.     return;
  91.   }
  92.  
  93.   if(type == 0) { // Step
  94.     order = finalOrder;
  95.   } else if(type == 1) { // Ramp
  96.     if(order != finalOrder)
  97.       order = min(1., (millis()-orderTime)/period)*(finalOrder-previousOrder)+previousOrder;
  98.   } else { // Complex shape to limit acceleration
  99.     tpP = min(1., (float)(millis()-orderTime)/period);
  100.     order = previousOrder + (finalOrder - previousOrder) * (10*pow(tpP,3)-15*pow(tpP,4)+6*pow(tpP,5));
  101.   }
  102.  
  103.   // Errors are moved 1 up, simple to use array
  104.   error4 = error3;
  105.   error3 = error2;
  106.   error2 = error;
  107.  
  108.   error = (float)counter/COUNTER_PER_MM-(float)order;
  109.  
  110.   // Calculation of the integrate value capped at |10000| to limit oscillations
  111.   integrate = max(-10000, min(10000, integrate+error*(float)dt));
  112.  
  113.   // Calculate the derivative over the last 3 error values to limit noise
  114.   derivate = (error-error4)/(float)dt/3.;
  115.  
  116.   // Calculate the power with our PID
  117.   power = error*paramP + integrate*paramI + derivate*paramD;
  118.  
  119.   // Direction of rotation of the motor
  120.   if(power > 0) {
  121.     digitalWrite(MOTOR_DIR_PIN, HIGH);
  122.   } else {
  123.     digitalWrite(MOTOR_DIR_PIN, LOW);
  124.   }
  125.  
  126.   // Setting the power PWM
  127.   analogWrite(MOTOR_SPEED_PIN, min(255, abs(power)));
  128.  
  129.   // Display compatible with serial graph
  130.   Serial.print(min(255, abs(power)));
  131.   Serial.print(" ");
  132.   Serial.print(order);
  133.   Serial.print(" ");
  134.   Serial.print(tpP);
  135.   Serial.print(" ");
  136.   Serial.println((float)counter/COUNTER_PER_MM);
  137. }
  138.  
  139. void channelAChange() {
  140.   if(chanAState == chanBState) {
  141.     dir = 1;
  142.   } else {
  143.     dir = -1;
  144.   }
  145.   counter += dir;
  146.  
  147.   chanAState = digitalRead(ENCODER_A_PIN);
  148. }
  149.  
  150. void channelBChange() {
  151.   if(chanAState == chanBState) {
  152.     dir = -1;
  153.   } else {
  154.     dir = 1;
  155.   }
  156.   counter += dir;
  157.  
  158.   chanBState = digitalRead(ENCODER_B_PIN);
  159. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement