Variable Reluctance (VR) Family Guide
Overview
The VR family is NAI’s line of variable-reluctance sensor and general-purpose pulse-counter smart function modules. Where an AD module asks “how much voltage is on this line?”, a VR module asks “how fast is this shaft turning, and how hard is it being twisted?” — it conditions the raw signal from a magnetic speed pickup and turns it into calibrated frequency, RPM, period, amplitude, phase, and torque readings your software can use directly. Each module has eight independent, isolated channels.
This page is the starting point for any VR module. Use it to understand what the family does, wire a sensor to a channel, set the front-end up for that sensor’s signal, and confirm the module is measuring. It’s aimed at engineers reading shaft speed, position, and torque — and counting pulses from any AC or pulsed source — across aircraft, marine, automotive, and industrial drivetrains.
A variable-reluctance (VR) sensor is a passive magnetic pickup: a permanent magnet and a coil mounted next to a rotating ferrous gear (a “reluctor” or “tone wheel”). As each tooth passes the pole piece it changes the magnetic flux, inducing an AC voltage in the coil — one cycle per tooth. Because the sensor is passive, both the amplitude and the frequency of that signal rise with shaft speed, and at low speed the signal can be very small and noisy. The VR1’s front end is built for exactly that: a high-gain programmable amplifier and comparator with adaptive thresholds and conditioning that re-define clean pulse edges even from a weak or noisy pickup, so the measurement stays solid across a wide speed range. The same front end also works as a general-purpose counter for any AC or pulsed signal (e.g. a Hall-effect sensor), handling inputs as large as ±100 V and frequencies to 1 MHz.
In a real system, a VR module is the rotational front-end. Concretely, it reads from: engine crankshaft and camshaft sensors, transmission and driveline speed pickups, brake and gear-rotor sensors, turbine and pump tachometers, and torque sensors that encode shaft twist as a phase shift between two pulse trains. It also tracks signal health per channel and can flag termination faults and signal loss so the host knows when a pickup has dropped out.
VR modules at a glance
VR1 is the current member of the family. All eight channels are independent, isolated, and identically capable — you configure each one to match the sensor wired to it.
| Module | Channels | Input range | Max frequency | Resolution | Manual |
|---|---|---|---|---|---|
| VR1 | 8 | ±100 V* | 1 MHz (continuous) | 1 ns period / 8 ns effective | VR1 Manual |
*±60 V on modules with FPGA rev 1.x. With auto-threshold and auto-ranging enabled, the practical measurement ceiling is ~20 kHz; higher rates need fixed range/threshold settings.
Channels are paired in groups of two — (1,2), (3,4), (5,6), (7,8) — which matters for torque, as explained below. Each channel runs an initiated built-in test (IBIT) against an internal reference, and reports BIT, termination-fault, signal-loss, and summary status.
What a VR channel can measure
A VR channel does three conceptually different jobs. They all use the same API — the “mode” is just a control bit plus which measurement you read — but it’s worth knowing which job you’re doing before you wire anything:
- Monopole (single sensor). One sensor, one pulse train. The channel reports amplitude, frequency, period, and — once you tell it how many teeth are on the wheel — RPM. This is the common speed/tach case.
- Dipole / paired channels (torque & phase). Torque is measured as the twist angle of a shaft, which shows up as a phase difference between two pulse trains taken at two points on the shaft. You can get that two ways: feed both pickups as one composite signal into a single channel (
Dipole Enable = 1), or feed them into the two channels of a pair and use paired mode (Dipole Enable = 0, the default — channel 1’s phase is measured against channel 2). Either way the channel reports phase and a percent-torque value scaled from your zero- and max-torque references. - General-purpose counter. Treat the input as plain pulses and read a free-running 32-bit cycle count of signal transitions — useful for any AC or pulsed sensor, not just VR pickups. Reset the count on demand.
The distinction that matters: monopole vs dipole is set with the Dipole Enable control; everything else is the same front-end and the same calls.
Physical setup
Each VR channel is an isolated, differential input. You bring the sensor’s two leads to the channel’s signal/return pins; the exact breakout pin numbers depend on your motherboard slot and connector, so always get them from the VR1 Manual pin-out appendix or the motherboard overlay. The pattern is the same for every channel:
- Identify the module’s slot number on your NAI motherboard or system.
- Bring the channel’s lines out through the breakout board, where the slot’s pins appear as generic IO# numbers.
- Map the IO# pins to that channel’s signal and return.
- Connect the sensor (and, for paired torque, the second sensor to the paired channel).
A few things hold for every VR channel:
- The front end is off-target until you configure it. Thresholds default to 0 V and range defaults to auto. A real VR pickup’s amplitude changes with speed, so you’ll usually either enable auto-threshold (track the threshold to a percentage of the measured peak) and auto-range, or set a fixed range and high/low voltage thresholds that match your signal. Leave everything at default with a weak signal and you may see no pulses.
- Termination is selectable. Each channel can present a 50 Ω (nominal) termination or a high-impedance input. Match it to your cable/sensor; a mismatch shows up as a termination-fault status.
- AC- or DC-couple per channel. AC-couple to strip a DC offset from the pickup, or DC-couple for signals referenced to ground.
- Polarity picks the active edge. Measure timing from the rising edge (default) or the falling edge.
- Pairs matter for torque. Channels pair as (1,2)/(3,4)/(5,6)/(7,8). For paired-mode torque, wire the two pickups to the two channels of one pair.
Example — single speed sensor (monopole):
- Wire the VR pickup to one channel’s signal/return.
- Set a range and high/low thresholds for the pickup’s amplitude (or enable auto-threshold + auto-range for a signal that varies widely with speed).
- Set the channel’s number of teeth to match the reluctor ring.
- Read frequency and RPM.
Example — shaft torque (paired channels):
- Wire the two pickups (one at each end of the shaft section) to the two channels of a pair, e.g. channels 1 and 2.
- Leave Dipole Enable = 0 (paired mode) on the pair.
- At a known zero-torque condition, strobe set-zero-torque-phase to null the reading; set the max-torque signal phase that corresponds to 100% torque.
- Read percent torque (and phase) from the channel.
Software
You drive a VR module through the naibrd_VR_* API in the NAI Software Support Kit (SSK). The same calls work across every OS NAI supports (PetaLinux/ARM Linux, VxWorks, DEOS, Windows) — only the build and deploy steps differ by platform.
There is no open/init/free lifecycle for a VR channel. Almost every call takes (cardIndex, module, channel) (a few module-wide calls take just (cardIndex, module)), so the working pattern is: configure the channel’s front end, then read its measurements.
- Configure the channel — range/threshold (or auto-threshold + auto-range), termination, AC/DC couple, polarity, debounce and averaging, then the measurement-specific settings (monopole/dipole, number of teeth for RPM, zero/max torque phase for torque).
- Read the channel — frequency, RPM, period, amplitude, phase, percent torque, or cycle count — and check status/BIT as needed.
Where to find what you need:
- Which functions/registers to call — the VR1 Manual documents every register (measurement, control, threshold, range, torque, status, BIT) and the SSK headers expose them through the
naibrd_VR_*calls below. - Building and deploying on your platform — Connecting to Boards covers the toolchain, deployment, and terminal access for PetaLinux/ARM Linux, VxWorks, DEOS, and Windows.
- Launching the app on the board itself — Running Applications from the Target walks through loading and launching your executable on the target.
Example — a 68ARM4 SBC with a VR1 module: pull the naibrd_VR_* calls from the VR1 Manual, set up the ARM Linux toolchain per Connecting to Boards, then load and launch a VR sample on the target per Running Applications from the Target.
Note
A VR channel reports its readings as a
float64_tdirectly fromnaibrd_VR_GetMeasurementregardless of the module’s integer/floating-point register mode — the SSK does the conversion for you, so you normally don’t touch the floating-point-mode register from your own code.
Confirm communication
A VR module measures an external signal, so confirm the path in two steps: first prove the module is alive and healthy with IBIT (no wiring), then prove it’s actually measuring with a known input signal.
Initiated built-in test (no wiring). The VR1 can momentarily take channels offline (~1 ms) and measure an internal reference signal, reporting the result in the BIT status. Run it and check that no BIT fault is latched:
/* SSK 2.x */
nai_status_bit_t bitStatus;
naibrd_VR_SetModuleBITEnable(cardIndex, module, NAIBRD_VR_TEST_ENABLE_IBIT_D3, NAI_TRUE); /* run IBIT */
naibrd_VR_GetChanMappedStatus(cardIndex, module, channel,
NAIBRD_VR_CHAN_MAPPED_STATUS_BIT_LATCHED, &bitStatus); /* any BIT fault? (LO = normal) *//* SSK 1.x */
nai_status_bit_t bitStatus;
naibrd_VR_SetModuleBITEnable(cardIndex, module, NAI_VR_TEST_ENABLE_IBIT_D3, TRUE); /* run IBIT */
naibrd_VR_GetChanMappedStatus(cardIndex, module, channel,
NAI_VR_CHAN_MAPPED_STATUS_BIT_LATCHED, &bitStatus); /* any BIT fault? (LO = normal) */A successful read with no latched BIT fault proves the link, the SSK, and the module’s front end are all working.
Known-signal check (minimal wiring). To prove a channel is actually converting, drive it from a signal whose frequency you can predict — a function/signal generator, or any sensor spinning at a known rate — then configure the front end and read it back:
/* SSK 2.x */
float64_t freq, rpm;
naibrd_VR_SetChanMappedControl(cardIndex, module, channel,
NAIBRD_VR_CHAN_MAPPED_CONTROL_AUTO_THRESHOLD_ENABLE, NAI_TRUE); /* track threshold to the signal */
naibrd_VR_SetRangeSelect(cardIndex, module, channel, NAIBRD_VR_RANGE_AUTO);
naibrd_VR_SetConfigValue(cardIndex, module, channel, NAIBRD_VR_CONFIG_NUMBER_OF_TEETH, 60.0);
naibrd_VR_GetMeasurement(cardIndex, module, channel, NAIBRD_VR_MEASURED_FREQUENCY, &freq); /* should match the source */
naibrd_VR_GetMeasurement(cardIndex, module, channel, NAIBRD_VR_MEASURED_RPM, &rpm);/* SSK 1.x */
float64_t freq, rpm;
naibrd_VR_SetChanMappedControl(cardIndex, module, channel,
NAI_VR_CHAN_MAPPED_CONTROL_AUTO_THRESHOLD_ENABLE, TRUE); /* track threshold to the signal */
naibrd_VR_SetRangeSelect(cardIndex, module, channel, NAI_VR_RANGE_AUTO);
naibrd_VR_SetConfigValue(cardIndex, module, channel, NAI_VR_CONFIG_NUMBER_OF_TEETH, 60.0);
naibrd_VR_GetMeasurement(cardIndex, module, channel, NAI_VR_MEASURED_FREQUENCY, &freq); /* should match the source */
naibrd_VR_GetMeasurement(cardIndex, module, channel, NAI_VR_MEASURED_RPM, &rpm);Feed in a known frequency and freq should match it; with the tooth count set, rpm follows. The VR BasicOps sample walks through this whole configure-and-read flow interactively — channel setup, continuous readings, test setup, and status monitoring.
Features
Everything a VR channel does falls into four areas: reading the measurements it computes, configuring the front end so those measurements are clean, configuring the measurement mode (monopole/dipole, teeth, torque references), and watching status and health. Each block below lists the naibrd_VR_* calls for that area, with SSK 1.x and 2.x signatures side by side. The function names are identical across versions — the only differences are the enum prefix (NAI_VR_… in 1.x, NAIBRD_VR_… in 2.x) and the interrupt-trigger type.
Read measurements
What it does: Returns whichever of the channel’s seven measured values you ask for through a single call — period, phase, percent torque, amplitude, frequency, RPM, or cycle count — as a float64_t in engineering units. The free-running cycle counter can be reset on demand.
Relevant APIs:
/* SSK 1.x */
nai_status_t naibrd_VR_GetMeasurement(int32_t cardIndex, int32_t module, int32_t channel, nai_vr_measured_value_type_t measValueType, float64_t* p_outMeasurement);
nai_status_t naibrd_VR_ResetCycleCount(int32_t cardIndex, int32_t module, int32_t channel);/* SSK 2.x */
nai_status_t naibrd_VR_GetMeasurement(int32_t cardIndex, int32_t module, int32_t channel, naibrd_vr_measured_value_type_t measValueType, float64_t* p_outMeasurement);
nai_status_t naibrd_VR_ResetCycleCount(int32_t cardIndex, int32_t module, int32_t channel);The measurement selector is NAIBRD_VR_MEASURED_PERIOD, …_PHASE, …_PERCENT_TORQUE, …_AMPLITUDE, …_FREQUENCY, …_RPM, …_CYCLE_COUNT (1.x: NAI_VR_MEASURED_…).
Exercise it: VR BasicOps (SSK 2.x) · Placeholder for SSK 1.X Sample App Page.
Configure the front end
What it does: Conditions the raw sensor signal so the channel triggers cleanly. Set the range/gain (fixed, or …_RANGE_AUTO for auto-ranging, with auto-down-range time controlling how fast gain increases), the high/low voltage thresholds (or enable auto-threshold to track the threshold to a percentage of the measured peak, with a hysteresis to reject noise), termination (50 Ω vs hi-Z), AC/DC couple, polarity (rising vs falling edge), plus averaging time (steadier readings) and debounce time (reject spurious transitions).
Relevant APIs:
/* SSK 1.x */
nai_status_t naibrd_VR_SetRangeSelect(int32_t cardIndex, int32_t module, int32_t channel, nai_vr_range_select_type_t range);
nai_status_t naibrd_VR_SetAutoDownRangeTime(int32_t cardIndex, int32_t module, int32_t channel, nai_vr_auto_down_range_time_type_t autoDownRangeTime);
nai_status_t naibrd_VR_SetConfigValue(int32_t cardIndex, int32_t module, int32_t channel, nai_vr_config_value_type_t configValueType, float64_t configValue);
nai_status_t naibrd_VR_SetChanMappedControl(int32_t cardIndex, int32_t module, int32_t channel, nai_vr_chan_mapped_control_type_t controlType, bool_t enable);
nai_status_t naibrd_VR_SetPowerSupplyEnable(int32_t cardIndex, int32_t module, bool_t enable);/* SSK 2.x */
nai_status_t naibrd_VR_SetRangeSelect(int32_t cardIndex, int32_t module, int32_t channel, naibrd_vr_range_select_type_t range);
nai_status_t naibrd_VR_SetAutoDownRangeTime(int32_t cardIndex, int32_t module, int32_t channel, naibrd_vr_auto_down_range_time_type_t autoDownRangeTime);
nai_status_t naibrd_VR_SetConfigValue(int32_t cardIndex, int32_t module, int32_t channel, naibrd_vr_config_value_type_t configValueType, float64_t configValue);
nai_status_t naibrd_VR_SetChanMappedControl(int32_t cardIndex, int32_t module, int32_t channel, naibrd_vr_chan_mapped_control_type_t controlType, bool_t enable);
nai_status_t naibrd_VR_SetPowerSupplyEnable(int32_t cardIndex, int32_t module, bool_t enable);Each setter has a matching naibrd_VR_Get… to read the value back. The front-end config values set through SetConfigValue are NAIBRD_VR_CONFIG_VOLTAGE_THRESHOLD_HIGH, …_VOLTAGE_THRESHOLD_LOW, …_AVERAGING_TIME, …_DEBOUNCE_TIME, …_MINIMUM_AMPLITUDE, …_MINIMUM_FREQUENCY, …_AUTO_THRESHOLD_PERCENT, and …_AUTO_THRESHOLD_HYSTERESIS; the on/off front-end controls set through SetChanMappedControl are NAIBRD_VR_CHAN_MAPPED_CONTROL_TERMINATION_ENABLE, …_AC_COUPLE_ENABLE, …_FALLING_EDGE_MEASUREMENT_ENABLE (polarity), and …_AUTO_THRESHOLD_ENABLE (1.x: NAI_VR_…). Range uses NAIBRD_VR_RANGE_AUTO / …_50mV … …_100V.
Exercise it: VR BasicOps (SSK 2.x) · Placeholder for SSK 1.X Sample App Page.
Configure the measurement mode
What it does: Tells the channel what it’s measuring. Enable the channel; pick monopole or dipole (DIPOLE_ENABLE); set the number of teeth so RPM is computed correctly; and for torque, set the zero-torque signal phase (or strobe SetZeroTorqueSignalPhaseToPhaseReading to capture the present phase as the zero reference) and the max-torque signal phase that represents 100% torque. Min-amplitude and min-frequency thresholds (set via SetConfigValue) define when a channel reports signal loss.
Relevant APIs:
/* SSK 1.x */
nai_status_t naibrd_VR_SetChanMappedControl(int32_t cardIndex, int32_t module, int32_t channel, nai_vr_chan_mapped_control_type_t controlType, bool_t enable);
nai_status_t naibrd_VR_SetConfigValue(int32_t cardIndex, int32_t module, int32_t channel, nai_vr_config_value_type_t configValueType, float64_t configValue);
nai_status_t naibrd_VR_SetZeroTorqueSignalPhaseToPhaseReading(int32_t cardIndex, int32_t module, int32_t channel);/* SSK 2.x */
nai_status_t naibrd_VR_SetChanMappedControl(int32_t cardIndex, int32_t module, int32_t channel, naibrd_vr_chan_mapped_control_type_t controlType, bool_t enable);
nai_status_t naibrd_VR_SetConfigValue(int32_t cardIndex, int32_t module, int32_t channel, naibrd_vr_config_value_type_t configValueType, float64_t configValue);
nai_status_t naibrd_VR_SetZeroTorqueSignalPhaseToPhaseReading(int32_t cardIndex, int32_t module, int32_t channel);The mode controls are NAIBRD_VR_CHAN_MAPPED_CONTROL_CHANNEL_ENABLE and …_DIPOLE_ENABLE (0 = monopole/paired, 1 = dipole); the mode config values are NAIBRD_VR_CONFIG_NUMBER_OF_TEETH, …_ZERO_TORQUE_SIGNAL_PHASE, …_MAX_TORQUE_SIGNAL_PHASE, …_MINIMUM_AMPLITUDE, and …_MINIMUM_FREQUENCY (1.x: NAI_VR_…).
Exercise it: VR BasicOps (SSK 2.x) · Placeholder for SSK 1.X Sample App Page.
Status, BIT & interrupts
What it does: Each channel reports BIT, termination-fault, signal-loss, and a summary status, each in latched and realtime forms, and each able to raise an interrupt. SetChanStatusEnable turns per-channel status reporting on (and can mask unused channels); SetModuleBITEnable runs the IBIT.
Relevant APIs:
/* SSK 1.x */
nai_status_t naibrd_VR_GetChanMappedStatus(int32_t cardIndex, int32_t module, int32_t channel, nai_vr_chan_mapped_status_type_t statusType, nai_status_bit_t* p_outStatusBit);
nai_status_t naibrd_VR_ClearChanMappedStatus(int32_t cardIndex, int32_t module, int32_t channel, nai_vr_chan_mapped_status_type_t statusType);
nai_status_t naibrd_VR_SetChanStatusEnable(int32_t cardIndex, int32_t module, int32_t channel, bool_t enable);
nai_status_t naibrd_VR_SetModuleBITEnable(int32_t cardIndex, int32_t module, nai_vr_test_enable_t type, bool_t bitEnable);
nai_status_t naibrd_VR_SetChanMappedInterruptEnable(int32_t cardIndex, int32_t module, int32_t channel, nai_vr_chan_mapped_status_type_t type, bool_t intEnable);
nai_status_t naibrd_VR_SetChanMappedInterruptTriggerType(int32_t cardIndex, int32_t module, int32_t channel, nai_vr_chan_mapped_status_type_t type, nai_vr_interrupt_t interruptType);/* SSK 2.x */
nai_status_t naibrd_VR_GetChanMappedStatus(int32_t cardIndex, int32_t module, int32_t channel, naibrd_vr_chan_mapped_status_type_t statusType, nai_status_bit_t* p_outStatusBit);
nai_status_t naibrd_VR_ClearChanMappedStatus(int32_t cardIndex, int32_t module, int32_t channel, naibrd_vr_chan_mapped_status_type_t statusType);
nai_status_t naibrd_VR_SetChanStatusEnable(int32_t cardIndex, int32_t module, int32_t channel, bool_t enable);
nai_status_t naibrd_VR_SetModuleBITEnable(int32_t cardIndex, int32_t module, naibrd_vr_test_enable_t type, bool_t bitEnable);
nai_status_t naibrd_VR_SetChanMappedInterruptEnable(int32_t cardIndex, int32_t module, int32_t channel, naibrd_vr_chan_mapped_status_type_t type, bool_t intEnable);
nai_status_t naibrd_VR_SetChanMappedInterruptTriggerType(int32_t cardIndex, int32_t module, int32_t channel, naibrd_vr_chan_mapped_status_type_t type, naibrd_int_trigger_type_t interruptType);The status selectors are NAIBRD_VR_CHAN_MAPPED_STATUS_BIT_LATCHED / …_BIT_REALTIME, …_TERMINATION_FAULT_LATCHED / …_REALTIME, …_SIGNAL_LOSS_LATCHED / …_REALTIME, and …_SUMMARY_LATCHED / …_REALTIME (1.x: NAI_VR_…). Interrupt vector and steering also have setters (…InterruptVector / …InterruptSteering) if you route interrupts to a specific handler.
Exercise it: VR BasicOps (SSK 2.x) · Placeholder for SSK 1.X Sample App Page.
Try it
Three short sequences that build on each other. They use card 0, module 1, channel 1; substitute your own slot and channel.
1. Set up a speed sensor and read frequency + RPM (monopole). Auto-range and auto-threshold let the channel track a signal whose amplitude changes with speed; set the tooth count so RPM is right:
/* SSK 1.x */
int32_t cardIndex = 0, module = 1, channel = 1;
float64_t freq, rpm;
naibrd_VR_SetChanMappedControl(cardIndex, module, channel, NAI_VR_CHAN_MAPPED_CONTROL_CHANNEL_ENABLE, TRUE);
naibrd_VR_SetChanMappedControl(cardIndex, module, channel, NAI_VR_CHAN_MAPPED_CONTROL_DIPOLE_ENABLE, FALSE); /* monopole */
naibrd_VR_SetRangeSelect(cardIndex, module, channel, NAI_VR_RANGE_AUTO);
naibrd_VR_SetChanMappedControl(cardIndex, module, channel, NAI_VR_CHAN_MAPPED_CONTROL_AUTO_THRESHOLD_ENABLE, TRUE);
naibrd_VR_SetConfigValue(cardIndex, module, channel, NAI_VR_CONFIG_NUMBER_OF_TEETH, 60.0);
naibrd_VR_GetMeasurement(cardIndex, module, channel, NAI_VR_MEASURED_FREQUENCY, &freq);
naibrd_VR_GetMeasurement(cardIndex, module, channel, NAI_VR_MEASURED_RPM, &rpm);/* SSK 2.x */
int32_t cardIndex = 0, module = 1, channel = 1;
float64_t freq, rpm;
naibrd_VR_SetChanMappedControl(cardIndex, module, channel, NAIBRD_VR_CHAN_MAPPED_CONTROL_CHANNEL_ENABLE, NAI_TRUE);
naibrd_VR_SetChanMappedControl(cardIndex, module, channel, NAIBRD_VR_CHAN_MAPPED_CONTROL_DIPOLE_ENABLE, NAI_FALSE); /* monopole */
naibrd_VR_SetRangeSelect(cardIndex, module, channel, NAIBRD_VR_RANGE_AUTO);
naibrd_VR_SetChanMappedControl(cardIndex, module, channel, NAIBRD_VR_CHAN_MAPPED_CONTROL_AUTO_THRESHOLD_ENABLE, NAI_TRUE);
naibrd_VR_SetConfigValue(cardIndex, module, channel, NAIBRD_VR_CONFIG_NUMBER_OF_TEETH, 60.0);
naibrd_VR_GetMeasurement(cardIndex, module, channel, NAIBRD_VR_MEASURED_FREQUENCY, &freq);
naibrd_VR_GetMeasurement(cardIndex, module, channel, NAIBRD_VR_MEASURED_RPM, &rpm);2. Measure shaft torque (paired channels). With both pickups wired to a pair and the pair in paired mode, null the reading at zero torque, set the phase that means 100% torque, then read percent torque:
/* SSK 1.x */
float64_t phase, pctTorque;
/* Pair (1,2) in paired mode: leave DIPOLE_ENABLE = FALSE on both channels */
naibrd_VR_SetConfigValue(cardIndex, module, channel, NAI_VR_CONFIG_MAX_TORQUE_SIGNAL_PHASE, 5.0); /* e.g. 5° = 100% */
/* At a known zero-torque condition, capture the present phase as the zero reference: */
naibrd_VR_SetZeroTorqueSignalPhaseToPhaseReading(cardIndex, module, channel);
naibrd_VR_GetMeasurement(cardIndex, module, channel, NAI_VR_MEASURED_PHASE, &phase);
naibrd_VR_GetMeasurement(cardIndex, module, channel, NAI_VR_MEASURED_PERCENT_TORQUE, &pctTorque);/* SSK 2.x */
float64_t phase, pctTorque;
/* Pair (1,2) in paired mode: leave DIPOLE_ENABLE = NAI_FALSE on both channels */
naibrd_VR_SetConfigValue(cardIndex, module, channel, NAIBRD_VR_CONFIG_MAX_TORQUE_SIGNAL_PHASE, 5.0); /* e.g. 5° = 100% */
/* At a known zero-torque condition, capture the present phase as the zero reference: */
naibrd_VR_SetZeroTorqueSignalPhaseToPhaseReading(cardIndex, module, channel);
naibrd_VR_GetMeasurement(cardIndex, module, channel, NAIBRD_VR_MEASURED_PHASE, &phase);
naibrd_VR_GetMeasurement(cardIndex, module, channel, NAIBRD_VR_MEASURED_PERCENT_TORQUE, &pctTorque);3. Count pulses (general-purpose counter). Read the free-running cycle count, then reset it:
/* SSK 1.x */
float64_t cycles;
naibrd_VR_GetMeasurement(cardIndex, module, channel, NAI_VR_MEASURED_CYCLE_COUNT, &cycles);
naibrd_VR_ResetCycleCount(cardIndex, module, channel); /* zero the counter *//* SSK 2.x */
float64_t cycles;
naibrd_VR_GetMeasurement(cardIndex, module, channel, NAIBRD_VR_MEASURED_CYCLE_COUNT, &cycles);
naibrd_VR_ResetCycleCount(cardIndex, module, channel); /* zero the counter */Run them: VR BasicOps (SSK 2.x) · Placeholder for SSK 1.X Sample App Page. For the full set of sample apps — and how to build and run them — see the sample-application guides: Using NAI SSK 2.x Sample Applications · Using NAI SSK 1.x Sample Applications.
Hardware capabilities and status monitoring
Beyond the measurements themselves, each VR channel provides hardware that conditions the signal and reports health you can monitor:
- Adaptive high-gain front end — a programmable amplifier and comparator with auto-threshold and auto-ranging that re-define clean pulse edges from weak or noisy pickups, with selectable range (±50 mV to ±100 V), debounce, and averaging.
- Per-channel signal conditioning — selectable 50 Ω termination, AC/DC coupling, and rising/falling-edge polarity.
- Isolated channels — eight isolated, differential inputs minimize false counts from electrical noise; unused channel pairs can be disabled to save power.
- Monopole / dipole / paired modes — single-sensor speed, composite-signal dipole, or paired-channel torque from one front end.
- General-purpose 32-bit counter — count up on any AC or pulsed signal, resettable on demand.
- Initiated BIT — an internal reference measurement on enabled channels (~1 ms offline) for an integrity check on demand.
Statuses you can monitor (each available as realtime and latched, each able to raise an interrupt):
| Status | Meaning |
|---|---|
| BIT | A built-in test fault on the channel. |
| Termination Fault | The channel’s termination is faulted (e.g. termination enabled into the wrong load). |
| Signal Loss | The input dropped below the channel’s minimum amplitude/frequency threshold. |
| Summary | Logical OR of the channel’s faults — poll this to check a channel at a glance. |
Read these per channel with naibrd_VR_GetChanMappedStatus, or poll the summary status to check the whole channel at once. SetChanStatusEnable can mask unused channels so they don’t report. ESP2’s status panel shows the same statuses interactively if you’d rather watch them in a GUI first.
Common pitfalls
- Thresholds/range left at default with no auto. Thresholds power up at 0 V and a fixed range may not match a weak pickup. For a real VR signal, enable auto-threshold + auto-range, or set a range and high/low thresholds that fit the signal — otherwise the channel may see no pulses.
- Wrong tooth count → wrong RPM. RPM is computed from frequency and the channel’s number of teeth; if it doesn’t match the reluctor ring, RPM is off by that ratio (frequency and period are still correct).
- Confusing dipole with paired mode.
Dipole Enable = 1expects one composite signal on a single channel;Dipole Enable = 0(default) uses paired mode, where a channel’s phase is measured against its pair partner ((1,2)/(3,4)/(5,6)/(7,8)). Pick the one that matches how you wired the two pickups. - Phase readings near the wrap points are unstable. Keep dipole phase away from the 0°/180° transition (center it near 90°) and monopole/paired phase away from 0°/360° (center near 180°); readings that cross those points jump.
- Termination mismatch. Enabling the 50 Ω termination into a source that expects high impedance (or vice-versa) degrades the signal and can raise a termination-fault status — match it to your cable/sensor.
- Latched statuses stay set until cleared. A latched BIT, termination-fault, or signal-loss bit remains set after the condition clears; clear it (
ClearChanMappedStatus) once handled so you can see the next event. - Auto-threshold needs enough signal. If auto-threshold isn’t tracking, the signal may be below the minimum amplitude — raise the signal level or adjust the minimum-amplitude setting.
Related resources
- VR1 Manual — full register descriptions (measurement, control, threshold, range, torque, status, BIT), electrical specs, and pin-out appendix.
- VR BasicOps (SSK 2.x) · Placeholder for SSK 1.X Sample App Page — configure a channel and read VR measurements interactively.
- Download the SSK — get the SSK and the
naibrd_VR_*headers and samples. - Connecting to Boards — toolchain, deployment, and terminal access per platform.
- Running Applications from the Target — load and launch your application on the board.
- ESP2 Quick Start — exercise VR channels with no code via the Embedded Soft Panel.
