# 介面 ## 實驗一 ### 實驗記錄 --- #### 工作日誌 1. 先把狀態空間模型寫出來了,只是太久沒碰了,矩陣的地方一直寫錯,花了蠻多時間,目前搞不懂如何使用Matlab產生u(k),也就是各種**頻率**的弦波 2. 目前已經做到matlab與M128互動了,也解決產生各種頻率的弦波 3. 完成實驗報告 #### 介面問題 1. HMI打開接收u(k)後,回傳y(k)給matlab,此時先把HMI的通訊阜關掉,再讓matlab run,跑出來的結果如照片右下角,無法接收到input。(已解決) 2. 這次只使用m128<->matlab,matlab putmatrix顯示可以但接收資料時卻顯示Error using remo_snget_matrix 還有sync failed,結果就沒辦法跑出接收到的數字(已解決) ![](https://i.imgur.com/l0igbnC.jpg) #### 流程圖 ![](https://i.imgur.com/tmqmBZd.jpg) ![](https://i.imgur.com/yJFbkU7.jpg) ![](https://i.imgur.com/rrpNeMz.jpg) #### 實驗步驟 ##### **dataAgent輔助開發狀態空間計算系統** 1. 程式碼 * C ```c= #include "c4mlib.h" #include "math.h" #include "stdlib.h" #include "stdio.h" int main(void) { C4M_DEVICE_set(); int n=2,m=1,r=1,k=100; float A[2][2]={{1.35,0.55},{-0.45,0.35}}; float B[2][1]={{0.5},{0.5}}; float C[1][2]={{3,1}}; float D[1][1]={{1}}; float x[2][1]={{0},{0}}; float u[100][1]={}; float y[0][0]; float E[2][1],F[2][1]; float outpute[100][1]={};//以上為設定狀態空間的值 printf("get u(k)\n");//傳送訊息給HMI HMI_snget_matrix(8,100,1,u);//從.met檔裡得到矩陣 for(int i=0;i<k;i++)//執行狀態空間模型 { for(int q=0;q<r;q++)//算C(k)x(k) { for(int w=0;w<1;w++) { E[q][w]=0; for(int e=0;e<n;e++) { E[q][w]+=C[q][e]*x[e][w]; } } } for(int q=0;q<r;q++)//算D(k)u(k) { for(int w=0;w<1;w++) { F[q][w]=0; for(int e=0;e<m;e++) { F[q][w]+=D[q][e]*u[i][0]; } } } for (int q=0; q<r; q++)//算y(k)=C(k)x(k)+D(k)u(k) { for (int w=0; w<1; w++) { y[q][w]=E[q][w]+F[q][w]; } } for(int q=0;q<n;q++)//算A(k)x(k) { for(int w=0;w<1;w++) { E[q][w]=0; for(int e=0;e<n;e++) { E[q][w]+=A[q][e]*x[e][w]; } } } for(int q=0;q<n;q++)//算B(k)u(k) { for(int w=0;w<1;w++) { F[q][w]=0; for(int e=0;e<m;e++) { F[q][w]+=B[q][e]*u[i][0]; } } } for (int q=0; q<n; q++)//算x(k+1)=A(k)x(k)+B(k)u(k) { for (int w=0; w<1; w++) { x[q][w]=E[q][w]+F[q][w]; } } outpute[i][0]=y[0][0]; } printf("send y(k)\n");//傳送訊息給HMI HMI_snput_matrix(8,100,1,outpute);//傳送矩陣給HMI return 0; } ``` 2. 參數及輸入數列傳給PC > HMI使用HMI_snget_matrix(8,100,1,u);要拿到數列u(k)值,所以先用matlabt產生弦波後存檔,接著在HMI讀取檔案.mat檔 ![](https://i.imgur.com/7jvLvTH.jpg) 3. 輸出pc傳給dataagent > 拿到數列後,會經過狀態空間計算產生u(k),接著使用HMI_snput_matrix(8,100,1,outpute);傳送u(k)到接收區,在使用右下角的儲存檔案,存為.met檔,就可以到matlab去畫圖比較 ![](https://i.imgur.com/ZQ3fYIC.jpg) 4. 輸出入數列繪圖(兩組) 50hz > 上圖為50hz的弦波,完整5次的波(後面補齊),而下圖則是經過狀態空間轉換而成的y(k)圖 ![](https://i.imgur.com/Qmu0jUM.jpg) 25hz > 上圖為25hz的弦波,而下圖則是經過狀態空間轉換而成的y(k)圖 ![](https://i.imgur.com/268XgB3.jpg) ##### **Matlab Remo put get 巨集輔助開發狀態空間計算系統** 1. 程式碼 * matlab ``` clc; portnum=5; t=(0:0.001:1)'; y=sin(2*pi*25*t);%可以改頻率的弦波 output=y(1:100); output=single(output);%轉型 port=remo_open(portnum);%打開com5 [input_u]=remo_get_msg(port);%得到ASA電腦傳的printf [err_1]=remo_snput_matrix(port,output);%傳送矩陣給ASA電腦 [input_y]=remo_get_msg(port);%得到ASA電腦傳的printf [input,err_2] = remo_snget_matrix(port);%得到ASA電腦給的矩陣 input=single(input);%轉型 remo_close(port);%關閉com5 disp(input_u);%顯示 disp(input_y);%顯示 disp(input);%顯示 subplot(2,1,1); plot(t(1:100),output(1:100));%畫u(k) xlabel('time(s)'); ylabel('input vector u(k)'); subplot(2,1,2); plot(t(1:100),input(1:100));%畫y(k) xlabel('time(s)'); ylabel('output vector y(k)'); ``` * C ```c= #include "c4mlib.h" #include "math.h" #include "stdlib.h" #include "stdio.h" int main(void) { C4M_DEVICE_set(); int n=2,m=1,r=1,k=100; float A[2][2]={{1.35,0.55},{-0.45,0.35}}; float B[2][1]={{0.5},{0.5}}; float C[1][2]={{3,1}}; float D[1][1]={{1}}; float x[2][1]={{0},{0}}; float u[100][1]={}; float y[0][0]; float E[2][1],F[2][1]; float outpute[100][1]={};//以上為設定狀態空間的值 printf("get u(k)\n");//傳送訊息給matlab HMI_snget_matrix(8,100,1,u);//從matlab得到矩陣 for(int i=0;i<k;i++)//執行狀態空間模型 { for(int q=0;q<r;q++)//算C(k)x(k) { for(int w=0;w<1;w++) { E[q][w]=0; for(int e=0;e<n;e++) { E[q][w]+=C[q][e]*x[e][w]; } } } for(int q=0;q<r;q++)//算D(k)u(k) { for(int w=0;w<1;w++) { F[q][w]=0; for(int e=0;e<m;e++) { F[q][w]+=D[q][e]*u[i][0]; } } } for (int q=0; q<r; q++)//算y(k)=C(k)x(k)+D(k)u(k) { for (int w=0; w<1; w++) { y[q][w]=E[q][w]+F[q][w]; } } for(int q=0;q<n;q++)//算A(k)x(k) { for(int w=0;w<1;w++) { E[q][w]=0; for(int e=0;e<n;e++) { E[q][w]+=A[q][e]*x[e][w]; } } } for(int q=0;q<n;q++)//算B(k)u(k) { for(int w=0;w<1;w++) { F[q][w]=0; for(int e=0;e<m;e++) { F[q][w]+=B[q][e]*u[i][0]; } } } for (int q=0; q<n; q++)//算x(k+1)=A(k)x(k)+B(k)u(k) { for (int w=0; w<1; w++) { x[q][w]=E[q][w]+F[q][w]; } } outpute[i][0]=y[0][0]; } printf("send y(k)\n");//傳送訊息給matlab HMI_snput_matrix(8,100,1,outpute);//傳送矩陣給matlab return 0; } ``` 2. matlab對話 > 使用matlab當作HMI,由下圖可以看到得到從ASA電腦傳送到的訊息 ![](https://i.imgur.com/TOmOhYH.jpg) 3. 輸出入數列繪圖 75hz > 上圖為75hz的弦波,而下圖則是經過狀態空間轉換而成的y(k)圖 ![](https://i.imgur.com/m1O6VSo.jpg) 100hz > 上圖為100hz的弦波,而下圖則是經過狀態空間轉換而成的y(k)圖 ![](https://i.imgur.com/1MeOgQm.jpg) ### 驗收成果 matlab ``` clear; close all; clc; portnum=5; t=(0:0.001:1)'; y=sin(2*pi*50*t);%可以改頻率的弦波 output=single(y(1:100));%轉型 port=remo_open(portnum);%打開com5 R=100;L=1;c=1; A=single([-R/L -1/L;1/c 0]); B=single([1/L;0]);C=single([0 1]);D=single(0); x=single([0;0]); [err_A]=remo_snput_matrix(port,A);%傳送矩陣A給ASA電腦 [err_B]=remo_snput_matrix(port,B);%傳送矩陣B給ASA電腦 [err_C]=remo_snput_matrix(port,C);%傳送矩陣C給ASA電腦 [err_D]=remo_snput_matrix(port,D);%傳送矩陣D給ASA電腦 [err_x]=remo_snput_matrix(port,x);%傳送矩陣x給ASA電腦 [err_u]=remo_snput_matrix(port,output);%傳送矩陣u給ASA電腦 [input,err_y] = remo_snget_matrix(port);%得到ASA電腦給的矩陣y input=single(input);%轉型 remo_close(port);%關閉com5 disp(input);%顯示 subplot(2,1,1); plot(t(1:100),output(1:100));%畫u(k) xlabel('time(s)'); ylabel('input vector u(k)'); subplot(2,1,2); plot(t(1:100),input(1:100));%畫y(k) xlabel('time(s)'); ylabel('output vector y(k)'); ``` c ```c= #include "c4mlib.h" #include "math.h" #include "stdlib.h" #include "stdio.h" int main(void) { C4M_DEVICE_set(); int n=2,m=1,r=1,k=100; //float R=12,L=0.15,c=0.000100; float A[2][2]={}; float B[2][1]={}; float C[1][2]={}; float D[1][1]={}; float tmp[2][1]={}; float x[2][1]={}; float u[100][1]={}; float y[0][0]; float E[2][1],F[2][1]; float outpute[101][1]={}; HMI_snget_matrix(8,2,2,A); HMI_snget_matrix(8,2,1,B); HMI_snget_matrix(8,1,2,C); HMI_snget_matrix(8,1,1,D); HMI_snget_matrix(8,2,1,x); HMI_snget_matrix(8,100,1,u);//從matlab得到矩陣 for(int i=0;i<k;i++) { for(int q=0;q<r;q++)//算C(k)x(k) { for(int w=0;w<1;w++) { E[q][w]=0; for(int e=0;e<n;e++) { E[q][w]+=C[q][e]*x[e][w]; } } } for(int q=0;q<r;q++)//算D(k)u(k) { for(int w=0;w<1;w++) { F[q][w]=0; for(int e=0;e<m;e++) { F[q][w]+=D[q][e]*u[i][0]; } } } for (int q=0; q<r; q++)//算y(k)=C(k)x(k)+D(k)u(k) { for (int w=0; w<1; w++) { y[q][w]=E[q][w]+F[q][w]; } } for(int q=0;q<n;q++)//算A(k)x(k) { for(int w=0;w<1;w++) { E[q][w]=0; for(int e=0;e<n;e++) { E[q][w]+=A[q][e]*x[e][w]; } } } for(int q=0;q<n;q++)//算B(k)u(k) { for(int w=0;w<1;w++) { F[q][w]=0; for(int e=0;e<m;e++) { F[q][w]+=B[q][e]*u[i][0]; } } } for (int q=0; q<n; q++)//算x(k+1)=A(k)x(k)+B(k)u(k) { for (int w=0; w<1; w++) { tmp[q][w]=E[q][w]+F[q][w]; } } x[0][0]=tmp[0][0]*0.001+x[0][0]; x[1][0]=tmp[1][0]*0.001+x[1][0]; outpute[i][0]=y[0][0]; } HMI_snput_matrix(8,100,1,outpute);//傳送矩陣給matlab return 0; } ``` #### 狀態空間表示 $$ \dot{x} = A x + B u \\ y=Cx + D u $$ ![](https://i.imgur.com/aPeHIeO.jpg) #### 驗收數據 R=100;L=1;c=1;dt=0.001; ![](https://i.imgur.com/AqH1jH6.jpg) R=20;L=1;c=0.0001;dt=0.001; ![](https://i.imgur.com/4OyCywM.jpg)