Saya mencoba mengendalikan fader bermotor (potensiometer geser linier) menggunakan Arduino.
Kontrol PID memberikan hasil yang baik untuk "melompat" ke posisi target tertentu, tetapi melacak jalur landai adalah masalah, itu tidak mulus sama sekali. Gerakannya sangat tersentak-sentak, apa pun yang saya coba.
Berikut plot posisi referensi, posisi yang diukur dan output motor saat melacak tanjakan:
Dan inilah video dari tes yang sama.
Pada sistem komersial, sepertinya lebih lancar, lihat ini .
Detail :
Motor fader adalah RSA0N11M9A0K Alps . Untuk mengendarainya, saya menggunakan jembatan ST L293D , ditenagai oleh catu daya 10 V DC yang diatur ( XL6009 ).
Pada Arduino UNO (ATmega328P), saya menggunakan pin 9 dan 10, dengan frekuensi PWM 31,372 kHz untuk membuatnya tidak terdengar (Timer1 dengan prescaler 1, TCCR1B = (TCCR1B & 0b11111000) | 0b001
).
Potensiometer dihubungkan antara ground dan 5V, dengan wiper menuju ADC0, seperti biasa.
Pengontrol :
Saya menggunakan pengontrol PID sederhana dengan anti-windup, yang diperbarui pada kecepatan 1 kHz (Ts = 1e-3 s):
float update(int16_t input) {
int16_t error = setpoint - input;
int16_t newIntegral = integral + error;
float output = k_p * error
+ k_i * newIntegral * Ts
+ k_d * (input - previousInput) / Ts;
if (output > maxOutput)
output = maxOutput;
else if (output < -maxOutput)
output = -maxOutput;
else
integral = newIntegral;
previousInput = input;
return output;
}
Output dari controller adalah nilai dari -127 hingga 127. Output PWM dihasilkan sebagai berikut:
const int8_t knee = 48;
uint8_t activation(int8_t val) {
if (val == 0)
return 0;
else {
return map(val, 0, 127, 2 * knee, 255);
}
}
void writeMotor(int8_t val) {
if (val >= 0) {
analogWrite(forward, activation(val));
digitalWrite(backward, 0);
} else {
analogWrite(backward, activation(-val));
digitalWrite(forward, 0);
}
}
Saya menambahkan 48 ke sinyal PWM 7-bit, karena di situlah motor mulai bergerak pada 31 kHz, dan kemudian saya skalakan ke angka 8-bit (karena itulah yang analogWrite
diharapkan fungsi):
Apa yang saya coba :
Saya sudah mencoba menambahkan filter EMA ke input, ke sinyal kontrol, ke komponen turunan dari kontroler PID, tetapi tidak berhasil. Saya juga mencoba menurunkan resolusi input analog, menggunakan histeresis untuk menghentikannya dari membalik di antara dua nilai ketika stasioner. Ini sepertinya tidak mempengaruhi apa pun. Meningkatkan langkah waktu ke 10 ms sepertinya juga tidak membantu.
Saya juga mencoba melakukan identifikasi sistem di MATLAB, dan mencoba menyetelnya di Simulink (mengikuti seri video ini ). Saya mendapat model dengan kecocokan 91%, tetapi saya tidak tahu bagaimana menangani input dan output non-linearitas dari model MATLAB, bagaimana mereka mempengaruhi penyetelan PID, dan bagaimana mengimplementasikannya pada Arduino.
Hal terakhir yang saya coba adalah membuat dua pengendali yang berbeda: satu untuk lompatan besar di posisi referensi, dan satu untuk kesalahan kecil saat melacak jalan. Ini sepertinya sedikit membantu, karena dengan begitu saya dapat meningkatkan koefisien integral saat melacak, tanpa meningkatkan overshoot saat melompat.
Namun, dengan meningkatkan gain integral (dan proporsional), motor sekarang selalu melakukan sesuatu, bahkan ketika itu harus diam dan referensi tidak berubah. (Ini tidak benar-benar bergerak, tetapi Anda bisa merasakannya bergetar.)
Saya hampir tidak memiliki keuntungan turunan, karena meningkatkannya lebih tinggi dari 1e-4 tampaknya membuatnya lebih brengsek, dan saya tidak benar-benar melihat perbedaan antara 0 dan 1e-4.
Dugaan saya adalah bahwa ia membutuhkan lebih banyak daya untuk mengatasi gesekan statis, maka gesekan dinamis kurang, sehingga melampaui batas, sehingga mendorong motor mundur, menyebabkannya berhenti lagi, maka ia harus mengatasi gesekan statis lagi, ia menembak ke depan lagi , dll.
Bagaimana pengontrol komersial mengatasi masalah ini?
Latar belakang saya :
Saya berada di tahun sarjana ketiga Teknik Elektro, saya telah mengikuti kursus tentang teori kontrol, pemrosesan sinyal digital, kontrol LQR dll. Jadi saya memiliki latar belakang teoretis, tetapi saya mengalami kesulitan menerapkan semua teori tersebut ke sistem dunia nyata ini.
Sunting :
Saya telah menguji pengukuran sensor loop terbuka, seperti yang direkomendasikan laptop2d, dan saya cukup terkejut dengan hasilnya: Pada frekuensi PWM tinggi, ada puncak buruk dalam pembacaan. Pada 490 Hz, tidak ada satu pun.
Dan ini adalah siklus kerja yang konstan, jadi saya tidak bisa membayangkan suara seperti apa yang saya dapatkan ketika motor berbalik arah dengan sangat cepat.
Jadi saya harus menemukan cara untuk menyaring kebisingan itu sebelum saya mulai bekerja pada controller lagi.
Sunting 2 :
Menggunakan filter rata-rata bergerak eksponensial tidak cukup untuk menyaring kebisingan.
Saya sudah mencoba dengan kutub di 0,25, 0,50 dan 0,75. Kutub kecil tidak memiliki banyak efek, dan kutub besar menambahkan terlalu banyak latensi, jadi saya harus menurunkan keuntungan agar tetap stabil, sehingga kinerja keseluruhan lebih buruk.
Saya telah menambahkan kapasitor 0,1 μF di seluruh potensiometer (antara penghapus dan tanah), dan yang sepertinya membersihkannya.
Untuk saat ini, ia bekerja dengan cukup baik. Sementara itu, saya membaca makalah yang diposting oleh Tim Wescott .
Terima kasih atas bantuannya.
This device is suitable for use in switching applications at frequencies up to 5 kHz.
Tetapi Karakteristik Listrik pada halaman 3 menyarankan maksimum absolut 690 kHz jika Anda menambahkan semua penundaan. (bawah 4 baris) Secara pribadi, saya akan jauh lebih lambat dari itu, tapi saya akan berpikir bahwa 31kHz harus memadai ... jika bukan karena catatan pada halaman 1.