HOME  >>  LED電子工作集 > R-5 PWMの利用

R-5 PWMの利用

■ はじめに

 今、RaspberryPiに挑戦している。 今回はPWM 制御について演習を実施した。 ラズパイを鉄道模型に活用しようとした場合には、このPWM制御は必要となるので、しっかり演習しておこう。

 

■ 演習9: PWM信号によるLEDの明るさの制御

 教則本の8章ではPWM 制御について説明されています。 Arduino UNO ではPWM信号を生成するための回路が6チャネルも組み込んれていますが、ラズパイに於いては2チャネルのみで、それも専用のモジュールソフトをインストールする必要があるとのこと。 しかし、精度は低いものの、ソフト的に出力できる方法が提供されています。 ソフト的に実施するので、出力ポートの制約はないようです。 モータやLEDの明るさ制御には、この制度の低いPWM信号で充分であるとのことなのでこの方法から演習します。

GPIO.setup(25, GPIO.OUT)
p1 = GPIO.PWM(25, 50)  # GPIO=25、周波数50Hz
p1.start(0)

try:
    while True:
        duty = xx.x  # duty比を設定
        p1.ChangeDutyCycle(duty)
  	-------------
p.stop()

 教則本には、まず、ひとつのLEDの明るさを調整する演習がありました。 そのサンプルプログラムの08-01-led.py で解説されていたポイントを要点すると、右の様に記述するとのことです。

 ピン番号25のピンに50HzのPWM信号を出力する場合には、

  p1.start(0) にてduty = 0 で開始し、 p1.ChangeDutyCycle(duty) で信号を出し、p.stop() で停止する簡単な命令で実施出来るです。

  Arduino では analogWrite(ピン指定, duty) で出力しますし、duty変数は0〜255 の値を使うなどの違いがあるようです。

 さて、今回はこのひとつのLEDの明るさを調整する演習をパスして、フルカラーLEDの明るさ制御を演習した。 その時の回路図を下に示します。 RGBフルカラーLED OSTA5131A を使い、プログラムは教則本のサンプルプログラム 08-02-rgbled.py をそのまま使用しました。

 

■ 演習10: PWM信号によるDCモータの速度制御

 今度は、LEDの代わりにDCモータを制御する。 モータドライバーは TA7291P を使い、モータは FA-130RAにした。 あとから気が付いたが、このモータは標準が1.5volt であり、電圧範囲は1.5〜3.0volt であったので、5ボルト電源ではヤバかったかも知れないのだ。

def accel():
    inputVal0 = readadc(adc_pin0, SPICLK, SPIMOSI,
                  SPIMISO, SPICS) if inputVal0 > 100 and inputVal0 < 2048: p1.ChangeDutyCycle(0) duty = (2048-inputVal0)*70/2048 for i in range(1,10): duty_a = duty*i/10 p0.ChangeDutyCycle(duty_a) sleep(0.8) elif inputVal0 >= 2048 and inputVal0 < 4000: p0.ChangeDutyCycle(0) duty = (inputVal0-2048)*70/2048 for i in range(1,10): duty_a = duty*i/10 p1.ChangeDutyCycle(duty_a) sleep(0.8) def brake(): inputVal0 = readadc(adc_pin0, SPICLK, SPIMOSI,
                   SPIMISO, SPICS) if inputVal0 > 100 and inputVal0 < 2048: p1.ChangeDutyCycle(0) duty = (2048-inputVal0)*70/2048 for i in range(1,10): duty_a = duty*(10-i)/10 p0.ChangeDutyCycle(duty_a) sleep(0.8) elif inputVal0 >= 2048 and inputVal0 < 4000: p0.ChangeDutyCycle(0) duty = (inputVal0-2048)*70/2048 for i in range(1,10): duty_a = duty*(10-i)/10 p1.ChangeDutyCycle(duty_a) sleep(0.8)  ------------------ try: while True: accel() sleep(5) brake() sleep(3)

 

 プログラムは教則本のサンプルプログラム 08-03-dcmotor.py をそのまま使用してテストしたが、このままでは面白くなかったので鉄道模型の電車の運転j制御を想定して、発進と停止を実行するように変更してみた。

 発進時のモータ回転をアップする関数と、停止時の回転をダウンさせる関数をつくり、それを交互に読み出す部分を追加した。 最大回転数はボリュームで調整し、ADコンバータから readadc で読み取っている部分は、サンプルの通りである。

 ここで、for 命令の書き方が教則本には記述されていなかった。 そこでArduino の例に従って記述したものの、エラーばかりであったので、ネットで調べて記述し直した。 書き方が違うのである!

 もう少しスマートな記述方法があると思われるが、無事に機能しているので良しとしよう。

  ****************  続く  **************************