工作と競馬2

電子工作、プログラミング、木工といった工作の記録記事、競馬に関する考察記事を掲載するブログ

pigpioで任意波形の出力

概要

pigpioで任意波形の出力を試した。


背景と目的

先日、pigpioのHardwarePWM機能を使ってパルス出力をしたのだが、時間精度のよい任意波形の出力が必要になった。そこで、pigpioのwave_*****関数群を使って、任意波形を出力するコードを書いて動作を試す。


詳細

1.実装

pigpioのドキュメントと、サンプルを読んである程度理解した。ドキュメントを見てもわかりにくい部分が、pigpio.pulseというメソッドの引数に何を与えるべきかというところ。サンプルを見て理解。

出力 第1引数 第2引数 第3引数
HIGH 1をGPIO番号分だけビットシフト 0 継続時間[usec]
LOW 0 1をGPIO番号分だけビットシフト

という風に指定する。

というわけで、実装してみた。dataというリストに、偶数番目をHIGH、奇数番目をLOWとして継続時間を波形データとして並べて格納。サンプルとして段々パルス幅が広がっていくような波形にしてある。


import pigpio
import time

GPIO_NUM = 18 # 使用するGPIO番号

pi = pigpio.pi()

pi.set_mode(GPIO_NUM, pigpio.OUTPUT)

# 波形データ
data = [
    1000,
    2000,
    3000,
    4000,
    5000,
    6000
]

pulses = [] # pulseオブジェクトを格納
for i in range(len(data)):
    delay_in_usec = data [i]
    if i % 2 == 0:
        pulses.append(pigpio.pulse(1<<GPIO_NUM, 0, delay_in_usec))
    else:
        pulses.append(pigpio.pulse(0, 1<<GPIO_NUM, delay_in_usec))

pi.wave_clear() # clear any existing waveforms

# データを追加
pi.wave_add_generic(pulses)

# 作成
waveId = pi.wave_create() # create and save id

# 出力
pi.wave_send_once(waveId)

# 出力終わるまで待つ
while pi.wave_tx_busy():
    time.sleep(0.1)

# 止める
pi.wave_tx_stop()

# clear all waveforms
pi.wave_clear() 

pi.stop()


2.動作確認

以下のように、指定通りの波形が得られた。時間精度も非常によく、指定通りの時間幅となっている。

f:id:dekuo-03:20191212225140p:plain

なお、注意が必要なのは、最後の波形データの出力レベルが残ること。今回でいえば5000usecのHIGH出力をしたらLOWに戻って終わりたいのだが、そのままだとHIGHが継続してしまうので、最後にLOWを追加している。wave_tx_stopメソッドでは、LOWにはならないので注意。また、while pi.wave_tx_busyループを出た直後にwrite(GPIO_NUM, 0)でLOWに戻しても、time.sleep(0.1)以内の誤差が出るはずなので、これもよくない。


まとめと今後の課題

pigpioで任意波形の出力を試し、正しく動作させることができた。