ApiRead(PcanChannel, PcanMessage) Method

Reads a CAN message from the receive queue of a PCAN Channel.

Definition

Namespace: Peak.Can.Basic
Assembly: PCANBasic.NET (in PCANBasic.NET.dll) Version: 4.9.0
C#
public static PcanStatus Read(
	PcanChannel channel,
	out PcanMessage msg
)

Parameters

channel  PcanChannel
The handle of a PCAN Channel.
msg  PcanMessage

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.

Return Value

PcanStatus

OK is returned on success. The typical errors in case of failure are:

  • IllegalHandle: Indicates that the channel contains an invalid value.
  • Initialize: Indicates that the channel cannot be used because it was not found in the list of reserved Channels of the calling application.
  • InvalidValue: Indicates that one or more of the values passed to the method are invalid.
  • ReceiveQueueEmpty: Indicates that there are no more messages in the receive queue of the Channel.
  • IllegalData: Indicates that the message that has been read is not permitted due to the current settings and has been discarded.

Remarks

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:

  • Time-Triggered Reading: Consists in periodically calls to the Read method. Typically, an application starts a timer that checks for messages every 50 or 100 milliseconds, calling the Read method in a loop until the ReceiveQueueEmpty error or another error condition is reached.
  • Event-Triggered Reading: Consists in reacting to a notification sent by the PCAN driver to a registered application, when a message is received and placed in its receive queue. See Using Events to obtain more information about reading with events.

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:

  • Performing an uninitialize / initialize cycle: This causes a hardware reset, but only when no more clients are connected to that channel.
  • Using the parameter HardResetStatus: It instructs this method to explicitly perform a hardware reset regardless of whether other clients are connected to that channel.

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.

Example

The following example shows the use of the Read(PcanChannel, PcanMessage) 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.

C#
private static void ReadExample()
{            
    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;
        do
        {                    
            result = Api.Read(channel, out msg);
            if (result == PcanStatus.OK)
            {
                // Process the received message
                // 
                ProcessMessage(msg);
            }
            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)
{
    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 += $"Data: ";
    for (int i = 0; i < msg.Length; i++)                
        msgText += $"{msg.Data[i]} ";

    Console.WriteLine(msgText);
}

Exceptions

DllNotFoundExceptionThe underlying PCANBasic.dll library could not be found.
PcanBasicExceptionThe 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.

See Also