Thử nghiệm động cơ trên mô hình thực tế

Một phần của tài liệu Đồ án: Điều khiển tốc độ servo bằng encoder từ tính (Trang 28 - 38)

Sau khi chế tạo và lắp đặt hệ thống, tiến hành quá trình chạy thử. Code PID được nhúng vào board Arduino

So sánh mô phỏng hệ thống và chạy thật:

Tiến hành: với đầu vào và thông số Kp, Ki, Kd giống như phần mô phỏng trên

proteus. Ta thu được kết quả sau: - Độ vọt lố thấp khoảng 2%. - Thời gian đáp ứng nhanh. - Sai số 1 vòng/phút.

Hình 3.7 Chạy thử mô hình với thống số mô phỏng

Ghi chú:

- Blue line: tốc độ đặt.

- Green line : tốc độ khi không qua bộ low-pass filter.

Thay đổi tốc độ từ 30v/p lên 90v/p:

Hình 3.8 Chạy thử trên mô hình - thay đổi tốc độ

Kết quả: Trong trường hợp trên, khi thay đổi tốc độ thời gian đáp ứng nhanh và

không có vọt lố.

Vấn đề gặp phải: Khi thay đổi tốc độ trong các khoảng từ 0 đến 175v/p là khác

nhau.

- Từ 0 - 60v/p: Độ vọt lố cao khoảng 20%. - Từ 60v/p – 175v/p: Độ vọt lố khoảng 2-5%.

Nguyên nhân: Do sự tăng đột ngột tốc độ đặt mà động cơ có mang hộp số nên

CHƯƠNG 4. KẾT QUẢ

Kết quả

+ Xây dựng được mô hình thực tế của hệ thống với sai số cho phép <1%

+ Nghiên cứu và tìm hiểu được các thông tin về encoder từ tính và cách đo, điều khiển.

Phương hướng phát triển

Đề tài có nhiều phương hướng phát triển khác nhau. Có thể kết hợp với modun mạng Esp 8266 để đưa thông tin hiển thị và điều khiển trên các hệ thống mạng khác như máy tính, web,.... Có thể áp dụng để điều khiển nhiều động cơ hay vị trí góc quay.

Ngoài ra còn có thể sử dụng báo cáo trong các mục đích đo lường khác, cải thiện hiệu suất động cơ,...

TÀI LIỆU THAM KHẢO [1] AKM.com, AKM, [Trực tuyến]. Available:

https://www.akm.com/us/en/technology/technical-tutorial/basic- knowledge-encoder/magnetic-encoder/.

[2] Arduino. [Trực tuyến]. Available: http://arduino.vn/bai-viet/42-arduino- uno-r3-la-gi.

[3] N. T. P. -. H. T. H. Hà, Lý thuyết điều khiển tự động, Hồ Chí Minh: Đại học Quốc gia thành phố Hồ Chí Minh - Trường Đại học Bách khoa. [4] N. Q. T. B. T. L. Lê Ngọc Duy (Chủ biên), Giáo trình Cảm biến và hệ

Phụ lục

#include <Wire.h> // thư viện hỗ trợ truyền tải cho I2C #include <LiquidCrystal_I2C.h> // thư viện LDC I2C

#include <Keypad.h> // thư viện keypad #include <TimerOne.h> // thư viện timer 1

LiquidCrystal_I2C lcd(0x27, 16, 2); // khia báo địa chỉ bus I2C, kích thước LCD

// --- --

// các biến đk động cơ float T,xung;

float v = 0; // tốc độ động cơ đang quay float setv = 0; // tốc độ đặt cho động cơ float E,E1,E2;

float alpha = 0, beta = 0, vfilt = 0 , vpre = 0; float Kp,Kd,Ki;

float output,lastv;

const int phase_a=2; // Chân encoder dùng để ngắt const int phase_b=14; // Chân encoder dùng để đọc const int int1 = 3; // Chân nối L298 chạy động cơ const int int2 = 4; // Chân nối L298 chạy động cơ const int PWM = 5; // Chân xuất xung

//--- // các biến và ma trận đk keypad

const byte rows = 4; // số hàng keypad const byte columns = 4; // số cột keypad

char keys[rows][columns] = // sơ đồ kí tự keypad { {'1', '2', '3', 'A'}, {'4', '5', '6', 'B'}, {'7', '8', '9', 'C'}, {'.', '0', '#', 'D'}, };

byte columnPins[columns] = {10,11,12,13 }; // chân cắm cột keypad String num1; // chuỗi nhập

float tocdo_tg; // tốc độ trung gian

unsigned long lastmillis =0 ; // thời gian cập nhật tốc độ hiển thị cuối cùng

Keypad keypad = Keypad(makeKeymap(keys), rowPins, columnPins, rows, columns); // khoi tao keypad

// Khai báo các chương trình con được sử dụng void hien_thi_v(); void hienthi(); void demxung(); void PID(); //==================================================== void setup(){ // setup LCD Serial.begin(9600); lcd.begin(16, 2);

lcd.init(); // khởi tạo lcd

lcd.backlight(); // bật đèn nền lcd lcd.setCursor(2,0);

