概要
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.動作確認
以下のように、指定通りの波形が得られた。時間精度も非常によく、指定通りの時間幅となっている。
なお、注意が必要なのは、最後の波形データの出力レベルが残ること。今回でいえば5000usecのHIGH出力をしたらLOWに戻って終わりたいのだが、そのままだとHIGHが継続してしまうので、最後にLOWを追加している。wave_tx_stopメソッドでは、LOWにはならないので注意。また、while pi.wave_tx_busyループを出た直後にwrite(GPIO_NUM, 0)でLOWに戻しても、time.sleep(0.1)以内の誤差が出るはずなので、これもよくない。
まとめと今後の課題
pigpioで任意波形の出力を試し、正しく動作させることができた。