12-11-2025 09:09 AM
I am using XNET to send and receive CAN messages. I have some CAN relay boards that take a 6 byte message with a command byte, four address bytes, and a data byte. I am using PXI-8512 2-channel CAN cards. Out of fifteen installations, one cell has randomly decided to not update the CAN message for one of the relay boards. The other continues just fine. I am calling for updates twice per second. In other words, one update per card per second.
When I found this issue, I put diagnostic messages in to try to capture the issue. I wanted to make sure that the actual write was still happening. The code is calling for the write, but the write isn't happening per my CAN logger running separately. I even have error catching if the write fails, but I'm not getting any errors. This is very bizarre because the message is going out, but it is only going out for one of the addresses and not the other. They are both sharing the same CAN message.
Any idea why one of the two writes is not updating the CAN message?
int CANRelayWrite(char RelayBoardAddress[], u8 data)
{
nxFrameCAN_t *l_pFrm;
u8 *l_pData;
Rect l_Range;
char message[200] = {'/0'};
int i;
uInt32 address = 0;
short count;
char TerminalMessage[200] = {'\0'};
char statusString[1024] = {'\0'};
sscanf(RelayBoardAddress, "%x", &address);
//allocate memory for the frame struct and data buffer
l_pFrm = (nxFrameCAN_t*)malloc(sizeof(nxFrameCAN_t));
l_pData = (u8*)malloc(6*sizeof(u8));
// Initialize the frame's attributes
l_pFrm->Timestamp=0;
l_pFrm->Flags=0;
l_pFrm->Type=0;
l_pFrm->PayloadLength=6;
l_pFrm->Payload[0]= 0x20;
l_pFrm->Payload[1]= (address >> 24) & 0xFF;
l_pFrm->Payload[2]= (address >> 16) & 0xFF;
l_pFrm->Payload[3]= (address >> 8) & 0xFF;
l_pFrm->Payload[4]= address & 0xFF;
l_pFrm->Payload[5]= data;
//DebugPrintf("Size of relay write: %d\r\n", sizeof(nxFrameCAN_t));
CANOutMSG_Status = nxWriteFrame (g_RelaySessionRef,l_pFrm,(u32)sizeof(nxFrameCAN_t),0);
if (CANOutMSG_Status != 0 && !flagCANMessageSent)
{
flagCANMessageSent = 1;
if (!flagOutputCANRelayError)
{
flagOutputCANRelayError = 1;
DebugPrintf("I'm in CAN Relay Out!\r\n");
nxStatusToString (CANOutMSG_Status, (u32)sizeof(statusString), statusString);
snprintf(TerminalMessage, 199, "Error on CAN Write[%d]: %s", (int) CANOutMSG_Status, statusString);
SleepUS(5000);
Terminal_Writeline(TerminalMessage);
DebugPrintf("%s\r\n", TerminalMessage);
}
}
else if (flagCANMessageSent)
{
if (debugIndex == 20 || debugIndex == 21)
{
SleepUS(5000);
//sprintf(message, "flagCANMessageSent", loopCounter, address, data);
Terminal_Writeline("flagCANMessageSent");
}
flagCANMessageSent = 0;
}
else
{
if (debugIndex == 20 || debugIndex == 21)
{
SleepUS(5000);
sprintf(message, "SUCCESSFUL UPDATE\tRELAY BOARD\t%d\t%x\t%d", loopCounter, address, data);
Terminal_Writeline(message);
}
flagCANMessageSent = 0;
}
free(l_pFrm);
free(l_pData);
return 0;
}
This is a screen shot of the terminal showing that the second message with a data value of 15 (four relays on) is reaching the code and not throwing an error.
This is a screen shot of the CAN logger showing that only one message is going out.
12-11-2025 07:12 PM
Try debugging using NI-XNET Bus Monitor.
Under Interface and Database Settings, enable the following:
12-16-2025 02:17 PM
I am having the issue right now. Both Windows and the PXI can monitor the CAN bus.
Windows PC shows it still writing to one CAN relay board:
XNET Bus Monitor shows the CAN relay board message when I select the options you requested, but it does not show it when I don't select them. Also, the relay message 0x108 (264) is only sending one address and data byte whereas the program is sending two.
Subordinate, transmissions, and errors not selected/logged.
Subordinate, transmissions, and errors selected/logged.
The drivers on the message update call are returning a successful write per my diagnostic messages:
I enabled logging to disk, but I'm having to search the entire hard drive for the file because it doesn't say where it saves it and doesn't give me the option to specify.
12-17-2025 08:08 AM
I found the file on the PXI drive. The help file did disclose this.
The found only has a log of what I can see on the screen. No errors. Just sending one address and data byte to relay boards when it should be sending two. My debug messages should be capturing the data right before it the call.
l_pFrm->Payload[0]= 0x20;
l_pFrm->Payload[1]= (address >> 24) & 0xFF;
l_pFrm->Payload[2]= (address >> 16) & 0xFF;
l_pFrm->Payload[3]= (address >> 8) & 0xFF;
l_pFrm->Payload[4]= address & 0xFF;
l_pFrm->Payload[5]= data;
CANOutMSG_Status = nxWriteFrame (g_RelaySessionRef,l_pFrm,(u32)sizeof(nxFrameCAN_t),0);
if (CANOutMSG_Status != 0 && !flagCANMessageSent)
{
flagCANMessageSent = 1;
if (!flagOutputCANRelayError)
{
...
}
}
else if (flagCANMessageSent)
{
...
}
else
{
if (debugIndex == 20 || debugIndex == 21)
{
SleepUS(5000);
sprintf(message, "SUCCESSFUL UPDATE\tRELAY BOARD\t%d\t%x\t%d", loopCounter, address, data);
Terminal_Writeline(message);
}
flagCANMessageSent = 0;
}