lcd.print("DO AN MON HOC"); lcd.setCursor(4,1); lcd.print("NHOM 12"); delay(500); lcd.clear(); hienthi(); hien_thi_v(); //--- //setup động cơ pinMode(int1,OUTPUT); pinMode(int2,OUTPUT);

pinMode(phase_a,INPUT_PULLUP); // doc encoder pinMode(phase_b,INPUT_PULLUP); // ngat

pinMode(PWM,OUTPUT); // chan enable A;

E = 0; E1 = 0; E2 = 0; output=0;

T=0.01;

Kp =10; Kd = 0; Ki =0.02; Serial.begin(9600);

attachInterrupt (0,demxung,FALLING);

Timer1.initialize(10000); //khoi dong ngat t=10000uS=0.001s Timer1.attachInterrupt(PID); // Goi ham PID khi xay ra ngat }

//==================================================== void loop(){

char key = keypad.getKey(); // lấy kí tự khi nhấn các phím trên keypad

// nhấn phím bất kì từ 1-> 9 để nhập tốc độ cho động cơ if (key == '1'||key == '2'||key == '3'||

key == '4'||key == '5'||key == '6'|| key == '7'||key == '8'||key == '9'|| key == '0'||key == '.')

{

num1 = num1 + key;

tocdo_tg = num1.toFloat(); // chiểu kí tự nhập vào từ kiểu String ==> Float

Serial.println(tocdo_tg);

int numLength = num1.length(); // đếm độ dài kí tự chuỗi lcd.setCursor(15 - numLength, 0); // dịch vị chí xuất hiện của kí tự sau mỗi lần nhập

lcd.print(num1); // hiển thị kí tự lên LCD }

// nhấn D reset tốc độ đặt vào if (key == 'D')

{

num1=' '; // reset chuỗi nhập lcd.clear(); // xóa màn hình }

// nhấn # để nạp tốc độ mới cho động cơ if ( key == '#' )

{

if ((tocdo_tg > 175 || tocdo_tg < 0) ) // nếu tốc độ nhập lớn hơn 175 hoặc nhỏ hơn 0 vòng/ phút hiển thị LCD thông báo nhập lại

tocdo_tg=0; // reset lại tốc độ trung gian để thoát vòng lặp if

lcd.clear();

lcd.setCursor(0, 0);

lcd.println(" Nhap toc do trong khoang 40-170 vong/phut "); for(int i = 0 ; i < 24 ; i++ ) // chạy 25 kí tự sang trái

{ lcd.scrollDisplayLeft(); delay(150); } num1=' '; }

else // nếu nhập đúng thì thay đổi tốc độ đặt mới {

setv = tocdo_tg; // gán tốc độ đặt mới cho động cơ

} } // Nhấn A để dừng động cơ if(key == 'A') { setv=0; lcd.clear(); lcd.setCursor(0, 0); lcd.print("Cho dong co dung !!!"); num1= ' '; lcd.clear();

}

// nếu nhập quá 6 kí tự sẽ thông báo nhập lại if (num1.length() > 6 )

{

lcd.clear(); lcd.setCursor(0, 0); lcd.println(" Nhap toc do trong khoang 0-175 vong/phut "); for(int i = 0 ; i < 24 ; i++ ){ lcd.scrollDisplayLeft(); // chạy chữ sang trái delay(150); }

num1=' '; } Serial.print(setv); Serial.print(" "); Serial.print(v); Serial.println(); hienthi();

hien_thi_v(); // hiển thị tốc độ động cơ đang quay }

//=================================================== // Hiển thị tốc độ dộng cơ đo được

void hien_thi_v(){

if (millis() - lastmillis >= 500){ // cập nhật tốc độ động cơ mỗi 0.5s

lcd.setCursor(11, 1);

lcd.print(vfilt ,DEC ); // hiển thị tốc độ kiểu flaot định dạng thập phân (DEC)

lastmillis = millis(); // đặt lại thời điểm cập nhật cuối cùng } } //--- // Hiển thị LCD void hienthi() {

lcd.setCursor(0, 0); // tạo vị trí xuất hiện trên LCD --- hàng 0, cột 0

lcd.print("Toc do dat:");

//lcd.cursor(); // tạo hiệu ứng nháy gạch vị trí nhập mới lcd.setCursor(0, 1); lcd.print("Dang quay:"); } //--- // đếm xung động cơ void demxung() { if(digitalRead(phase_b) == LOW) xung++; else xung--;

}

//--- // điều khiển PID

void PID() {

v = (xung/374)*(1/T)*60;// toc do rpm xung=0;

vfilt = 0.854 * vfilt + 0.0728*v + 0.0728*vpre; vpre = v;

E = setv-vfilt;// tinh sai so alpha += Ki*E*10;

beta = (vfilt - lastv)/10;

output = Kp * E + alpha + Kd * beta; if(output>255) output = 255;

else if ( output<-255) output = 0; lastv = vfilt; if(output>0) { analogWrite(PWM,output); digitalWrite(int1,HIGH); digitalWrite(int2,LOW); } else { analogWrite(PWM,0); digitalWrite(int1,LOW); digitalWrite(int2,LOW); } }

Một phần của tài liệu Đồ án: Điều khiển tốc độ servo bằng encoder từ tính (Trang 28 - 38)

Tải bản đầy đủ (PDF)

(38 trang)