I had no experience with Controller Area Networks(CAN) or ValueCAN3 prior to this project, and I used an example from Intrepid for my reading of messages. However I am having issues with efficiency and frequency of the updates for my GUI which displays the analog and digital signals I am reading.
My GUI consists of 16 numeric up/down boxes for analog channels and 36 buttons that change to green depending if a digital signal is turned on (1) or off(0). While reading in my CAN messages I then update the GUI controls to display the appropriate feedback. However the digital channels respond almost instantly when I press a button on a CAN joystick that is plugged in, whereas the analog signals don't update that fast with the string pots I am using to vary the signal. Sometimes it takes an analog signal 1 - 2 seconds to respond.
Currently I set the GUI controls, and then I read the values from the GUI controls and send the values out over a socket connection to another application via UDP. I should probably change this to sending the data from the signals I receive directly rather then reading from the GUI controls I am setting, but I don't think that is the issue.
I am using System::Timers::Timer objects to update, read messages, and send out data packets. I need a rate of 50hz - 100hz, preferably closer to 100hz. Using the socket on the other end I can see that my packets are sent frequently enough, but the data doesn't change smoothly or frequently for the analog channels. If anyone has any thoughts on what I might be doing wrong, or how to process the data in a more efficient way please state it.
Here is the segment of code from Intrepid that reads the CAN messages:
// Read the messages every timer event (1000 ms)
if (m_bPortOpen) // only if the port is open
{
// call icsneoGetMessages to read out the messages
lResult = icsneoGetMessages(hObject,stMessages,&lNumberOfMessages,&lNumberOfErrors);
if (lResult != 0)
{
// a successful read
mNumberOfErrorsRead = lNumberOfErrors;
mNumberOfMessagesRead = lNumberOfMessages; // store the number of messages in the current buffer
}
}
My form requests a msg from my CanReader Object using:
msg = can->GetLatestMsg();
and that method grabs the last message received.
public: icsSpyMessage* GetLatestMsg()
{
return &stMessages[mNumberOfMessagesRead - 1];
};
I think this GetLatestMsg() seems like a bad way to implement the retrival of the latest message, but I'm not entirely sure how much this is affecting my program or how else I could do this because the CanReader is seperate from the Form so I'd have to pass an array of messages I think otherwise. I do suspect this might be skipping messages because it only reads the last one grabbed and not the ones leading up to it, which if those were read should make the GUI output appear smoother for transitions.
Another thing to note is that I am reading from 6 different PGNs, the analog signals correspond to 4 of the PGNs and 2 correspond to the digital signals.
UPDATE
After playing with my application and using the string pots on different analog channels I am noticing that some channels are updating more then others. And by checking the PGNs being accessed I find that I am accessing some more frequently then others.
Doesn't a CAN device broadcast the data at relatively the same rates for the different PGNs? and if yes then my GetLatestMsg() method must not be reading the different PGNs effectively. It reads a new msg every 5 milliseconds.
Additionally, does anyone know if I should make seperate reading timers to detect the different PGNs seperately?
If there is additional code I can provide for clarity please let me know.