Signal Conditioning

cancel
Showing results for 
Search instead for 
Did you mean: 

Continous voltage output in waveform

Hey Guys,

im trying to get my USB 6366 to output a voltage in a waveform (sine and saw). My Code works so far but i have some problems. I can output a saw wave with amplitude and offset but i cant realy change the frequency of that wave (i can change it by using cfg_samp_clk_timing(rate) but if i have a smaler frequency the wave wont fully generate and wont generate multiple times.

MY Questions:

How can i output a wave for a infinite time?

How can i cnage the frequency of my wave?

 

My Code:

# Continuous write single channel
from itertools import accumulate
from re import I
import numpy as np
import matplotlib.pyplot as plt
import time
import nidaqmx
from nidaqmx.stream_writers import (AnalogSingleChannelWriter)
from nidaqmx import constants
from nidaqmx.constants import AcquisitionType
import math

#variables
global rate_outcfg
global counter_limit
global voltage
global stream
global counter
global v_inc
global i
num_samples = 1000
rate_outcfg = 1500 #frequenz #60 ms
len_list = 101
v_inc = 0.01
task = nidaqmx.Task()
counter = 0
i = 0
offset = 0    
amplitude = 3
#Voltage list
voltage = np.empty((len_list,))
voltage [:] = -v_inc

#Basic list                                                                                                                                             "
while counter < len_list:  
    voltage[i:] = voltage[i:] + v_inc
    counter = counter + 1
    i = i+1


voltage_fin = voltage[:] * amplitude + offset

print(voltage_fin)

def SAW ():
    task = nidaqmx.Task()
    task.ao_channels.add_ao_voltage_chan("Dev1/ao0")
    task.timing.cfg_samp_clk_timing(rate = rate_outcfg, sample_mode = AcquisitionType.CONTINUOUS) #, samps_per_chan = num_samples)

                                       

    stream = AnalogSingleChannelWriter(task.out_stream, auto_start=True)
    stream.write_many_sample(voltage_fin, timeout = 10.0)
    nidaqmx.Task.start()

SAW()

 
Thank You for your help!
jo_dkt
0 Kudos
Message 1 of 2
(1,407 Views)

Hey,

solved it. If anyone needs help:

this code works for me

 

from PyQt5 import QtWidgets
from PyQt5.QtGui import QIcon, QPixmap
from PyQt5.QtWidgets import *
from PyQt5.QtWidgets import QLabel, QWidget, QPushButton, QComboBox, QGroupBox, QGridLayout, QMainWindow, QCheckBox, QDialog, QLineEdit, QApplication, QTabWidget, QLineEdit, QTextBrowser, QVBoxLayout
from PyQt5 import QtCore, QtGui
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from pyqtgraph import PlotWidget, plot
import pyqtgraph as pg
import sys
from cmath import sin
import numpy as np
import time
import nidaqmx
import nidaqmx.task
import nidaqmx.stream_readers
from nidaqmx.stream_writers import (AnalogSingleChannelWriter)
import nidaqmx.stream_readers
from nidaqmx.stream_readers import AnalogSingleChannelReader
from nidaqmx import constants
from nidaqmx.constants import AcquisitionType
from nidaqmx.constants import RegenerationMode
from nidaqmx.constants import TerminalConfiguration
import nidaqmx.system.device
import nidaqmx.system.physical_channel
from nidaqmx.task import Triggers
import math


class MyWindow(QMainWindow😞
    #Variabeln
    global voltage_saw_fin, freq, oS, amp, t, num_samples_ai, voltage_saw, voltage_sin, counter_2, i_2
    i_2 = 0
    i_3 = 0
    counter_2 = 0
    len_list = 100 #Definiert NUmmer der Samples für eine Periode
    freq = 0 #Frequenz
    oS = 0 #Offset
    amp = 0 #Amplitude
    t = 0 #Samples/s zum auslesen
    v_inc = 0.01 #Schritte mit der sich die Spannung erhöht (100 * 0.01 = 1)
    #List_create
    voltage_sin = np.zeros(90)

    def __init__(self😞
        super().__init__()
        self.initUI()

    def initUI(self😞

        #Label
        self.setWindowTitle("Nidaqmx-Spannung")
        self.setGeometry(200, 100, 700, 900)
        self.setWindowIconText("Nidaqmx Spannungsausgabe")
        self.Main_Widget = QDialog()
        self.Main_Widget.label_freq = QtWidgets.QLabel(self)
        self.Main_Widget.label_freq.move(60, 80)
        self.Main_Widget.label_freq.setText("Frequenz:")
        self.Main_Widget.label_freq.setGeometry(60, 80, 200, 30)
        self.Main_Widget.label_OS = QtWidgets.QLabel(self)
        self.Main_Widget.label_OS.move(60, 120)
        self.Main_Widget.label_OS.setText("Offset:")
        self.Main_Widget.label_Amp = QtWidgets.QLabel(self)
        self.Main_Widget.label_Amp.move(60, 160)
        self.Main_Widget.label_Amp.setText("Amplitude:")
        self.Main_Widget.label_Amp.setGeometry(60, 160, 200, 30)
        self.Main_Widget.label_t = QtWidgets.QLabel(self)
        self.Main_Widget.label_t.move(60, 200)
        self.Main_Widget.label_t.setText("Samples:")
        self.Main_Widget.label_Über = QtWidgets.QLabel(self)
        self.Main_Widget.label_Über.move(100, 0)
        self.Main_Widget.label_Über.setText("Nidaqmx.Spannungsausgabe")
        self.Main_Widget.label_Über.setGeometry(180, 0, 350, 50)

        #LineEdit
        self.Main_Widget.LineEdit_freq = QtWidgets.QLineEdit(self)
        self.Main_Widget.LineEdit_freq.move(200, 80)
        self.Main_Widget.LineEdit_freq.textChanged.connect(self.pressed_freq)
        self.Main_Widget.LineEdit_OS = QtWidgets.QLineEdit(self)
        self.Main_Widget.LineEdit_OS.move(200, 120)
        self.Main_Widget.LineEdit_OS.textChanged.connect(self.pressed_OS)
        self.Main_Widget.LineEdit_Amp = QtWidgets.QLineEdit(self)
        self.Main_Widget.LineEdit_Amp.move(200, 160)
        self.Main_Widget.LineEdit_Amp.textChanged.connect(self.pressed_Amp)
        self.Main_Widget.LineEdit_t = QtWidgets.QLineEdit(self)
        self.Main_Widget.LineEdit_t.move(200, 200)
        self.Main_Widget.LineEdit_t.textChanged.connect(self.pressed_t)

        #PushButton
        self.Main_Widget.PushButton_start_SAW = QtWidgets.QPushButton(self)
        self.Main_Widget.PushButton_start_SAW.move(400, 80)
        self.Main_Widget.PushButton_start_SAW.setText("SAW")
        self.Main_Widget.PushButton_start_SAW.setGeometry(400, 80, 200, 40)
        self.Main_Widget.PushButton_start_SINE = QtWidgets.QPushButton(self)
        self.Main_Widget.PushButton_start_SINE.move(400, 120)
        self.Main_Widget.PushButton_start_SINE.setText("SINE")
        self.Main_Widget.PushButton_start_SINE.setGeometry(400, 130, 200, 40)
        self.Main_Widget.PushButton_reset = QtWidgets.QPushButton(self)
        self.Main_Widget.PushButton_reset.move(400, 160)
        self.Main_Widget.PushButton_reset.setText("Reset Voltage")
        self.Main_Widget.PushButton_reset.setGeometry(400, 180, 200, 40)
        self.Main_Widget.PushButton_reset.setCheckable(True)
        self.Main_Widget.PushButton_stop = QtWidgets.QPushButton(self)
        self.Main_Widget.PushButton_stop.move(400, 200)
        self.Main_Widget.PushButton_stop.setText("Stop")
        self.Main_Widget.PushButton_stop.setGeometry(400, 230, 200, 40)

        #Pixmap
        self.Main_Widget.graph = pg.PlotWidget(self)
        self.Main_Widget.graph.move(20, 370)
        self.Main_Widget.graph.resize(600, 500)
        self.Main_Widget.graph.setTitle("Voltage")
        self.Main_Widget.graph.setLabel("left", "Voltage")
        self.Main_Widget.graph.setLabel("bottom", "Samples")
        self.Main_Widget.graph.showGrid(x=True, y=True)

        #Label Out
        self.Main_Widget.label_out = QtWidgets.QLabel(self)
        self.Main_Widget.label_out.move(20, 325)
        self.Main_Widget.label_out.setGeometry(20, 325, 500, 50)
        self.Main_Widget.label_out.setText("Output")

       
        #Saw_clicked
        self.Main_Widget.PushButton_start_SAW.clicked.connect(self.list_saw)
        self.Main_Widget.PushButton_start_SAW.clicked.connect(self.write_saw)
        self.Main_Widget.PushButton_start_SAW.clicked.connect(self.read)


        #SIN_clicked
        self.Main_Widget.PushButton_start_SINE.clicked.connect(self.list_sin)
        self.Main_Widget.PushButton_start_SINE.clicked.connect(self.write_sin)
        self.Main_Widget.PushButton_start_SINE.clicked.connect(self.read)

        #Reset_clicked
        self.Main_Widget.PushButton_reset.clicked.connect(self.reset_voltage)
        self.Main_Widget.PushButton_reset.clicked.connect(self.read)

        #Stop_clicked
        self.Main_Widget.PushButton_stop.clicked.connect(self.stop)

    def pressed_freq(self😞
        global freq
        if self.Main_Widget.LineEdit_freq.text().isdigit():
            freq = int(self.Main_Widget.LineEdit_freq.text())
        else:
            if self.Main_Widget.LineEdit_freq.text() == "":
                freq = 0
            else:
                self.Main_Widget.LineEdit_freq.setText(str(freq))


    def pressed_OS(self😞
        global oS
        if self.Main_Widget.LineEdit_OS.text().isdigit():
            oS = int(self.Main_Widget.LineEdit_OS.text())
        else:
            if self.Main_Widget.LineEdit_OS.text() == "":
                oS = 0
            else:
                self.Main_Widget.LineEdit_OS.setText(str(oS))

    def pressed_Amp(self😞
        global amp
        if self.Main_Widget.LineEdit_Amp.text().isdigit():
            amp = int(self.Main_Widget.LineEdit_Amp.text())
        else:
            if self.Main_Widget.LineEdit_Amp.text() == "":
                amp = 0
            else:
                self.Main_Widget.LineEdit_Amp.setText(str(amp))
       
    def pressed_t(self😞
        global num_samples_ai
        if self.Main_Widget.LineEdit_t.text().isdigit():
            num_samples_ai = int(self.Main_Widget.LineEdit_t.text())
        else:
            if self.Main_Widget.LineEdit_t.text() == "":
                num_samples_ai = 10000
            else:
                self.Main_Widget.LineEdit_t.setText(str(num_samples_ai))

    #Basic list SAW
    def list_saw(self😞
        global voltage_saw
        counter_1 = 0
        i_1 = 0
        len_list = 2000000/freq
        v_inc = 1/len_list
        voltage_saw = np.zeros((int(len_list)),)
        while counter_1 < len_list:
            voltage_saw[i_1:] = voltage_saw[i_1:] + v_inc
            counter_1 += 1
            i_1 += 1
   
    #Basic list SIN
    def list_sin(self😞
        global voltage_sin
        len_list= 2000000/freq
        voltage_sin = np.zeros((int(len_list)),)
        counter = 0
        i_2 = 0
        i_3 = 0
        v_inc = 360/len_list
        while counter < len_list:  
            voltage_sin[i_2] = math.sin(i_3 * math.pi/180) #Erstellt eine Sinuskurve mit X Samples
            counter = counter + 1
            i_2 = i_2+1
            i_3 = i_3 + v_inc

    def stop(self😞 #Funktion die 1. Alle Tasks stopt und 2. Den Graphen löscht
        try:
            task_r.stop()
            task_r.close()
        except Exception:
            pass
        try:
            task.stop()
            task.close()
        except Exception:
            pass
        try:
            task_s.stop()
            task_s.close()
        except Exception:
            pass
        try:
            task_2.stop()
            task_2.close()
        except Exception:
            pass
        self.Main_Widget.graph.clear()
        self.Main_Widget.label_out.setText("task cleared")
        deviceObject = nidaqmx.system.device.Device("Dev1")
        deviceObject.reset_device()

    def reset_voltage(self😞 #Funktion die Spannung auf 0 V setzt
        try:
            global task_r
            task_r = nidaqmx.Task("write") #Erstellt Task
            task_r.ao_channels.add_ao_voltage_chan('Dev1/ao0', 'mychannel', 0, 6) #Definiert Channel
            task_r.write(0, timeout = 100) #Schreibt den Output
            self.Main_Widget.label_out.setText("voltage reseted")
        except Exception as e:
            print(e)
            self.Main_Widget.label_out.setText("error")
            pass

    def write_saw(self😞 #Ausgabe Sägezahn
        try:
            voltage_saw_fin = voltage_saw[:] * amp + oS #Spannungsliste mit Amplitude und Offset
            global task
            task = nidaqmx.Task("write") #Erstellt task
            task.ao_channels.add_ao_voltage_chan('Dev1/ao0', 'DAQmx_Val_AO') #, Terminal_config = TerminalConfiguration.RSE) #Definiert Channel
            task.timing.cfg_samp_clk_timing(rate = 123456, sample_mode = AcquisitionType.CONTINUOUS) #Definiert Clock
            task.channels.ao_use_only_on_brd_mem = True
            task.triggers.start_trigger.cfg_dig_edge_start_trig("/Dev1/ai/StartTrigger") #???
            task.write(np.array(voltage_saw_fin), timeout = 100) #Schreibt den Output
            task.out_stream.regen_mode = RegenerationMode.ALLOW_REGENERATION #Wiederholt den Output
            task.start()
            self.Main_Widget.label_out.setText("successful")
        except Exception as e:
            print(e)
            self.Main_Widget.label_out.setText("error")
            pass
   
    def write_sin(self😞
        try:
            voltage_sin_fin = voltage_sin[:] * amp + oS #Spannungsliste mit Amplitude und Offset
            global freq_1
            freq_1 = freq * 90 #Frequenz umrechnen (F = Ausgabe_Samples/s * Samples/Periode)
            global task_s
            task_s = nidaqmx.Task("write") #Erstellt task
            task_s.ao_channels.add_ao_voltage_chan('Dev1/ao0', 'DAQmx_Val_AO') #Definiert Channel)
            task_s.timing.cfg_samp_clk_timing(rate = freq_1, sample_mode = AcquisitionType.CONTINUOUS) #Definiert Clock
            task_s.channels.ao_use_only_on_brd_mem = True
            task_s.triggers.start_trigger.cfg_dig_edge_start_trig("/Dev1/ai/StartTrigger")
            task_s.write(np.array(voltage_sin_fin), timeout = 100) #Schreibt den Output
            task_s.out_stream.regen_mode = RegenerationMode.ALLOW_REGENERATION #Wiederholt den Output
            task_s.start()
            self.Main_Widget.label_out.setText("successful")
        except Exception as e:
            print(e)
            pass

    def read (self😞
        global task_2
        value = np.zeros(num_samples_ai) #Erstellt leere Liste für Input
        x_axis = np.arange(0, len(value), 1) #Erstellt X-Achse zum Plotten
        task_2 = nidaqmx.Task("read") #Definiert Task
        task_2.ai_channels.add_ai_voltage_chan("Dev1/ai0", "DAQmx_Val_Ai", terminal_config = TerminalConfiguration.DEFAULT) #Definiert Channel
        #task_2.triggers.start_trigger.cfg_dig_edge_start_trig
        #task_2.triggers.start_trigger.cfg_dig_edge_start_trig("Dev1/ao0")
        task_2.timing.cfg_samp_clk_timing(rate = 2000000, samps_per_chan = num_samples_ai) #Definiert Clock
        stream_read = AnalogSingleChannelReader(task_in_stream = task_2.in_stream) #Definiert Task für Streamreader
        task_2.start()
        nidaqmx.stream_readers.AnalogSingleChannelReader.read_many_sample(stream_read, data = value, number_of_samples_per_channel = num_samples_ai, timeout = 100) #Auslesen der Werte + Speichern in "value"
        pen = pg.mkPen(color=(0, 255, 0)) #Farbe Plot
        self.Main_Widget.graph.plot(x_axis, value, pen = pen) #Plot
        self.Main_Widget.graph.setYRange(-amp-3, amp +3) #XRange Plot
        self.Main_Widget.graph.setXRange(0, num_samples_ai) #YRange Plot
        task_2.close()

def window():
    app = QApplication(sys.argv)
    win = MyWindow()


    win.show()
    sys.exit(app.exec_())
   
if __name__=="__main__":
    window()
   

You need PyQt5 an nidaqmx
0 Kudos
Message 2 of 2
(1,292 Views)