01-09-2020 06:41 AM
Hello,
I'm trying to read the state of the cDAQ-9136 user LED and switch. The controller is running Windows (WES7). However I'm having no luck with the NI System Configuration API.
This works to get the device's serial number:
NISysCfgGetResourceProperty(ResourceHandle, NISysCfgResourcePropertySerialNumber, &SerialNumber);
so the code is generally working OK, but:
NISysCfgGetResourceProperty(ResourceHandle, NISysCfgResourcePropertyNumberOfUserLedIndicators, &NumberOfUserLedIndicators);
NISysCfgGetResourceProperty(ResourceHandle, NISysCfgResourcePropertyNumberOfUserSwitches, &NumberOfUserSwitches);
returns error code NISysCfg_PropDoesNotExist (-2147220623)
Is it possible to read/set LED or switch states with this hardware?
Many thanks, Ben.
Solved! Go to Solution.
01-14-2020 05:57 AM
Hi Ben,
In the NI cDAQ-913x manual, there is a description on how you can control the User LED's.
For information about programming the USER1 button, go to ni.com/info and enter the Info Code ex4b9n.
As for your Error -2147220623. Please see the attached link.
01-17-2020 05:00 AM
Hi Danielle,
Thanks for your help.
I've already read the manual which lead me to using the above function calls (I am using DAQmx with C, not LabVIEW). I've attached the code which reads the serial number OK but does not return the LED or button states due to the above error code.
The error link does not really help much as this refers to a different function call.
I'm really looking for confirmation here that the API is broken or I've done something wrong.
Thanks again, Ben.
#include "nisyscfg.h"
#include <stdio.h>
#pragma comment(lib, "nisyscfg.lib")
static NISysCfgResourceHandle ResourceHandle;
static NISysCfgEnumResourceHandle EnumResourceHandle;
static NISysCfgSessionHandle SessionHandle;
void* test;
char productName[NISYSCFG_SIMPLE_STRING_LENGTH];
int main(int argc, char *argv[])
{
NISysCfgStatus status = NISysCfgInitializeSession(NULL, NULL, NULL, NISysCfgLocaleDefault, NISysCfgBoolTrue, 10000, NULL, &SessionHandle);
if (status == 0) {
NISysCfgFindHardware(SessionHandle, NISysCfgFilterModeMatchValuesAll, NULL, "daqmx", &EnumResourceHandle);
int i = 0;
while (NISysCfgNextResource(SessionHandle, EnumResourceHandle, &ResourceHandle) == 0) {
char SerialNumber[NISYSCFG_SIMPLE_STRING_LENGTH];
SerialNumber[0] = 0x00;
unsigned int ProductId = 0;
NISysCfgGetResourceProperty(ResourceHandle, NISysCfgResourcePropertyProductName, &productName);
NISysCfgGetResourceProperty(ResourceHandle, NISysCfgResourcePropertyProductId, &ProductId);
NISysCfgGetResourceProperty(ResourceHandle, NISysCfgResourcePropertySerialNumber, &SerialNumber);
int NumberOfUserLedIndicators;
int NumberOfUserSwitches;
status = NISysCfgGetResourceProperty(ResourceHandle, NISysCfgResourcePropertyNumberOfUserLedIndicators, &NumberOfUserLedIndicators);
if (status != 0)
{
printf(" Error getting number of LED indicators %d\n", status);
NumberOfUserLedIndicators = 2;
}
status = NISysCfgGetResourceProperty(ResourceHandle, NISysCfgResourcePropertyNumberOfUserSwitches, &NumberOfUserSwitches);
if (status != 0)
{
printf(" Error getting number of switches %d\n", status);
NumberOfUserSwitches = 1;
}
printf("%d: %s\n Serial: %s ProductID: %04X\n Number of LEDs: %d Number of Switches: %d\n", i, productName, SerialNumber, ProductId, NumberOfUserLedIndicators, NumberOfUserSwitches);
NISysCfgSwitchState SwitchState = NISysCfgSwitchStateDisabled;
NISysCfgLedState LedState = NISysCfgLedStateOff;
int s;
char SwitchName[NISYSCFG_SIMPLE_STRING_LENGTH];
for (s = 0; s < NumberOfUserSwitches; s++)
{
status = NISysCfgGetResourceIndexedProperty(ResourceHandle, NISysCfgIndexedPropertyUserSwitchName, s, &SwitchName);
if (status != 0)
{
printf(" Error getting switch name %d\n", status);
}
if (NISysCfgGetResourceIndexedProperty(ResourceHandle, NISysCfgIndexedPropertyUserSwitchState, s, &SwitchState) != 0)
{
printf(" Error getting switch state %d\n", status);
}
printf(" Switch '%s': %d\n", SwitchName, SwitchState);
}
int l;
char LedName[NISYSCFG_SIMPLE_STRING_LENGTH];
for (l = 0;l<NumberOfUserLedIndicators;l++)
{
status = NISysCfgGetResourceIndexedProperty(ResourceHandle, NISysCfgIndexedPropertyUserLedName, l, &LedName);
if (status != 0)
{
printf(" Error getting LED name %d\n", status);
}
status = NISysCfgGetResourceIndexedProperty(ResourceHandle, NISysCfgIndexedPropertyUserLedState, l, &LedState);
if (status != 0)
{
printf(" Error getting LED state %d\n", status);
}
printf(" LED '%s': %d\n", LedName, LedState);
}
i++;
}
}
else {
printf("NiSysCfgInitializeSession Error Code %d", status);
}
return 0;
}
01-27-2020 03:38 PM
NISysCfgFindHardware(SessionHandle, NISysCfgFilterModeMatchValuesAll, NULL, "daqmx", &EnumResourceHandle);
I suspect this might be your problem; the buttons-and-lights on the cDAQ chassis are controlled through a different driver that isn't DAQmx. (The "expert name" for this driver in the NISysCfg API isn't documented in this list, but should be "nipie". You may also want to consider leaving this parameter as an empty string, which will return results from all drivers.)
01-29-2020 01:52 AM
Many thanks Brandon, by removing the 'daqmx' it is now returning the number, names and states of the switch and LED. It doesn't work for simulated hardware but it does for the real thing.
I noticed that when it iterates the available hardware it finds "NI cDAQ-9136" twice. Once with product ID 7834 which does not have any LED/Switches, and again as "NI cDAQ-9136" with product ID 7833 (which does not appear on the list of NI devices in "NI-DAQmx C Reference Help").
Next question is how do I set the state of the LED? There doesn't seem to be a NISysCfgSetResourceIndexedProperty but in nisyscfg.h:
// Read/Write properties
NISysCfgIndexedPropertyUserLedState = 17289216, // NISysCfgLedState
but the only function that accepts an NISysCfgIndexedProperty enumeration is NISysCfgGetResourceIndexedProperty.
Thanks again, Ben.
01-30-2020 03:51 PM
The list of devices that you reference is for devices that are usable with the NI-DAQmx API. The device with product ID 7834 is the C Series backplane device, which is device that you use with the NI-DAQmx API. The device with product ID is a different peripheral device that controls the buttons and lights on the controller. (And yes, confusingly, both are named "NI cDAQ-9136".) This is why it doesn't work with simulation-- simulation only simulates the C Series backplane device in DAQmx.
There does appear to be a lack of a NISysCfgSetResourceIndexedProperty. I've filed Bug 966684 on this discrepancy. In the meantime, you might give the following a try:
NISysCfgSetResourceProperty(ResourceHandle, (NISysCfgResourceProperty)(NISysCfgIndexedPropertyUserLedState + index), NISysCfgLedStateSolidYellow)
This utilizes an internal detail, which is that the property IDs for indexed properties store the index in the low-order bits.
02-01-2020 07:48 AM
Many thanks Brandon. I am now able to change the LED status with this and appreciate the detailed answers.
I can't set the LED to NISysCfgLedStateBlinkingGreen or NISysCfgLedStateBlinkingYellow. Is this a limitation of the cDAQ-9136 or an error? The error manifests itself as NISysCfgSaveResourceChanges returning:
NISysCfg_NoPropValidated = -2147220612L, /* 0x8004037C: None of the changed properties could be validated. */
Thanks again, Ben.
In case it is of help in the future to someone. The code I now have is:
#include "nisyscfg.h"
#include <stdio.h>
#pragma comment(lib, "nisyscfg.lib")
static NISysCfgResourceHandle ResourceHandle;
static NISysCfgEnumResourceHandle EnumResourceHandle;
static NISysCfgSessionHandle SessionHandle;
void* test;
char productName[NISYSCFG_SIMPLE_STRING_LENGTH];
NISYSCFGCFUNC NISysCfgSetResourceIndexedProperty(
NISysCfgResourceHandle resourceHandle,
NISysCfgIndexedProperty propertyID,
unsigned int index,
int value
)
{
return NISysCfgSetResourceProperty(resourceHandle, (NISysCfgResourceProperty)(propertyID + index), value);
}
int main(int argc, char *argv[])
{
NISysCfgStatus status = NISysCfgInitializeSession(NULL, NULL, NULL, NISysCfgLocaleDefault, NISysCfgBoolTrue, 10000, NULL, &SessionHandle);
if (status == 0) {
status = NISysCfgFindHardware(SessionHandle, NISysCfgFilterModeMatchValuesAll, NULL, NULL, &EnumResourceHandle);
if (status != 0)
{
printf(" Error finding hardware %d", status);
}
int i = 0;
while (NISysCfgNextResource(SessionHandle, EnumResourceHandle, &ResourceHandle) == 0) {
char SerialNumber[NISYSCFG_SIMPLE_STRING_LENGTH];
SerialNumber[0] = 0x00;
unsigned int ProductId = 0;
NISysCfgGetResourceProperty(ResourceHandle, NISysCfgResourcePropertyProductName, &productName);
NISysCfgGetResourceProperty(ResourceHandle, NISysCfgResourcePropertyProductId, &ProductId);
NISysCfgGetResourceProperty(ResourceHandle, NISysCfgResourcePropertySerialNumber, &SerialNumber);
printf("%d: %s Serial: %s ProductID: %04X\n", i, productName, SerialNumber, ProductId);
int NumberOfUserLedIndicators;
int NumberOfUserSwitches;
status = NISysCfgGetResourceProperty(ResourceHandle, NISysCfgResourcePropertyNumberOfUserLedIndicators, &NumberOfUserLedIndicators);
if (status != 0)
{
//printf(" Error getting number of LED indicators %d\n", status);
NumberOfUserLedIndicators = 0;
}
status = NISysCfgGetResourceProperty(ResourceHandle, NISysCfgResourcePropertyNumberOfUserSwitches, &NumberOfUserSwitches);
if (status != 0)
{
//printf(" Error getting number of switches %d\n", status);
NumberOfUserSwitches = 0;
}
printf(" Number of LEDs: %d Number of Switches: %d\n", NumberOfUserLedIndicators, NumberOfUserSwitches);
NISysCfgSwitchState SwitchState = NISysCfgSwitchStateDisabled;
NISysCfgLedState LedState = NISysCfgLedStateOff;
int s;
char SwitchName[NISYSCFG_SIMPLE_STRING_LENGTH];
for (s = 0; s < NumberOfUserSwitches; s++)
{
status = NISysCfgGetResourceIndexedProperty(ResourceHandle, NISysCfgIndexedPropertyUserSwitchName, s, &SwitchName);
if (status != 0)
{
printf(" Error getting switch name %d\n", status);
}
if (NISysCfgGetResourceIndexedProperty(ResourceHandle, NISysCfgIndexedPropertyUserSwitchState, s, &SwitchState) != 0)
{
printf(" Error getting switch state %d\n", status);
}
printf(" Switch '%s': %d\n", SwitchName, SwitchState);
}
int l;
char LedName[NISYSCFG_SIMPLE_STRING_LENGTH];
for (l = 0;l<NumberOfUserLedIndicators;l++)
{
status = NISysCfgGetResourceIndexedProperty(ResourceHandle, NISysCfgIndexedPropertyUserLedName, l, &LedName);
if (status != 0)
{
printf(" Error getting LED name %d\n", status);
}
status = NISysCfgGetResourceIndexedProperty(ResourceHandle, NISysCfgIndexedPropertyUserLedState, l, &LedState);
if (status != 0)
{
printf(" Error getting LED state %d\n", status);
}
printf(" LED '%s': %d\n", LedName, LedState);
if (l % 2 == 1)
{
LedState = NISysCfgLedStateSolidGreen;
}
else
{
LedState = NISysCfgLedStateSolidYellow;
}
status = NISysCfgSetResourceIndexedProperty(ResourceHandle, NISysCfgIndexedPropertyUserLedState, l, LedState);
if (status != 0)
{
printf(" Error setting LED state %d\n", status);
}
}
status = NISysCfgSaveResourceChanges(ResourceHandle, 0, NULL);
if (status != 0)
{
printf(" Error saving resource %d\n", status);
}
status = NISysCfgCloseHandle(ResourceHandle);
if (status != 0)
{
printf("Error closing resource handle %d\n", status);
}
i++;
}
status = NISysCfgCloseHandle(EnumResourceHandle);
if (status != 0)
{
printf("Error closing enumresource handle %d\n", status);
}
}
else {
printf("NiSysCfgInitializeSession Error Code %d", status);
}
return 0;
}
02-05-2020 01:33 PM
The "Blinking" states are supported by other devices that also use API, but the cDAQ-9136 and the other 913x controllers only support the simpler on/off states.
(You could of course blink the LED in software by successively toggling it on and off; there's just no timer-driven hardware built-in to let us have a fire-and-forget "blink" state.)
02-09-2020 12:07 PM
Thanks for the confirmation Brandon.
In the end I did exactly that at converted BlinkingGreen/Yellow into alternating Green/Yellow and Off states.