Incorrect CAN reading

Programmable Converter for RS-232 to CAN
Post Reply
piemmepi
Posts: 2
Joined: Tue 4. Oct 2016, 13:28

Incorrect CAN reading

Post by piemmepi » Tue 4. Oct 2016, 13:45

Hello,

I am currently in the process of writing some code for the PCAN-RS232 module, and I am having issues with the CAN communication. The function of the code is to:

- Get values from an incoming CAN message and encode it into a serial message as a setpoint for an RS232 device (MFC – mass flow controller)
- Request the feedback from the MFC via RS232, read the response, and encode it into a different outgoing CAN message

The CAN network is very lightly loaded, just the relevant incoming message is sent via PCAN-View every 100 ms. The issue I am having is that the reception of the CAN messages on the PCAN-RS232 is often showing:
- CAN messages received with the correct ID, but the wrong content
- CAN messages with fictitious IDs are being received

Here are some snippets of how the CAN driver is configured:

Code: Select all

//At startup

void  CAN_UserInit ( void)
{

	// init CAN1

	CAN_ReferenceTxQueue ( CAN_BUS1, &TxQueueCAN1[0], CAN1_TX_QUEUE_SIZE);				// Reference above Arrays as Queues
	CAN_ReferenceRxQueue ( CAN_BUS1, &RxQueueCAN1[0], CAN1_RX_QUEUE_SIZE);

	CAN_SetTimestampHandler ( CAN_BUS1, NULL);

	VICVectAddr1 = (u32_t) CAN_GetIsrVector ( CAN1_TX_INTSOURCE);
	VICVectAddr3 = (u32_t) CAN_GetIsrVector ( CAN1_RX_INTSOURCE);

	VICVectCntl1 = 1 << 5 | CAN1_TX_INTSOURCE;											// Setup VIC
	VICVectCntl3 = 1 << 5 | CAN1_RX_INTSOURCE;

	VICIntEnable = 1 << CAN1_TX_INTSOURCE | 1 << CAN1_RX_INTSOURCE;

	CAN_SetErrorLimit ( CAN_BUS1, STD_TX_ERRORLIMIT);

	CAN_SetTxErrorCallback ( CAN_BUS1, NULL);											// Set ErrorLimit & Callbacks
	CAN_SetRxCallback ( CAN_BUS1, NULL);

	CAN_SetChannelInfo ( CAN_BUS1, NULL);													// Textinfo is NULL


	// Set Error Handler

	VICVectAddr0 = (u32_t) CAN_GetIsrVector ( GLOBAL_CAN_INTSOURCE);
	VICVectCntl0 = 1 << 5 | GLOBAL_CAN_INTSOURCE;
	VICIntEnable = 1 << GLOBAL_CAN_INTSOURCE;


	// Setup Filters

	CAN_InitFilters();										// Clear Filter LUT
    CAN_FilterAddId(CAN_BUS1, FILTER_11BIT_ID, CANMSG_SETPOINT_ID);
    CAN_FilterAddId(CAN_BUS1, FILTER_11BIT_ID, CANMSG_SUPPLYPRESSURE_ID);
	CAN_SetFilterMode ( AF_ON);				// No Filters ( Bypassed)

	// init CAN1
	CAN_InitChannel ( CAN_BUS1, CAN_BAUD_500K);


	//
	CAN_SetTransceiverMode ( CAN_BUS1, CAN_TRANSCEIVER_MODE_NORMAL);


	// Buses on

	CAN_SetBusMode ( CAN_BUS1, BUS_ON);					// CAN Bus On

}
The code that does the reading is in an infinite, non-timed while loop:

