Difference between revisions of "Python:DAQ 1"

From PrattWiki
Jump to navigation Jump to search
(Code)
(Code)
Line 78: Line 78:
 
=== Imports ===
 
=== Imports ===
 
To access the functions to work with the DAQ card, you will need to import the PyDAQmx module.  Since this module is dependent on numpy, you need to import numpy as well.  Start your code with:
 
To access the functions to work with the DAQ card, you will need to import the PyDAQmx module.  Since this module is dependent on numpy, you need to import numpy as well.  Start your code with:
<syntaxhighlight lang="python">
+
<syntaxhighlight lang="python" start='1' line>
 
#%% Import modules
 
#%% Import modules
 
import numpy as np
 
import numpy as np
Line 85: Line 85:
 
=== Create a Task ===
 
=== Create a Task ===
 
DAQ functions are run via a Task object, so next you will tell the daq module to create a task:  
 
DAQ functions are run via a Task object, so next you will tell the daq module to create a task:  
<syntaxhighlight lang="python">
+
<syntaxhighlight lang="python" start='5' line>
 
#%% Create a task
 
#%% Create a task
 
task = daq.Task()
 
task = daq.Task()
Line 94: Line 94:
  
 
The first one has all the code needed to take a list of binary digits (zeros and ones) and send them to the data acquisition card.  Note that this function works using the task that you created earlier.
 
The first one has all the code needed to take a list of binary digits (zeros and ones) and send them to the data acquisition card.  Note that this function works using the task that you created earlier.
<syntaxhighlight lang="python">
+
<syntaxhighlight lang="python" start='8' line>
 
#%% Define useful functions
 
#%% Define useful functions
 
# Function to change daq outputs
 
# Function to change daq outputs
Line 105: Line 105:
  
 
The second useful function converts a decimal number into a reverse-ordered list of binary digits.  The reason for converting to binary is that the write_data() function needs binary digits.  The reason for reversing the order is that write_data will take the first entry of the list and give it to the first output line you opened.  The first line you opened is going to represent the 1s digit, followed to the 2s digit, followed by the 4s digit.  That means you need to give the data from what you think of as right-to-left; this function will thus reverse the order for you:
 
The second useful function converts a decimal number into a reverse-ordered list of binary digits.  The reason for converting to binary is that the write_data() function needs binary digits.  The reason for reversing the order is that write_data will take the first entry of the list and give it to the first output line you opened.  The first line you opened is going to represent the 1s digit, followed to the 2s digit, followed by the 4s digit.  That means you need to give the data from what you think of as right-to-left; this function will thus reverse the order for you:
<syntaxhighlight lang="python">
+
<syntaxhighlight lang="python" start='16' line>
 
# Function to make 3-element LSB-first binary list from integer
 
# Function to make 3-element LSB-first binary list from integer
 
def d_to_b(n):
 
def d_to_b(n):
Line 114: Line 114:
 
=== Adding Lines and Starting Tasks ===
 
=== Adding Lines and Starting Tasks ===
 
This part of the code will use the CreateDOChan to open digital output channels on the card specified in the first argument.  Specifically, the card is Dev1 and on that device, the first bank of digital output lines is on port0.  Within port 0, there are up to 8 lines - this code opens lines 0 through 2 (0:2).  Once the lines are added, the code stops the task (in case it was still running) and then starts it - the card is now ready to work.
 
This part of the code will use the CreateDOChan to open digital output channels on the card specified in the first argument.  Specifically, the card is Dev1 and on that device, the first bank of digital output lines is on port0.  Within port 0, there are up to 8 lines - this code opens lines 0 through 2 (0:2).  Once the lines are added, the code stops the task (in case it was still running) and then starts it - the card is now ready to work.
<syntaxhighlight lang="python">
+
<syntaxhighlight lang="python" start='21' line>
 
#%% Add digital output lines
 
#%% Add digital output lines
 
