Note
On Windows, the timestamp contains the number of microseconds elapsed since system start.
On Linux, the timestamp contains the number of microseconds elapsed since the epoch (00:00 UTC, January 1st 1970).
public static PcanStatus Read(
PcanChannel channel,
out PcanMessage msg,
out ulong timestamp
)
Public Shared Function Read (
channel As PcanChannel,
<OutAttribute> ByRef msg As PcanMessage,
<OutAttribute> ByRef timestamp As ULong
) As PcanStatus
public:
static PcanStatus Read(
PcanChannel channel,
[OutAttribute] PcanMessage^% msg,
[OutAttribute] unsigned long long% timestamp
)
Contains the next available CAN frame stored in the FIFO receive queue of channel.
The content of msg is only valid if the returned value of this method is OK.
Contains the timestamp, in microseconds, of when the msg was received.
The content of timestamp is only valid if the returned value of this method is OK.
OK is returned on success. The typical errors in case of failure are:
The Read method returns CAN frames from the receive queue. It is important to call Read repeatedly until the receive queue becomes empty. In case there are no more messages to retrieve, the error ReceiveQueueEmpty is returned. The ReceiveQueueEmpty error is also returned if the reception of messages, configurable through the ReceiveStatus parameter, is disabled.
The receive queue can contain up to 32768 messages.
There are two possibilities for reading messages from the receive queue of a Channel:
About bus errors / status messages
If a bus-off error occur, an application cannot use the channel to communicate anymore, until the CAN controller is reset. Consider using the BusOffAutoReset parameter, which instructs the API to automatically reset the CAN controller when a bus-off state is detected.
Another way to reset bus errors like BusOff, BusPassive, and others:
The MsgType of a PcanMessage object indicates the kind of CAN frame it describes. This value should be checked every time a message has been read successfully.
If the MsgType of a PcanMessage contains the value Error, then the message is an Error Frame.
If the MsgType of a PcanMessage contains the value Status, then the message is a Status Frame.
The following example shows the use of the Read(PcanChannel, PcanMessage, UInt64) method using the USB interface (first PCAN-USB hardware). A Channel is initialized and used to read messages within 1 second.
In case of failure, the returned code will be translated to a text (according with the operating system language) in English, German, Italian, French or Spanish, and it will be shown to the user.
private static void ReadWithTimestampExample()
{
PcanChannel channel = PcanChannel.Usb01;
// The hardware represented by the given handle is initialized with 500 kBit/s bit rate (BTR0/BTR1 0x001C)
//
PcanStatus result = Api.Initialize(channel, Bitrate.Pcan500);
if (result != PcanStatus.OK)
{
// An error occurred
//
Api.GetErrorText(result, out var errorText);
Console.WriteLine(errorText);
}
else
{
// A success message on connection is shown.
//
Console.WriteLine($"The hardware represented by the handle {channel} was successfully initialized.");
// Wait some time to get messages stored in the reception queue of the Channel
//
Console.WriteLine("The reception queue will be read out after 1 second...");
System.Threading.Thread.Sleep(1000);
// Messages are read and processed until the reception queue is empty
//
PcanMessage msg;
ulong timestamp;
do
{
result = Api.Read(channel, out msg, out timestamp);
if (result == PcanStatus.OK)
{
// Process the received message
//
ProcessMessage(msg, timestamp);
}
else
{
if ((result & PcanStatus.ReceiveQueueEmpty) != PcanStatus.ReceiveQueueEmpty)
{
// An unexpected error occurred
//
Api.GetErrorText(result, out var errorText);
Console.WriteLine("Reading process canceled due to unexpected error: " + errorText);
break;
}
}
} while ((result & PcanStatus.ReceiveQueueEmpty) != PcanStatus.ReceiveQueueEmpty);
// The connection to the hardware is finalized when it is no longer needed
//
result = Api.Uninitialize(channel);
if (result != PcanStatus.OK)
{
// An error occurred
//
Api.GetErrorText(result, out var errorText);
Console.WriteLine(errorText);
}
else
Console.WriteLine($"The hardware represented by the handle {channel} was successfully finalized.");
}
}
// Formats a CAN frame as string and writes it to the console output
//
private static void ProcessMessage(PcanMessage msg, ulong timestamp)
{
string msgText = $"Type: {msg.MsgType} | ";
if ((msg.MsgType & MessageType.Extended) == MessageType.Extended)
msgText += $"ID: {msg.ID:X8} | ";
else
msgText += $"ID: {msg.ID:X4} | ";
msgText += $"Length: {msg.Length} | ";
msgText += $"Time (ms): {timestamp / 1000:F1} | ";
msgText += $"Data: ";
for (int i = 0; i < msg.Length; i++)
msgText += $"{msg.Data[i]} ";
Console.WriteLine(msgText);
}
Private Sub ReadWithTimstampExample()
Dim channel As PcanChannel = PcanChannel.Usb01
' The hardware represented by the given handle is initialized with 500 kBit/s bit rate (BTR0/BTR1 0x001C)
'
Dim result As PcanStatus = Api.Initialize(channel, Bitrate.Pcan500)
' An error occurred
'
' An unexpected error occurred
'
Dim errorText = Nothing
If result <> PcanStatus.OK Then
Api.GetErrorText(result, errorText)
Console.WriteLine(errorText)
Else
' A success message on connection is shown.
'
Console.WriteLine($"The hardware represented by the handle {channel} was successfully initialized.")
' Wait some time to get messages stored in the reception queue of the Channel
'
Console.WriteLine("The reception queue will be read out after 1 second...")
System.Threading.Thread.Sleep(1000)
' Messages are read and processed until the reception queue is empty
'
Dim msg As PcanMessage = Nothing
Dim timestamp As UInt64 = 0
Do
result = Api.Read(channel, msg, timestamp)
If result = PcanStatus.OK Then
' Process the received message
'
ProcessMessage(msg, timestamp)
Else
If (result And PcanStatus.ReceiveQueueEmpty) <> PcanStatus.ReceiveQueueEmpty Then
Api.GetErrorText(result, errorText)
Console.WriteLine("Reading process canceled due to unexpected error: " & errorText)
Exit Do
End If
End If
Loop While (result And PcanStatus.ReceiveQueueEmpty) <> PcanStatus.ReceiveQueueEmpty
' The connection to the hardware is finalized when it is no longer needed
'
result = Api.Uninitialize(channel)
If result <> PcanStatus.OK Then
' An error occurred
'
Api.GetErrorText(result, errorText)
Console.WriteLine(errorText)
Else
Console.WriteLine($"The hardware represented by the handle {channel} was successfully finalized.")
End If
End If
End Sub
' Formats a CAN frame as string and writes it to the console output
'
Private Sub ProcessMessage(ByVal msg As PcanMessage, ByVal timestamp As ULong)
Dim msgText = $"Type: {msg.MsgType} | "
If (msg.MsgType And MessageType.Extended) = MessageType.Extended Then
msgText += $"ID: {msg.ID:X8} | "
Else
msgText += $"ID: {msg.ID:X4} | "
End If
msgText += $"Length: {msg.Length} | "
msgText += $"Time (ms): {timestamp / 1000:F1} | "
msgText += $"Data: "
For i As Integer = 0 To msg.Length - 1
msgText += $"{msg.Data(i)} "
Next
Console.WriteLine(msgText)
End Sub
void ReadWithTimestampExample()
{
String^ errorText;
PcanChannel channel = PcanChannel::Usb01;
// The hardware represented by the given handle is initialized with 500 kBit/s bit rate (BTR0/BTR1 0x001C)
//
PcanStatus result = Api::Initialize(channel, Bitrate::Pcan500);
if (result != PcanStatus::OK)
{
// An error occurred
//
Api::GetErrorText(result, errorText);
Console::WriteLine(errorText);
}
else
{
// A success message on connection is shown.
//
Console::WriteLine("The hardware represented by the handle {0} was successfully initialized.", channel);
// Wait some time to get messages stored in the reception queue of the Channel
//
Console::WriteLine("The reception queue will be read out after 1 second...");
System::Threading::Thread::Sleep(1000);
// Messages are read and processed until the reception queue is empty
//
PcanMessage^ msg;
UInt64 timestamp;
do
{
result = Api::Read(channel, msg, timestamp);
if (result == PcanStatus::OK)
{
// Process the received message
//
ProcessMessage(msg, timestamp);
}
else
{
if ((result & PcanStatus::ReceiveQueueEmpty) != PcanStatus::ReceiveQueueEmpty)
{
// An unexpected error occurred
//
Api::GetErrorText(result, errorText);
Console::WriteLine("Reading process canceled due to unexpected error: {0}", errorText);
break;
}
}
} while ((result & PcanStatus::ReceiveQueueEmpty) != PcanStatus::ReceiveQueueEmpty);
}
}
// Formats a CAN frame as string and writes it to the console output
//
void ProcessMessage(PcanMessage^ msg, UInt64 timestamp)
{
String^ msgText = String::Format("Type: {0} | ", msg->MsgType);
if ((msg->MsgType & MessageType::Extended) == MessageType::Extended)
msgText += String::Format("ID: {0:X8} | ", msg->ID);
else
msgText += String::Format("ID: {0:X4} | ", msg->ID);
msgText += String::Format("Length: {0} | ", msg->Length);
msgText += String::Format("Time (ms): {0:F1} | ", timestamp / 1000);
msgText += "Data: ";
for (int i = 0; i < msg->Length; i++)
msgText += String::Format("{0:X2} ", msg->Data[i]);
Console::WriteLine(msgText);
}
DllNotFoundException | The underlying PCANBasic.dll library could not be found. |
PcanBasicException | The execution of a PCAN-Basic related check operation ended with an unexpected result. Typically, this exception is triggered when a device driver is not installed or is not up to date. |