---
# System prepended metadata

title: 76th305工程專題實作紀錄

---

# 工程專題：遙控車製作



## 2/23上課討論—獲取資訊：從老師獲得的建議與參考
- 車載平台：
    - 自製平台
    - 老師好棒(生科教室提供雷切木板、3D列印)
- 馬達和輪子：
    - 直流馬達：
        - 大顆的：520金屬直流減速馬達(400元)
        - 小顆的：N20直流馬達(150元)
- 輪子：
    - Pololu Wheels
    - Elegoo Smart Robot Car Wheel
- 馬達驅動板：
    - L298N雙H橋馬達驅動板
    - TB6612FNG雙H橋馬達驅動板
    - Adafruit Motor Shield
- 電源供應：
    - 18650鋰電池
- AA或AAA電池盒
- 電池座


- 感測器：
    - HC-SR04超聲波感測器
    - TCRT5000紅外線感測器
    - Raspberry Pi攝像頭模塊
- 機械結構和連接件：
    - 螺絲、螺母、螺栓等連接件（視需要而定）
    - 鉗子、剪刀等基本工具
- tips 前輪驅動較佳，輪子建議去模型店買

## 2/27線上討論—決定走向

## 閱讀資料

[1: 遙控車a](https://www.youtube.com/watch?v=PHdtGIrSu4o)
[2: 遙控車b](https://www.youtube.com/watch?v=sz_R9VOnnPk) <--- 暫定採用
[3: 遙控車b-轉向架](https://www.youtube.com/watch?v=i6aAgBIqS2c)

## 採買清單

- 電池
- 電池盒
- 滑輪
- 金屬軸
- 橡膠皮金
- 輪胎
- ...


# 2/28採買零件@光華資訊商圈
![121943](https://hackmd.io/_uploads/SJr3gj62a.jpg)
> *鉛線是在小北百貨購買的


## 2/29 

### 主板初設置

第一步首先是安裝Arduino IDE。
安裝完畢準備連接ESP32時，卻發現`Tools/port`欄位是灰色的 (greyed out)，在[Arduino官網的某討論串](https://forum.arduino.cc/t/port-grayed-out-under-tools-port/408689/7)查到這可能是因為裝置未成功連接到電腦，於是便嘗試更新ESP32驅動程式。在[這個網站](https://meshtastic.org/docs/getting-started/serial-drivers/esp32/)找到適當的韌體，並成功在`裝置管理員`更新好，port於是就成功顯示`COM3`的連接了。

### 測試：七段顯示器連接
![esp32-TM1637](https://hackmd.io/_uploads/H1Sqzoa26.png)

[七段顯示器軟體庫 - TM1637](https://github.com/avishorp/TM1637)
[教學 - ESP32 AND TM1637 7 SEGMENT DISPLAY EXAMPLE](https://www.esp32learning.com/code/esp32-and-tm1637-7-segment-display-example.php)


### 馬達
使用的馬達驅動: L9110S驅動板
![L9110S](https://hackmd.io/_uploads/HJlzgq0-R.jpg)
[參考教學](https://www.google.com/amp/s/blog.jmaker.com.tw/l9110s/amp/)

[範例](https://randomnerdtutorials.com/esp32-dc-motor-l298n-motor-driver-control-speed-direction/)
```c
/*********
  Rui Santos
  Complete project details at https://RandomNerdTutorials.com/esp32-dc-motor-l298n-motor-driver-control-speed-direction/
*********/

// Motor A
int motor1Pin1 = 27; 
int motor1Pin2 = 26; 
int enable1Pin = 14; 

// Setting PWM properties
const int freq = 30000;
const int pwmChannel = 0;
const int resolution = 8;
int dutyCycle = 200;

void setup() {
  // sets the pins as outputs:
  pinMode(motor1Pin1, OUTPUT);
  pinMode(motor1Pin2, OUTPUT);
  pinMode(enable1Pin, OUTPUT);
  
  // configure LED PWM functionalitites
  ledcSetup(pwmChannel, freq, resolution);
  
  // attach the channel to the GPIO to be controlled
  ledcAttachPin(enable1Pin, pwmChannel);

  Serial.begin(115200);

  // testing
  Serial.print("Testing DC Motor...");
}

void loop() {
  // Move the DC motor forward at maximum speed
  Serial.println("Moving Forward");
  digitalWrite(motor1Pin1, LOW);
  digitalWrite(motor1Pin2, HIGH); 
  delay(2000);

  // Stop the DC motor
  Serial.println("Motor stopped");
  digitalWrite(motor1Pin1, LOW);
  digitalWrite(motor1Pin2, LOW);
  delay(1000);

  // Move DC motor backwards at maximum speed
  Serial.println("Moving Backwards");
  digitalWrite(motor1Pin1, HIGH);
  digitalWrite(motor1Pin2, LOW); 
  delay(2000);

  // Stop the DC motor
  Serial.println("Motor stopped");
  digitalWrite(motor1Pin1, LOW);
  digitalWrite(motor1Pin2, LOW);
  delay(1000);

  // Move DC motor forward with increasing speed
  digitalWrite(motor1Pin1, HIGH);
  digitalWrite(motor1Pin2, LOW);
  while (dutyCycle <= 255){
    ledcWrite(pwmChannel, dutyCycle);   
    Serial.print("Forward with duty cycle: ");
    Serial.println(dutyCycle);
    dutyCycle = dutyCycle + 5;
    delay(500);
  }
  dutyCycle = 200;
}
```



### 軟體：手機端遙控
[教學 - Remotely Controlling ESP32 Using an Android App](https://www.instructables.com/Easy-IOT-Remotely-Controlling-ESP32-Using-an-Andro-1/)
[連結](https://youyouyou.pixnet.net/blog/post/119687001-esp32-%E9%A1%9E%E6%AF%94pwm%E8%BC%B8%E5%87%BA)


### 藍芽控制：ESP32
[官網根目錄文件](https://docs.espressif.com/projects/esp-idf/en/stable/esp32/api-reference/bluetooth/index.html)

[ESP32藍芽簡介](https://simon1500.pixnet.net/blog/post/28678360-esp32-%E8%97%8D%E8%8A%BD)


## 3/7

### 電子部份: 藍芽操控
- 花了一些時間尋找出了適合的app
    - 採用: Android "Arduino BlueControl"

## 3/21

### 將車體板子切好

使用Fusion360來繪製車體造型，板子的形狀也是模仿2/27的遙控車b。
(學校電腦好卡！)


## 3/28: 放棄原計畫
今天買來了智慧小車常用的便宜黃色馬達，一邊裝一個，並且重新設定程式，改為左右輪驅動。

### 燒錄程式
```c
//version final
#include <BluetoothSerial.h> 
BluetoothSerial SerialBT; 

#define LEFT 4
#define RIGHT 3

#define A_1A 5
#define A_1B 18
#define B_1A 19
#define B_1B 21

void setMotor(int a_1a, int a_1b, int b_1a, int b_1b) {
  digitalWrite(A_1A, a_1a);
  digitalWrite(A_1B, a_1b);
  digitalWrite(B_1A, b_1a);
  digitalWrite(B_1B, b_1b);
}

void setup() {
  pinMode(A_1A, OUTPUT);
  pinMode(A_1B, OUTPUT);
  pinMode(B_1A, OUTPUT);
  pinMode(B_1B, OUTPUT);
  Serial.begin(115200);
  SerialBT.begin("ESP32_BT"); //藍牙顯示名稱，可自行更改，需避免與他人重複命名
}

int count = 0;

void loop() {
  if (Serial.available()) { //send
    SerialBT.write(Serial.read());
  }
  int left = 0;
  int right = 0;
  int front = 0;
  int back = 0;

  if (SerialBT.available()) { //receive 
    while (SerialBT.available()) {
      int val = SerialBT.read();
      switch (val) {
        case 49:
          front++;
          break;
        case 50:
          back++;
          break;
        case 51:
          right++;
          break;
        case 52:
          left++;
          break;
        default:
          Serial.print(val);
          break;
      }
    }
    Serial.print("(");
    Serial.print("F:");
    Serial.print(front);
    Serial.print("B:");
    Serial.print(back);
    Serial.print(";");
    Serial.print("R:");
    Serial.print(right);
    Serial.print("L:");
    Serial.print(left);
    Serial.print(")");

    if (front > 3) setMotor(1,0,1,0);
    else if (back > 3) setMotor(0,1,0,1);
    else if (left > 3) setMotor(1,0,0,0);
    else if (right > 3) setMotor(0,0,1,0);
    else setMotor(0,0,0,0);
  }      
  else {
    Serial.print("None");
    setMotor(0,0,0,0);
  }

  count++;
  if (count == 15) {
    count = 0;
    Serial.println();
  }
  delay(200);
}
```

## 4/18: 遙控車就緒！

### 組裝
![1714489361307](https://hackmd.io/_uploads/SJoxy5C-R.jpg)
![1714489361301](https://hackmd.io/_uploads/Hkix150bR.jpg)
![1714489361284](https://hackmd.io/_uploads/rynly90bR.jpg)
- 我們在前輪的地方安裝了萬向輪，讓車子可以跑得更順，不用用木板拖地
![Uploading file..._k99phjqen]()



## 4/29: 校園繞行巡禮
### 留影
Youtube 縮時影片：[---->影片連結<----](https://youtube.com/shorts/lXfn2pcu9EU?si=InjD3xsu_Stbe4Hs)
＊因為本組錄了縮時，因此附上錄影開始、結束時間，以作證據：![IMG_20240430_233415](https://hackmd.io/_uploads/ryCD-qCb0.jpg)


### 精選照片
![1714489488590](https://hackmd.io/_uploads/rJlACK0ZR.jpg)
![1714489488584](https://hackmd.io/_uploads/rygAAF0WR.jpg)
![1714489488578](https://hackmd.io/_uploads/S1b0CtCZC.jpg)
![1714489488572](https://hackmd.io/_uploads/Hy-A0Y0b0.jpg)



# 期末回顧

（紀錄： 組員 楊銘煌）

## 成品的檢討
- 跑得很慢
    - 最後倉促裝上了便宜的黃色馬達，轉速太低
    - 解決方案：買更好的馬達搭配可配速的馬達驅動
- 遙控的使用體驗稍差
    - 選用的遙控APP按鍵無法長按連續發訊，只能用陀螺儀感測，在操控上稍微有點不便
    - 解決方案一：尋找更適合的APP（不一定能找到）
    - 解決方案二：研究ESP32的藍芽機能，並用JS＋網頁頁面自行實作遙控機能（比較費力）
- 前輪的滾珠很快就卡住而沒有作用
    - 小滾珠其實不適合在柏油路上跑（對於小車而言，一般路面已經算是越野了）
    - 解決方案：因為期末作業的要求是跑校園一圈，而其中的路線只有四個直角彎道，因此可以直接前輪也接上兩顆輪子
## 如果能夠重來...
- 在車子的功能性完全實現之前，目標不應該包含任何美觀的要求（即MVP，最簡可行產品）
    - 在本學期的實作中，本組花了許多時間研究遙控車車架的製作，包含板子的形狀，軟體的使用等，因而花費了很多時間
    - 在切板子時，應該只需要一個簡單形狀就好，甚至可以用鋸子切）避免軟體操作上的諸多不便）
- 在初期規劃中，內容應當愈清楚愈好，最好是每一個細節都講求毫無闕漏
    - 本組在一開始曾經一度決議要採用一個較為複雜的方案（後輪驅動＋轉向架），並參考了網路上的全程教學影片，但是卻沒有確保教學中的每一種材料都能備好——正好相反，實際上我們能準備的與片中需要的大相逕庭，導致車體製作進度不斷延宕，直至最後完全放棄還原片中成品，得出與所設目標相差甚遠的結果，殘酷地說，這在專案規劃的角度而言很失敗。
    - 我們一開始似乎都對自身的設計能力不太有信心，（加上筆者當初堅持要做出轉向架，）因此才決定完全複製現成的方案。但就結果看來，也許我們應該畫出一份完全出自己手的設計圖，反而會進行得更順利。
## 如果能夠重來... （組員楊銘煌筆者角度）
- 我有很長的時間都糾結在「目標要有挑戰性」的迷思，當組員都提出要不要把目標簡化為左右輪傳動時，我卻一直一意孤行，堅持要保持原計畫，卻沒有在做車體的工作上做相應的付出，也許這才是結果不如預期的原因。
- 在最後妥協於迫近的死線時，我在參與實作改變後的計畫時，發覺其仍然帶給我許多收穫與成就感，也冒出許多改進的點子，這些都是在原目標撲朔迷離時無法發生的事。
- 如果能夠重來一次，我會和組員原先的意見一致，付出最小的努力與經費做出最簡單的車，然後再根據所得經驗**迭代**出下一個更好的產品。
## 未來展望/延伸
- 紅外線避障
- 結合深度學習與視訊鏡頭，實作自動駕駛
- 在WiFi連線下在主板上架設伺服器，在手機、電腦上實作客戶端，實現區域網內遠端遙控