5
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

PythonでNI-DAQの利用2

Posted at

NI-DAQのPythonプログラミングの覚えとして記載します。

NI-DAQのPCへのインストールはこちらを参照してください。
参考1:PythonでNI-DAQの利用 #Python - Qiita

Pythonで凝ったDAQの使い方をするときは、基本的にはLabVIEWのプログラムと同じようにコードを書く必要があります。(LabVIEWでもDAQをちょっと凝った使い方をしようとするといろいろと設定が必要になります。)

PythonでDAQのプログラミングには、こちらのドキュメントが参考になります。
参考2:NI-DAQmxにおける10種類の関数の習得および多くのデータ集録アプリケーションに対処できる処理について
参考3:テキストベースのプログラミング環境でNI-DAQmxを使用する

例えば、参考2のドキュメントの中には、「外部サンプルクロックによる連続アナログ出力生成を構成する方法」があります。

「NI-DAQmxタイミング」VIのサンプルクロックインスタンスを使用して、外部サンプルクロックによる連続アナログ出力生成を構成する方法を示しています。

サンプルクロックのソース、サンプルクロックのレート、収集または生成するサンプル数を設定するには、「Channel.Timinging.ConfigureSampleClock()」関数を使用します。以下のコードスニペットは、デバイスのPFI 0に接続された外部サンプルクロックに基づく連続収集を作成します。

3_Configure_Task_Timing.png

※LabVIEWでのアイコンは関数を表していて、配線で関数に引数を与えています。

例えば、一番左のAO Voltageは関数で、引数にMinimum ValueMaximum ValuePysical Channelsがあります。返り値はアイコンの右側になります。この場合、Pysical ChannelsErrorです。
次のSample Clock関数では、SamplingRateTrimingSourceContinupousSamplingの引数があります。

右側のグレーの枠で囲まれているのがWhileループで繰り返しが行われます。

(1)Sin波を連続でアナログ出力する

参考4:On The Fly Waveform Configuration with DAQmx - NI Community
参考5:GitHub - ni/nidaqmx-python: A Python API for interacting with NI-DAQmx
参考4に記載されているLabVIEWプログラムを参考にプログラムを作成します。
Front Panel.PNG

bd.png

用いているDAQデバイスは、NI-USBの6001です。作成するプログラムは、100Hzで振幅0.5のSin波を生成し、連続出力します。LabVIEWには波形生成関数(上の図でWhileループ内の関数)が部品として与えられていますが、Pythonではそのようなプログラムはないので、こちらも作成します。出力波形はオシロスコープで確かめてください。

import numpy as np
import nidaqmx as ni
from nidaqmx.constants import Edge, AcquisitionType

# Sin波形生成関数
def t_unit_wave(freq=100, n_sampling=128, n_period=1):
    tx_ = np.linspace(0, n_period, freq*n_sampling)
    return tx_

def t_unit_sin(freq=100, amp=1, phi=0, dc=0, n_sampling=128, n_period=1):
    PI2=2*np.pi
    tx = t_unit_wave(freq=freq, n_sampling=n_sampling, n_period=n_period)
    wav = amp*np.sin(freq*PI2*tx+phi) + dc
    return tx, wav

# DAQの設定
DAQ_IO_ao = 'DAQ6001/ao0'
sampling_rate = 5000


freqency = 100
amplitude = 0.5

n_sampling = int(sampling_rate/freqency)

with ni.Task() as task:
    task.ao_channels.add_ao_voltage_chan(DAQ_IO_ao )  
    task.timing.cfg_samp_clk_timing(
                                    rate = sampling_rate,  
                                    sample_mode = AcquisitionType.CONTINUOUS
                                    )
    task.out_stream.regen_mode = ni.constants.RegenerationMode.DONT_ALLOW_REGENERATION # 波形の再生成を禁止
    
    try:
        while True:
            _, wav = t_unit_sin(freq=freqency, amp=amplitude, phi=0, dc=0, n_sampling=n_sampling, n_period=1) 
            task.write(wav, auto_start=True) # 波形出力    

    except KeyboardInterrupt: # Ctrl + c
        task.write(wav*0)
   

(2)連続でデータを取り込む

連続でデータを取り込むときのプログラム。グラフをリアルタイムで更新するためにplt.pause()を使っています。ループから抜けるには、Ctrl + cを入力してください。

"""
データを連続収集してグラフ表示
"""

import time
import numpy as np
import matplotlib.pyplot as plt
import nidaqmx as ni
from nidaqmx.constants import AcquisitionType, TerminalConfiguration


# Configure NI DAQmx settings
DAQ_IO_ai = 'DAQ6001/ai0'

sampling_rate = 5000
samples = 500

fig, ax = plt.subplots()

with ni.Task() as task:
    task.ai_channels.add_ai_voltage_chan(DAQ_IO_ai, 
                                            min_val=-10, 
                                            max_val=10,
                                            terminal_config=TerminalConfiguration.DIFF) # 収集モード:差動
                                            # terminal_config=TerminalConfiguration.RSE) # 収集モード:RES
    task.timing.cfg_samp_clk_timing(rate=sampling_rate, 
                                       sample_mode=AcquisitionType.CONTINUOUS)
                                        # sample_mode=AcquisitionType.FINITE # バッファーのメモリが足りないときはこちらの方が良い時がある

    
    try:
        while True:
            new_data = task.read(samples)  

            ax.cla()
            ax.plot(new_data,'ro-')

            ax.grid()
            plt.pause(0.01)
        
    except KeyboardInterrupt: # Ctrl + C
        task.stop()
        plt.ioff()  # Turn off interactive mode
        print('Stop')
    

(3)一定電圧を出力する

これは、私の実験で必要だったのでおまけです。(サンプルプログラムと同じ)。

AOチャンネルから5Vを出力、5秒後に0Vにして終了するプログラム。

import numpy as np
import matplotlib.pyplot as plt
import nidaqmx as ni
from nidaqmx.constants import AcquisitionType, TerminalConfiguration
import time


# 自身のデバイスに合わせて変更する
DAQ_IO_ao = 'DAQ6001/ao1'

with ni.Task() as task:
    set_bias = 5
    task.ao_channels.add_ao_voltage_chan(DAQ_IO_ao) 
    task.write(set_bias)
    
    time.sleep(5)
    task.write(0)

どなたかの参考になれば。

5
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?