我的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()
{
}
留言列表