task.CreateDOChan("Dev1/port0/line0:2", "",
 
task.CreateDOChan("Dev1/port0/line0:2", "",
Line 126: Line 126:
 
=== Checking Lights ===
 
=== Checking Lights ===
 
Before doing anything interesting with the code, you will want to make sure all the lights are working.  The following code will first turn the three channels on then it will wait for you to provide an input (you can just hit return).  After that is done, it will turn the lights off.
 
Before doing anything interesting with the code, you will want to make sure all the lights are working.  The following code will first turn the three channels on then it will wait for you to provide an input (you can just hit return).  After that is done, it will turn the lights off.
<syntaxhighlight lang="python">
+
<syntaxhighlight lang="python" start='29' line>
 
#%% Check lights
 
#%% Check lights
 
write_data([1, 1, 1])
 
write_data([1, 1, 1])
Line 135: Line 135:
 
=== Updating and Lighting Values ===
 
=== Updating and Lighting Values ===
 
This part of the code will start by turning the lights off, then it will ask the user for an input.  The code converts that input to an integer (since input always returns strings) and sends that value to the write_data() function by first passing it through the d_to_b() function.  That is, the code will convert the decimal number to a least-significant-bit-first 3-entry list, then it will send that list to the card.
 
This part of the code will start by turning the lights off, then it will ask the user for an input.  The code converts that input to an integer (since input always returns strings) and sends that value to the write_data() function by first passing it through the d_to_b() function.  That is, the code will convert the decimal number to a least-significant-bit-first 3-entry list, then it will send that list to the card.
<syntaxhighlight lang="python">
+
<syntaxhighlight lang="python" start='34' line>
 
#%% Write values to output using base 10
 
#%% Write values to output using base 10
 
val = 0
 
val = 0
Line 145: Line 145:
 
=== Cleaning Up ===
 
=== Cleaning Up ===
 
When the program is done, it should turn all the lights off and then stop the task.
 
When the program is done, it should turn all the lights off and then stop the task.
<syntaxhighlight lang="python">
+
<syntaxhighlight lang="python" start='40' line>
 
#%% Turn all off when finished and stop task
 
#%% Turn all off when finished and stop task
 
write_data(d_to_b(0))
 
write_data(d_to_b(0))
Line 154: Line 154:
 
=== Full Code ===
 
=== Full Code ===
 
Here is what the code will eventually look like:
 
Here is what the code will eventually look like:
<syntaxhighlight lang="python">
+
<syntaxhighlight lang="python" line>
 
#%% Import modules
 
#%% Import modules
 
import numpy as np
 
import numpy as np

Revision as of 17:13, 29 September 2019

This page contains pictures and graphs related to Data Acquisition Laboratory 1 (DAQ 1) of EGR 103. It has been updated for Fall, 2019 - including changing the language to Python and updating pictures and descriptions.

Supporting Pundit Pages

Typographical Errors / Clarifications

  • If the computer says your device is not found, try 'Dev2' instead of 'Dev1' in the
task.CreateDOChan("Dev1/port0/line0:2","",
                  daq.DAQmx_Val_ChanForAllLines)
line.
  • If the you run the code and get an error:
DAQError: Specified operation cannot be performed while the task is running.
or
DAQError: Requested operation could not be performed, because the specified digital lines are either reserved or the device is not present in NI-DAQmx. 
that generally means you had a task running and did not get a chance to stop it (for instance, if your code had an error before getting to the task.StopTask() line. To troubleshoot that:
  • Try to run the code again - the task.StopTask() in the code might overcome the problem
  • If that does not work, clear the variables by clicking the black and white eraser rhombus to the right above the IPython console. That generally removes all tasks so you can try again.

Module Installation

  • From the Start menu, find the Anaconda3 folder
  • In the Anaconda3 folder, start the Anaconda Prompt
  • In the Anaconda Prompt, type pip install pydaqmx

Equipment Used

National Instruments Data Acquisition Cards

NI PCI 6014e
Same card, after overheating

B209 has machines with two different data acquisition cards. Most of the machines have NI PCI 6014e cards, which will be what is discussed here. The others have a newer NI PCI 6221 cards. The NI PCI 6014e card can read up to 16 single-ended (8 differential) analog voltage measurements, has two analog outputs, and has 8 configurable digital input/output lines. The 6221 cards are more powerful but, generally in EGR 103, we will limit ourselves to the features available on the 6014e cards.

Be careful when making connections; improperly connecting wires can lead to catastrophic damage on the DAQ cards, as is shown on the second picture at right.


CB-68LP

NI CB-68LP

During this lab, you will use the CB-68LP to connect wires to parts of the NI PCI 6014e card. Be sure to use the proper connections - a map is available at the CB-68LP Pinout page.


Radio Shack Experimentor 350

Radio Shack Experimentor 350

The Experimentor 350 is a simple, but useful, prototyping board. It has two distribution strips (rows X and Y) with 20 pins each and 46 groups of 5 pins on its terminal strip. All the pins in row X are connected together, and all the pins in row Y are connected together; note, however, that X is not connected to Y.

For the main part of the board, half-columns are connected together. For example, rows (ABCDE) in column 3 are all connected. Note, however, that ABCDE are not connected to FGHIJ.

Also, there are some helpful index numbers at the top and bottom to help determine which column you are in. For rows X and Y, some indices do not exist. For example, there is no pin at X6, X12, X18, Y6, Y12, or Y18.

Resistors

Three resistors

Resistors take energy out of an electric circuit and convert that energy to heat. In this case, the light emitting diodes cannot handle the amount of current that the DAQ card can produce, so resistors are placed in parallel to reduce that current. You can use the Resistor Color Codes to determine the resistance of the resistors pictures at right; there should be four resistors (at least) in your box.

LEDs

Several Light Emitting Diodes
Closeup of two round LEDs
File:LED, 5mm, green (en).svg
Drawing of LED from Wikipedia Light-emitting_diode page

A diode is an electrical element that generally only allows current to flow in one direction - and only after there is a sufficient voltage difference across the appropriate terminals. LEDs - Light Emitting Diodes - are a special form of diode that emit light when current flows through them.

Because diodes and LEDs are directional, there are visible clues about which side is which. In the first picture at right, the lengths of the leads on the diodes are clearly different - the longer lead should be placed where the higher voltage is expected, as current will be allowed to flow into the longer lead, through the diode, and out through the shorter lead. For the round LEDs, a flat is ground into the collar of the LED on the lower-voltage side - this is shown more clearly in the second picture. Finally, within the diode itself, the larger "flag" of metal inside the diode is on the lower voltage side.

Note that the color of the plastic is not what determines the color of the light - rather the specific semiconductor material and the geometry of the LED do that. The plastic is a convenient way of knowing what color the light will be, however.


Circuit Construction

Circuit built on breadboard
Connections to CB-68LP

The pictures at right show both the breadboard and the CB-68LP once everything has been properly connected. Note especially on the CB-68LP where the wires are - there will be no connections in the first two columns and there is only one connection - the black wire for digital ground - in the fifth column.

Code

The following code listing is for three_bits.py In lab, do not put all this code in at once! Follow along, save the code after each section, and run it.

Imports

To access the functions to work with the DAQ card, you will need to import the PyDAQmx module. Since this module is dependent on numpy, you need to import numpy as well. Start your code with:

1 #%% Import modules
2 import numpy as np
3 import PyDAQmx as daq

Create a Task

DAQ functions are run via a Task object, so next you will tell the daq module to create a task:

5 #%% Create a task
6 task = daq.Task()

Useful Functions

There are two useful functions defined in this section.

The first one has all the code needed to take a list of binary digits (zeros and ones) and send them to the data acquisition card. Note that this function works using the task that you created earlier.

 8 #%% Define useful functions
 9 # Function to change daq outputs
10 def write_data(data):
11     task.WriteDigitalLines(1, 1, 10.0,
12                            daq.DAQmx_Val_GroupByChannel,
13                            np.array(data, dtype=np.uint8),
14                            None, None)

The second useful function converts a decimal number into a reverse-ordered list of binary digits. The reason for converting to binary is that the write_data() function needs binary digits. The reason for reversing the order is that write_data will take the first entry of the list and give it to the first output line you opened. The first line you opened is going to represent the 1s digit, followed to the 2s digit, followed by the 4s digit. That means you need to give the data from what you think of as right-to-left; this function will thus reverse the order for you:

16 # Function to make 3-element LSB-first binary list from integer
17 def d_to_b(n):
18     bits = list(map(int, '{:03b}'.format(n)))
19     return bits[::-1]

Adding Lines and Starting Tasks

This part of the code will use the CreateDOChan to open digital output channels on the card specified in the first argument. Specifically, the card is Dev1 and on that device, the first bank of digital output lines is on port0. Within port 0, there are up to 8 lines - this code opens lines 0 through 2 (0:2). Once the lines are added, the code stops the task (in case it was still running) and then starts it - the card is now ready to work.

21 #%% Add digital output lines
22 task.CreateDOChan("Dev1/port0/line0:2", "",
23                   daq.DAQmx_Val_ChanForAllLines)
24 
25 #%% Stop and start task
26 task.StopTask()
27 task.StartTask()

Checking Lights

Before doing anything interesting with the code, you will want to make sure all the lights are working. The following code will first turn the three channels on then it will wait for you to provide an input (you can just hit return). After that is done, it will turn the lights off.

29 #%% Check lights
30 write_data([1, 1, 1])
31 input('PAUSED - Hit return to continue ')
32 write_data([0, 0, 0])

Updating and Lighting Values

This part of the code will start by turning the lights off, then it will ask the user for an input. The code converts that input to an integer (since input always returns strings) and sends that value to the write_data() function by first passing it through the d_to_b() function. That is, the code will convert the decimal number to a least-significant-bit-first 3-entry list, then it will send that list to the card.

34 #%% Write values to output using base 10
35 val = 0
36 while 0 <= val <= 7:
37     write_data(d_to_b(val))
38     val = int(input('Enter a number between 0 a 7: '))

Cleaning Up

When the program is done, it should turn all the lights off and then stop the task.

40 #%% Turn all off when finished and stop task
41 write_data(d_to_b(0))
42 task.StopTask()


Full Code

Here is what the code will eventually look like:

 1 #%% Import modules
 2 import numpy as np
 3 import PyDAQmx as daq
 4 
 5 #%% Create a task
 6 task = daq.Task()
 7 
 8 #%% Define useful functions
 9 # Function to change daq outputs
10 def write_data(data):
11     task.WriteDigitalLines(1, 1, 10.0,
12                            daq.DAQmx_Val_GroupByChannel,
13                            np.array(data, dtype=np.uint8),
14                            None, None)
15 
16 # Function to make 3-element LSB-first binary list from integer
17 def d_to_b(n):
18     bits = list(map(int, '{:03b}'.format(n)))
19     return bits[::-1]
20 
21 #%% Add digital output lines
22 task.CreateDOChan("Dev1/port0/line0:2", "",
23                   daq.DAQmx_Val_ChanForAllLines)
24 
25 #%% Stop and start task
26 task.StopTask()
27 task.StartTask()
28 
29 #%% Check lights
30 write_data([1, 1, 1])
31 input('PAUSED - Hit return to continue ')
32 write_data([0, 0, 0])
33 
34 #%% Write values to output using base 10
35 val = 0
36 while 0 <= val <= 7:
37     write_data(d_to_b(val))
38     val = int(input('Enter a number between 0 a 7: '))
39 
40 #%% Turn all off when finished and stop task
41 write_data(d_to_b(0))
42 task.StopTask()

Other Resources

  • Landing Lights Animation:

LLGifSmall.gif

Questions

Post your questions by editing the discussion page of this article. Edit the page, then scroll to the bottom and add a question by putting in the characters *{{Q}}, followed by your question and finally your signature (with four tildes, i.e. ~~~~). Using the {{Q}} will automatically put the page in the category of pages with questions - other editors hoping to help out can then go to that category page to see where the questions are. See the page for Template:Q for details and examples.

External Links

References