---
# System prepended metadata

title: 實驗一 人機介面

---

# 實驗一 人機介面
## 工作日誌
### 遭遇問題
* 不熟悉Matlab與ASA的溝通方式


### 解決方法
* 詢問助教和同學

## 程式碼
### DataAgent輔助開發狀態空間計算系統
#### ASA
```c
#include "c4mlib.h"
# define K 100
int main()
{
	C4M_DEVICE_set();
	
	/*double A[2][2];
	double B[2][1];
	double C[1][2];
	double D[1][1];
	double x_0[2][1];
	double u[1][K];
	double y[1][K];*/
	
	double A[2][2] = {{1.35 ,0.55}, {-0.45, 0.35}};
	double B[2][1] = {0.5, 0.5};
	double C[1][2] = {3, 1};
	double D[1][1] = {1};
	double x_0[2][1] = {0, 0};
	double u[1][K];
	double y[1][K];
	
	//設定狀態空間方程式的A,B,C,D,x_0和數列u(k)
	/*printf("Please give matrix A\n");
	HMI_snget_matrix(8, 2, 2, &A);
	printf("Please give matrix B\n");
	HMI_snget_matrix(8, 2, 1, &B);
	printf("Please give matrix C\n");
	HMI_snget_matrix(8, 1, 2, &C);
	printf("Please give matrix D\n");
	HMI_snget_matrix(8, 1, 1, &D);
	printf("Please give matrix x_0\n");
	HMI_snget_matrix(8, 2, 1, &x_0);*/
	printf("Please give matrix u\n");
	HMI_snget_matrix(8, 1, K, &u);
	
	//設定x1,x2達到數列x(k)作用
	double x1[2][1];
	double x2[2][1];
	x1[0][0]=x_0[0][0];
	x2[0][0]=x_0[0][0];
	x1[1][0]=x_0[1][0];
	x2[1][0]=x_0[1][0];
	
	//狀態更新方程式x(k+1)=Ax(k)+Bu(k)、y(k)=Cx(k)+Du(k)
	for(int i = 0; i < K; i++){
		x2[0][0]=A[0][0]*x1[0][0]+A[0][1]*x1[1][0]+B[0][0]*u[0][i];
		x2[1][0]=A[1][0]*x1[0][0]+A[1][1]*x1[1][0]+B[1][0]*u[0][i];
		y[0][i]=C[0][0]*x1[0][0]+C[0][1]*x1[1][0]+D[0][0]*u[0][i];
		x1[0][0]=x2[0][0];
		x1[1][0]=x2[1][0];
		printf("%f\n",y[0][i]);
	}
	HMI_snput_matrix(8, 1, K, &y);
	printf("end\n");
}}
```
#### MATLAB generate_u
```matlab
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
clear all  % 
clc     %   
close all


f = 10;%頻率
omega = 2*pi*f;
K = 100;%100個點

for i = 0:1:K-1
     u(i + 1) = sin(omega*i/K);
end

u = cast(u,'single');
save datau u;
```
#### MATLAB plot
```matlab
clear   %清除記憶體內儲存變數
clc       %清除command window訊息
close all   %清除已開啟的作圖視窗

load datau;
load datay.mat;

k = 0.01:0.01:1;
plot(k , u, 'B-o', k, data0, 'R-x');

xlabel('t');  
ylabel('u(k) , y(k)');  
title('u(k) and y(k)');  
legend('u(k)=sin(wk)','y(k)');
```
### Matlab Remo put get 巨集輔助開發狀態空間計算系統
#### ASA
```c
#include "c4mlib.h"

int main()
{
	C4M_DEVICE_set();
	float A[2][2] = {{0.0, 0.0}, {0.0, 0.0}};
	float B[2][1] = {{0.0}, {0.0}};
	float C[1][2] = {0.0, 0.0};
	float D[1][1] = {0.0};
	float x_0[2][1] = {{0.0}, {0.0}};
	float u[1][100];
	float y[1][100];
	
	HMI_snput_matrix(8, 2, 2, &A);
	HMI_snput_matrix(8, 2, 1, &B);
	HMI_snput_matrix(8, 1, 2, &C);
	HMI_snput_matrix(8, 1, 1, &D);
	HMI_snput_matrix(8, 2, 1, &x_0);

	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_0);
	HMI_snget_matrix(8, 1, 100, &u);
	
	float x1[2][1];
	float x2[2][1];
	x1[0][0]=x_0[0][0];
	x2[0][0]=x_0[0][0];
	x1[1][0]=x_0[1][0];
	x2[1][0]=x_0[1][0];
	
	for(int k = 0; k < 100; k++){
		x2[0][0]=A[0][0]*x1[0][0]+A[0][1]*x1[1][0]+B[0][0]*u[0][k];
		x2[1][0]=A[1][0]*x1[0][0]+A[1][1]*x1[1][0]+B[1][0]*u[0][k];
		y[0][k]=C[0][0]*x1[0][0]+C[0][1]*x1[1][0]+D[0][0]*u[0][k];
		x1[0][0]=x2[0][0];
		x1[1][0]=x2[1][0];
	}
	HMI_snput_matrix(8, 1, 100, &y);

}
```
#### MATLAB
```matlab
clear       %清除記憶體內儲存變數
clc         %清除command window訊息
close all   %清除已開啟的作圖視窗

load datau;
port = remo_open(9);

A = remo_snget_matrix(port);
B = remo_snget_matrix(port);
C = remo_snget_matrix(port);
D = remo_snget_matrix(port);
x_0 = remo_snget_matrix(port);

A = [1.35 0.55;
    -0.45 0.35];
B = [0.5;
     0.5];
C = [3 1];
D = [1];
x_0 = [0;
       0];
   
A = cast(A,'single');
B = cast(B,'single');
C = cast(C,'single');
D = cast(D,'single');
x_0 = cast(x_0,'single');
   
remo_snput_matrix(port, A);
remo_snput_matrix(port, B);
remo_snput_matrix(port, C);
remo_snput_matrix(port, D);
remo_snput_matrix(port, x_0);
remo_snput_matrix(port, u);

y = remo_snget_matrix(port);
remo_close(port);

k = 0.01:0.01:1;
plot(k, u, 'B-o', k, y, 'R-x');

xlabel('t');  
ylabel('u(k) and y(k)')  
title('u(k) and y(k)');  
legend('u(k)=sin(wk)','y(k)');
```
## 流程圖
###  DataAgent輔助開發狀態空間計算系統
![](https://i.imgur.com/SZtSmh6.png)


###  Matlab Remo put get 巨集輔助開發狀態空間計算系統
![](https://i.imgur.com/IPiHXur.png)


## 實驗數據
###  DataAgent輔助開發狀態空間計算系統
#### 第一組數據

f = 5HZ
w = 2 * pi * f
u=sin(wt)


![](https://i.imgur.com/MnyQOrt.jpg)
![](https://i.imgur.com/aJta8ok.png)




#### 第二組數據
f = 10HZ
w = 2 * pi * f
u=sin(wt)


![](https://i.imgur.com/MnyQOrt.jpg)
![](https://i.imgur.com/fXVj4Qs.png)








###  Matlab Remo put get 巨集輔助開發狀態空間計算系統
#### 第一組數據
f = 5HZ
w = 2 * pi * f
u=sin(wt)


![](https://i.imgur.com/MnyQOrt.jpg)
![](https://i.imgur.com/VSilDEd.png)






#### 第二組數據
f = 10HZ
w = 2 * pi * f
u=sin(wt)


![](https://i.imgur.com/MnyQOrt.jpg)
![](https://i.imgur.com/abJVmlo.png)







## 驗收題目
:::info
> [name=cy023]

- 題目:
    1. 請先了解 [Moving Average](https://en.wikipedia.org/wiki/Moving_average) 演算法。
    2. 由 Matlab 傳送 500 筆 `uint8_t` 型態變數至 M128 端。
    3. 在 M128 端實作 **Exponential Moving Average** 演算法，將上述資料做濾波後送回 Matlab。
    4. Matlab 將原始數據與 M128 計算結果疊圖輸出，比較濾波效果。

- 要求:
    1. 數據不限於亂數產生、蒐集股價資訊 ... 等
    2. 至少需 3 種不同 **Exponential Moving Average** 參數，並討論其差異。
    3. 需與以額外方式驗證演算法正確性，不限於使用 Matlab built-in function、網路上現成計算機...等。

- 延伸閱讀:
    [An Easy-to-Use Digital Filter](https://blog.stratifylabs.co/device/2013-10-04-An-Easy-to-Use-Digital-Filter/)
    [股票投資新手攻略：解構股票用語　技術分析篇](https://www.moneyhero.com.hk/blog/zh/%E8%82%A1%E7%A5%A8%E6%8A%95%E8%B3%87%E6%96%B0%E6%89%8B%E6%94%BB%E7%95%A5-%E8%A7%A3%E6%A7%8B%E8%82%A1%E7%A5%A8%E7%94%A8%E8%AA%9E-%E6%8A%80%E8%A1%93%E5%88%86%E6%9E%90%E7%AF%87)
:::

###  
股票選擇:1101台泥
日期:2021/12/1~2022/9/23 共200天
#### 第一組數據
EMA = 5
前5日EMA設為0，從第11日開始畫

藍線為收盤價，棕線為EMA
## Matlab Plot
![](https://i.imgur.com/h5kLcsx.png)


## Tradingview 驗證
![](https://i.imgur.com/dTPe2Yc.png)

程式碼
```ASA
#include "c4mlib.h"
# define K 200
# define n 5


int main()
{
	C4M_DEVICE_set();
	float x[1][K];
	float y[1][K];
	float temp[1][K];
	
	float alpha;//平滑constant
	
	alpha = 2.0 / (n + 1);
	//printf("alpha = %f\n", alpha);
	
	printf("Please give matrix x\n");
	HMI_snget_matrix(8, 1, K, &x);
	
	
	for(int i = 0; i < K; i++){
		if(i < n){
			temp[0][i] = 0;
		}
		else{
			//printf("%f\n",x[0][i]);
			temp[0][i] = temp[0][i - 1]*(1 - alpha) + x[0][i]* alpha;
		}
		if(i < 2*n){
			y[0][i] = 0;
		}
		else{
			y[0][i] = temp[0][i];
		}
		//printf("%f\n",y[0][i]);
	}
	HMI_snput_matrix(8, 1, K, &y);
	printf("end\n");

}
```
#### 第二組數據
EMA = 20
前20日EMA設為0，從第21日開始畫

藍線為收盤價，棕線為EMA
## Matlab Plot
![](https://i.imgur.com/0UbfTHT.png)



## Tradingview 驗證
![](https://i.imgur.com/VI3c9d7.png)


程式碼
```ASA
#include "c4mlib.h"
# define K 200
# define n 20


int main()
{
	C4M_DEVICE_set();
	float x[1][K];
	float y[1][K];
	float temp[1][K];
	
	float alpha;//平滑constant
	
	alpha = 2.0 / (n + 1);
	//printf("alpha = %f\n", alpha);
	
	printf("Please give matrix x\n");
	HMI_snget_matrix(8, 1, K, &x);
	
	
	for(int i = 0; i < K; i++){
		if(i < n){
			temp[0][i] = 0;
		}
		else{
			//printf("%f\n",x[0][i]);
			temp[0][i] = temp[0][i - 1]*(1 - alpha) + x[0][i]* alpha;
		}
		if(i < 2*n){
			y[0][i] = 0;
		}
		else{
			y[0][i] = temp[0][i];
		}
		//printf("%f\n",y[0][i]);
	}
	HMI_snput_matrix(8, 1, K, &y);
	printf("end\n");

}
```
#### 第三組數據
EMA = 50
前50日EMA設為0，從第51日開始畫

藍線為收盤價，棕線為EMA
## Matlab Plot
![](https://i.imgur.com/Kvy1zKU.png)




## Tradingview 驗證
![](https://i.imgur.com/my99Mgo.png)


程式碼
```ASA
#include "c4mlib.h"
# define K 200
# define n 50


int main()
{
	C4M_DEVICE_set();
	float x[1][K];
	float y[1][K];
	float temp[1][K];
	
	float alpha;//平滑constant
	
	alpha = 2.0 / (n + 1);
	//printf("alpha = %f\n", alpha);
	
	printf("Please give matrix x\n");
	HMI_snget_matrix(8, 1, K, &x);
	
	
	for(int i = 0; i < K; i++){
		if(i < n){
			temp[0][i] = 0;
		}
		else{
			//printf("%f\n",x[0][i]);
			temp[0][i] = temp[0][i - 1]*(1 - alpha) + x[0][i]* alpha;
		}
		if(i < 2*n){
			y[0][i] = 0;
		}
		else{
			y[0][i] = temp[0][i];
		}
		//printf("%f\n",y[0][i]);
	}
	HMI_snput_matrix(8, 1, K, &y);
	printf("end\n");

}
```
#### MATLAB
```matlab
clear   %清除記憶體內儲存變數
clc       %清除command window訊息
close all   %清除已開啟的作圖視窗

load datax;
load datay.mat;


k = 1:1:200;

plot(k , x, 'B-', k, data0, '.');



xlabel('Day');  
ylabel('收盤價 , EMA5');  
title('台泥1101');  
legend('收盤價','EMA5');
```
# 討論
EMA是取加權平均，算出來的值會比SMA更靈活。所選天數越小越貼近股價。由於N天的EMA前N天沒辦法算平均，因此我把前N天設為0，而由於前N天用0去算，EMA會有誤差，所以取2N天才畫EMA線。
