單晶片lab6結報

tags: arduino
實驗日期 : 2021/10/28

上課教材

lab1

SPEC

當距離越近,duty cycle越高。

  • 使用PWM,數位訊號高頻率的切換來模擬類比訊號
  • 使用超音波模組測距離
  • 使用示波器測量duty cycle
  • I2C LCD顯示距離

實現方法

Arduino官方doc

analogWrite(pin, value)
parameter function data type
pin the Arduino pin to write to int
value the duty cycle: between 0 (always off) and 255 (always on) int

cm = (duration / 2) / 29.1;
duty_cycle = 255 - (255 / 20) * cm;

將時間換算成距離,再mapping到

x[0,1,2,......,255] 的整數空間(analogWrite參數只接受整數的資料型態),例如最小值0對應是255,最大值20對應是0

lab2

SPEC

利用2個超聲波模組測方位,當物體在50公分內,將測得方位(前、左、右、太近)顯示於LCD上。

實現方法

lab4實現方法的子集合,由於組裝超音波模組位置擺放不同,加上左右接收與發射端不對稱,因此藉由trial and error,不斷嘗試找到合適參數。

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →
最終找到合適的條件如下 :

if (cm_right < 20 && cm_left < 20) {
    Serial.println("too close");
} else if (cm_right > (cm_left + 30) && cm_left < 50) {
    Serial.println("right");
} else if (cm_left > (cm_right + 10) && cm_right < 50) {
    Serial.println("left");
} else if ((cm_left < 100 || cm_right < 100) && abs(cm_right - cm_left) <= 10) {
    Serial.println("straight");
} else {
    Serial.println("non of objected detected");
}

lab3

SPEC

利用L298N各別控制左右2個馬達完成正轉、反轉、停止功能。

序列視窗輸入 車子
w 前進
a 左轉
d 右轉
s 後退
q 停止

實現方法

lab4實現方法的子集合,序列視窗輸入功能為個人加入的SPEC,方便控制與測試。

  • L298N控制訊號(ENA, ENB可用PWM來改變馬達轉速)
DC moter 轉向 IN1 IN2 ENA(PWM) IN3 IN4 ENB(PWM)
M1 正轉 H L H - - -
M1 反轉 L H H - - -
M1 停止 L L H - - -
M2 正轉 - - - H L H
M2 反轉 - - - L H H
M2 停止 - - - L L H

舉例來說 : 若要讓車子向前,要使兩端馬達正轉,並給定合適的轉速PWM寫入。

// 決定轉動方向
digitalWrite(LEFT1, HIGH);
digitalWrite(LEFT2, LOW);
digitalWrite(RIGHT1, HIGH);
digitalWrite(RIGHT2, LOW);
// 向馬達輸出指定的類比電壓值
motor_speed = 150;
analogWrite(LEFT_PWM, motor_speed);
analogWrite(RIGHT_PWM, motor_speed + 30);
// 實際上給定PWM,2端輪子轉速不一致,因此需要有offset = 30的誤差修正

lab4

SPEC

利用2個超音波模組、L298N控制2個馬達轉動,實作跟隨自走車

跟隨物位置 自走車反應
太靠近時 後退
在右 右轉
在左 左轉
前方一定範圍 向前
沒有物件 停止

實現方法

lab2實現方法2個超音波模組測距離與方位、如la3實現方法L298N控制2個馬達轉動。另外遇到的問題是左右轉彎時轉動幅度過大,解決方法是內輪改為不轉,外輪維持正轉,但轉速降低,也就是PWM從150降為100

lab5

SPEC

利用藍牙模組HC-05,結合lab4跟隨自走車,實作遙控車

序列視窗輸入 車子
w, f 前進
a, l 左轉
d, r 右轉
s, b 後退
q 停止

藍芽燈號判讀

燈號 功能
2秒閃爍一次 進入AT模式,準備設定
連續快閃 等待配對中
快閃2下後停2秒 已配對成功,運作中

藍芽的AT mode(key接5V)

command 序列埠回應 功能
AT OK 確認藍芽與序列埠溝通正常
AT+UART? +UART:XXXXX,0,0 得知目前Baud rate設定
AT+ADDR? +ADDR:98d3:b1:fd6ece 查詢address
AT+VERSION 版本資訊 查看韌體版本
AT + NAME=XXXX OK 設定藍芽名稱
AT + PSWD=XXXX OK 設定密碼
AT + UART=38400,0,0 (鮑率, 停止位元, 同位位元) OK 設定鮑率/停止位元0->1 bit、1->2 bits/0->無、1->odd parity、2->even parity
AT+ROLE=1 / 0 OK 設定模式主動/被動
AT+BIND=XXXXXXXX OK 綁定藍芽位置
AT+CMODE=0 OK 指定藍芽位置連接模式
AT+RESET OK 重啟藍牙
AT+ORGL OK 回復預設值

