Transmitting messages in required order

Windows® Compatible Software for Displaying CAN Messages
Vlad
Posts: 8
Joined: Sat 15. Jan 2011, 03:49

Re: Transmitting messages in required order

Post by Vlad » Sat 29. Jan 2011, 09:06

Here is a C code example of a simple DOS command line executable that sends a list of CAN commands over PEAK USB using PCAN-view *.xmt or *.trc file formats:

Code: Select all

// Transmit a list of CAN bus messages through PEAK USB.
// The list of CAN bus messages is stored in a file specified as command line argument to this program.
// Two file (message) formats are supported:
// 1. PcanView trace (received) files with extension *.trc
// 2. PcanView transmit files with extension *.xmt

#include "stdafx.h"
#include <windows.h>
#include "PCANBasic.h"

int _tmain(int argc, _TCHAR* argv[])
{
	TPCANStatus result;
	char line[256];
	TPCANMsg msg;
	FILE *fp;
	unsigned char messageType;
	bool xmtFileFormat = false;

	if (argc != 2) {
		printf("Input file not specified.\n");
		exit(1);
	}

	if (strstr(argv[1], ".xmt") != NULL)
		xmtFileFormat = true;
	else if (strstr(argv[1], ".trc") == NULL) {
		printf("Specified file %s does not have extension *.trc or *.xmt\n", argv[1]);
		exit(1);
	}

	if ((fp = fopen(argv[1], "r")) == NULL) {
		printf("Cannot open file %s - %s\n", argv[1], strerror(int errno));
		exit(1);
	}

	result = CAN_Initialize(PCAN_USBBUS1, (TPCANBaudrate)0x1D14); // 33.333 kBits
	if(result != PCAN_ERROR_OK) {
		CAN_GetErrorText(result, 0, line);
		printf("%s\n", line);
		exit(1);
    }

	while (fgets(line, sizeof line, fp) != NULL ) { /* read a line */
		if (line[0] == ';')	// skip comment lines starting with ;
			continue;
		// extract the CAN message fields from the line
		if (xmtFileFormat) {
			// PcanView transmit file with extension *.xmt
			// message example format:
			//                 1001C040h  0   8  D   07h    65h   14h    80h    00h    00h    00h    00h
			result = sscanf(line, "%X%*c %*s %hd %c %hX%*c %hX%*c %hX%*c %hX%*c %hX%*c %hX%*c %hX%*c %hX%*c",
							&msg.ID, &msg.LEN, &messageType, &msg.DATA[0], &msg.DATA[1], &msg.DATA[2], &msg.DATA[3], &msg.DATA[4], &msg.DATA[5], &msg.DATA[6], &msg.DATA[7]);
			if (messageType != 'D')
				continue;	// skip no Data messages
			if (line[3] == 'h')
				msg.MSGTYPE = PCAN_MESSAGE_STANDARD;	// standard message ID is three digits followed by 'h'
			else if (line[8] == 'h')
				msg.MSGTYPE = PCAN_MESSAGE_EXTENDED;	// extended message ID is eight digits followed by 'h'
			else
				continue;								// skip lines with unexpected ID format
		} else {
			// PcanView trace (received) file with extension *.trc
			// message example format:
			//                 120) 24551.8 Rx 0621 8 01  12  00  00  00  00  00  00
			result = sscanf(line, "%*s %*s %*s %X %hd %hx %hx %hx %hx %hx %hx %hx %hx",
							&msg.ID, &msg.LEN, &msg.DATA[0], &msg.DATA[1], &msg.DATA[2], &msg.DATA[3], &msg.DATA[4], &msg.DATA[5], &msg.DATA[6], &msg.DATA[7]);
			if (line[28] == ' ')
				msg.MSGTYPE = PCAN_MESSAGE_STANDARD;	// standard message ID is three 4 followed prefixed with 4 spaces e.g. "    0621"
			else
				msg.MSGTYPE = PCAN_MESSAGE_EXTENDED;	// extended message ID is eight digits e.g. "0FFFE099"
		}

		// finally send the CAN message
		while ((result = CAN_Write(PCAN_USBBUS1, &msg)) == PCAN_ERROR_QXMTFULL);
		if (result != PCAN_ERROR_OK) {
			CAN_GetErrorText(result, 0, line);
			printf("%s\n", line);
			break;
		}
	}
	CAN_Uninitialize(PCAN_USBBUS1);

	return 0;
}
And here are the steps of how to build it with MS Visual C++ 2010 Express:

