# 訊號與控制
###### tags: `控制組`
## Arduino UNO

---
## 常見訊號種類
### 1. Digital
#### 概述
二進位 由0、1組成 其電壓值的範圍由參考電壓決定 通常是0到5V
優點:
- 不會受到參考電壓值的改變而影響資料讀取
- 容易處理資料
#### Arduino code
```
int val = digitalRead(輸入腳位)
digitalWrite(輸出腳位, HIGH或LOW)
```

---
### 2. Analog
#### 概述
在給予的電壓範圍內的連續訊號值 8bit時 訊號值為0到255
通常感測到的訊號都為類比 如:聲波、光、壓力、位移
:::warning
Arduino的A0到A5可輸入類比訊號 但**不可輸出**
:::
#### Arduino code
```
int val = analogRead(輸入腳位)
```

---
### 3. PWM(Analog to Digital)
#### 概述
以數位的方式模擬類比值 藉由高電位佔的比例來表示連續值
#### Arduino code
```
analogWrite(輸出腳位, 輸出值)
```

:::info
### 應用實例
一般使用LED只分高低電位(Digital) 可以透過光敏電阻得知其亮度(Analog)並使用PWM訊號給予LED值 使LED可以漸暗、漸亮
#### 接線原理圖

#### Arduino code
```
const int sensorPin = A0; // 光敏電阻的pin腳
const int ledPin = 9; // LED的pin腳
int sensorValue = 0; // 光敏電阻讀取值
int sensorMin = 1023; // 預設最小值
int sensorMax = 0; // 預設最大值
void setup() {
pinMode(13, OUTPUT);
digitalWrite(13, HIGH); // 亮燈
// 取前五秒
while (millis() < 5000) {
sensorValue = analogRead(sensorPin);
// 紀錄最大值
if (sensorValue > sensorMax) {
sensorMax = sensorValue;
}
// 紀錄最小值
if (sensorValue < sensorMin) {
sensorMin = sensorValue;
}
}
digitalWrite(13, LOW);
}
void loop() {
// 光敏電阻值讀取
sensorValue = analogRead(sensorPin);
// 限制讀取值範圍 避免超出
sensorValue = constrain(sensorValue, sensorMin, sensorMax);
// 將讀取值按比例切割為8 bits
sensorValue = map(sensorValue, sensorMin, sensorMax, 0, 255);
// LED漸亮
analogWrite(ledPin, sensorValue);
}
```
:::
---
## 通訊協定
### 1. UART
#### 概述
TX負責傳送資料 RX負責接收資料為一對一的通訊
可讓兩台Arduino溝通
### 2. I^2^C
#### 概述
可以串聯多個裝置 至少一個Master一個Slave 每一個Slave都有唯一地址
一條資料線(SDA) 一條時脈線(SCL)
如:IMU、壓力計等感測器 皆使用I^2^C
:::info
常見的通訊協定也包含SPI 但我們這不常用因此不細講 有興趣的人可以自己去看
:::
---
## 自動控制 PID Control
<iframe width="1664" height="770" src="https://www.youtube.com/embed/wkfEZmsQqiA" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>