藍芽配對

lab3 lab2-1與lab2-2實現方法,我們當初實作是錯誤的,直到這次lab才搞懂。

參照這部影片進行改進,藍芽配對如以下步驟 :

  • 進入AT mode
    1. key接5V(高電位)
    2. Serial Monitor鮑率選9600
    3. 換行規則選NL&CR
    4. 輸入AT指令第一次會出現ERROR:(0),第二次輸入AT出現 OK
  • slave的HC-05
    1. 所有AT參數恢復為原廠設定
    ​​​​AT+ORGL
    
    1. 設定藍芽傳輸速率(Baud)
    ​​​​AT+UART=38400
    
    1. 設定角色為從端
    ​​​​AT+ROLE=0
    
    1. 取得從端地址,並記住
    ​​​​AT+ADDR?
    
  • master的HC-05
    1. 所有AT參數恢復為原廠設定
    ​​​​AT+ORGL
    
    1. 設定藍芽傳輸速率(Baud)
    ​​​​AT+UART=38400
    
    1. 設定角色為主端
    ​​​​AT+ROLE=1
    
    1. 連接模式 : 指定藍芽位置
    ​​​​AT+CMODE=0
    
    1. 設定要連線的slave地址,須將前面獲得從端地址的逗號:改為冒號,
    ​​​​AT+BIND=0021,13,00AD4E
    

實現方法

關鍵在於2個藍芽之間的配對,這部分其實是lab3 lab2的實驗內容,但因為當初搞錯題目也沒有實作出來。參照網路教學How To Configure and Pair Two HC-05 Bluetooth Module as Master and Slave | AT Commands,在進入AT mode一開始,還需額外輸入AT+ORGL指令,意思是將所有AT參數恢復為原廠設定,以免這次未設定的參數被前一次所設定的參數所影響。

  • 需要注意軟接口有參建構函數,以下範例第1個參數是10是藍芽TX,對應是Arduino的RX;第2個參數11是藍芽RX,對應是Arduino的TX
// 定義連接藍牙模組的序列埠
SoftwareSerial BT(10, 11);

課後習題

Question 1

詳述雙超聲波模組感測方位原理。

Answer 1

lab2實現方法的圖示,至於確切的邊界條件,需不斷嘗試,最終得出合理判斷。

Question 2

詳述Arduino是如何產生PWM訊號(Hint : 與內部Timer有關)。

Answer 2

當然可以在不使用內建函式analogWrite(pin, dutyCycle),而透過"手動"數位反覆開關來產生PWM訊號。

digitalWrite(13, HIGH);
delayMicroseconds(100); // Approximately 10% duty cycle @ 1KHz
digitalWrite(13, LOW);
delayMicroseconds(1000 - 100);

優點是所有數位輸出腳位都可以使用,還可以控制duty cycle與頻率,但這會造成當MCU在執行其他程序時,PWM輸出無法繼續運行,因此我們必須借助ATmega168P(Arduino Uno的MCU)內的3個Timer來控制6個PWM輸出


每個Timer都有2個output compare register,決定輸出PWM寬度 - 當定時器達到output compare register值時,相應的輸出被toggle。

Timer一開始需要有個prescaler須要把系統的CLK(16MHz)除頻獲得較低的頻率。Timer還有不同模式,主要有Fast PWM"和"Phase-correct PWM,可以運行在0到255或是0到某一固定值。

這些Timer由register控制,如下表。

register 簡寫 用途
Timer Counter Control Register A TCCRnA 決定Timer的運作模式
Timer Counter Control Register B TCCRnB 決定Timer的prescale value
Timer Counter Register TCNTn 儲存Timer目前的累積計數(計數器)
Output Compare Register A OCRnA 當TCNTn累積計數到OCRnA的計數時,觸發中斷
Output Compare Register B OCRnB 當TCNTn累積計數到OCRnB的計數時,觸發中斷
Timer Counter Interrupt Mask Register TIMSKn 開啟/結束中斷
  • Fast PWM
    Timer會從0到255重複計數,當Timer值達到output compare register值會關閉輸出,而當Timer值是0時會開啟輸出。
  • Phase-correct PWM
    Timer會從0到255計數,然後返回到0。當Timer值在上升途中達到output compare register值會關閉輸出,而當Timer下降時又會開啟輸出。
  • ref 1 : Secrets of Arduino PWM
  • ref 2 : analogWrite怎麼做PWM輸出?改PWM頻率,定时器相關

Question 3

舉例PWM在電機領域的3個應用。

