0 đánh giá

Điều khiển tốc độ động cơ dùng PID với Arduino

Các bạn nào đã học lý thuyết về PID rồi thì có thể hiểu đc bài viết này, bài này hướng dẫn bạn cách để điều khiển tốc độ động cơ dùng PID. Tốc độ động cơ được vẽ lên màn hình để ta theo dõi.

Bước 1: Chuẩn bị linh kiện

- Động cơ có sensor.

- Cầu H.

- Arduino

- Máy tính

Bước 2: Video hướng dẫn

Bạn xem Video hướng dẫn trước

Bước 3: Chương trình nạp cho Arduino
void loop() {
  if (stringComplete) {
    // clear the string when COM receiving is completed
    mySt = ; //note: in code below, mySt will not become blank, mySt is blank until 
 is received
    stringComplete = false;
  }
  //receive command from Visual Studio
  if (mySt.substring(0, 8) == vs_start) {
    digitalWrite(pin_fwd, 1); //run motor run forward
    digitalWrite(pin_bwd, 0);
    motor_start = true;
  }
  if (mySt.substring(0, 7) == vs_stop) {
    digitalWrite(pin_fwd, 0);
    digitalWrite(pin_bwd, 0); //stop motor
    motor_start = false;
  }
  if (mySt.substring(0, 12) == vs_set_speed) {
    set_speed = mySt.substring(12, mySt.length()).toFloat(); //get string after set_speed
  }
  if (mySt.substring(0, 5) == vs_kp) {
    kp = mySt.substring(5, mySt.length()).toFloat(); //get string after vs_kp
  }
  if (mySt.substring(0, 5) == vs_ki) {
    ki = mySt.substring(5, mySt.length()).toFloat(); //get string after vs_ki
  }
  if (mySt.substring(0, 5) == vs_kd) {
    kd = mySt.substring(5, mySt.length()).toFloat(); //get string after vs_kd
  }
}
void detect_a() {
  encoder += 1; //increasing encoder at new pulse
  m_direction = digitalRead(pin_b); //read direction of motor
}
ISR(TIMER1_OVF_vect) // interrupt service routine - tick every 0.1sec
{
  TCNT1 = timer1_counter; // set timer
  pv_speed = 60.0 * (encoder / 200.0) / 0.1; //calculate motor speed, unit is rpm
  encoder = 0;
  //print out speed
  if (Serial.available() <= 0) {
    Serial.print(speed);
    Serial.println(pv_speed); //Print speed (rpm) value to Visual Studio
  }
  //PID program
  if (motor_start) {
    e_speed = set_speed - pv_speed;
    pwm_pulse = e_speed * kp + e_speed_sum * ki + (e_speed - e_speed_pre) * kd;
    e_speed_pre = e_speed; //save last (previous) error
    e_speed_sum += e_speed; //sum of error
    if (e_speed_sum > 4000) e_speed_sum = 4000;
    if (e_speed_sum < -4000) e_speed_sum = -4000;
  }
  else {
    e_speed = 0;
    e_speed_pre = 0;
    e_speed_sum = 0;
    pwm_pulse = 0;
  }
  //update new speed
  if (pwm_pulse <255 & pwm_pulse >0) {
    analogWrite(pin_pwm, pwm_pulse); //set motor speed
  }
  else {
    if (pwm_pulse > 255) {
      analogWrite(pin_pwm, 255);
    }
    else {
      analogWrite(pin_pwm, 0);
    }
  }
  //}

bạn nối chân pin_fwd (động cơ tiến), pin_bwd (động cờ lui), pin_pwm(cảm biến tốc độ) vào arduino như thế nào thì đoạn đầu định nghĩa nó nhé.

Bước 4: Chương trình C++ để hiển thị lên máy tính

Chương trình chính:

#pragma endregion
 private: System::Void Form1_Load(System::Object^  sender, System::EventArgs^  e) {
     serialPort1->Open();
     timer1->Start();
     mStr = 0;
     i=300;
    }
 private: System::Void button1_Click(System::Object^  sender, System::EventArgs^  e) {
     serialPort1->WriteLine(vs_set_speed+textBox1->Text); //send set_speed to Arduino
     serialPort1->WriteLine(vs_kp+textBox2->Text); //send kP to Arduino
     serialPort1->WriteLine(vs_ki+textBox3->Text); //send kI to Arduino
     serialPort1->WriteLine(vs_kd+textBox4->Text); //send kD to Arduino
    }
 private: System::Void timer1_Tick(System::Object^  sender, System::EventArgs^  e) {
     String^ length;
     length=mStr->Length.ToString();
     if(mStr->Substring(0,5)==speed){
      speed=mStr->Substring(5,System::Convert::ToInt32(length)-6);
      label1->Text=speed;
      //print motor speed into Chart
      this->chart1->Series[Series1]->Points->AddXY(i,System::Convert::ToDouble(speed));
      i++;
      this->chart1->ChartAreas[ChartArea1]->AxisX->Minimum=i-300; //shift x-axis
     }
   }
 private: System::Void serialPort1_DataReceived(System::Object^  sender, System::IO::Ports::SerialDataReceivedEventArgs^  e) {
    mStr=serialPort1->ReadLine();
   }
private: System::Void button2_Click(System::Object^  sender, System::EventArgs^  e) {
    serialPort1->WriteLine(vs_start); //start motor
   }
private: System::Void button3_Click(System::Object^  sender, System::EventArgs^  e) {
    serialPort1->WriteLine(vs_stop);  //stop motor
   }

Chương trình trên máy tính được viết bằng C++, mã nguồn bạn tải về tại đây vì nó quá dài. Bạn dùng Visual Studio để mở nhé

Bước 5: Hoàn chỉnh và chạy thử

Nhập thông số kI, kP,kD vào ứng dụng trên máy tính. chọn tốc độ và chọn cổng COM của arduino và bắt đầu.

(!) Nếu có bất kỳ thắc mắc nào cần hỏi vui lòng đặt câu hỏi tại HỏiHay.Net, Cộng đồng Hỏi đáp Hỏi Hay sẽ trả lời bạn.
3,039 lượt xem ^tháng ^ngày
admin 2,030 điểm

Please log in or register to Comment this Media.