Bài 1: ĐIỀU KHIỂN CÁC PHẦN TỬ KHÍ NÉNI Phân biệt các loại cảm biến: Cảm biến quang: khi đưa bất cứ vật nào che đầu cảm biến thì cảm biến sẽ lên mức 1.. II Các ví dụ chương trình mẫu:
Trang 1Bài 1: ĐIỀU KHIỂN CÁC PHẦN TỬ KHÍ NÉN
I) Phân biệt các loại cảm biến:
Cảm biến quang: khi đưa bất cứ vật nào che đầu cảm biến thì cảm biến sẽ lên mức 1
Càm biến điện dung: khi đưa một vật bất kì lại thật gần thì cảm biến sẽ lên mức 1
Cảm biến điện cảm : chỉ lên mức 1 khi đưa vật bằng kim loại lại gần
II) Các ví dụ chương trình mẫu:
1)Thí nghiệm 1C:
Viết chương trình điếu khiển xi lanh I,mỗi khi nhấn SW2 xi lanh I đẩy
ra,sau 2 s thì xi lanh tự đẩy vào
SW2
Trang 2#0020 //Thiết lập 2 trạng thái đẩy ra và thu vào là ngược nhau
Trang 3//Dùng timer 0 có chu kì 4s để cho phép xi lanh I và J đẩy ra tuần tự nhau
LD 1007 AND NOT TIM 000 OUT 1000
LD 1007 AND TIM 000 OUT 1002 //Thiết lập chế độ đẩy ra và thu vào của xi lanh I ngược nhau
LD 1000 AND 1007 OUT 1001 //Tạo ra xung chu kì 8s (ON 4s và OFF 4s) cho timer 0
LD 1007 AND NOT TIM 001 TIM 000
#0040
LD 1007 AND TIM 000 TIM 001
#0040
3)Thí nghiệm 2D: (mở rộng của 2A,2B,2C):
-Viết chương trình phân loại chai bia,nếu gặp chai lỗi thì cho xi lanh I đẩy ra
để đưa chai lỗi về băng chuyền để sửa chữa,khi đủ 12 chai thì xi lanh J được đẩy từ trên xuống để đóng nút chai
-Dây truyền có dùng cảm biến quang để phát hiện lỗi kẹt chai,nếu quá 30s
ma cảm biến quang ko phát hiện được chai đi qua sẽ hú còi báo động
-Nếu bị mất điện thì bộ đếm số chai sẽ không thay đổi và khi có điện thì vẫn hoạt động bình thường
Trang 4SW2
Trang 5//Khi băng chuyền bắt đầu hoạt động,nếu cảm biến quang báo có chai đi ngang (CB1 ON) và cảm biến dung báo chai lỗi (CB2 ON) thì cho xi lanh I hoạt động trong 2 s để đẩy chai lỗi ra
Trang 6OR 1000 AND 0001 AND 0002 AND NOT TIM 0 OUT 1000
LD 1000 TIM 000
#0020
LD NOT 1000 AND 1007
OUT 1001 //khi băng chuyền hoạt động,cảm biến quang báo có chai đi ngang(CB1 ON)
và cảm biến dung không báo lỗi chai thì ta bắt đầu đếm số chai xuống.Khi số chai đếm xuống bằng 0(đủ 12 chai) thì reset số chai đếm về 12
LD 1007 AND 0001 AND NOT 0002
LD CNT1 CNT 001
12 //Khi đã đủ 12 chai thì cho xi lanh J hoạt động (trong 4s) để đóng nắp chai
LD CNT1
OR 1002 AND NOT TIM 002 OUT 1002
LD 1002 TIM 002
#0040 //Thiết lập chế độ báo động còi khi có lỗi kẹt chai:khi băng chuyền hoạt động,và cảm biến quang chưa xác định có chai tới thì ta sẽ cho timer 3
chạy,nếu sau 30s mà không có chai đi ngang (tức bị kẹt chai) timer 3 sẽ on
và hú còi báo
LD 1007 AND NOT 0001 TIM 003
#0300
LD TIM3 OUT 1004
III) Thực hiện phương án được giao:
Khi nhấn Start (SW2) , hệ thống sẽ thực hiện một cách tuần tự các bước sau:
1/ xi lanh I đẩy ra
Trang 72/ xi lanh J đẩy ra 3/ xi lanh K đẩy ra 4/ xi lanh I,J thu vào 5/ xi lanh K thu vào
6/ xi lanh K đẩy ra
7/ xi lanh J đẩy ra
8/ xi lanh I đẩy ra 9/ xi lanh J,K thu vào
10/ xi lanh I thu vào 11/ tắt hệ thống Mỗi bước cách nhau 1s Khi nhấn Stop (SW3) hệ thống dừng lại
Trang 9//Khi hệ thống đã bắt đầu hoạt động,ta kích cho các timer chạy,mỗi timer tương ứng với mỗi mốc thời gian bắt đầu các bước
LD 1007 TIM 001
Trang 10LD 1007 TIM 002
#0020
………
LD 1007 TIM 011
#0110 //dựa vào yêu cầu ta có xi lanh I sẽ đẩy ra khi timer 1 ON và thu vào khi timer 4 ON,và lại đẩy ra khi timer 8 ON thu vào khi timer 10 ON
LD TIM1 AND NOT TIM4 OUT 1000
LD TIM8 AND NOT TIM10 OUT 1000
LD 1007 AND NOT 1000 OUT 1001
//Tương tự ta có xi lanh J đẩy ra khi timer 2 ON và thu vào khi timer 4
ON,tiếp tục đẩy ra khi timer 7 ON,thu vào khi timer 9 ON
LD TIM2 AND NOT TIM4 OUT 1002
LD TIM7 AND NOT TIM9 OUT 1002
//Tương tự ta có xi lanh K đẩy ra khi timer 3 ON và thu vào khi timer 5 ON,tiếp tục đẩy ra khi timer 6 ON,thu vào khi timer 9 ON
LD TIM3 AND NOT TIM5 OUT 1003
LD TIM6 AND NOT TIM9 OUT 1003
Nhận xét: hệ thống hoạt động đúng theo yêu cầu
Trang 11Bài 2: ĐIỀU KHIỂN DÙNG PLC OMRON
Trang 13OR 20000 AND NOT 00002 OUT 20000
//Cho timer 1 chạy để delay 5s sau khi nhấn STAR
LD 20000 TIM 001
#0050 //thiết lập chế độ PAUSE dùng địa chỉ 20002 để làm biến trung gian
LD TIM1 AND 00003
LD TIM1 AND 20002 KEEP 20002 //Sử dụng địa chỉ 20002 để làm điều kiện cho hàm khóa đoạn chương trình
LD 20002
IL //Bắt đầu đoạn chương trình trong hàm khóa
//Nếu đã delay đủ 5s và băng tải thùng dừng thì cho băng tải táo chạy
LD TIM1 AND NOT 10001 OUT 10000
//khi công tắc hành trình ON,báo thùng đã đến đúng vị trí thì reset counter đếm táo và dùng cảm biến táo để đếm số táo đi qua
LD 00000
LD NOT 00007 CNT 000
#0010 //băng tải thùng sẽ chạy khi timer 5s đã ON và công tắc hành trình không ON(tức thùng chưa đến đúng vị trí để bỏ táo vào) hoặc băng tài thùng sẽ chạy khi táo đã bỏ đủ (CNT0 ON),
LD CNT0
OR NOT 00007 AND TIM1
OUT 10001 //Mỗi lần đã bỏ xong 1 thùng táo (CNT0 ON) thì cho counter đếm thùng tăng thêm 1 và dùng biến trung gian chạy chương trình (20000) để reset counter đếm thùng(mỗi lần hệ thống hoạt động lại thì reset counter)
LD CNT0
LD 25314
LD 20000 CNTR 0000 #0010 //thiết lập giá trị so sánh liên tục cho counter đếm thùng
LD 25313
Trang 14CMP 00000 #0010 //dừng hệ thống khi bộ so sánh báo đã đếm đủ 10 thùng (25506 ON)
LD 25506 OUT 20001 //dừng đoạn chương trình trong hàm khóa
ILC
II) Thực hiện phương án được giao:
Sau khi nhấn Start, hệ thống sẽ tự động đóng gói 1 thùng 5 táo Sau đó hệ thống nghỉ trong 10s Kế tiếp đóng liên tục 3 thùng theo thứ tự gồm 3 táo, 2 táo và
1 táo Hệ thống sẽ dừng hoàn toàn sau khi thực hiện xong tất cả các bước trên hoặc khi ta nhấn Stop
Khi hệ thống đang trong trạng thái dừng, nếu ta nhấn Start, hệ thống sẽ thực hiện lại tất cả công việc theo thứ tự như trên
Chương trình LADDER:
Trang 18Chương trình danh sách lệnh:
//Để giải quyết bài toán ta chia bài toán ra làm 2 giai đoạn,giai đoạn sau khi nhấn START và giai đoạn sau khi TIMER 0 ON tức là sau khi ngừng hệ thống 10s
//giai đoạn đầu sẽ chạy với biến tự giữ 20000
//giai đoạn sau sẽ chạy với biến timer 0
LD 000.01
OR 200.00 AND NOT 000.02 AND NOT TIM001 OUT 200.00
//thiết lập điều kiện cho băng tải táo chạy:
+biến hoạt động của giai đoạn 1 hoặc 2 đã ON (20000 và TIMER 0 ON)
+băng tải thùng phải đang dừng
LD 200.00 AND NOT 100.01
LD NOT 200.01
OR TIM000
Trang 19AND LD OUT 100.00 //thiết lập các Counter đếm số thứ tự thùng tới (1 4) và Counter đếm số táo cho mỗi thùng:
LD 000.00 //Counter 7 đếm 5 táo cho thùng 1
LD NOT 000.07 CNT 007 005
LD CNT020 //Counter 8 đếm 3 táo cho thùng 2 AND 000.00
LD NOT 000.07 CNT 008 003
LD CNT002 //Counter 9 đếm 2 táo cho thùng 3 AND 000.00
LD NOT 000.07 CNT 009 002
LD CNT003 //Counter 10 đếm 1 táo cho thùng 4 AND 000.00
LD NOT 000.07 CNT 010 001
LD 000.07 //Counter 20 ON khi đã có 2 thùng qua
LD 000.01 CNT 020 002
LD 000.07 //Counter 2 ON khi đã có 3 thùng qua
LD 000.01 CNT 002 003
LD 000.07 //Counter 3 ON khi đã có 4 thùng qua
LD 000.01 CNT 003 004 //Thiết lập điều kiện chạy cho băng tải thùng: gồm 5 điều kiện tương ứng cho từng trường hợp
LD NOT 200.01 AND CNT007
OR NOT 000.07
OR CNT008
OR CNT009
OR CNT010
Trang 20AND 200.00 OUT 100.01
//Thiết lập Timer0 để Delay hệ thống 10s sau khi đã đóng xong thùng thứ 1 (ở đây mô phỏng chỉ 2s)
LD CNT020 TIM 000 020 OUT 200.01
//Sau khi đã đóng xong tất cả các thùng thì cho biến 20003 ON và kích hoạt Timer1 Sau thời gian 2s, hệ thống sẽ dừng hoàn toàn và chờ nhấn START để khởi động lại
LD CNT010
OR 200.03 AND NOT TIM001 OUT 200.02
LD 200.02 OUT 200.03
LD 200.03 TIM 001 020 END
Nhận xét: hệ thống trên Board thí nghiệm hoạt động đúng như yêu cầu
Bài 3: ĐIỀU KHIỂN NHIỆT ĐỘ BẰNG
Trang 21CÁC PHƯƠNG PHÁP ĐIỀU KHIỂN CỔ ĐIỂN
I) Đoạn chương trình mẫu:
// Sự kiện khi khởi động chương trình
BOOL CBai3_3Dlg::OnInitDialog()
{
CDialog::OnInitDialog();
// Set the icon for this dialog The framework does this automatically
CPaintDC dc(this); // device context for painting
SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
// Center icon in client rectangle int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// Draw the icon dc.DrawIcon(x, y, m_hIcon);
// The system calls this to obtain the cursor to display while the user drags
// the minimized window
Trang 22// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
// TODO: Add extra initialization here
Trang 23// If you add a minimize button to your dialog, you will need the code below
// to draw the icon For MFC applications using the document/view model,
// this is automatically done for you by the framework
// CSetting message handlers
// Sự kiện khi nhấn nút Start
void CBai3_3Dlg::OnStart()
{
// TODO: Add your control notification handler code here
// Select and Open Device
if(!flag) DRV_SelectDevice(m_hWnd,FALSE,&m_DeviceNume, m_DeviceName);
ptAIVoltageIn.TrigMode = 0; // internal trigger
ptAIVoltageIn.voltage = (FLOAT far *)&Input;
// configures the gain for the specifed analog output channel
Trang 24Scope1.Channels[1].Data.AddYPoint(Temp);
s.Format("%0.2lf",pw);
// Pwr = 100 ; this->SetDlgItemText(IDC_POWER, s);
Scope2.Channels[0].Data.AddYPoint(Pwr);
}
dwCurrentTime = GetTickCount()- gdwStartTime;
Trang 25// TODO: If this is a RICHEDIT control, the control will not
// send this notification unless you override the CDialog::OnInitDialog()
// function and call CRichEditCtrl().SetEventMask()
// with the ENM_CHANGE flag ORed into the mask
// TODO: Add your control notification handler code her
}
void CSetting::OnChangeT0()
{
// TODO: If this is a RICHEDIT control, the control will not
// send this notification unless you override the CDialog::OnInitDialog()
// function and call CRichEditCtrl().SetEventMask()
// with the ENM_CHANGE flag ORed into the mask
// TODO: Add your control notification handler code here
}
II) Các đoạn chương trình điều khiển ON-OFF và PID:
Trang 261) Điều khiển PID:
- Đoạn đọc tín hiệu nhiệt độ:
DRV_AIVoltageIn(DriverHandle,(LPT_AIVoltageIn)&ptAIVoltageIn);
- Đoạn tính và xuất tín hiệu điều khiển:
Error = Temp - 62.5*Input;
2) Điều khiển ON-OFF:
- Đoạn đọc tín hiệu nhiệt độ:
// read input data
DRV_AIVoltageIn(DriverHandle,(LPT_AIVoltageIn)&ptAIVoltageIn);
- Đoạn tính và xuất tín hiệu điều khiển:
// write output data
ptAOConfig.chan = gwChannelOutput ;
Trang 27a=KL/T=7.5 T i =2L=100 T d =0.5L=25
K p =1,20/a=0.16 K i =K p /T i =1.6*10 -3 K d =K p *T d =4
2) Khảo sát vòng kín với bộ điều khiển PID:
Khảo sát với các hệ số PID tính được từ vòng hở:
Đáp ứng thu được:
Trang 28Khảo sát với các hệ số PID mặc định:
Sai số xác lập ( 0 C)
3) Khảo sát vòng kín với bộ điều khiển ON-OFF:
Vẽ các đáp ứng lần lượt với các vùng trễ Db là 1 o C , 0.2oC
Trang 30Sai số xác lập ( 0 C)
=> Nhận xét:
- Ở điều khiển ON-OFF khi độ rộng vùng chết càng nhỏ thì sai số xác lập càng nhỏ
- Bộ điều khiển PID cho sai số nhỏ hơn so với bộ điều khiển ON-OFF.Chất lượng bộ điều khiển PID tốt hơn nhiều so với ON-OFF
Câu hỏi thêm: làm cho “mịn” đặc tuyến khi điều khiển ON-OFF (đoạn nhấp nhô đều
nhau ở 2 bên giá trị xác lập)
Trang 31Bài 4: ĐIỀU KHIỂN TỐC ĐỘ VÀ VỊ TRÍ ĐỘNG CƠ DC
I) Các đoạn chương trình mẫu :
// Đoạn chương trình đọc xung:
PT_DioReadPortByte ptDioReadPortByte0,ptDioReadPortByte1;
USHORT DataLo,DataHi;
double Pulse;
double Delta_Pulse;
static double PrevPulse;
// read low byte
ptDioReadPortByte0.port = 0;
ptDioReadPortByte0.value = (USHORT far *)&DataLo;
// read high byte
ptDioReadPortByte1.port = 1;
ptDioReadPortByte1.value = (USHORT far *)&DataHi;
DRV_DioReadPortByte(DriverHandle,(LPT_DioReadPortByte)&ptDioReadPortByte0);
DRV_DioReadPortByte(DriverHandle,(LPT_DioReadPortByte)&ptDioReadPortByte1);
Pulse = DataHi*256 + DataLo;
Delta_Pulse = Pulse - PrevPulse;
PrevPulse = Pulse;
// processing counter overflow
if(Delta_Pulse>+32768) Delta_Pulse = Delta_Pulse - 65536;
if(Delta_Pulse<-32768) Delta_Pulse = Delta_Pulse + 65536;
//configure input and output of the PCI card
if(!flag) DRV_SelectDevice(m_hWnd,FALSE,&m_DeviceNume, m_DeviceName); DRV_DeviceOpen(m_DeviceNume,&DriverHandle);
// configures the gain for the specifed analog input channel
ptAIVoltageIn.TrigMode = 0; // internal trigger
ptAIVoltageIn.voltage = (FLOAT far *)&Input;
Trang 32// configures the gain for the specifed analog output channel
//Đoạn tính tín hiệu điều khiển:
double CBAI4Dlg::PID(double currentspeed)
{
static double u[2];
static double e[3];
e[2] = SetSpeed - currentspeed;
u[1] = u[0] + a0*e[2] + a1*e[1] + a2*e[0];
// Đoạn xuất tín hiệu điều khiển:
void CBAI4Dlg::OnTimer(UINT nIDEvent)
{
// TODO: Add your message handler code here and/or call default
CString s;
Trang 34II) Tiến hành thí nghiệm:
1)Điều khiển tốc độ động cơ:
Thí nghiệm với Kp thay đổi,Ki=0.015,Kd=1e-6:
Kp 0.001 0.002 0.003 0.004 0.005 0.006 0.007 Thời gian lên (s)
Thời gian xác lập (s) 14 6.2 5.5 4.1 3.6 3.2 3
Độ vọt lố (%) 26 27 28 30 32 34 35 Sai số xác lập (v/p) 2 5 6 9 11 13 16
Trang 35Đáp ứng thu được:
+ Trường hợp Kp=0.001:
+ Trường hợp Kp=0.002:
Trang 36 Thí Nghiệm với Ki thay đổi,Kp=0.0004,Kd=e^(-6):
Trang 37+ Trường hợp Kd=3.10^(-4):
2) Điều khiển vị trí động cơ:
Thí Nghiệm với Ki=0.05,Kp=0.002,Kd=0.025
Thời gian lên 0.07s
Thời gian xl (s) 1.6s
Độ vọt lố (%) 15%
Sai số xl (v/p) 0.41
Trang 38
III) Nhận xét ảnh hưởng của các thành phần Kp , Ki , Kd của bộ
điều khiển PID:
Khi tăng Kp : sai số xác lập càng nhỏ, thời gian xác lập tăng, độ vọt lố càng
cao Khi tăng Kp thì các cực của hệ thống nói chung có xu huớng di chuyển
ra xa trục thực Nếu tăng Kp quá giá trị hệ số khuếch đại giới hạn thì hệ thống sẽ trở nên mất ổn định (dao động)
Khi tăng Ki : làm chậm đáp ứng quá độ thời gian xác lập tăng , độ vọt lố
tăng , sai số xác lập giảm Do hệ số khuếch đại của khâu PI bằng vô cùng tại tần số bằng 0 nên khâu PI có thể làm cho sai số của tín hiệu vào là hàm nấc của hệ thống không có khâu vi phân lý tưởng bằng 0 Ngoài ra, do khâu PI là một bộ lọc thông thấp nên nó còn có tác dụng triệt tiêu nhiễu tần số cao tác động vào hệ thống
Khi tăng Kd : đáp ứng của hệ thống càng nhanh ,thời gian lên ngắn,nhưng
thời gian xác lập tăng , độ vọt lố tăng và sai số xác lập tăng
Trang 39Bài 5:ĐIỀU KHIỂN THÍCH NGHI TỐC ĐỘ ĐỘNG CƠ DC
I) Yêu cầu của thầy:
Tạo thêm 1 nút nhấn REVERSE để đảo chiều quay của động cơ nhưng chỉ nhấn REVERSE được 1 lần
II) Các đoạn chương trình mẫu của giải thuật PID thích nghi:
//Đoạn đọc tín hiệu xung:
double CBAI4Dlg::DataPulse()
{
PT_DioReadPortByte ptDioReadPortByte0,ptDioReadPortByte1;
USHORT DataLo,DataHi;
double Pulse;
double Delta_Pulse;
//static double PrevPulse;
// read low byte ptDioReadPortByte0.port = 0;
ptDioReadPortByte0.value = (USHORT far *)&DataLo;
// read high byte ptDioReadPortByte1.port = 1;
ptDioReadPortByte1.value = (USHORT far *)&DataHi;
DRV_DioReadPortByte(DriverHandle,(LPT_DioReadPortByte)&ptDioReadPort Byte0);
DRV_DioReadPortByte(DriverHandle,(LPT_DioReadPortByte)&ptDioReadPort Byte1);
Pulse = DataHi*256 + DataLo;
Delta_Pulse = Pulse - PrevPulse;