Answer 3

  1. LED呼吸燈
    一般人眼睛對於80Hz以上刷新頻率則完全沒有閃爍感,那麽我們平時見到的LED燈,當它的頻率大於50Hz的時候,人眼就會產生視覺暫留效果,基本就看不到閃爍了,而是誤以為是一個常亮的LED燈。

    由於頻率很高時看不到閃爍,占空比越大LED越亮,占空比越小LED越暗。所以,在頻率一定時,可以用不同占空比改變LED燈的亮度,使其達到一個呼吸燈的效果。 PWM對電機轉速的控制

  2. PWM對電機轉速的控制
    調節占空比可以實現不同電壓的輸出,實現對電機轉速的調節

    對於直流電機來講,電機輸出端引腳是高電平電機就可以轉動,當輸出端高電平時,電機會轉動,但是是一點一點的提速,在高電平突然轉向低電平時,電機由於電感有防止電流突變的作用是不會停止的,會保持這原有的轉速,以此往覆,電機的轉速就是周期內輸出的平均電壓值,所以實質上我們調速是將電機處於一種,似停非停,似全速轉動又非全速轉動的狀態,那麽在一個周期的平均速度就是我們占空比調出來的速度了。

    在電機控制中,電壓越大,電機轉速越快,而通過PWM輸出不同的模擬電壓,便可以使電機達到不同的輸出轉速。

    當然在電機控制中,不同的電機都有其適應的頻率 頻率太低會導致運動不穩定,如果頻率剛好在人耳聽覺範圍,有時還會聽到呼嘯聲。頻率太高時,電機可能反應不過來,正常的電機頻率在6-16kHZ之間為好。

  3. PWM對舵機的控制
    舵機的控制就是通過一個固定的頻率,給其不同的占空比來控制舵機不同的轉角

    舵機的頻率一般為頻率為50Hz,也就是一個20ms左右的時基脈衝,而脈衝的高電平部分一般為0.5ms-2.5ms範圍,來控制舵機不同的轉角。500-2500us的PWM高電平部分對應控制180度舵機的0-180度。

    下圖演示占空比從1ms變化到2ms時,轉角的變化。

心得

劉永勝

這次實驗利用PWM輸出,改變

Vrms,使馬達的轉速不同。不像是之前由類比輸出馬達,轉速只能藉由激磁速度調整。這次是增加電壓,使馬達額定轉速上升。兩個可正反的轉馬達,即可始自走車前進、後退、左轉、右轉。

超音波測距,若只有一個模組,則量測距離只能是直線。如同人眼一般,需要兩個超音波模組,才可以360度的測量。可能會因為模組擺放位置不對稱,須調整函數的判斷式。

藍芽配對操控自走車,在之前lab就已經進行過藍芽配對,但最近才發現那時的配對並沒有成功,輸出的值並非從藍芽模組發送。在配對時,先將藍芽模組還原原廠,確保內部參數重製,在從AT模式設定主從即可完成配對。

李宇洋

此次實驗麻煩的點有組裝車體、2個超音波模組互相測得數據如何校正出合理的範圍,大部分時間都花在調整超音波模組的位置等參數。還有馬達模組的控制,因為左右馬達轉速不同、地面磨擦係數、凹凸不平,我們需要調整一些參數才讓車子能正常行駛。

因為所需接線較多,必須要花很多時間確認哪條線要接到哪裡,以及線會在車子行進時脫落,因此還需重新接線,下次若遇到相同狀況需先整線,實作效率才會高。

陳旭祺

這次實驗我了解PWM訊號,利用數位訊號高頻率的切換,調整開關的比例,以模擬類比訊號,因此以下程式對編譯器來說是兩兩是等價的。

analogWrite(pin, 0);
digitalWrite(pin, 0);
analogWrite(pin, 255);
digitalWrite(pin, 1);

應用是這顆控制馬達ICL298NENA、ENB腳位,藉由0-255的數值去控制馬達轉速。也了解實際上PWM是由借助ATmega168P(Arduino Uno的MCU)內的3個Timer來控制6個PWM輸出。


實作方面是卡在lab4和lab5,其中lab4是跟隨自走車,結合lab2超音波距離輸入與lab3的馬達轉速輸出,lab5是藍芽遙控車,遇到問題如下 :

問題 解決方法
自走車的接線不斷脫落 用泡棉膠、紙膠帶固定電路在車子上。
左右輪就算施加相同力,自走車還是不會直走 推測原因是測試時地板不平、兩端車輪與馬達無法精準卡住,因此須反覆測試兩輪之間的offset數值,用軟體給予不同轉速,解決硬體的誤差。
兩個藍芽配對照教學還是做不出來 沒先還原所有設定為原廠AT+ORGL,以免這次未設定的參數被前一次所設定的參數所影響。