我的ESP32實做書籍:https://youyouyou.pixnet.net/blog/post/121105860
博客來網址:https://www.books.com.tw/products/0010901195


ESP32什麼都好,但是PWM是一個問題,傳統UNO可以用analogWrite簡單的實現類比輸出,像是讓LED慢慢亮起,或者發出不同頻率的蜂鳴器等,但是ESP32沒有analogWrite的功能。

一開始我幾乎沒用到PWM所以也沒差,後來有學生問如何用RGB LED才發現我不會,google一下才發現原來是用LEDchannel參閱:「 https://randomnerdtutorials.com/esp32-pwm-arduino-ide/ 」,依據規格書ESP32合計有16個LEDchannel,只是我沒用過這麼多,曾經測試一顆RGB LED用了三個LEDchannel沒問題,就沒測試更多的時候會不會運作。

程式的部份主要分成三個:1.設定頻道LEDchannel、2.附加到PIN腳、3.決定輸出大小。

1.設定頻道LEDchannel屬性

ledcSetup(LEDChannel, freq, resolution);
//LEDChannel設定為0-15(自己猜的),不同輸出要設定到不同頻道,例如RGB LED就要開三個頻道分別管理R、G、B
//freq輸出頻率,建議值5000 Hz
//resolution代表輸出解析度,例如8代表0-255,10代表0-1023

2.附加到PIN腳

ledcAttachPin(ledPin, LEDChannel);
//ledPin代表腳位,看你把設備接在哪個腳位上面
//LEDchannel代表步驟1所宣告的LEDchannel,也就是說把設定好的LEDchannel屬性附加到某個腳位上

3.決定輸出大小。

ledcWrite(LEDChannel, dutyCycle);
//將LEDchannel輸出dutyCycle的值。

以下範例程式將使接在Pin16的LED逐漸亮起並熄滅,本範例複製於 https://randomnerdtutorials.com/esp32-pwm-arduino-ide/


// the number of the LED pin
const int ledPin = 16;  // 16 corresponds to GPIO16

// setting PWM properties
const int freq = 5000;
const int ledChannel = 0;
const int resolution = 8;
 
void setup(){
  //宣告ledChannel特性
  ledcSetup(ledChannel, freq, resolution);
  
  //將上述ledChannel附加到ledPin腳位上
  ledcAttachPin(ledPin, ledChannel);
}
 
void loop(){
  // 逐漸增加亮度
  for(int dutyCycle = 0; dutyCycle <= 255; dutyCycle++){   
    // changing the LED brightness with PWM
    ledcWrite(ledChannel, dutyCycle);
    delay(15);
  }

  // 逐漸減低亮度
  for(int dutyCycle = 255; dutyCycle >= 0; dutyCycle--){
    // changing the LED brightness with PWM
    ledcWrite(ledChannel, dutyCycle); 
    delay(15);
  }
}


另外一個案例將使用L9110 Fan Motor,這個雖然比DC小馬達貴一點,但是可以用PWM控制轉速,也不會像DC馬達一起動吃掉電流,導致當機。

接線的部份如下圖,將INB、INA分別接在GPIO16及GPIO4上,INB與INA代表正反轉,其輸出與結果如下表

數位輸出時結果

INA INB 結果
HIGH LOW 正轉
LOW HIGH 反轉
LOW LOW 停止
HIGH HIGH 停止

類比輸出要注意的地方則是,由於電壓太低通常無法啟動,所以先把output加到255,再從80逐漸上升。

INA INB 結果
80~255 LOW 慢慢增加正轉
LOW 80~255 慢慢增加反轉


int INA = 16; 
int INB = 4;

void setup() 

  Serial.begin(9600);
  pinMode(INA,OUTPUT); 
  pinMode(INB,OUTPUT); 
  //digital output test
  Serial.println("INA=LOW,INB=HIGH");
  digitalWrite(INA,LOW);
  digitalWrite(INB,HIGH); 
  delay(3000); 
  Serial.println("INA=HIGH,INB=LOW");
  digitalWrite(INA,HIGH);
  digitalWrite(INB,LOW); 
  delay(3000); 
  Serial.println("INA=LOW,INB=LOW");
  digitalWrite(INA,LOW);
  digitalWrite(INB,LOW); 
  delay(3000); 
  Serial.println("INA=HIGH,INB=HIGH");
  digitalWrite(INA,HIGH);
  digitalWrite(INB,HIGH); 
  delay(3000); 
  //analog output(PWM) test  
  ledcSetup(0, 5000, 8);
  ledcSetup(1, 5000, 8);
  ledcAttachPin(INA, 0);
  ledcAttachPin(INB, 1);  
  //prepare forward
  Serial.println("INA=i++,INB=LOW");
  ledcWrite(1, 0);
  ledcWrite(0, 255);//避免電流太低無法啟動
  delay(300);

  for (int i=80;i<=255;i++)
  {
    ledcWrite(0, i);
    ledcWrite(1, 0);
    Serial.println(i);
    delay(100);
  }
  ledcWrite(0, 0);
  ledcWrite(1, 0);
  delay(3000); 
  //prepare reverse
  Serial.println("INA=LOW,INB=i++");
  ledcWrite(0, 0);
  ledcWrite(1, 255);//避免電流太低無法啟動
  delay(300);

  for (int i=80;i<=255;i++)
  {
    ledcWrite(1, i);
    ledcWrite(0, 0);
    Serial.println(i);
    delay(100);
  }
  ledcWrite(0, 0);
  ledcWrite(1, 0);
    delay(3000); 
}
 
void loop() 

}


 

arrow
arrow
    文章標籤
    ESP32 Arduino PWN
    全站熱搜
    創作者介紹
    創作者 夜市 小霸王 的頭像
    夜市 小霸王

    夜市小霸王

    夜市 小霸王 發表在 痞客邦 留言(1) 人氣()