# 2023第一屆創客松營隊
### :car:循跡避障自走車
#### Step1 環境安裝
[Arduino IDE 2.0.3]a(https://www.arduino.cc/en/software)

---
#### Step2 硬體認識
##### Arduino UNO

腳位功能

##### 麵包板

##### 線材
杜邦線

##### 被動/主動元件

---
#### Step3 Blink
##### 接線
LED電阻很小->直接用導線接->電流過大->LED燒掉
:::success
如何使用電阻?
* [如何挑選 LED 用的電阻](https://www.digikey.tw/zh/blog/atm-how-to-select-a-resistor-for-an-led)
* [LED與電阻的必學之術](https://www.lazytomatolab.com/as-06/)
* [電阻器色碼計算](https://shop.mirotek.com.tw/arduino/start/a100021/)

:::
##### 接線

##### 程式
```cpp=
void setup() {
pinMode(3, OUTPUT); //設定Pin3為輸出腳位
}
void loop() {
digitalWrite(3, HIGH); //Pin3高電位(5V)
delay(1000); //延遲1秒
digitalWrite(3, LOW); //Pin3低電位(0V)
delay(1000); //延遲1秒
}
```
---
#### Step4 紅綠燈條件判斷
##### Parking Sensor
``` cpp=
// 設定腳位
int led1 = 3;
int led2 = 4;
int trigPin = 11;
int echoPin = 12;
long duration, cm;
void setup() {
Serial.begin(9600);
pinMode(led1, OUTPUT); // 設定led1為輸出腳位
pinMode(led2, OUTPUT); // 設定led2為輸出腳位
pinMode(trigPin, OUTPUT); // 設定trigPin為輸出腳位
pinMode(echoPin, INPUT); // 設定echoPin為輸出腳位
}
void loop() {
digitalWrite(trigPin, LOW);
delayMicroseconds(5);
digitalWrite(trigPin, HIGH); // trigPin發射
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
pinMode(echoPin, INPUT); // echoPin接收
duration = pulseIn(echoPin, HIGH); // 當echoPin收到訊號 設為HIGH
cm = (duration/2) / 29.1;
if(cm < 15){
digitalWrite(led1, HIGH);
digitalWrite(led2, LOW);
} else{
digitalWrite(led1, LOW);
digitalWrite(led2, HIGH);
}
delay(250);
}
```
##### 按鈕
```cpp=
const int BUTTON_PIN = 7; // 按鍵的接腳
const int LED_PIN = 3; // LED燈的接腳
int buttonState = 0; // 按鈕的狀態
void setup() {
pinMode(LED_PIN, OUTPUT); //設定LED的PIN腳為輸出
pinMode(BUTTON_PIN, INPUT); //設定按鈕的接腳為輸入,因為我們要讀取它的狀態
}
void loop() {
buttonState = digitalRead(BUTTON_PIN); //讀取按鍵的狀態
if(buttonState == LOW){ //如果按鍵按了
digitalWrite(LED_PIN, HIGH); //LED就亮了
}else{ //如果按鍵是未按下
digitalWrite(LED_PIN, LOW); //LED就不亮
}
}
```
---
#### Step5 組裝
##### 焊接馬達
1. 黑紅電子線焊上接口
2. 另一端剝出更長銅線,對折後上錫(鎖在模組電源座較不容易鬆脫)
##### 壓克力雷切 ---超音波感測器座
:::warning
雷切軟體下載
* [LaserMaker](https://www.lasermaker.com.cn/)
* [RDWorksV8](https://www.thunderlaser.tw/laser-download)
:::

##### 車體組裝
1. 鎖就對了
* 先鎖馬達
* 然後驅動模組(L9110S)

* 電池盒
* Arduino UNO
* Sensor擴充板

2. 嗯對然後接線
* 馬達接驅動板
* 電池盒接擴充版
---
#### Step6 Drivetrain Control
1. 挑選支援PWM腳位控制馬達驅動板
2. 腳位5、6控制一顆馬達;腳位 9、10 控制另一顆馬達
3. 定義腳位輸入/輸出
```cpp
pinMode(腳位, OUTPUT);
```
4. 控制腳位輸出
```cpp
analogWrite(腳位, 強度); //強度範圍(0~255)
```
##### 前進三秒完整程式
```cpp=
void setup() {
pinMode(5, OUTPUT);
pinMode(6, OUTPUT);
pinMode(9, OUTPUT);
pinMode(10, OUTPUT);
analogWrite(5, 200);
analogWrite(6, 0);
analogWrite(9, 200);
analogWrite(10, 0);
delay(3000);
analogWrite(5, 0);
analogWrite(6, 0);
analogWrite(9, 0);
analogWrite(10, 0);
}
```
:::info

* 5號腳輸出強度200/6號腳無輸出(0)時->馬達順時針旋轉
:::
---
#### Step7 循線功能
##### 循線感測器組裝&接線

**感測原理**
循線感測器是由一個紅外線發射器,與一個紅外線接收器所組成。當正常供電時紅外線發射器會不停的發射紅外線,當紅外線經過物體表面會有二種情形:
1. 絕大部份的紅外線經由表面反射
2. 絕大部份的紅外線經由表面吸收,極少部份反射。
##### 讀取循線感測器數值
1. 啟動序列埠
```cpp
Serial.begin(9600);
```
> 鮑率 9600
2. 新增A0/A1腳位,分別讀取兩個循線感測器(INPUT)
```cpp
pinMode(類比腳位, INPUT);
```
3. 讀取訊號
```cpp
byte IR_L = digitalRead(類比腳位);
```
4. 監控視窗列印
```
Serial.print(); //不換行
Serial.println(""); //換行
```
##### 實現循線方法
1. 定義同時控制四個馬達腳位的Function

狀態1 前行;狀態2 向右偏移;狀態3 向左偏移;
```cpp
//定義'motor'設定四支腳位狀態
void motor(byte LA, byte LB, byte RA, byte RB) {
analogWrite(9, LA);
analogWrite(10, LB);
analogWrite(6, RA);
analogWrite(5, RB);
}
```
```cpp
//不同狀態馬達對應控制動作
if (IR_L == 0 && IR_R == 0) {
motor(200, 0, 200, 0);
}
else if (IR_L == 1 && IR_R == 0) {
motor(200, 0, 0, 0);
}
else if (IR_L == 0 && IR_R == 1) {
motor(0, 0, 200, 0);
}
else {
}
```
---
#### Step8 避障功能
##### 超音波感測器組裝&接線


:::warning
型號:HC-SR04
測量範圍:2~450cm
:::
##### 讀取超音波感測器數值
```cpp
#include <NewPing.h> //匯入函式庫「NewPing.h」
```
1. 定義腳位
```cpp
#define TRIGGER_PIN 11
#define ECHO_PIN 12
#define MAX_DISTANCE 200
NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE);
```
2. 輸出超音波感測器數值(可跳過)
```cpp
void loop() {
delay(50);
Serial.print("Ping: ");
Serial.print(sonar.ping_cm());
Serial.println("cm");
}
```
##### 實現避障功能
當偵測距離大於 20 公分,自走車以強度 150 前進,反之則以強度 150 轉彎
```cpp
void loop() {
if (sonar.ping_cm() > 20) {
motor(150, 0, 150, 0);
}
else {
motor(0, 150, 150, 0);
}
}
```
---
#### Step9 Combine
完整程式
```cpp=
#include <NewPing.h>
#define TRIGGER_PIN 11
#define ECHO_PIN 12
#define MAX_DISTANCE 200
NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE);
void setup() {
pinMode(5, OUTPUT);
pinMode(6, OUTPUT);
pinMode(9, OUTPUT);
pinMode(10, OUTPUT);
Serial.begin(9600);
pinMode(A0, INPUT);
pinMode(A1, INPUT);
}
void loop() {
if (sonar.ping_cm() > 20) {
line_following(); //沒有遇到障礙物則循線自走
}
else {
motor(0, 0, 0, 0);
}
}
void motor(byte LA, byte LB, byte RA, byte RB) {
analogWrite(9, LA);
analogWrite(10, LB);
analogWrite(6, RA);
analogWrite(5, RB);
}
void line_following() {
byte IR_L = digitalRead(A0);
byte IR_R = digitalRead(A1);
if (IR_L == 0 && IR_R == 0) {
motor(150, 0, 150, 0);
}
else if (IR_L == 1 && IR_R == 0) {
motor(150, 0, 0, 0);
}
else if (IR_L == 0 && IR_R == 1) {
motor(0, 0, 150, 0);
}
else {
}
}
```
---
#### Step10 Try it!
---
### :robot_face: 一二三 木頭人
#### 材料準備
##### 木材

:::warning
【愛教不教】木工知識補充影片
* [木材挑選,教你怎麼分辨板材](https://youtu.be/vh9D3PdLfsk)
* [木頭組裝,教你組裝木材](https://youtu.be/JIeHDRmy99E)
* [木頭表面處理,教你做表面功夫](https://youtu.be/B5QQIJfVUFw)
:::
##### 螺絲
###### 部位名稱:

A:頸、頸下(承面) B:頭(頭部) C:螺紋部 D:螺絲尾端 E:頸下長度 F:全長 G:槽深

A:**外徑** 指外螺紋的螺紋之間的直徑,即用以表示粗細的「公稱直徑」。
B:**節圓直徑** 螺紋寬度與螺紋槽寬度相等的圓的直徑。
C:**底徑** 外螺紋/內螺紋的螺谷之間的直徑。
D:**螺紋角** 螺紋從螺峰到螺谷所開的角度。
E:**螺距** 螺紋上兩個相鄰螺峰的距離。
F:**內徑** 內螺紋的螺紋之間的直徑。
###### 材質:
鍍鋅鐵、中碳鋼、不鏽鋼、銅、尼龍、鈦、鋁、壓克力
丸頭螺絲/沉頭螺絲
一字、十字、內六腳
類型、直徑、長度
英制、公制、美規
M425
攻牙
#### 工具使用
##### 大型機具
##### 手持電動機具
##### 手工具
台灣:KING TONY/日本:KTC/德國:Wera/美國:Blue Point/瑞士:PB Swiss
##### 手作工具
:::info
:shopping_trolley: 購買管道
* 木材:[木百貨](https://woodmall.com.tw/shop/)
* 電子零件:[iCShop](https://www.icshop.com.tw/)
* 電動機具:[Makita](https://makita.com.tw/)/[Bosch](https://www.bosch-pt.com.tw/tw/zh/)/[Milwaukee](https://www.milwaukeetool.com.tw/)
:::