Code: Select all

1.	Sellect File->New->Project.
2.	In the “Name:” field specify the name of the program (e.g. can_tx).
3.	Specify where the project should be located in the “Location:” field.
4.	Leave the “Solution name:” field the same as the name selected at step 2.
5.	Select “Win32 Console Application".
6.	Click “OK” button.
7.	Click “Finish” button in the following screen.
8.	Copy and replace the auto generated code with the example source code above.
9.	Right click on the “can_tx” in the “Solution Explorer” pan on the left side of the screen and select “Properties”. Click on the “+” sign of the “Configuration Properties“ in the left pan of the dialog and select “VC++ Directories”. Next select “Include Directories” and click on the down arrow (on the right end of “Include Directories”) and select “<edit>”. Click on the yellow directory button “New Line (Ctrl-Insert)” and browse to the directory where “pcan-basic” zip file has been extracted.  Then select “pcan-basic\PCAN-Basic API\Include” directory and click “OK”. Click “Apply” and “OK” buttons in the parent window.
10.	Once again Right click on the “can_tx” in the “Solution Explorer” pan on the left side of the screen and select “Properties”. Click on the “+” sign of the “Configuration Properties“ in the left pan of the dialog, select “General”. Next select “Character Set” and click on the down arrow (on the right end of “Character Set”) and select “Use Multi-Byte Character Set”. Click “Apply” and “OK” buttons.
11.	Once again Right click on the “can_tx” in the “Solution Explorer” pan on the left side of the screen and select “Add existing Item…”. Browse to the directory where “pcan-basic” zip file has been extracted.  Then select “pcan-basic\PCAN-Basic API\Win32\VC_LIB\PCANBasic.lib” and click the “Add” button.
12.	Click on “Build” and then on “Build Solution” (short cut for this operation is F7).
13.	Open DOS command prompt and change directory to the “VC++ Express” project location chosen at step 3. The built executable “can_tx.exe” will be in “can_tx\Debug” subdirectory. Change the directory to where the “can_tx.exe” executable have been generated.
14.	Copy “PCANBasic.dll” from the  “pcan-basic\PCAN-Basic API\Win32” directory to “can_tx\Debug” where the “can_tx.exe” executable is.
15.	Run “can_tx.exe my_can_tx_list.xmt”, where “my_can_tx_list.xmt” is the file containing the CAN messages to be sent. “my_can_tx_list.xmt” can be manually generated or by “PCAN-View”. Here is an example of two CAN commands in “my_can_tx_list.xmt” generated by “PCAN-View”:

; C:\temp\my_can_tx_list.xmt
16.	; CAN messages saved by PCAN-View 3.0.8
17.	;
18.	; Columns descriptions:
19.	; ~~~~~~~~~~~~~~~~~~~~~
20.	; +Message ID
21.	; |            +Cycle time in ms (0=manual)
22.	; |            |  +Length of message
23.	; |            |  |  +Frame type: D)ata or R)emote request
24.	; |            |  |  |  +Message data
25.	; |            |  |  |  |
26.	621h           0  8  D 00h 40h 00h 00h 00h 00h 00h 00h
27.	10026040h      0  8  D 37h 4Ch 38h 37h 31h 37h 35h 38h

K.Wagner
Software Development
Software Development
Posts: 1080
Joined: Wed 22. Sep 2010, 13:36

Re: Transmitting messages in required order

