赤外線LEDでスイッチを使って複数の数値の赤外線信号を送信する送信機をつくります。

赤外線LEDで複数の数字データーの赤外線信号を送信

以前作った赤外線センサー送信機にスイッチをつけて赤外線パルスで複数の数字データーを送信します。

赤外線LED

配線図

プラス端子 GP 17   長い方
Gnd アース(GND)   短い方  タクトスイッチ GP14 15 19 20   GND

 

MicroPythonプログラム

# GPIOピン制御・PWM制御のライブラリを読み込む
from machine import Pin, PWM

# 時間関連のライブラリを読み込む
import utime

# スイッチが押されたときの値を保存する変数
last_pressed_value = 0

def initialize_switches(switch_pins):
    return {pin: machine.Pin(pin, machine.Pin.IN, machine.Pin.PULL_UP) for pin in switch_pins}

def is_switch_pressed(switch, debounce_threshold=10):
    if switch.value() == 0:
        utime.sleep_ms(10)  # デバウンシングのための待機時間
        return switch.value() == 0
    return False

def process_switch(pin):
    value = switch_values.get(pin, 0)
    print(f"タクトスイッチ {pin} が押されました。 値: {value}")
    global last_pressed_value
    last_pressed_value = value

# タクトスイッチが接続されたGPIOピンのリスト
switch_pins = [14, 15, 19, 20]

# タクトスイッチの状態を保持するピンの辞書
switches = initialize_switches(switch_pins)

# タクトスイッチが最後に押された時間の辞書
last_pressed_times = {pin: 0 for pin in switch_pins}

# タクトスイッチごとに割り当てる値
switch_values = {
    14: 8,
    15: 10,
    19: 12,
    20: 14
}

# タクトスイッチが押されたかどうかを確認するための閾値
pressed_threshold = 20  # ミリ秒
# PWM制御を行うピンの設定
ir = PWM(Pin(17, Pin.OUT))
# PWM制御の動作周波数を設定
# 一般的なリモコンで使用されている周波数 = 38KHz
f = 38000
ir.freq(f)
# PWM制御の周期(波が上下に1回振動するのにかかる時間)
# 周期 = 1/周波数(38kHz)= 26μs
# PWMのデューティー比(HIGHとLOWの比率)
# 一般的なリモコンのデューティー比 = HIGH:1/3、LOW:2/3
# 16bitの最大値 = FFFF(16進数)= 65535(10進数)
# 65535 * 0.3333 = 21845(10進数)= 5555(16進数)
dty = 0x5555
# 解析したデータが信号を一つ送るのに掛かっていた時間 = 300us
# 300usの長さの信号になるようにPWM信号を繰り返す
# 300us/26us = 11.5回
# しかしtime.ticksで赤外線通信の稼働時間を計測した結果、
# 理想のフレーム長(53ms~55ms)に足りない
# よって稼働時間が53ms以上になるように「20」と調整した
adj = 20


def decimal_to_binary_list(decimal):
    binary_list = list(bin(decimal)[2:])
# bin()関数で2進数文字列を取得し、最初の2文字('0b')を取り除く
    binary_list = [int(bit) for bit in binary_list]
# 文字列を整数のリストに変換
    return binary_list

def sendcode(data):
    decimal_number = data

# 10進数を2進数に変換
    binary_result = decimal_to_binary_list(decimal_number)

# 結果を表示
    print(binary_result)
    
# 赤外線通信の稼働時間を計測開始
    start = utime.ticks_us()

# 16bitのコードを読み込む
    for bit in binary_result:
       
# コードの値が「1」のときの処理
        if(bit == 1):
        
# デューティー比1/3がHIGHのPWM信号を送信(adj回分)
            for i in range(1, 1*adj):
                ir.duty_u16(dty)
            
# LOWのPWM信号を送信(7×adj回分)
            for i in range(1, 7*adj):
                ir.duty_u16(0)
         
# コードの値が「0」のときの処理
        else:
        
        # デューティー比1/3がHIGHのPWM信号を送信(adj回分)
            for i in range(1, 1*adj):
                ir.duty_u16(dty)
            
        # LOWのPWM信号を送信(7×adj回分)
            for i in range(1, 3*adj):
                    ir.duty_u16(0)
    
# ストップビット(データの終端を示す信号)
    for l in range(1,1*adj):
        ir.duty_u16(dty)

# トレーラー(通信の終わりを示す信号)
    for l in range(1,1*adj):
        for i in range(1,97):
            ir.duty_u16(0)
              
# 赤外線通信の稼働時間を出力(53000us以上になっていればOK)
#print(time.ticks_diff(time.ticks_us(), start))
#data = 0    
while True:
    #print("現在のswitch_values:", switch_values)  # グローバル変数を出力
    for pin, switch in switches.items():
        current_time = utime.ticks_ms()

        # デバウンシング処理
        if is_switch_pressed(switch):
            if utime.ticks_diff(current_time, last_pressed_times[pin]) > pressed_threshold:
                process_switch(pin)
                last_pressed_times[pin] = current_time

    print("メインループで使う値:", last_pressed_value)

        
    # スイッチの反応を防ぐために少し待機
    utime.sleep_ms(100)
    

    #data = pressed_value
    sendcode(last_pressed_value)
    utime.sleep_ms(1000)

 

 一般的なリモコンで使用されている周波数 をPWMで発生させて赤外線LEDに送り発進させます。

リモコンで使われている設定に合わせる
# タクトスイッチごとに割り当てる値をセットします。
switch_values をGP14: 8, GP15: 10, GP19: 12, GP20: 14にします。

実行

 

スイッチを押すと押したGP番号とセットした値を表示します。

自由研究

テンテン
テンテン

今回は4桁の2進数なので0〜15までの数値を送信できます。
受信機を作ると赤外線リモコンができます。