半固定抵抗を使ってLEDの明るさを変える事ができる回路をラズパイで試した
Contents
LEDの調光機能
Raspberry Pi 3 B+にてLEDをアナログの様に多段階で光の強さを変更するプログラムを作成した時の備忘録。
PythonのプログラムからGPIOに対してHIGHを設定するとLEDは点灯してLOWにするとLEDは消灯する。
点灯または消灯の2種類では無くて調光機能のついている照明の様に多段階で明るさを調整するプログラムを作成してみた。
光の強さは半固定抵抗のつまみを回すことで調整する。
PWMの説明
LOW、HIGHのデジタル信号を擬似的なアナログ信号で出力するためにはPWM(Pulse Width Modulation)を利用する。
信号を一定の周期で何回もLOW、HIGHと切り替えるのだがHIGHの比率を高くするとLEDが強く光り、低くするとLEDが弱く光る。
つまり実際には高速で点滅を繰り返しているのだが点灯の時間の比率が多いと強く光っているように見えて少ないと弱く光っているように見えるという仕組みだ。
例えば50Hzであれば1秒間に50回LOW、HIGHを繰り返すので周期は20msになる。(1秒÷50=20ミリ秒)
また周期に対するHIGH(パルス)の比率の事をデューティー比と呼ぶ。
例えば20ms中でHIGHが18ms、LOWが2msの時のデューティー比は90%となる。
尚、デューティー比が100(%)だと点灯、0(%)だと消灯になる。
回路図
半固定抵抗のつまみで調整するLEDの調光の回路図は以下の通り。
概略
10KΩの半固定抵抗のつまみを回すと半固定抵抗内部の抵抗値が変わりADコンバーターのピン0に出力される電圧が変わる。(電圧が変わる仕組みについてはこちらの半固定抵抗の記事を参照して欲しい)
ADコンバーターではアナログ値をデジタル値に変換して0~4095の値でRaspberry Piに出力している。
Raspberry PiではADコンバーターの値を元にPWMに変換してGPIO25に出力してLEDの光の強さを調整している。
参考書籍
尚、上記の回路図は「Raspberry Piで学ぶ電子工作」を参考にさせて貰っている。
今回、自分はRaspberry Pi 3 B+で作成したが今ラズパイを購入するのであれば4だと思う。
ラズパイ4対応の書籍も出ていたので紹介しておく。
主なパーツ
回路図で使用している主なパーツは以下の通り。
半固定抵抗
つまみを回すことにより抵抗値を変更できる抵抗。
LEDと抵抗
3mmLEDと抵抗(330Ω)。
ADコンバーター
アナログからデジタルに変換するコンバーター
その他、ラズパイ本体などはこちらの記事の「必要なモノ」を参照して欲しい。
事前準備
ラズパイの設定画面のインターフェースタブにてspiを有効にした後、spidev(Pythonからspiを制御するライブラリー)をインストールする。
spiの有効化の方法とspidevのインストールについては以前の記事を参照して欲しい。
プログラム
ソースコード
プログラムは以下の通り。
# -*- coding: utf-8 -*-
"""
Created on Sun Aug 9 21:05:02 2020
@author: Souichirou Kikuchi
"""
import spidev
import RPi.GPIO as GPIO
from time import sleep
CHN = 0 # 接続チャンネル
LED = 25 # LED点灯用GPIO
GPIO.setmode(GPIO.BCM)
GPIO.setup(LED, GPIO.OUT)
pwm = GPIO.PWM(LED, 50) # 周波数50Hz
pwm.start(0)
spi = spidev.SpiDev()
spi.open(0, 0) # 0:SPI0、0:CE0
spi.max_speed_hz = 1000000 # 1MHz SPIのバージョンアップによりこの指定をしないと動かない
def get_data():
dout = spi.xfer2([((0b1000+CHN)>>2)+0b100,((0b1000+CHN)&0b0011)<<6,0]) # Din(RasPi→MCP3208)を指定
bit12 = ((dout[1]&0b1111) << 8) + dout[2] # Dout(MCP3208→RasPi)から12ビットを取り出す
return float(bit12) # 0~4095
try:
print('--- start program ---')
while True:
val = get_data()
print('val= ',val)
duty = val * 100 / 4095
pwm.ChangeDutyCycle(duty)
sleep(0.2)
except KeyboardInterrupt:
pass
finally:
pwm.stop()
spi.close()
GPIO.cleanup()
print('--- stop program ---')
補足説明
変数
12~13行目で変数を定義している。
CHNはADコンバーターのチャンネルで一番左の0チャンネルに接続している。
またLEDの25はLED点灯用のGPIO25を表している。
PWM
16~18行目でGPIO25に対して周波数50HzでPWM(Pulse Width Modulation)でoutputする事を指定している。
ADコンバーター
24~27行目の関数は分圧抵抗の電圧をADコンバーターから取得している。
半固定抵抗のつまみを回すことにより抵抗値が変わり分圧抵抗の計算式に基づいてADコンバーターのチャンネル0に出力される電圧が変わる。
分圧抵抗の計算についてはこちらの記事を参照して欲しい。
またADコンバーター(MCP3208)に信号を送って(Din)、返ってきた値7(Dout)を12ビットで取得しているのだが詳細は以前のこちらの記事を参照して欲しい。
例外処理
29行目からのtry~except~finallyで例外時の処理を行っている。
finally以下はプログラム終了時に実行される処理を記述している。
メイン処理
32行目の関数で取得した値(0~4095)を4095で割って100をかけて0~100の値に変換してChangeDutyCycleでGPIO25に出力している。
ChangeDutyCycleはデューティー比を変更するメソッドである。
動画
半固定抵抗のつまみを回すことによりLEDの光を調整する様子。
以上で今回の記事は終了とする。
この記事が何処かで誰かの役に立つことを願っている。
尚、当記事中の商品へのリンクはAmazonアソシエイトへのリンクが含まれています。Amazonのアソシエイトとして、当メディアは適格販売により収入を得ていますのでご了承ください。
最近のコメント