---
# System prepended metadata

title: 韌體
tags: [NTU Master Thesis]

---

###### tags: `NTU Master Thesis`

# 韌體
韌體寫在 VMSM 上面的兩套電路上，這兩套電路分別為 AVR ATTiny13a 喚醒電路和 Arduino Pro Mini 通訊電路。AVR ATTiny13a 作為外部的 Timer，會定期開啟 Arduino Pro Mini，使其傳送訊息到 I2PDM 系統上。韌體的程式語言為 C/C++
<br>
![](https://i.imgur.com/X7UZnQo.png)

另外
* 若要**更改資料傳送頻率**，要於 AVR ATTiny13a 上更改 ***closeTime8xSecond*** 的數值
* 若要**在 VMSM 上接別的感測器**，需更動 Arduino Pro Mini 的程式碼。目前 VMSM 能支持 ModBus RTU、SDI12、類比電壓 (0~1024) 、數位電壓 (0、1) 等四種通訊方法

## 套件和軟體版本
### ATTiny13 
ATTiny13 使用 AVR 的原生套件，因此不需額外添增

### Arduino 
Arduino 則使用到三個外部套件，如下所示 (版本號應不影響，依你到時使用的板號即可)：
* AltSoftSerial
* RTClib
* SdFat

## AVR ATTiny13a 的程式 
在 AVR ATTiny13a 喚醒電路中有將之進入睡眠模式，以達到節電的作用。睡眠主要是透過 watch dog 喚醒的。以下程式碼是設定 watch dog 中的 WDTCR register，詳細的設置方法可以看 AVR ATTiny13a 的文件，裡面有說明 WDE、WDTIE、WDCE、WDP3...的功能是什麼
```C
// WDT setting
WDTCR = 0;
WDTCR |= (0 << WDE)  | (1 << WDTIE) | (1 << WDCE) |
	 (1 << WDP3) | (0 << WDP2)  | (0 << WDP1) | (1 << WDP0);
```

另外，以下程式碼則是讓 AVR ATTiny13a 進入睡眠的關鍵。在最下方的 main() 中的一個 loop 呼叫 go_sleep() 函數，ATTiny13a 便會進入睡眠。接著，如果在 8 秒內沒有喂 watch dog (也就是使用 wdt_reset() 重設 watch dog timer)，即會觸發 ISR，也就是下方中間部分的程式碼。此時，ISR 程式會喂 watch dog。接著，由於 go_sleep() 會被執行 closeTime_8x_Second 次，因此 ATTiny13a 又會再跑一次 go_sleep()，進到下一個 8 秒的睡眠。總地來說，若要設定 Arduino 被開啟的頻率，就要更改 closeTime_8x_Second 的值。closeTime_8x_Second 的值越大，ATTiny13a 就會睡越久

```C
// Sleep Function
void go_sleep()
{
    set_sleep_mode(SLEEP_MODE_PWR_DOWN);
    power_all_disable();
    sleep_bod_disable();
    sleep_enable();
    sleep_cpu();
}

// WDT ISR
ISR (WDT_vect)
{
    wdt_reset();
}

// In main() function
for (int i = 0 ; i < closeTime_8x_Second ; i++)
    go_sleep();
```

## Arduino 的程式
若要添增感測器，需要更改 data 陣列的大小和 getData_andSend 的內容。其中，比較值得注意的是，呼叫 BTSerial.write 的 data 一定要是 byte 形式的陣列，否則傳送時會出錯。並且，BLE 一次傳送的 bytes 數量是有限制的，必須小於等於 20 筆

```C/C++
void getData_andSend()
{
  // Data : MQ4
  int d1 = analogRead(MQ4);
  
  data[0] = highByte(d1);
  data[1] = lowByte(d1);
  
  Serial.print("MQ4 : ");
  Serial.println(d1);
  
  // Send
  BTSerial.write(data, sizeof(data)); // Send data to Rpi HC-08 Module
}
```

## 燒錄方法
### 在 AVR ATTiny13a 上的燒錄方法
利用 Microchip Studio for AVR 撰寫程式，將 Arduino 作為 Programmer，以 AVRDUDESS 把程式燒錄進 ATTiny13a 中。詳細的燒錄方法請見台大生機郭彥甫教授在YouTube的教學影片，[微控制器教學 -- 05AVR嵌入式C語言 -- 輸出與輸入](https://www.youtube.com/watch?v=JWqGJcmo4to&t=4419s)

### 在 Arduino Pro Mini 上的燒錄方法
利用 USB to TTL 和 Arduino IDE，將程式燒錄進 Arduino Pro Mini 中。詳細燒錄方法請看，[Arduino | Arduino pro mini 燒錄方式](https://hugheschung.blogspot.com/2018/05/arduino-pro-mini.html)
