Raspberry Pi and Variable-Resistor
Plan
ADコンバータを使わずにRasPiに可変抵抗器(ボリューム)を接続してアナログ的な指示を入力する。変換速度の制約がないのでコンデンサへ充電させ充電時間を測定することで可変抵抗器の抵抗値をパルス幅へ変換する。遅いけどいいのだ。
Schematic
最小限の構成を考える。GPIO5から充放電パルス波形を出力しGPIO6に時定数だけ遅れたパルスを入力する。
Simulation
期待通り動作するかLTspiceで事前にシミュレーションする。
Symbol | Discription |
---|---|
V1 | 充放電タイミングを生成GPIO出力 |
V2 | ロジック電源3.3V |
Q1 | 充電用トランジスタスイッチ |
Q2 | 放電用トランジスタスイッチ |
Q3 | GPIO入力信号整形用トランジスタ |
R2 | 外付け可変抵抗器 |
C1 | 時定数を決めるコンデンサ |
Simulation result
Green: GPIO出力充放電タイミングパルス電圧
Blue: 時定数決定用コンデンサ端子電圧
Red: GPIO入力電圧
Green波形の立下りからRed波形の立下りまでの時間を測定しパルス幅とする。
Conversion 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
fdt_z1: float = 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, fdt_z1, fdt
t1 = pi.get_current_tick() # [us]
dt = t1 - t0 # [us]
fdt = fdt_z1 * 0.2 + dt * 0.8 # [us] filter
fdt_z1 = fdt
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
(つづく)
- History
2021-08-17: フィルタのコードに誤り。訂正。