update method for finding comedi numbers
@@ -1,206 +1,259 @@
|
||||
Orocos needs to be configured to your hardware, this involves:
|
||||
|
||||
1. Identifying (or verifying) the device numbers that Comedi is assigning to each card
|
||||
2. Set the correct device numbers in the Orocos start.ops file
|
||||
3. Load and use the correct hardware drivers in the Orocos start.ops file
|
||||
|
||||
## Agilent Interferometer PCI cards
|
||||
|
||||
The Agilent PCI cards don't have a proper kernel driver any more and are now accessed by Orocos directly via the PCI slot. This is different from other hardware and the configuration is also special. To configure access, use `lspci` to see which PCI address (number on the left) corresponds to your Agilent card and make sure that your `start.ops` includes lines similar to:
|
||||
|
||||
```
|
||||
import("SensorAgilentPCI")
|
||||
loadComponent("Sensor1","SensorAgilentPCI")
|
||||
Sensor1.deviceName = "/sys/bus/pci/devices/0000:07:00.0/"
|
||||
```
|
||||
|
||||
You should be able to see a directory in your file system that matches the `deviceName` string.
|
||||
|
||||
## Identify Device Numbers
|
||||
|
||||
The device numbers assigned to each card can be found in the kernel message log, which is printed with `dmesg` (might need `sudo dmesg`). There can be a lot of messages to sort through, so you can narrow it down with `dmesg | grep comedi`. This should produce output that includes lines like (example from PolLux):
|
||||
|
||||
```
|
||||
[ 2.507480] comedi4: ni_660x:
|
||||
[ 2.507890] comedi: cannot get unshared interrupt, will not use RT interrupts.
|
||||
[ 2.511676] comedi1: ni_pcimio:
|
||||
[ 2.544959] comedi2: ni_pcimio:
|
||||
[ 2.546311] comedi: cannot get unshared interrupt, will not use RT interrupts.
|
||||
[ 2.547515] comedi2: ni_pcimio: possible problem - never saw adc go busy?
|
||||
[ 2.699254] comedi0: ni_660x:
|
||||
```
|
||||
We are looking for messages in the format of `comedi4: ni_660x:`, which tells us that an NI6602 card (with `ni_660x` kernel module) has been assigned the device number `4` by Comedi. Further information can often be found in the lines in between those containing "comedi" and you can use the timestamp on the left to quickly find the appropriate section of the message log. Some other useful commands for identifying hardware include:
|
||||
- `lspci`
|
||||
- `comedi_board_info /dev/comedi0` (try with each device found with `ls /dev/comedi?`)
|
||||
|
||||
This corresponds to a PolLux configuration with:
|
||||
- NI-6602 (ni_660x) assigned device number 0
|
||||
- NI-6289 (ni_pcimio) assigned device number 1
|
||||
- NI-6733 (ni_pcimio) assigned device number 2
|
||||
- Agilent N1231 (n1231a) that the kernel (i.e. Comedi) doesn't see, but is observed in PCI slot 7
|
||||
- NI-6602 (ni_660x; used for reading the output of the Attocube interferometer) assigned device number 4
|
||||
|
||||
If you have multiple cards using the same driver, then it can be a bit complicated to figure out which is which. As a rule, Comedi will tend to assign a smaller device number to the card with the higher PCI address.
|
||||
|
||||
## Setting Device Numbers In start.ops
|
||||
|
||||
The device numbers must be assigned correctly in the `start.ops` file used to configure Orocos. The first section of the `start.ops` file for PolLux looks like:
|
||||
|
||||
```
|
||||
// deployer-gnulinux -s start.ops -linfo
|
||||
|
||||
import("SensorAgilentPCI")
|
||||
import("SensorAttocube")
|
||||
import("PIDLoop")
|
||||
import("ComController")
|
||||
import("zmqStreamer")
|
||||
import("AnalogOutputComedi")
|
||||
import("DigitalOutputComedi")
|
||||
import("TrajectoryGenerator")
|
||||
import("PositionSampler")
|
||||
import("RealtimeSampler")
|
||||
import("DigitalInputComedi")
|
||||
|
||||
|
||||
loadComponent("Sensor1","SensorAgilentPCI")
|
||||
loadComponent("Sensor2","SensorAttocube")
|
||||
loadComponent("PID0","PIDLoop")
|
||||
loadComponent("PID1","PIDLoop")
|
||||
loadComponent("PID2","PIDLoop")
|
||||
loadComponent("ComCon", "ComController")
|
||||
loadComponent("zmqStream0", "ZmqStreamer")
|
||||
loadComponent("AO1", "AnalogOutputComedi")
|
||||
loadComponent("DO1", "DigitalOutputComedi")
|
||||
loadComponent("TrajGen","TrajectoryGenerator")
|
||||
loadComponent("PosSampler","PositionSampler")
|
||||
loadComponent("RtSampler","RealtimeSampler")
|
||||
loadComponent("DI1", "DigitalInputComedi")
|
||||
```
|
||||
|
||||
Take note of each `loadComponent` command where the imported object (second argument) has "Sensor", "Input" or "Output" in the name. Each of these will need to be assigned a device number, using the name given in the first argument of the command.
|
||||
|
||||
In this case, we should declare the following assignments:
|
||||
```
|
||||
Sensor1.deviceName = "/sys/bus/pci/devices/0000:07:00.0/"
|
||||
Sensor2.deviceNr=4
|
||||
AO1.deviceNr=2
|
||||
DO1.deviceNr=2
|
||||
DI1.deviceNr=2
|
||||
```
|
||||
These assignments must be declared after the corresponding device names are defined with `loadComponent` and before they are configured with a command like `Sensor1.configure()`.
|
||||
|
||||
**WARNING** : There are currently some inconsistencies in the device number variable names and whether the "configure" and "start" functions use parentheses. The plan is to standardise on "deviceNr" and "configure()"
|
||||
|
||||
| Device Type | Variable Name | Function Syntax |
|
||||
| ------ | ------ | ------ |
|
||||
| SensorAgilentPCI | deviceName | configure; start |
|
||||
| SensorAttocube | device_nr | configure; start |
|
||||
| AnalogOutputComedi | device_nr | configure(); start() |
|
||||
| DigitalOutputComedi | device_nr | configure(); start() |
|
||||
| DigitalInputComedi | deviceNr | configure; start |
|
||||
|
||||
## Configuring start.ops
|
||||
|
||||
The `start.ops` file tells Orocos how to define devices and how signals are interconnected. Note that the feedback loops are "PID0" for the X-axis, "PID1" for the Y-axis and "PID2" for the Z-axis.
|
||||
|
||||
It is probably best to start with the file configured for PolLux ([PixelatorRealtime/startup/PolLux/start.ops](https://gitlab.psi.ch/microspectro/pixelator/-/blob/master/PixelatorRealtime/startup/PolLux/start.ops)) and adapting to your instrument. There are three things that might make PolLux different from your system:
|
||||
1. The device numbers.
|
||||
2. The interferometer module(s).
|
||||
3. The number of interferometer axes being used.
|
||||
|
||||
### Device Numbers
|
||||
Currently, the device numbers at PolLux match the hard-coded defaults and so no device numbers are set. The section above discusses how to set the appropriate device numbers in `start.ops`.
|
||||
|
||||
### Interferometer Module(s) and Axes
|
||||
An interferometer module is first imported (`import()`) and then loaded and assigned a name (`loadComponent()`). PolLux uses an Agilent interferometer for the X- and Y-axes, and an Attocube interferometer for the Z-axis. You should only import the module(s) that you need for the interferometer type(s) used in your instrument. If you only have one interferometer type, then you should delete one of the `import()` commands and one of the `loadComponent()` commands so that the remaining commands refer to the interferometer module that you want to use. Further, ensure that the `loadComponent()` command uses a name (first argument, e.g. "Sensor1") that is used consistently for later commands.
|
||||
|
||||
Next, you should set the interferometer resolution for each channel, for example:
|
||||
```
|
||||
Sensor1.resolution[0]=0.000309078
|
||||
Sensor1.resolution[1]=0.000309078
|
||||
Sensor1.resolution[2]=0.000309078
|
||||
```
|
||||
It is OK to set as many channels as exists on the hardware (usually 3), even if you are not measuring that many axes. The resolution value is calculated by the laser wavelength (in microns) divided by the interpolator factor (Agilent N1231A is 512 and N1231B is 1024) and then divided by the number of laser paths (a double-pass, with 2 bounces off the mirror gives 4).
|
||||
|
||||
Next, you will need to modify or delete a bunch of commands, depending on whether you have a Z-axis interferometer.
|
||||
|
||||
#### Two Interferometer Axes (of same type)
|
||||
If you have only X- and Y-axis interferometers, you can delete all commands (the full line) that include either "Sensor2" or "PID2" (or both). Need to include the line `ComCon.nrPID=2` in start.ops.
|
||||
|
||||
#### Three Interferometer Axes (of same type)
|
||||
If you have X-, Y- and Z-axis interferometers, you should first look at every `connect()` command and change any instance of "Sensor2.*Output_0" (where * is either "position" or "status") in that command to "Sensor1.*Output_2". After doing this throughout the file, you should delete any command (the full line) that still contains "Sensor2". Need to include the line `ComCon.nrPID=3` in start.ops.
|
||||
|
||||
|
||||
## Manual Loading of Kernel Driver Modules (optional)
|
||||
|
||||
Comedi is now part of the Linux kernel and it can automatically load the correct modules for the hardware present. If you have problems then you could set up manual loading of a specific set of kernel modules. The correct module names for your hardware can be found on the [Comedi website](https://www.comedi.org/hardware.html). Searching for just the number part of the card name is a quick way to find it.
|
||||
|
||||
|
||||
Manual loading of kernel modules is done in two steps:
|
||||
1. Turning off automatic loading:
|
||||
Add the line `options comedi comedi_autoconfig=0` to the file `/etc/modprobe.d`
|
||||
|
||||
2. Provide the set of modules to be loaded by the kernel:
|
||||
First, copy and link the service script:
|
||||
```
|
||||
sudo cp ~/work/stxm/SystemInstall/ComediLoadModules /etc/init.d
|
||||
cd /etc/rc5.d
|
||||
sudo ln -s ../init.d/ComediLoadModules S98ComediLoadModules
|
||||
```
|
||||
|
||||
Next, edit the `loadComedi` section of `/etc/init.d/ComediLoadModules` file to load the correct driver modules with `modprobe` commands and assign the modules to comedi devices. The PolLux version look like:
|
||||
```
|
||||
. /lib/lsb/init-functions
|
||||
. /etc/default/rcS
|
||||
|
||||
loadComedi()
|
||||
{
|
||||
|
||||
sync
|
||||
modprobe comedi
|
||||
#2> /dev/null
|
||||
modprobe kcomedilib
|
||||
#2> /dev/null
|
||||
insmod $RTAI_MODULES_DIR/rtai_comedi.ko
|
||||
#2> /dev/null
|
||||
|
||||
modprobe ni_660x
|
||||
#2> /dev/null
|
||||
|
||||
modprobe ni_pcimio
|
||||
|
||||
modprobe agilent_n1231
|
||||
|
||||
sync
|
||||
|
||||
/usr/local/sbin/comedi_config /dev/comedi4 ni_660x
|
||||
/usr/local/sbin/comedi_config /dev/comedi1 ni_pcimio
|
||||
/usr/local/sbin/comedi_config /dev/comedi2 ni_pcimio
|
||||
/usr/local/sbin/comedi_config /dev/comedi3 n1231a
|
||||
/usr/local/sbin/comedi_config /dev/comedi0 ni_660x
|
||||
|
||||
chmod go+rw /dev/comedi*
|
||||
|
||||
sync
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
The Comedi device numbers ("/dev/comedi#") assigned in the loadComedi section of the script are the numbers that are referred to in the following section, so they will hopefully match when you check them. Note that the command only assigns a Comedi device number to a kernel module and not a specific card, so it is not exactly specific if you have cards sharing the same module. In such cases you can follow the rule that Comedi will first find and assign the card with the higher PCI address.
|
||||
|
||||
In the example of PolLux, `lspci` shows:
|
||||
```
|
||||
03:00.0 Bridge: Agilent Technologies Device 0a00 (rev 01)
|
||||
03:01.0 Unassigned class [ff00]: National Instruments PCI-6602 (rev 01)
|
||||
03:02.0 Unassigned class [ff00]: National Instruments PCI-6733
|
||||
03:03.0 Unassigned class [ff00]: National Instruments PCI-6289
|
||||
03:04.0 Unassigned class [ff00]: National Instruments PCI-6602 (rev 01)
|
||||
```
|
||||
|
||||
and therefore the command `/usr/local/sbin/comedi_config /dev/comedi4 ni_660x` will start by looking at the NI-6602 card in address "03:04.0" and assign it to `/dev/comedi4`.
|
||||
|
||||
The next command `/usr/local/sbin/comedi_config /dev/comedi1 ni_pcimio` will start by looking at the NI-6602 card in address "03:04.0" and ignore it because it uses a different module (as well as already being assigned), then look at the NI-6289 card in address "03:03.0", see that the module is appropriate and assign it to `/dev/comedi1`.
|
||||
|
||||
The next command `/usr/local/sbin/comedi_config /dev/comedi2 ni_pcimio` will look past address "03:04.0" (wrong module) and "03:03.0" (already assigned), and then assign `/dev/comedi2` to the NI-6733 card in PCI address "03:02.0".
|
||||
|
||||
The next two commands assign `/dev/comedi3` to the Agilent N1231A card in PCI address "03:00.0", and then assign `/dev/comedi0` to the NI-6602 card in PCI address "03:01.0"
|
||||
Orocos needs to be configured to your hardware, this involves:
|
||||
|
||||
1. Identifying (or verifying) the device numbers that Comedi is assigning to each card
|
||||
2. Set the correct device numbers in the Orocos start.ops file
|
||||
3. Load and use the correct hardware drivers in the Orocos start.ops file
|
||||
|
||||
## Agilent Interferometer PCI cards
|
||||
|
||||
The Agilent PCI cards don't have a proper kernel driver any more and are now accessed by Orocos directly via the PCI slot. This is different from other hardware and the configuration is also special. To configure access, use `lspci` to see which PCI address (number on the left) corresponds to your Agilent card and make sure that your `start.ops` includes lines similar to:
|
||||
|
||||
```
|
||||
import("SensorAgilentPCI")
|
||||
loadComponent("Sensor1","SensorAgilentPCI")
|
||||
Sensor1.deviceName = "/sys/bus/pci/devices/0000:07:00.0/"
|
||||
```
|
||||
|
||||
You should be able to see a directory in your file system that matches the `deviceName` string.
|
||||
|
||||
## Identify Device Numbers
|
||||
|
||||
The current configuration system relies on knowing the "comedi number" of each PCI card. Recent Linux kernels have stopped providing stable comedi numbers, which means that the number for each card (and the required Pixelator/Orocos configuration) can change between reboots. Future versions will be configured using the `deviceName` string that looks like "/sys/bus/pci/devices/0000:07:00.0/".
|
||||
|
||||
The command `lspci` will give a list of devices and you should note the numbers at the start of each line. These digits refer to the bus, device and function numbers. The command `ls /sys/bus/pci/devices/0000*/comedi/` will list the hardware addresses of the devices recognised by comedi. For example from PolLux:
|
||||
<pre><code>
|
||||
control@x07da-stxm-1:~$ lspci
|
||||
00:00.0 Host bridge: Intel Corporation Xeon E3-1200 v2/3rd Gen Core processor DRAM Controller (rev 09)
|
||||
00:02.0 VGA compatible controller: Intel Corporation Xeon E3-1200 v2/3rd Gen Core processor Graphics Controller (rev 09)
|
||||
00:14.0 USB controller: Intel Corporation 7 Series/C210 Series Chipset Family USB xHCI Host Controller (rev 04)
|
||||
00:16.0 Communication controller: Intel Corporation 7 Series/C216 Chipset Family MEI Controller #1 (rev 04)
|
||||
00:16.3 Serial controller: Intel Corporation 7 Series/C210 Series Chipset Family KT Controller (rev 04)
|
||||
00:19.0 Ethernet controller: Intel Corporation 82579LM Gigabit Network Connection (Lewisville) (rev 04)
|
||||
00:1a.0 USB controller: Intel Corporation 7 Series/C216 Chipset Family USB Enhanced Host Controller #2 (rev 04)
|
||||
00:1b.0 Audio device: Intel Corporation 7 Series/C216 Chipset Family High Definition Audio Controller (rev 04)
|
||||
00:1c.0 PCI bridge: Intel Corporation 7 Series/C216 Chipset Family PCI Express Root Port 1 (rev c4)
|
||||
00:1c.5 PCI bridge: Intel Corporation 7 Series/C210 Series Chipset Family PCI Express Root Port 6 (rev c4)
|
||||
00:1d.0 USB controller: Intel Corporation 7 Series/C216 Chipset Family USB Enhanced Host Controller #1 (rev 04)
|
||||
00:1e.0 PCI bridge: Intel Corporation 82801 PCI Bridge (rev a4)
|
||||
00:1f.0 ISA bridge: Intel Corporation Q77 Express Chipset LPC Controller (rev 04)
|
||||
00:1f.2 SATA controller: Intel Corporation 7 Series/C210 Series Chipset Family 6-port SATA Controller [AHCI mode] (rev 04)
|
||||
00:1f.3 SMBus: Intel Corporation 7 Series/C216 Chipset Family SMBus Controller (rev 04)
|
||||
02:00.0 Ethernet controller: Intel Corporation 82583V Gigabit Network Connection
|
||||
<b>03:00.0 Bridge: Agilent Technologies Device 0a00 (rev 01)
|
||||
03:01.0 Unassigned class [ff00]: National Instruments PCI-6602 (rev 01)
|
||||
03:02.0 Unassigned class [ff00]: National Instruments PCI-6733
|
||||
03:03.0 Unassigned class [ff00]: National Instruments PCI-6289
|
||||
03:04.0 Unassigned class [ff00]: National Instruments PCI-6602 (rev 01)</b>
|
||||
|
||||
control@x07da-stxm-1:~$ ls /sys/bus/pci/devices/0000*/comedi/
|
||||
'/sys/bus/pci/devices/0000:03:01.0/comedi/':
|
||||
comedi1
|
||||
|
||||
'/sys/bus/pci/devices/0000:03:02.0/comedi/':
|
||||
comedi0
|
||||
|
||||
'/sys/bus/pci/devices/0000:03:03.0/comedi/':
|
||||
comedi3
|
||||
|
||||
'/sys/bus/pci/devices/0000:03:04.0/comedi/':
|
||||
comedi2
|
||||
</pre></code>
|
||||
|
||||
We can use the above info to conclude:
|
||||
* comedi0 is the PCI-6733
|
||||
* comedi1 is the PCI-6602
|
||||
* comedi2 is the PCI-6602
|
||||
* comedi3 is the PCI-6289
|
||||
|
||||
|
||||
|
||||
|
||||
<details>
|
||||
<summary>Obsolete Method</summary>
|
||||
The device numbers assigned to each card can be found in the kernel message log, which is printed with `dmesg` (might need `sudo dmesg`). There can be a lot of messages to sort through, so you can narrow it down with `dmesg | grep comedi`. This should produce output that includes lines like (example from PolLux):
|
||||
|
||||
```
|
||||
[ 2.507480] comedi4: ni_660x:
|
||||
[ 2.507890] comedi: cannot get unshared interrupt, will not use RT interrupts.
|
||||
[ 2.511676] comedi1: ni_pcimio:
|
||||
[ 2.544959] comedi2: ni_pcimio:
|
||||
[ 2.546311] comedi: cannot get unshared interrupt, will not use RT interrupts.
|
||||
[ 2.547515] comedi2: ni_pcimio: possible problem - never saw adc go busy?
|
||||
[ 2.699254] comedi0: ni_660x:
|
||||
```
|
||||
We are looking for messages in the format of `comedi4: ni_660x:`, which tells us that an NI6602 card (with `ni_660x` kernel module) has been assigned the device number `4` by Comedi. Further information can often be found in the lines in between those containing "comedi" and you can use the timestamp on the left to quickly find the appropriate section of the message log. Some other useful commands for identifying hardware include:
|
||||
- `lspci`
|
||||
- `comedi_board_info /dev/comedi0` (try with each device found with `ls /dev/comedi?`)
|
||||
|
||||
This corresponds to a PolLux configuration with:
|
||||
- NI-6602 (ni_660x) assigned device number 0
|
||||
- NI-6289 (ni_pcimio) assigned device number 1
|
||||
- NI-6733 (ni_pcimio) assigned device number 2
|
||||
- Agilent N1231 (n1231a) that the kernel (i.e. Comedi) doesn't see, but is observed in PCI slot 7
|
||||
- NI-6602 (ni_660x; used for reading the output of the Attocube interferometer) assigned device number 4
|
||||
|
||||
If you have multiple cards using the same driver, then it can be a bit complicated to figure out which is which. As a rule, Comedi will tend to assign a smaller device number to the card with the higher PCI address.
|
||||
</details>
|
||||
|
||||
## Setting Device Numbers In start.ops
|
||||
|
||||
The device numbers must be assigned correctly in the `start.ops` file used to configure Orocos. The first section of the `start.ops` file for PolLux looks like:
|
||||
|
||||
```
|
||||
// deployer-gnulinux -s start.ops -linfo
|
||||
|
||||
import("SensorAgilentPCI")
|
||||
import("SensorAttocube")
|
||||
import("PIDLoop")
|
||||
import("ComController")
|
||||
import("zmqStreamer")
|
||||
import("AnalogOutputComedi")
|
||||
import("DigitalOutputComedi")
|
||||
import("TrajectoryGenerator")
|
||||
import("PositionSampler")
|
||||
import("RealtimeSampler")
|
||||
import("DigitalInputComedi")
|
||||
|
||||
|
||||
loadComponent("Sensor1","SensorAgilentPCI")
|
||||
loadComponent("Sensor2","SensorAttocube")
|
||||
loadComponent("PID0","PIDLoop")
|
||||
loadComponent("PID1","PIDLoop")
|
||||
loadComponent("PID2","PIDLoop")
|
||||
loadComponent("ComCon", "ComController")
|
||||
loadComponent("zmqStream0", "ZmqStreamer")
|
||||
loadComponent("AO1", "AnalogOutputComedi")
|
||||
loadComponent("DO1", "DigitalOutputComedi")
|
||||
loadComponent("TrajGen","TrajectoryGenerator")
|
||||
loadComponent("PosSampler","PositionSampler")
|
||||
loadComponent("RtSampler","RealtimeSampler")
|
||||
loadComponent("DI1", "DigitalInputComedi")
|
||||
```
|
||||
|
||||
Take note of each `loadComponent` command where the imported object (second argument) has "Sensor", "Input" or "Output" in the name. Each of these will need to be assigned a device number, using the name given in the first argument of the command.
|
||||
|
||||
In this case, we should declare the following assignments:
|
||||
```
|
||||
Sensor1.deviceName = "/sys/bus/pci/devices/0000:07:00.0/"
|
||||
Sensor2.deviceNr=4
|
||||
AO1.deviceNr=2
|
||||
DO1.deviceNr=2
|
||||
DI1.deviceNr=2
|
||||
```
|
||||
These assignments must be declared after the corresponding device names are defined with `loadComponent` and before they are configured with a command like `Sensor1.configure()`.
|
||||
|
||||
**WARNING** : There are currently some inconsistencies in the device number variable names and whether the "configure" and "start" functions use parentheses. The plan is to standardise on "deviceNr" and "configure()"
|
||||
|
||||
| Device Type | Variable Name | Function Syntax |
|
||||
| ------ | ------ | ------ |
|
||||
| SensorAgilentPCI | deviceName | configure; start |
|
||||
| SensorAttocube | device_nr | configure; start |
|
||||
| AnalogOutputComedi | device_nr | configure(); start() |
|
||||
| DigitalOutputComedi | device_nr | configure(); start() |
|
||||
| DigitalInputComedi | deviceNr | configure; start |
|
||||
|
||||
## Configuring start.ops
|
||||
|
||||
The `start.ops` file tells Orocos how to define devices and how signals are interconnected. Note that the feedback loops are "PID0" for the X-axis, "PID1" for the Y-axis and "PID2" for the Z-axis.
|
||||
|
||||
It is probably best to start with the file configured for PolLux ([PixelatorRealtime/startup/PolLux/start.ops](https://gitlab.psi.ch/microspectro/pixelator/-/blob/master/PixelatorRealtime/startup/PolLux/start.ops)) and adapting to your instrument. There are three things that might make PolLux different from your system:
|
||||
1. The device numbers.
|
||||
2. The interferometer module(s).
|
||||
3. The number of interferometer axes being used.
|
||||
|
||||
### Device Numbers
|
||||
Currently, the device numbers at PolLux match the hard-coded defaults and so no device numbers are set. The section above discusses how to set the appropriate device numbers in `start.ops`.
|
||||
|
||||
### Interferometer Module(s) and Axes
|
||||
An interferometer module is first imported (`import()`) and then loaded and assigned a name (`loadComponent()`). PolLux uses an Agilent interferometer for the X- and Y-axes, and an Attocube interferometer for the Z-axis. You should only import the module(s) that you need for the interferometer type(s) used in your instrument. If you only have one interferometer type, then you should delete one of the `import()` commands and one of the `loadComponent()` commands so that the remaining commands refer to the interferometer module that you want to use. Further, ensure that the `loadComponent()` command uses a name (first argument, e.g. "Sensor1") that is used consistently for later commands.
|
||||
|
||||
Next, you should set the interferometer resolution for each channel, for example:
|
||||
```
|
||||
Sensor1.resolution[0]=0.000309078
|
||||
Sensor1.resolution[1]=0.000309078
|
||||
Sensor1.resolution[2]=0.000309078
|
||||
```
|
||||
It is OK to set as many channels as exists on the hardware (usually 3), even if you are not measuring that many axes. The resolution value is calculated by the laser wavelength (in microns) divided by the interpolator factor (Agilent N1231A is 512 and N1231B is 1024) and then divided by the number of laser paths (a double-pass, with 2 bounces off the mirror gives 4).
|
||||
|
||||
Next, you will need to modify or delete a bunch of commands, depending on whether you have a Z-axis interferometer.
|
||||
|
||||
#### Two Interferometer Axes (of same type)
|
||||
If you have only X- and Y-axis interferometers, you can delete all commands (the full line) that include either "Sensor2" or "PID2" (or both). Need to include the line `ComCon.nrPID=2` in start.ops.
|
||||
|
||||
#### Three Interferometer Axes (of same type)
|
||||
If you have X-, Y- and Z-axis interferometers, you should first look at every `connect()` command and change any instance of "Sensor2.*Output_0" (where * is either "position" or "status") in that command to "Sensor1.*Output_2". After doing this throughout the file, you should delete any command (the full line) that still contains "Sensor2". Need to include the line `ComCon.nrPID=3` in start.ops.
|
||||
|
||||
|
||||
## Manual Loading of Kernel Driver Modules (optional)
|
||||
|
||||
Comedi is now part of the Linux kernel and it can automatically load the correct modules for the hardware present. If you have problems then you could set up manual loading of a specific set of kernel modules. The correct module names for your hardware can be found on the [Comedi website](https://www.comedi.org/hardware.html). Searching for just the number part of the card name is a quick way to find it.
|
||||
|
||||
|
||||
Manual loading of kernel modules is done in two steps:
|
||||
1. Turning off automatic loading:
|
||||
Add the line `options comedi comedi_autoconfig=0` to the file `/etc/modprobe.d`
|
||||
|
||||
2. Provide the set of modules to be loaded by the kernel:
|
||||
First, copy and link the service script:
|
||||
```
|
||||
sudo cp ~/work/stxm/SystemInstall/ComediLoadModules /etc/init.d
|
||||
cd /etc/rc5.d
|
||||
sudo ln -s ../init.d/ComediLoadModules S98ComediLoadModules
|
||||
```
|
||||
|
||||
Next, edit the `loadComedi` section of `/etc/init.d/ComediLoadModules` file to load the correct driver modules with `modprobe` commands and assign the modules to comedi devices. The PolLux version look like:
|
||||
```
|
||||
. /lib/lsb/init-functions
|
||||
. /etc/default/rcS
|
||||
|
||||
loadComedi()
|
||||
{
|
||||
|
||||
sync
|
||||
modprobe comedi
|
||||
#2> /dev/null
|
||||
modprobe kcomedilib
|
||||
#2> /dev/null
|
||||
insmod $RTAI_MODULES_DIR/rtai_comedi.ko
|
||||
#2> /dev/null
|
||||
|
||||
modprobe ni_660x
|
||||
#2> /dev/null
|
||||
|
||||
modprobe ni_pcimio
|
||||
|
||||
modprobe agilent_n1231
|
||||
|
||||
sync
|
||||
|
||||
/usr/local/sbin/comedi_config /dev/comedi4 ni_660x
|
||||
/usr/local/sbin/comedi_config /dev/comedi1 ni_pcimio
|
||||
/usr/local/sbin/comedi_config /dev/comedi2 ni_pcimio
|
||||
/usr/local/sbin/comedi_config /dev/comedi3 n1231a
|
||||
/usr/local/sbin/comedi_config /dev/comedi0 ni_660x
|
||||
|
||||
chmod go+rw /dev/comedi*
|
||||
|
||||
sync
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
The Comedi device numbers ("/dev/comedi#") assigned in the loadComedi section of the script are the numbers that are referred to in the following section, so they will hopefully match when you check them. Note that the command only assigns a Comedi device number to a kernel module and not a specific card, so it is not exactly specific if you have cards sharing the same module. In such cases you can follow the rule that Comedi will first find and assign the card with the higher PCI address.
|
||||
|
||||
In the example of PolLux, `lspci` shows:
|
||||
```
|
||||
03:00.0 Bridge: Agilent Technologies Device 0a00 (rev 01)
|
||||
03:01.0 Unassigned class [ff00]: National Instruments PCI-6602 (rev 01)
|
||||
03:02.0 Unassigned class [ff00]: National Instruments PCI-6733
|
||||
03:03.0 Unassigned class [ff00]: National Instruments PCI-6289
|
||||
03:04.0 Unassigned class [ff00]: National Instruments PCI-6602 (rev 01)
|
||||
```
|
||||
|
||||
and therefore the command `/usr/local/sbin/comedi_config /dev/comedi4 ni_660x` will start by looking at the NI-6602 card in address "03:04.0" and assign it to `/dev/comedi4`.
|
||||
|
||||
The next command `/usr/local/sbin/comedi_config /dev/comedi1 ni_pcimio` will start by looking at the NI-6602 card in address "03:04.0" and ignore it because it uses a different module (as well as already being assigned), then look at the NI-6289 card in address "03:03.0", see that the module is appropriate and assign it to `/dev/comedi1`.
|
||||
|
||||
The next command `/usr/local/sbin/comedi_config /dev/comedi2 ni_pcimio` will look past address "03:04.0" (wrong module) and "03:03.0" (already assigned), and then assign `/dev/comedi2` to the NI-6733 card in PCI address "03:02.0".
|
||||
|
||||
The next two commands assign `/dev/comedi3` to the Agilent N1231A card in PCI address "03:00.0", and then assign `/dev/comedi0` to the NI-6602 card in PCI address "03:01.0"
|
||||
|
||||
Reference in New Issue
Block a user