---
# System prepended metadata

title: 介面

---

#    介面
##    實驗一
###    實驗記錄
---
####    工作日誌
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)










