clade / PyDAQmx

Interface to National Instrument NIDAQmx driver
Other
133 stars 55 forks source link

error getting string size #39

Open Misfittech opened 8 years ago

Misfittech commented 8 years ago

I was looking for a forum to post this question but could not find one.

I am trying to get size of string for the device names using the following function. I copied from a NI C++ example. import ctypes import PyDAQmx as pydaq import numpy as np

n=pydaq.DAQmxGetSystemInfoAttribute(pydaq.DAQmx_Sys_DevNames,None)

I get the following error:

Traceback (most recent call last): File "C:\HMRI\Calorimeter\python\main.py", line 9, in print pydaq.DAQmxGetSystemInfoAttribute(pydaq.DAQmx_Sys_DevNames,None) File "", line 2, in function File "C:\Anaconda2\lib\site-packages\PyDAQmx\DAQmxFunctions.py", line 34, in mafunction raise DAQError(error,errBuff.value.decode("utf-8"), f.name) PyDAQmx.DAQmxFunctions.DAQError: NI-488: Interface has lost power. in function DAQmxGetSystemInfoAttribute

clade commented 8 years ago

This is a bug that should be corrected : by default all the functions are supposed to return an error code. An exception was made to a generic case of function (see DAQmxFunctions.py the catch_error function) but not to DAQmxGetSystemInfoAttribute

You should be able to get your attribute by passing a long enough string (create_string_buffer(xxx)).

Second options : use the DAQmxGetSysDevNames functions. This function will have the correct behaviour :

n = DAQmxGetSysDevNames(None, None)
buffer = create_string_buffer(n)
DAQmxGetSysDevNames(buffer, n)
Misfittech commented 8 years ago

I was working on trying to record multiple channel data from NI 9220. It took me awhile as I did not realize you could pass multiple channel string to the CreateAIVoltageChan() function. Here is a quick example of what I coded up. This would/could make a nice example for the documentation.

from ctypes import * import PyDAQmx as pydaq import numpy as np import time import threading import datetime from itertools import imap import os

class NI_9220: def init(self): self.thread=None self.filename=None self.pydaqTask=None self.event=None self.fs=0; self.numChannels=0 self.file=None

#channels is a string like 'cDAQ1Mod1/ai0:4' to record first 4 channels
def startRecording(self, filename,channels,fs,

numChannels,comments=""):

init member variables

    self.fs=fs;
    self.numChannels=numChannels;
    self.filename=filename
    #open file for writting
    self.file=open(filename,"wt")

    #setup the DAQ to fill buffer once a second
    self.pydaqTask=pydaq.Task();

self.pydaqTask.CreateAIVoltageChan(channels,"",pydaq.DAQmx_Val_Cfg_Default,-10.0,10.0,pydaq.DAQmx_Val_Volts,None)

self.pydaqTask.CfgSampClkTiming("",fs,pydaq.DAQmx_Val_Rising,pydaq.DAQmx_Val_ContSamps,1)

    self.file.write("#comments=%s\n\r" % comments);
    self.file.write("#channels=%s\n\r" % channels);
    self.file.write("#samples per second=%s\n\r" % fs);
    self.file.write("#numchannels=%s\n\r" % numChannels);
    self.file.write("#units=volts\n\r");
    #start the data recording
    self.pydaqTask.StartTask()
    t=datetime.datetime.now().time();
    self.file.write("#date=%s\n\r" % datetime.date.today())
    self.file.write("#time=%s\n\r" % t);

    #setup thread to hanndle the processing of the data
    self.event=threading.Event();
    self.thread=threading.Thread(target=self.writeToFile,

args=(self.event,)) self.thread.daemon=True self.thread.start()

    print "starting"

def writeToFile(self, event):
    data = np.zeros((self.fs*self.numChannels,), dtype=np.float64)
    print "running thread"
    t=0;
    while not event.isSet():
        read = pydaq.int32()

self.pydaqTask.ReadAnalogF64(-1,10.0,pydaq.DAQmx_Val_GroupByChannel,data,self.fs_self.numChannels,byref(read),None) n=read.value; x=data[0:(n_self.numChannels)].reshape(self.numChannels,n)

        x= x.transpose()
        for y in x:
            s=",".join(imap(str,y))+"\n\r"
            #print s
            self.file.write(s)

        #flush the file to disk once a second
        if (time.time()-t)> 1:
            self.file.flush();
            t=time.time()
            print("%s - %d bytes" %

(self.filename,os.path.getsize(self.filename)))

        time.sleep(.1)
    print "thread done"
    self.file.close()

def stop(self):
    print "stopping"
    self.event.set();

analog=NI_9220() analog.startRecording('test.txt','cDAQ1Mod1/ai0:1',10000,2) time.sleep(10) analog.stop(); exit()

On Mon, Sep 19, 2016 at 8:20 AM, Pierre Cladé notifications@github.com wrote:

This is a bug that should be corrected : by default all the functions are supposed to return an error code. An exception was made to a generic case of function (see DAQmxFunctions.py the catch_error function) but not to DAQmxGetSystemInfoAttribute

You should be able to get your attribute by passing a long enough string ( create_string_buffer(xxx)).

Second options : use the DAQmxGetSysDevNames functions. This function will have the correct behaviour :

n = DAQmxGetSysDevNames(None, None) buffer = create_string_buffer(n) DAQmxGetSysDevNames(buffer, n)

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/clade/PyDAQmx/issues/39#issuecomment-247978068, or mute the thread https://github.com/notifications/unsubscribe-auth/AT7GxmjnSpGVKj1_TZyQ7Ko0GoPIpH0nks5qrn4HgaJpZM4KAZig .