半固定抵抗を使ってLEDの明るさを変える事ができる回路をラズパイで試した | そう備忘録

半固定抵抗を使ってLEDの明るさを変える事ができる回路をラズパイで試した

LEDの調光機能

Raspberry Pi 3 B+にてLEDをアナログの様に多段階で光の強さを変更するプログラムを作成した時の備忘録。

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%となる。

PWM説明図

尚、デューティー比が100(%)だと点灯、0(%)だと消灯になる。

回路図

半固定抵抗のつまみで調整するLEDの調光の回路図は以下の通り。

PWMを使った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のアソシエイトとして、当メディアは適格販売により収入を得ていますのでご了承ください。

souichirou

やった事を忘れない為の備忘録 同じような事をやりたい人の参考になればと思ってブログにしてます。 主にレゴ、AWS(Amazon Web Services)、WordPress、Deep Learning、RaspberryPiに関するブログを書いています。 仕事では工場に協働ロボットの導入や中小企業へのAI/IoT導入のアドバイザーをやっています。 2019年7月にJDLA(一般社団法人 日本デイープラーニング協会)Deep Learning for GENERALに合格しました。 質問は記事一番下にあるコメントかメニュー上部の問い合わせからお願いします。

おすすめ

質問やコメントや励ましの言葉などを残す

名前、メール、サイト欄は任意です。
またメールアドレスは公開されません。