Post by K.Wagner » Mon 31. Jan 2011, 11:57

Hello Vlad,
Vlad wrote:Once CAN_Write() returns PCAN_ERROR_QXMTFULL it never seam to flush the transmit buffer out and to return PCAN_ERROR_OK again. I see the PEAK USB interface continuously sending data in this state. The only way to get PEAK USB back to normal is to disconnect and connect the USB cable from the PC.
Am I missing something or this is a bug in the driver?
First of all, here are some facts to take in consideration:
  • If the send-queue is full (32.768 messages waiting to be sent), then PCAN_ERROR_QXMTFULL is returned for further calls to CAN_Write. CAN_Write will return PCAN_ERROR_OK at the moment it can store a new message again in the queue (e.g. one of the 32.768 was sent).
  • A Channel sends messages from its queue while it is active (initialized). If the channel is uninitialized before the send-queue is empty, all messages are "disposed", which it means, no further messages are sent. So in your code, you should have a Sleep(xxx) before calling the CAN_Uninitialize function to avoid the deletion of "not yet sent" messages.
  • If a send-queue reaches the 32.768 messages and the channel is not uninitialized, the messages of the queue are sent as fast as possible (depends on the baudrate with which the channel was initialized). If the communication is low (e.g. 33,333 kBit/s), than the sending of those messages take its time (32.768 messages at 33,333 kBit/s can take up to 2 minutes). This case normally happens when, while debugging an application, the debug process is stopped without reaching the place where the CAN_Uninitialize is called. So, in background remains a client sending messages from its queue
Nevertheless, I have found a bug within the API. The API is capable to recognize an abandoned connection and to automatically delete it, avoiding unwanted states. But the recognitions pattern has a small problem, so that not all clients are catched. This will be repared within the release of the next version.

We thank you for helping us to find this bug. If you want to have the new version, please send us an E-Mail to support@peak-system.com
Best regards,
Keneth

User avatar
PEAK-Support
Sales & Support
Sales & Support
Posts: 1646
Joined: Fri 10. Sep 2010, 19:34

Re: Transmitting messages in required order

Post by PEAK-Support » Tue 15. Feb 2011, 16:39

Vlad wrote:Here is a C code example of a simple DOS command line executable that sends a list of CAN commands over PEAK USB using PCAN-view *.xmt or *.trc file formats:

Code: Select all

// Transmit a list of CAN bus messages through PEAK USB.
// The list of CAN bus messages is stored in a file specified as command line argument to this program.
// Two file (message) formats are supported:
// 1. PcanView trace (received) files with extension *.trc
// 2. PcanView transmit files with extension *.xmt

#include "stdafx.h"
#include <windows.h>
#include "PCANBasic.h"