Code: Select all

    stCANStatus = CAN_UserRead ( CAN_BUS1, &RxMsg);

		if (stCANStatus == CAN_ERR_OK)
        {
            #if DEBUG_MODE
                ctsBufferLength = sprintf(txSerialBufferSend,  "CAN message received, ID is %d\r\n",RxMsg.Id);
                SER_Write(SER_PORT1, txSerialBufferSend, ctsBufferLength);
            #endif
            if (RxMsg.Id == CANMSG_SETPOINT_ID) {
                tiLastSetpointMsgReceived = SYSTIME_NOW;
                // message received from CAN1
                LED_toggleCAN1 ^= 1;

                if ( LED_toggleCAN1)
                {
                    HW_SetLED ( HW_LED_CAN1, HW_LED_ORANGE);
                }

                else
                {
                    HW_SetLED ( HW_LED_CAN1, HW_LED_GREEN);
                }

                // TODOConvert setpoint and send it to serial
                // SG_ dmFuelFcmH2DesByp : 0|16@1+ (0.0009765625,0) [0|65535] "mg/s" Vector__XXX
                dmSetpoint = (float)(RxMsg.Data16[0]*FLOW_CAN_SCALING); // ToDo we need to swap the bytes?
                if (dmSetpoint > dmSetpointMax)
                {
                    dmSetpoint = dmSetpointMax;
                } else {
                    if (dmSetpoint < 0)
                    {
                        dmSetpoint = 0;
                    }
                }
                ctFlowSetpoint = (u16_t)(dmSetpoint*facDmSetpointToBronkhorstSetpoint);
                #if DEBUG_MODE
                    ctsBufferLength = sprintf(txSerialBufferSend,  "Flow setpoint received: %f, converted to %d\r\n", dmSetpoint,ctFlowSetpoint);
                    SER_Write(SER_PORT1, txSerialBufferSend, ctsBufferLength);
                #endif
                ctsBufferLength = sprintf(txtCtSetpoint, "%04x", ctFlowSetpoint);    // FIXME - check formatting
                ctsBufferLength = sprintf(txSerialBufferSend,  ":0601010121%s\r\n", txtCtSetpoint);   // FIXME THIS SHOULD CONTAIN THE SETPOINT
                SER_Write(SER_PORT1, &txSerialBufferSend, ctsBufferLength);
                // TODO add checking the response
            } else {
                if (RxMsg.Id == CANMSG_SUPPLYPRESSURE_ID)
                {
                    // Just copy it across to another variable
                    ctPSpl = RxMsg.Data16[2];
                    #if DEBUG_MODE
                        ctsBufferLength = sprintf(txSerialBufferSend,  "Pressure received: %d\r\n", ctPSpl);
                        SER_Write(SER_PORT1, txSerialBufferSend, ctsBufferLength);
                    #endif
                } else {
                    // Do nothing
                #if DEBUG_MODE
                    ctsBufferLength = sprintf(txSerialBufferSend,  "Message %d not recognised\r\n",RxMsg.Id);
                    SER_Write(SER_PORT1, txSerialBufferSend, ctsBufferLength);
                #endif

                }
            }
        }
As you can see, I have placed debug statements in the code, and these show up as follows:
CAN message received, ID is 1903
Flow setpoint received: 3.203125, converted to 3422

:06010101210d5e
:06030401210120
:0401000000
CAN message received, ID is 4
Message 4 not recognised
:06030401210120
CAN message received, ID is 1
:06010101212485
:06030401210120
:0401000000
CAN message received, ID is 1903
Flow setpoint received: 8.750977, converted to 9349

:06010101212485
:06030401210120
:0401000000
CAN message received, ID is 1073745340
Message 1073745340 not recognised
:06030401210120
:0401000000
CAN message received, ID is 54648
Message 54648 not recognised
:06030401210120
CAN message received, ID is 0
:06010101210d5e
CAN message received, ID is 1903
Flow setpoint received: 8.750977, converted to 9349

:06010101212485
:06030401210120
I have tried to use the highlighting as much in order to facilitate the interpretation.

- The messages highlighted in blue are sent by my laptop using RealTerm.
- Some incorrect messages are often showing (highlighted in red), plus the correct message (1903) often has the wrong content (3422 - yellow) rather than the correct one (9349 - green).

The further outputs on the serial are part of a different functionality on the code.

User avatar
P.Steil
Hardware Development
Hardware Development
Posts: 32
Joined: Fri 14. Jan 2011, 10:27

Re: Incorrect CAN reading

Post by P.Steil » Tue 4. Oct 2016, 16:20

Hello,

at first you can reduce your code to a minimum until the bad CAN-IDs will be received no more.
One reason could be the sprintf function. It will need much stack space so the stack might
overwrite data from other variables. Take a look into the flash.ld file and check if the
USR_Stack_Size
is set e.g. to 2048 . This should be enough stack space.


Regards
--------------------------------------------
PEAK-System HW development Team
support@peak-system.com
phone: +49-6151-8173-20
fax: +49-6151-8173-29
--------------------------------------------

piemmepi
Posts: 2
Joined: Tue 4. Oct 2016, 13:28

Re: Incorrect CAN reading

Post by piemmepi » Tue 4. Oct 2016, 16:51

Hello and thank you for your reply.

I was actually seeing a higher rate of failures with the debug instructions, so this makes sense. The stack size was 512, and I have now increased it to 2048.

I haven't seen a failure since, even with the debugging activated.

Thank you!

Post Reply