# 介面
## 實驗一
### 實驗記錄
---
#### 工作日誌
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,結果就沒辦法跑出接收到的數字(已解決)

#### 流程圖



#### 實驗步驟
##### **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檔

3. 輸出pc傳給dataagent
> 拿到數列後,會經過狀態空間計算產生u(k),接著使用HMI_snput_matrix(8,100,1,outpute);傳送u(k)到接收區,在使用右下角的儲存檔案,存為.met檔,就可以到matlab去畫圖比較

4. 輸出入數列繪圖(兩組)
50hz
> 上圖為50hz的弦波,完整5次的波(後面補齊),而下圖則是經過狀態空間轉換而成的y(k)圖

25hz
> 上圖為25hz的弦波,而下圖則是經過狀態空間轉換而成的y(k)圖

##### **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電腦傳送到的訊息

3. 輸出入數列繪圖
75hz
> 上圖為75hz的弦波,而下圖則是經過狀態空間轉換而成的y(k)圖

100hz
> 上圖為100hz的弦波,而下圖則是經過狀態空間轉換而成的y(k)圖

### 驗收成果
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
$$

#### 驗收數據
R=100;L=1;c=1;dt=0.001;

R=20;L=1;c=0.0001;dt=0.001;