int _tmain(int argc, _TCHAR* argv[])
{
	TPCANStatus result;
	char line[256];
	TPCANMsg msg;
	FILE *fp;
	unsigned char messageType;
	bool xmtFileFormat = false;

	if (argc != 2) {
		printf("Input file not specified.\n");
		exit(1);
	}

	if (strstr(argv[1], ".xmt") != NULL)
		xmtFileFormat = true;
	else if (strstr(argv[1], ".trc") == NULL) {
		printf("Specified file %s does not have extension *.trc or *.xmt\n", argv[1]);
		exit(1);
	}

	if ((fp = fopen(argv[1], "r")) == NULL) {
		printf("Cannot open file %s - %s\n", argv[1], strerror(int errno));
		exit(1);
	}

	result = CAN_Initialize(PCAN_USBBUS1, (TPCANBaudrate)0x1D14); // 33.333 kBits
	if(result != PCAN_ERROR_OK) {
		CAN_GetErrorText(result, 0, line);
		printf("%s\n", line);
		exit(1);
    }

	while (fgets(line, sizeof line, fp) != NULL ) { /* read a line */
		if (line[0] == ';')	// skip comment lines starting with ;
			continue;
		// extract the CAN message fields from the line
		if (xmtFileFormat) {
			// PcanView transmit file with extension *.xmt
			// message example format:
			//                 1001C040h  0   8  D   07h    65h   14h    80h    00h    00h    00h    00h
			result = sscanf(line, "%X%*c %*s %hd %c %hX%*c %hX%*c %hX%*c %hX%*c %hX%*c %hX%*c %hX%*c %hX%*c",
							&msg.ID, &msg.LEN, &messageType, &msg.DATA[0], &msg.DATA[1], &msg.DATA[2], &msg.DATA[3], &msg.DATA[4], &msg.DATA[5], &msg.DATA[6], &msg.DATA[7]);
			if (messageType != 'D')
				continue;	// skip no Data messages
			if (line[3] == 'h')
				msg.MSGTYPE = PCAN_MESSAGE_STANDARD;	// standard message ID is three digits followed by 'h'
			else if (line[8] == 'h')
				msg.MSGTYPE = PCAN_MESSAGE_EXTENDED;	// extended message ID is eight digits followed by 'h'
			else
				continue;								// skip lines with unexpected ID format
		} else {
			// PcanView trace (received) file with extension *.trc
			// message example format:
			//                 120) 24551.8 Rx 0621 8 01  12  00  00  00  00  00  00
			result = sscanf(line, "%*s %*s %*s %X %hd %hx %hx %hx %hx %hx %hx %hx %hx",
							&msg.ID, &msg.LEN, &msg.DATA[0], &msg.DATA[1], &msg.DATA[2], &msg.DATA[3], &msg.DATA[4], &msg.DATA[5], &msg.DATA[6], &msg.DATA[7]);
			if (line[28] == ' ')
				msg.MSGTYPE = PCAN_MESSAGE_STANDARD;	// standard message ID is three 4 followed prefixed with 4 spaces e.g. "    0621"
			else
				msg.MSGTYPE = PCAN_MESSAGE_EXTENDED;	// extended message ID is eight digits e.g. "0FFFE099"
		}

		// finally send the CAN message
		while ((result = CAN_Write(PCAN_USBBUS1, &msg)) == PCAN_ERROR_QXMTFULL);
		if (result != PCAN_ERROR_OK) {
			CAN_GetErrorText(result, 0, line);
			printf("%s\n", line);
			break;
		}
	}
	CAN_Uninitialize(PCAN_USBBUS1);

	return 0;
}
And here are the steps of how to build it with MS Visual C++ 2010 Express:

Code: Select all

1.	Sellect File->New->Project.
2.	In the “Name:” field specify the name of the program (e.g. can_tx).
3.	Specify where the project should be located in the “Location:” field.
4.	Leave the “Solution name:” field the same as the name selected at step 2.
5.	Select “Win32 Console Application".
6.	Click “OK” button.
7.	Click “Finish” button in the following screen.
8.	Copy and replace the auto generated code with the example source code above.
9.	Right click on the “can_tx” in the “Solution Explorer” pan on the left side of the screen and select “Properties”. Click on the “+” sign of the “Configuration Properties“ in the left pan of the dialog and select “VC++ Directories”. Next select “Include Directories” and click on the down arrow (on the right end of “Include Directories”) and select “<edit>”. Click on the yellow directory button “New Line (Ctrl-Insert)” and browse to the directory where “pcan-basic” zip file has been extracted.  Then select “pcan-basic\PCAN-Basic API\Include” directory and click “OK”. Click “Apply” and “OK” buttons in the parent window.
10.	Once again Right click on the “can_tx” in the “Solution Explorer” pan on the left side of the screen and select “Properties”. Click on the “+” sign of the “Configuration Properties“ in the left pan of the dialog, select “General”. Next select “Character Set” and click on the down arrow (on the right end of “Character Set”) and select “Use Multi-Byte Character Set”. Click “Apply” and “OK” buttons.
11.	Once again Right click on the “can_tx” in the “Solution Explorer” pan on the left side of the screen and select “Add existing Item…”. Browse to the directory where “pcan-basic” zip file has been extracted.  Then select “pcan-basic\PCAN-Basic API\Win32\VC_LIB\PCANBasic.lib” and click the “Add” button.
12.	Click on “Build” and then on “Build Solution” (short cut for this operation is F7).
13.	Open DOS command prompt and change directory to the “VC++ Express” project location chosen at step 3. The built executable “can_tx.exe” will be in “can_tx\Debug” subdirectory. Change the directory to where the “can_tx.exe” executable have been generated.
14.	Copy “PCANBasic.dll” from the  “pcan-basic\PCAN-Basic API\Win32” directory to “can_tx\Debug” where the “can_tx.exe” executable is.
15.	Run “can_tx.exe my_can_tx_list.xmt”, where “my_can_tx_list.xmt” is the file containing the CAN messages to be sent. “my_can_tx_list.xmt” can be manually generated or by “PCAN-View”. Here is an example of two CAN commands in “my_can_tx_list.xmt” generated by “PCAN-View”:

; C:\temp\my_can_tx_list.xmt
16.	; CAN messages saved by PCAN-View 3.0.8
17.	;
18.	; Columns descriptions:
19.	; ~~~~~~~~~~~~~~~~~~~~~
20.	; +Message ID
21.	; |            +Cycle time in ms (0=manual)
22.	; |            |  +Length of message
23.	; |            |  |  +Frame type: D)ata or R)emote request
24.	; |            |  |  |  +Message data
25.	; |            |  |  |  |
26.	621h           0  8  D 00h 40h 00h 00h 00h 00h 00h 00h
27.	10026040h      0  8  D 37h 4Ch 38h 37h 31h 37h 35h 38h
Hi,
nice and short code.There is on think to do:
Before you call

Code: Select all

CAN_Uninitialize(PCAN_USBBUS1);
you need to be sure that all messages are send! If not, the queue is deleted and not all messages are send. Wait a few seconds until deinit the CAN Interface.
--------------------------------
PEAK-System Technik
Technical Support Team
support[at]peak-system.com
-------------------------------

F.Gloessner
Posts: 1
Joined: Thu 21. Mar 2013, 10:31

Re: Transmitting messages in required order

Post by F.Gloessner » Thu 21. Mar 2013, 10:35

Hello,

is there a tool which can send CAN messages out of a textfile (like this small application) but can write the received answers into another textfile?

best regards,

Frank

User avatar
PEAK-Support
Sales & Support
Sales & Support
Posts: 1646
Joined: Fri 10. Sep 2010, 19:34

Re: Transmitting messages in required order

Post by PEAK-Support » Thu 21. Mar 2013, 11:46

no, but build your own - it´s simple - 10 lines of code more...
--------------------------------
PEAK-System Technik
Technical Support Team
support[at]peak-system.com
-------------------------------

mahalinr
Posts: 2
Joined: Tue 5. Nov 2013, 11:18

Re: Transmitting messages in required order

Post by mahalinr » Fri 15. Nov 2013, 09:51

How to Transmit a message from PCAN USB to Microcontroller LPC11C14

Thx in advance

User avatar
PEAK-Support
Sales & Support
Sales & Support
Posts: 1646
Joined: Fri 10. Sep 2010, 19:34

Re: Transmitting messages in required order

Post by PEAK-Support » Fri 15. Nov 2013, 10:00

Be sure you have the CAN-H and CAN-L connected to each unit
Be sure you have the CAN Cable terminated (120 Ohm on each end between CAN-H & CAN-L)
Start PCAN-View
Select PCAN-USB Hardware
Select your used Baudrate
Send a Message from PCAN-View
If you do not get any error on the status line - your µC have ACK the CAN Frame
see also the answer from Michael
--------------------------------
PEAK-System Technik
Technical Support Team
support[at]peak-system.com
-------------------------------

Post Reply