つれづれなる備忘録

日々の発見をあるがままに綴る

TinkercadによるArduinoシミュレーション27 ~ PWMからアナログ波形出力

1. アナログ波形の情報表示

 今回はArduino Unoでのアナログ電圧の出力を利用して、波形電圧を出力する方法を紹介する。Arduino Unoの場合アナログ電圧を出力する場合、0~5Vの中間電圧に応じたデューティー比を有するPWM(Pulse Width Modulation)により出力される。

atatat.hatenablog.com

このPWMのパルス波形をCRフィルタ(ローパス)を通すことにより0-5Vの中間電圧を生成し、さらに中間電圧を時間的に変動させることによりアナログ波形出力を実現させる。

2. CRフィルタの設定

 Arduino UnoでPWM出力が可能なピン(3,5,6,10,11)のうち、5,6のパルス周波数は980Hzで残りは490Hzだが、今回は高い周波数をパルス出力する5ピンを利用する。パルス周波数980Hzに対してCRフィルタのカットオフ周波数が小さくなるように抵抗値とコンデンサ容量を選択する。カットオフ周波数fcCRローパス・フィルタ計算ツールなどを参考にした。下記二通りの抵抗、コンデンサ容量、カットオフ周波数のCRフィルタにより、PWM出力を中間電圧に変換できるかTinkercadでシミュレーションする。

フィルタ名 抵抗R(Ω) 容量C(uF) カットオフ周波数fc(Hz)
CRフィルタ1 100 30 53
CRフィルタ2 100 100 16

3. CRフィルタによるPWMから中間電圧生成

 出力する電圧を2.5Vとして、5ピンからPWMを生成するスケッチを以下に示す。

//PWM生成
float Vin=0;
int val; 
void setup()
{
  pinMode(5, OUTPUT);
}

void loop()
{
  Vin=2.5;
  val=int(51*Vin); //電圧→0-255への変換
  analogWrite(5, val);
}

Arduinoの5ピンの出力電圧をマルチメータおよびオシロスコープで電圧・波形を観察し、さらにCRフィルタ1(fc=53Hz)の出力に対してマルチメータとオシロスコープを接続している。下図から、マルチメータは入力側、出力側いずれも約2.5Vを示し、オシロスコープの波形は入力側のパルス波形に対して、出力側はリップルを伴った2.5Vの中間電圧が出力できていることがわかる。

CRフィルタ1による中間電圧生成
CRフィルタ1による中間電圧生成

同様にCRフィルタ2(fc=16Hz)の場合、下図のようになり中間電圧のリップル量が減少していることがわかる。

CRフィルタ2による中間電圧生成
CRフィルタ2による中間電圧生成

3. PWM出力から正弦波出力

  CRフィルタによりPWMから中間電圧を生成できることが確認できたので、次に正弦(Sin)波を出力してみる。正弦波を生成するためには、関数sin(rad);とプログラム経過時間を取得するmillis()を利用する。周波数をfとしたときにVin=(1+sin(2*3.14*f*t))*Vamp;とすることで周波数fで0-2xVampの間で正弦波を生成することができる。生成した電圧値を0-255に変換してanalogWrite(5,val);に書き込んで5ピンから出力する。Arduinoの出力時点ではパルスデューティー比が時間に対して正弦的に変化するようなPWM出力でCRフィルタを通すことで正弦波に変換される。

// 正弦波生成
float Vamp, Vin;
int val; // 
float f; //周波数
unsigned long tm;
float t;
void setup()
{
  Serial.begin(9600);
  pinMode(5, OUTPUT);
  Vamp=2.5;
  f=5;
}

void loop()
{
  tm=millis(); 
  t=(float)tm/1000; // 時間単位ms→sへ変換
  Vin=(1+sin(2*3.14*f*t))*Vamp;
  val=int(51*Vin);
  analogWrite(5, val);
}

周波数f=5Hz, Vamp=2.5V(振幅5V)で、CRフィルタ1を用いて正弦波を生成したのが下図になる。(接続はPWMから中間電圧生成のものと同じ)

CRフィルタ1による正弦波生成
CRフィルタ1による正弦波生成

上にArduino出力直後の波形で下がCRフィルタ1後の波形を示しており、PWMのパルス波形が正弦波の電圧波形に変換されていることが確認できる。ただし正弦波に若干リップルによる歪みが見られるので、さらにカットオフ周波数が低いCRフィルタ2を用いた場合は、下図のようになる。

CRフィルタ2による正弦波生成
CRフィルタ2による正弦波生成

カットオフ周波数がCRフィルタ1より低いことで、正弦波の周波数以外に混入していた高周波数の成分がカットされることで見た目はかなりきれいな正弦波が生成できている。

CRフィルタを用いる方法では、周波数が少なくともCRフィルタのカットオフ周波数である必要がある。また波形を歪みなく再現するには、さらにカットオフ周波数自体を小さくする必要があり、結果として生成できる正弦波の周波数範囲が狭まってしまう。

4. PWM出力からのこぎり波生成

 正弦波以外にのこぎり波を生成する例を示す。のこぎり波を生成するにはVin=(t*f-int(t*f))*Vamp;とする。

//のこぎり波生成
float Vamp, Vin;
int val,tint; 
float f; //周波数
unsigned long tm;
float t;
void setup()
{
  pinMode(5, OUTPUT);
  Vamp=5;
  f=5;
}

void loop()
{
  tm=millis();
  t=(float)tm/1000*f;
  tint=int(tm/1000*f);
  Vin=(t-tint)*Vamp;
  val=int(51*Vin);
  analogWrite(5,val);
}

周波数はf=5Hzとして、振幅Vamp=5Vとしてのこぎり波を生成したものが下図で、CR1フィルタ(カットオフ53Hz)を使用した場合の波形が左で、CR2フィルタ2(カットオフ16Hz)を使用した場合を右に示す。

のこぎり波の生成
のこぎり波の生成

いずれものこぎり波は生成できているが、CRフィルタ1の場合は直線部分にリップルによる歪みはあるがエッジはきれいに生成できている。またCRフィルタ2の場合は、直線部分の歪みはないが、エッジ部分が丸まっている。 これは高周波をカットすることで直線部分の歪みは除去できるが、エッジの高周波成分も除去してしまって丸まってしまっていると考えられる。このように生成する波形自体に高周波成分を含むような場合は、波形の歪みとエッジ部の再現のバランスをとる必要がでてくる。

5. まとめ

 今回はCRフィルタを用いることでArduino Unoのアナログ電圧出力であるPWMに対して中間電圧を生成し、中間電圧を時間的に変動させることでアナログ波形として正弦波およびのこぎり波をTinkercadのシミュレーション上で生成した。