Reading In Voltages

9th Feb 2012
Here are my notes on how to read an analogue voltage into Matlab.
I used an NI USB-9800 Data Acquisition System (£204 in 2011). This plugs into a USB port and was relatively painless to use. It comes with several different analogue and digital inputs. NI’s “Measurements and Automation Explorer” made it relatively easy to test the system.
Here is a diagram of what the thing looks like.

Reading in analogue signals

I wanted to read in the voltages across three different objects. Let’s call the voltages across object A VA1 and VA2, i.e. I wanted to measure the voltage across A, i.e. the potential difference (VA2-VA1). I connected VA1 to DAQ input #5 and VA2 to DAQ input #6, which jointly form the DAQ’s Analogue Input 1. So now AI1 reports the voltage across A. Similarly I connected VB1 to DAQ #8 and VB2 to DAQ #9, so that the DAQ AI2 measures the potential across B. And I connected VC1  to DAQ #11 and VC2 to DAQ #12.
I also connected ground to the DAQ inputs #4, #7 and #10. To be honest, I’m not sure this was necessary, but I figured it couldn’t hurt.
This is the Matlab code I used for reading in the analogue data. Note that it uses code from Matlab’s Data Acquisition Toolbox.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
% Note that I have grouped everything together into a big "Experiment" structure for ease of passing stuff around between different functions. Obviously no need to do this if you don't want to.
    Experiment.AI = analoginput('nidaq','Dev1');
    Experiment.AI.SampleRate=1000;
    Experiment.TimeToReadIn = 1000;
    Experiment.AI.SamplesPerTrigger = handles.Coordination.TimeToReadIn*handles.Coordination.AI.SampleRate;
    Experiment.AI.TriggerType='Immediate';
% In this experiment, I was reading in voltages from 3 different sources, each connected to a different analogue input of the NI DAQ.
    Experiment.chan = addchannel(handles.Coordination.AI, [1 2 3],{'Source A' 'Source B' 'Source C'});
 
% At the relevant point in the experiment, start recording data:
% Start recording analogue voltage from the wire:
    start(Experiment.AI);
% ... stuff happens...
% Now you want to stop recording:
    stop(Experiment.AI)
% Read in the voltages:
    nsamples = get(Experiment.AI,'SamplesAvailable');
[voltages, time] = getdata(Experiment.AI,nsamples);
% voltages is now an array of dimensions (nsamples,nchan), where nsamples is the number of voltage samples and nchans is the number of analogue input channels I am reading (here 3)

The only issue I have had is that I get weird errors if I save the channel object (here, variable “AI”) to a .mat file. It sometimes seems to corrupt things so that I can’t load the file (“invalid object” error messages). I have no need to keep the AI object so I just make sure I don’t include it in the list of variables to be saved to the file.

 

Reading in digital signals

I also read in voltages as digital signals. This was in order to start and stop bits of my experiment when a switch was pressed. The digital signals connected to the NI DAQ were the outputs of logic gates. For example, I connected the output of a NOT gate to DAQ port #17, which appears as P0.0. I connected ground to the ground input of the logic gate, and also to DAQ #32, which defines “0V” for the digital inputs. Ground was defined by the negative input from an external power supply. The other input from the power supply was +5V. I connected this to the “HI” input of the logic gate. The NI DAQ’s digital inputs return “FALSE” (low) if they are reading a voltage between -0.3V and +0.8V. They return “TRUE” (high) if they are reading a voltage between 2V and 5.8V. So connecting 5V to the logic gate achieved this. I did however discover that I could only use one gate on each chip. I was using a CMOS IC, a 4069 hex NOT gate which in theory has 6 outputs, but in practice it couldn’t manage to set two gates to HIGH at the same time. So I had to use a different chip for each gate in my circuit (my deep gratitude to Marc for figuring this out and wiring up the resulting massive circuit!)
This is the Matlab code I used for reading in the digital data. Again, it uses code from Matlab’s Data Acquisition Toolbox.

Here are the basic Matlab commands:

1
2
3
4
5
6
% Open up a digital input:
    DI=digitalio('nidaq','Dev1');
% Add an input:
    addline(DI,0,0,'In',{'name });
% Read the current state of this input:
    out = getvalue(DI.Line(1));

and here is a more elaborate code fragment from my experiments:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
%%% Initial set-up:
% Open up a digital input:
    Experiment.DI=digitalio('nidaq','Dev1');
% In this experiment, I was monitoring 6 digital inputs. These were respectively the "start" and "stop" signals for 3 different tasks.
    addline(Experiment.DI,[0 1 2 3 4 5],0,'In',{'Start Task 1' 'Stop Task 1' 'Start Task 2' 'Stop Task 2' 'Start Task 3' 'Stop Task 3' });
% Make a note of which indices relate to the start signals and which ones relate to the stop signals
    Experiment.DIStartIndices = [1 3 5];
    Experiment.DIFinishIndices = [2 4 6];
%%% In the experiment:
% Check that none of the start signals are on initially:
ready=0;
while ~ready
% Read the current values of the three "start" signals
    out = getvalue(Experiment.DI.Line(Experiment.DIStartIndices));
    ready = (sum(out==0) == length(out) );
    if ~ready
        h=errordlg('Please ensure all start signals are off.','Error','modal');
        uiwait(h)
    end
end
% Later on, wait for one of the start signals to be pressed:
started=0;
while ~started
    out = getvalue(Experiment.DI.Line(Experiment.DIStartIndices));
% Wait till any(out==1), but also check it stays 1 for 100ms, to avoid responding to momentary fluctuations:
    if any(out==1);
% Find which start signal has come on:
        j=find(out==1);
        t1=GetSecs;
        % See if that signals stays on for 0.1s:
        cnt=0;
        while GetSecs

2 thoughts on “Reading In Voltages

  1. i have problem with usb-6008
    %%get connected devices
    d = daq.getDevices
    %create session
    s = daq.createSession(‘ni’)
    %add analog channel s.addAnalogInputChannel(‘ID’,channel num, ‘measurement type’)
    s.addAnalogInputChannel(‘Dev1’,0, ‘Voltage’)

    % set rate of scan 4 scans/second , run for 3 seconds
    s.Rate=200;
    s.DurationInSeconds=30;

    v= s.Channels(1);
    set(v)
    %_____________________________
    %%
    v.TerminalConfig = ‘SingleEnded’
    v.Coupling = ‘ DC’

    %%
    %start continuous aquisition and plot

    h = s.addlistener(‘DataAvailable’, @(src,event) plot(event.TimeStamps, event.Data/1));
    s.NotifyWhenDataAvailableExceeds = 200;
    s.startBackground();
    %%
    %start sample aquisition and plot
    %[data,time] = s.startForeground;
    %irradiation = data/1
    %plot(time,irradiation)
    grid on
    xlabel(‘Time (sec)’)
    ylabel(‘voltage in v’)
    %s.release()

Leave a Reply

Your email address will not be published. Required fields are marked *