close

Arduino本身其實不直接提供類比輸出,也就是analog output,但可以透過PWM模式輸出,可以

作為Arduino的類比輸出。

 

先看Arduino UNO的介面圖:

Arduino UNO PWM output

 

Arduino UNO上有6個PWM控制腳可以用,PCB上有標示~的就是有PWM功能的腳位,

共有 pin 3,5,6,9,10,11 這六個腳位。

 

先前介紹風扇的文章中也介紹了PWM技術,如下圖:

pwm1.gif (601×197)

 

對PWM技術來說,很重要的參數就是佔空比(Duty cycle),Arduino可以設定為0-255,也就是8bit

深度。

而不同接腳能輸出的頻率不一樣,

pin 5,6 可以輸出976.5625Hz,也就是約1K Hz

pin 3,9,10,11則是490.196Hz,也就是約500Hz

 

Arduino PWM輸出的控制指令非常簡單:

 

analogWrite(接腳編號,類比數值);

 

接腳編號就是上述的那幾隻腳,類比數值就是上述的0-255之間。

 

PWM的電壓輸出可以用公式換算,計算公式:

 

類比輸出電壓=佔空比 * 高電位值

 

反過來算:

佔空比 = 輸出電壓 / 高電位值

 

假設要輸出3.3V類比電壓,高電位值=5V

所以是3.3/5 = 66%

因Arduino的設定是0-255,所以是255*66%=168

PWM的類比數值填168,即可讓PWM接腳輸出3.3V

以上的計算很簡單。

 

利用可變電阻控制PWM輸出

 

如上述要改變PWM的輸出很簡單也很方便計算,但不太可能

每次要調整轉速時就修改程式一次,不方便也不合理。

 

所以實務上可以透過一個可變電阻(VR),利用類比輸入腳進行偵測,

並將結果輸出到PWM腳上,這樣就能靠控制轉動VR的角度來改變風扇

的轉速輸出。

 

最近修改後的程式碼:

/*
 * 重新改寫Analog input & PMW out程式
 *  
 * VR可變電阻輸入,輸入腳為A0,PWM由Arduino UNO的pin9輸出到N MOS-FET
 * 2021.07.31 Luyaku
 * 程式名稱 analog_in_PWM_out.ino
 */
 
const byte analogPin = A0; //設定VR的中間腳位接到A0這個類比輸入腳

int PWM_Out = 9; //設定 Arduino PWM輸出腳位在 9 pin
int VR_Value; //VR經ADC讀進來的值,0到1023,10bit解析度
int PWM_Map; //透過map指令轉換為PWM0到255輸出,8bit解析度
int Percent_Map; //轉換成百分比,這是我自己想看的值


void setup() {

  Serial.begin(9600);
  pinMode(PWM_Out, OUTPUT); //定義 pinmode 為 pin 9 PWM OUTPUT 輸出
 
}

 

void loop() {

  VR_Value = analogRead(analogPin); //由A0腳讀入VR值
  PWM_Map = map(VR_Value,0,1023,00,255); //用map函數將類比值0-1023轉為0-255
  Percent_Map = map(VR_Value,0,1023,0,99); //轉換成百分比,非必要可刪除,這只是給我自己看的
  analogWrite(PWM_Out,PWM_Map); //我們設定pin 9為PWM輸出,輸出值為map轉換後的值

  Serial.println(PWM_Map);
  Serial.println(Percent_Map);
  Serial.println(VR_Value);
  Serial.print(VR_Value*0.0048828125);
  Serial.println("V""\n");

//將相關讀值從序列埠上輸出,最後兩行是將讀值轉為電壓值

//以上都是為了深入了解及學習轉換過程才輸出這麼多,真正使用時其實可以都拿掉

  delay(100); //延遲100mS,也就是每秒讀取10次 //原先設定為1000mS,也就是一秒一次,但反應速度較慢,改快一點

}

此程式預設是PWM接腳輸出為pin9,VR接到A0輸入,

因類比輸入解析度有0-1023段,但PWM輸出只有0-255,

所以中間需要mapping一下,我有特別標示出來。

 

map指令比之前用算式計算好用很多,舊版我是這樣計算的:

 int fan_speed = pot * (255 / 1023.0); //這個公式將會計算風扇速度的pwm輸出介於 0-255

但這有個缺點就是很死硬,而用map可以指定轉換範圍,例如從0到1023轉換為50到255,

這樣最低輸出就是50而不是0。

這樣跟原本用公式算有什麼差別?

差別在於如果你不想要風扇或是負載進入死區,也就是不工作區,

例如風扇的啟動電壓在XXV,就可以自己將值算好代入,這樣PWM輸出就不會讓風扇或負載進入不運轉狀態。

com port輸出如下圖:

2021-08-01

 

輸出數值會隨著VR轉動角度不同而改變,最高為255最低為0,而這範圍可以由map指令來選定轉換範圍。

 

 

arrow
arrow
    全站熱搜

    呂阿谷 發表在 痞客邦 留言(0) 人氣()