Converting multiple CAN messages to one serial

Programmable Converter for RS-232 to CAN
Post Reply
SajadMRV
Posts: 1
Joined: Fri 14. Feb 2020, 12:28

Converting multiple CAN messages to one serial

Post by SajadMRV » Tue 18. Feb 2020, 14:30

Hi
I'm using PCAN-RS-232 to convert CAN message to serial and vice versa. the problem is that sometimes our serial commands are more than 8 bytes so when I want to send these messages from CAN I have to send them as 2 separate CAN Message and when I got two of them to merge them together and write them in serial. To understand which message should merge to other messages I used the first byte of Data that means If I put it 0x11 it should get another message from CAN and merge its data to the previous one and send them together. I can get the first message correctly when the length of the message is equal or less than 8 but when I am sending 2 CAN message the second message is not correctly receiving and the response of "CAN_UserRead(CAN_BUS1, &CanRxMsg);" is always "CAN_ERR_FAIL"
(I also increased the length of the buffer so that is not the problem)

Code: Select all

void ProcessMsgFromCan()
//*************************************************
//! @brief
//! Reads message from CAN.
//!
//! @param	void
//!
//! @return	void
//!
//-------------------------------------------------
{
	u8_t j; //iterator over CAN
	u8_t counter;
	counter = 0;
	SerXmtBufPtr = 0;

	if (CAN_UserRead (CAN_BUS1, &CanRxMsg) == CAN_ERR_OK) // read one CAN message
	{	
		for (j = 0; j < 7; ++j) {//Read the first message and add it in buffer

			SerXmtBuf[SerXmtBufPtr + (j * 2)] = hex2ascii((CanRxMsg.Data8[j + 1] & 0xF0) >> 4);
			SerXmtBuf[SerXmtBufPtr + 1 + (j * 2)] = hex2ascii(CanRxMsg.Data8[j + 1] & 0x0F);
		
		}
		
		if (CanRxMsg.Data8[0] == 0x11) { //check if the first byte of first CAN message is equal to 0x11
			flag = 1;
		}
	}
	SerXmtBufPtr = SerXmtBufPtr + 14; //Length of message is 14 because we are adding 7 bytes to serial
	
	if (flag) { //IF the First byte of First CAN message is equal to 0x11

		if (CAN_UserRead(CAN_BUS1, &CanRxMsg2) == CAN_ERR_OK){ //read second CAN message 
		
			for (j = 0; j < 7; ++j) { //Read the second message and add it to buffer

				SerXmtBuf[SerXmtBufPtr + (j * 2)] = hex2ascii((CanRxMsg2.Data8[j + 1] & 0xF0) >> 4);
				SerXmtBuf[SerXmtBufPtr + 1 + (j * 2)] = hex2ascii(CanRxMsg2.Data8[j + 1] & 0x0F);
			
			}
		counter = counter + 1;
		}
	}
	
	SerXmtBufPtr = SerXmtBufPtr + (counter * 14);

	SerXmtBuf[SerXmtBufPtr] = '\r'; // Append <CR>
	SerXmtBufPtr++;
	
	SER_Write(SER_PORT1, &SerXmtBuf, SerXmtBufPtr);
	
	SerXmtBufPtr = 0;
	counter = 0;
		
}
I am calling this function in main() so it is running all the time

When I am sending these 2 CAN messages
[0x11,0x21,0x22,0x23,0x24,0x25,0x26,0x27]
and
[0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07]]

the serial result is
0x21 0x22 0x23 0x24 0x25 0x26 0x27 \r
but what I want is
0x21 0x22 0x23 0x24 0x25 0x26 0x27 0x01 0x02 0x03 0x04 0x05 0x06 0x07 \r

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

Re: Converting multiple CAN messages to one serial

Post by PEAK-Support » Tue 18. Feb 2020, 14:55

You need to be sure what happend after you received the first CAN Message:

Code: Select all

if (flag) { //IF the First byte of First CAN message is equal to 0x11
you read some µS later the CAN Buffer again - but there is no Msg in queue - that is to fast ...
and next time you start reading again in your first CAN Read (because the flag doesnt make any differnce here)

Code: Select all

	if (CAN_UserRead (CAN_BUS1, &CanRxMsg) == CAN_ERR_OK) // read one CAN message
You need to use your flag more global for this function, check it also at the begining, and also reset it after finished the 2nd CAN Read....

But this is a programmer logic problem - not a product related problem.
--------------------------------
PEAK-System Technik
Technical Support Team
support[at]peak-system.com
-------------------------------

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

Re: Converting multiple CAN messages to one serial

Post by PEAK-Support » Thu 20. Feb 2020, 13:38

Attached a simple project that merge the Data from 3 CAN Frames with the same ID 0x100 to a string, and send it on the Serial port.
It could be easy chnaged for any need - based on a simple state machine

Code: Select all

// catch ID 100h, which will come 3 times, and send all 2x 8 plus 1x 1-8  Bytes on serial as ascii...
			if ( RxMsg.Id == 0x100  &&  RxMsg.Type == CAN_MSG_STANDARD)
			{
				switch (myState)
				{
					case State_IDLE:
						#ifdef DEBUG
							sprintf(StatusText, "State: %d", myState); 
							SER_Write ( SER_PORT1, &StatusText, strlen(StatusText));
						#endif
						if(RxMsg.Len == 8) // it MUST be 8 DataBytes available
						{
							for(int i =0; i<RxMsg.Len; i++)
								SerTextBuff[i]=RxMsg.Data8[i];
							myState = State_CAN1;
							SerTextlen = RxMsg.Len;
						}
						else // no 8 Data Bytes - wrong protocol...
							break;
					break;
				
					case State_CAN1:
						#ifdef DEBUG
							sprintf(StatusText, "State: %d", myState); 
							SER_Write ( SER_PORT1, &StatusText, strlen(StatusText));
						#endif					
						if(RxMsg.Len == 8) // it MUST be 8 DataBytes available
						{
							for(int i =0; i<RxMsg.Len; i++)
								SerTextBuff[i+SerTextlen]=RxMsg.Data8[i];
							myState = State_CAN2;
							SerTextlen = SerTextlen + RxMsg.Len;
						}
						else // no 8 Data Bytes - wrong protocol...
							break;
					break;

					case State_CAN2:
						#ifdef DEBUG
							sprintf(StatusText, "State: %d", myState); 
							SER_Write ( SER_PORT1, &StatusText, strlen(StatusText));
						#endif					
						if(RxMsg.Len != 0) // could be from 1 to 8 - ZERo is WRONG!
						{
							for(int i =0; i<RxMsg.Len ; i++)
								SerTextBuff[i+SerTextlen]=RxMsg.Data8[i];
							SerTextlen = SerTextlen + RxMsg.Len;
							// and now we send it .. 
							SER_Write ( SER_PORT1, &SerTextBuff[0], SerTextlen);
							// Send CR / LF
							SER_Write ( SER_PORT1, "\n\r", 2);
 							
							// job done - Idle again....
							myState = State_IDLE;
							SerTextlen = 0;
						}
						else // no 8 Data Bytes - wrong protocol...
							break;						
					break;

					default:

					break;
				}
			}
Attachments
Merge_mCANtoSer.zip
(33 KiB) Downloaded 1911 times
--------------------------------
PEAK-System Technik
Technical Support Team
support[at]peak-system.com
-------------------------------

Post Reply