0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

ArduinoのSoftPWMについて

Last updated at Posted at 2020-12-12

13pinを$duty=100/255$でpwmする.プログラム

# include <SoftPWM.h>
void setup()
{
  SoftPWMBegin();  
  SoftPWMSet(13, 0);
}

void loop()
{
  SoftPWMSet(13, 255);  
}

image.png

LOW:66μs
HIGH:16692μs
少し,LOWが入るようだ

SoftPWMSet(13, 256);

ー>すべてLOW

SoftPWMSet(13, 100);

image.png
1周期=16.7ms
HIGH=6.53ms
LOW=10.2ms

まとめ

  • 60Hz(変更する方法不明)
  • 255(max)指定時一瞬LOWが入る

インストールは
「スケッチ」->「ライブラリをインクルード」->「ライブラリを管理」->「softPWM」
でインストールできます.

もっと高周波が欲しい方

私は,200Hzぐらいは最低で欲しいので,もう少し考えます.
ソフト割り込みでは,かなりArduinoのリソースを消耗することになってしまうので注意が必要です.
分解能を下げることで対応は一応可能です.

TimerOneを使用します.
分解能10,

# include <TimerOne.h>

volatile byte duty1=0;
volatile byte duty2=0;
volatile byte duty3=0;
volatile byte duty4=0;
volatile byte pwm_count = 0;

void soft_pwm(){
  pwm_count++;
  if(pwm_count>=10){
    pwm_count = 0;
    PORTD |= _BV(6);    //pin6 HIGH
    PORTD |= _BV(7);    //pin7
    PORTB |= _BV(0);    //pin8
    PORTB |= _BV(1);    //pin9
  }
  if(pwm_count>=duty1){
    PORTD &= ~_BV(6);    //pin6 LOW
  }
  if(pwm_count>=duty2){
    PORTD &= ~_BV(7);    //pin7 LOW
  }
  if(pwm_count>=duty3){
    PORTB &= ~_BV(0);    //pin8 LOW
  }
  if(pwm_count>=duty4){
    PORTB &= ~_BV(1);    //pin9 LOW
  }
  
}

void setup() {
  Timer1.initialize(200);           //0.2ms
  Timer1.attachInterrupt(soft_pwm);
  pinMode(6,OUTPUT);
  pinMode(7,OUTPUT);
  pinMode(8,OUTPUT);
  pinMode(9,OUTPUT);
  
}

void loop() {
  

}

image.png

周期0.2ms*10=2ms(500Hz),分解能10
4出力で,duty0とすると一瞬1がプログラムの都合上入ります.
image.png
割り込みには2μs使用しています.

分解能を256にすると(byte)
周期0.2ms*256=2ms(19.5Hz),分解能256
で遅くなります.

分解能を20ぐらいがちょうどよさそうです.
周期0.2ms*20=2ms(250Hz),分解能20

# include <TimerOne.h>

volatile byte duty1 = 0;
volatile byte duty2 = 1;
volatile byte duty3 = 2;
volatile byte duty4 = 3;
volatile byte pwm_count = 0;

void soft_pwm() {
  pwm_count++;
  if (pwm_count >= 20) {
    pwm_count = 0;
    if (duty1 != 0) {
      PORTD |= _BV(6);    //pin6 HIGH
    }
    if (duty2 != 0) {
      PORTD |= _BV(7);    //pin7
    }
    if (duty3 != 0) {
      PORTB |= _BV(0);    //pin8
    }
    if (duty4 != 0) {
      PORTB |= _BV(1);    //pin9
    }
  } else {
    if (pwm_count >= duty1) {
      PORTD &= ~_BV(6);    //pin6 LOW
    }
    if (pwm_count >= duty2) {
      PORTD &= ~_BV(7);    //pin7 LOW
    }
    if (pwm_count >= duty3) {
      PORTB &= ~_BV(0);    //pin8 LOW
    }
    if (pwm_count >= duty4) {
      PORTB &= ~_BV(1);    //pin9 LOW
    }
  }
}

void setup() {
  Timer1.initialize(200);           //0.2ms
  Timer1.attachInterrupt(soft_pwm);
  pinMode(6, OUTPUT);
  pinMode(7, OUTPUT);
  pinMode(8, OUTPUT);
  pinMode(9, OUTPUT);
  Serial.begin(250000);

}

void loop() {
  Serial.println("hello");
}

これだと
image.png
こんな感じになります.

duty1->200μs
duty2->400μs
duty3->600μs
周期4ms=250Hz

となります.

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?