Raspberry Pi 可変抵抗器の接続と読み込み

Raspberry Pi and Variable-Resistor

Plan

RasPiに可変抵抗器(ボリューム)を接続してアナログ的な指示を入力する。ADコンバータをI2C端子に接続して構成するのが正攻法だと思うが、今回は変換速度の制約もないためコンデンサへ充電させ充電時間を測定することで可変抵抗器の抵抗値をパルス幅へ変換する。

Schematic

最小限の構成を考える。GPIO5から充放電パルス波形を出力しGPIO6に時定数だけ遅れたパルスを入力する。

Schematic

Simulation

期待通り動作するかLTspiceで事前にシミュレーションする。

Schematic

Symbol Discription
V1 充放電タイミングを生成GPIO出力
V2 ロジック電源3.3V
Q1 充電用トランジスタスイッチ
Q2 放電用トランジスタスイッチ
Q3 GPIO入力信号整形用トランジスタ
R2 外付け可変抵抗器
C1 時定数を決めるコンデンサ

Simulation result

Green: GPIO出力充放電タイミングパルス電圧
Blue: 時定数決定用コンデンサ端子電圧
Red: GPIO入力電圧
Green波形の立下りからRed波形の立下りまでの時間を測定しパルス幅とする。

Waveform

Conversion characteristics

可変抵抗器の値を変化させシミュレーションしパルス幅を記録する。

横軸: パルス幅
縦軸: 可変抵抗器の抵抗値

Characteristics

実装は実機にてパルス幅を測定し変換テーブルか近似式を作成して利用する。

Sample software

可変抵抗の値に応じてターミナルにテキストでゲージを表示するサンプル。

#!/usr/bin/python3

import time
import pigpio

pi = pigpio.pi()

pi.set_mode(5, pigpio.OUTPUT)
pi.set_mode(6, pigpio.INPUT)
pi.set_pull_up_down(6, pigpio.PUD_UP)

pi.set_PWM_range(5, 100)      # gpio,[digit/100%]
pi.set_PWM_frequency(5, 10)  # gpio,[Hz]
pi.set_PWM_dutycycle(5, 5)    # gpio,[digit]

t0: int = 0
t1: int = 0
dt: int = 0
dt_z1: int = 0
fdt: float = 0

def start_chg(gpio, level, tick):
    global t0
    t0 = pi.get_current_tick()       # [us]

def detect_t(gpio, level, tick):
    global t0, t1, dt, dt_z1, fdt
    dt_z1 = dt
    t1 = pi.get_current_tick()      # [us]
    dt = t1 - t0                        # [us]
    fdt = dt_z1 * 0.9 + dt * 0.1   # [us] filter

chg = pi.callback(5, pigpio.FALLING_EDGE, start_chg)
det = pi.callback(6, pigpio.FALLING_EDGE, detect_t)

while(True):
    time.sleep(0.5)        # [s]
    print("*" * int(fdt / 1000))

動作例
https://youtube.com/shorts/-v3EsGzK_bQ?feature=share