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.
- Động cơ có sensor.
- Cầu H.
- Arduino
- Máy tính
Bạn xem Video hướng dẫn trước
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é.
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é
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.