cancel
Showing results for 
Search instead for 
Did you mean: 

OBD2 request frames rejection issues

MR17
Associate II
I tried doing an OBD2 request via Car's OBD2 port.

I am able to see the CAN BUS traffic using an oscilloscope , just my request frames are rejected by car. I am using STM32h735G-DK development board to send OBD2 requests. It consists of an inbuilt FDCAN transceiver.

Settings are fine (removed termination resistor as car already has two), baudrate is 500kbps  with 87.5% sample point. I am using the following code to send OBD2 request frames:

I am able to receive CAN frames and able to log CAN frame frames it is just that frames sent are rejected. What am i doing wrong here?

FDCAN Code excerpt:
 
/* ============ 500 kbit/s Bit Timing Derivation ============
   *
   * Step 1: FDCAN Kernel Clock
   *   fCAN = 80 MHz (from Clock Configuration)
   *
   * Step 2: Prescaler
   *   Prescaler = 10
   *
   * Step 3: Time Quantum (tq)
   *   tq = Prescaler / fCAN
   *   tq = 10 / 80,000,000 Hz = 0.125 µs = 125 ns
   *
   * Step 4: Bit Segments (in TQ)
   *   Sync Segment   = 1 TQ  (fixed, always 1)
   *   Time Segment 1 = 12 TQ (Prop_Seg + Phase_Seg1)
   *   Time Segment 2 = 3 TQ  (Phase_Seg2)
   *
   * Step 5: Total Time Quanta per Bit
   *   Total TQ = Sync + TS1 + TS2 = 1 + 12 + 3 = 16 TQ
   *
   * Step 6: Bit Time
   *   Bit Time = Total TQ × tq = 16 × 125 ns = 2000 ns = 2 µs
   *
   * Step 7: Nominal Bit Rate
   *   Bit Rate = 1 / Bit Time = 1 / 2 µs = 500 kbit/s
   *
   * Step 8: Sample Point
   *   Sample Point = (Sync + TS1) / Total TQ = (1 + 13) / 16 = 87.5%
   *
   */ 
  ----------------
  MX_FDCAN2_Init();

  -----------------
  FDCAN_FilterTypeDef sFilterConfig;
  sFilterConfig.IdType = FDCAN_STANDARD_ID;
  sFilterConfig.FilterIndex = 0;
  sFilterConfig.FilterType = FDCAN_FILTER_MASK;         /* Classic ID + mask mode          */
  sFilterConfig.FilterConfig = FDCAN_FILTER_TO_RXFIFO0; /* Matching frames → RX FIFO 0     */
  sFilterConfig.FilterID1 = 0x7E8;                      /* Expected ECU response base ID   */
  sFilterConfig.FilterID2 = 0x7F8;                      /* Mask: match 0x7E8 – 0x7EF       */
  if (HAL_FDCAN_ConfigFilter(&hfdcan2, &sFilterConfig) != HAL_OK) {
    Error_Handler();
  }
  /* Reject all non-matching frames (no global accept) */
  if (HAL_FDCAN_ConfigGlobalFilter(&hfdcan2, FDCAN_REJECT, FDCAN_REJECT, FDCAN_REJECT_REMOTE, FDCAN_REJECT_REMOTE) != HAL_OK) {
    Error_Handler();
  }

  if (HAL_FDCAN_Start(&hfdcan2) != HAL_OK) {
    Error_Handler();
  }

  -----------------
  static void MX_FDCAN2_Init(void) {

  /* USER CODE BEGIN FDCAN2_Init 0 */

  /* USER CODE END FDCAN2_Init 0 */

  /* USER CODE BEGIN FDCAN2_Init 1 */

  /* USER CODE END FDCAN2_Init 1 */
  hfdcan2.Instance = FDCAN2;
  hfdcan2.Init.FrameFormat = FDCAN_FRAME_CLASSIC;
  hfdcan2.Init.Mode = FDCAN_MODE_NORMAL;
  hfdcan2.Init.AutoRetransmission = ENABLE;
  hfdcan2.Init.TransmitPause = DISABLE;
  hfdcan2.Init.ProtocolException = DISABLE;
  hfdcan2.Init.NominalPrescaler = 10;
  hfdcan2.Init.NominalSyncJumpWidth = 1;
  hfdcan2.Init.NominalTimeSeg1 = 13;
  hfdcan2.Init.NominalTimeSeg2 = 2;
  hfdcan2.Init.DataPrescaler = 1;
  hfdcan2.Init.DataSyncJumpWidth = 1;
  hfdcan2.Init.DataTimeSeg1 = 1;
  hfdcan2.Init.DataTimeSeg2 = 1;
  hfdcan2.Init.MessageRAMOffset = 0x000;
  hfdcan2.Init.StdFiltersNbr = 1;
  hfdcan2.Init.ExtFiltersNbr = 0;
  hfdcan2.Init.RxFifo0ElmtsNbr = 32;
  hfdcan2.Init.RxFifo0ElmtSize = FDCAN_DATA_BYTES_8;
  hfdcan2.Init.RxFifo1ElmtsNbr = 0;
  hfdcan2.Init.RxFifo1ElmtSize = FDCAN_DATA_BYTES_8;
  hfdcan2.Init.RxBuffersNbr = 0;
  hfdcan2.Init.RxBufferSize = FDCAN_DATA_BYTES_8;
  hfdcan2.Init.TxEventsNbr = 0;
  hfdcan2.Init.TxBuffersNbr = 0;
  hfdcan2.Init.TxFifoQueueElmtsNbr = 32;
  hfdcan2.Init.TxFifoQueueMode = FDCAN_TX_FIFO_OPERATION;
  hfdcan2.Init.TxElmtSize = FDCAN_DATA_BYTES_8;
  if (HAL_FDCAN_Init(&hfdcan2) != HAL_OK) {
    Error_Handler();
  }
  /* USER CODE BEGIN FDCAN2_Init 2 */

  /* USER CODE END FDCAN2_Init 2 */
}

-----------------
/* This callback is triggered by TIM1 overflow every 1 second to send an OBD-II RPM request frame */
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef* htim) { 
  if (htim->Instance == TIM1) {
    FDCAN_TxHeaderTypeDef TxHeader;
    uint8_t TxData[DATA_LEN] = {0};
    TxHeader.Identifier = 0x7E0; // OBD-II request ID for Engine ECU, cycled through 0x7E0-0x7E7 for different ECUs, same rejection issue
    TxHeader.IdType = FDCAN_STANDARD_ID;
    TxHeader.TxFrameType = FDCAN_DATA_FRAME;
    TxHeader.DataLength = FDCAN_DLC_BYTES_8;
    TxHeader.ErrorStateIndicator = FDCAN_ESI_ACTIVE;
    TxHeader.BitRateSwitch = FDCAN_BRS_OFF;
    TxHeader.FDFormat = FDCAN_CLASSIC_CAN;
    TxHeader.TxEventFifoControl = FDCAN_NO_TX_EVENTS;
    TxHeader.MessageMarker = 0;
    TxData[0] = 0x02; // SF, 2 data bytes
    TxData[1] = 0x01; // Service 01
    TxData[2] = 0x0C; // PID 0C — RPM

    HAL_FDCAN_AddMessageToTxFifoQ(&hfdcan2, &TxHeader, TxData);
  }
}
1 ACCEPTED SOLUTION

Accepted Solutions

Indeed you are using HSI. It’s recommended to use HSE and a crystal for CAN communication. I don’t have my PC now (i’m posting with my phone) but the disco board has already a crystal (crystal oscillator XO).
So please use it instead of HSI:

IMG_4830.png

You shoud select HSE in bypass mode and set the crystal value to 25MHz in the clock view.

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.

View solution in original post

20 REPLIES 20
Ozone
Principal III

> I am able to see the CAN BUS traffic using an oscilloscope , just my request frames are rejected by car. 

You need to be more specific here. What does "rejected by car" look like ?

I don't know OBD specifics, but this is basically the higher protocol transported via CAN.
Does the physical layer cause errors, or does your application violate OBD protocol ?
If the former is the case, the CAN error counters (TEC and REC) should indicate that.

MR17
Associate II

Please see the file attached , filter ID column with 7E and select all. You will see that DLC 0 and DATA empty and CRC invalid , not  ACKed and Valid 0. 

TEC increased more than 127 , goes to error passive after a few milliseconds. 

OBD2 request frames.png

 02 01 0C with first byte 02 means it is a request for RPM in live mode (show current data). I don't even flood the bus since my requests are periodic with 1s , and i address it to each physical address from 7E0-7E7 and 7DF(broadcasting to all ECUs)

Ozone
Principal III

> TEC increased more than 127 , goes to error passive after a few milliseconds. 

Which means you almost certainly have a problem with the physical signal, either wiring, or missing/improper termination resistance.

As said, I don't know OBD, but Wikipedia states :

  - ISO 15765 CAN (250 kbit/s or 500 kbit/s).

Have you tried 250kbit/s ?

mƎALLEm
ST Employee

Hello @MR17 and welcome to the ST community,

As you are receiving well the CAN frames sent by the car, the communication is fine as well as your hardware. If your car is not accepting your frames (especially when they were acknowledged) that means the CAN IDs are dropped by the car. So we cannot help you at this stage as we are not OBD specification experts here. You need to check it again and verify the correct IDs and the data content needed for that communication.

Good luck!

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.
MR17
Associate II

@Ozone wrote:

> TEC increased more than 127 , goes to error passive after a few milliseconds. 

Which means you almost certainly have a problem with the physical signal, either wiring, or missing/improper termination resistance.

As said, I don't know OBD, but Wikipedia states :

  - ISO 15765 CAN (250 kbit/s or 500 kbit/s).

Have you tried 250kbit/s ?



OBD2 Request are only for High Speed CAN. And the pins of OBD2 port are CANH pin 6 , CANH pin 14 and GND pin 5 or 4

> TEC increased more than 127 , goes to error passive after a few milliseconds. 

Which means you almost certainly have a problem with the physical signal, either wiring, or missing/improper termination resistance.


 It is fine , otherwise my oscilloscope would have not decoded the frames and the FDCAN present in the board would have not received the frames and logged via USART3 VCOM .

Ozone
Principal III

> It is fine , otherwise my oscilloscope would have not decoded the frames and the FDCAN present in the board would have not received the frames and logged via USART3 VCOM .

The other side (the car) seems to disagree.
And TEC / REC are going up on physical signal errors.
What you see on one end is not necessarily what the other side sees.

Sorry I didn't see that post:


@MR17 wrote:

Please see the file attached , filter ID column with 7E and select all. You will see that DLC 0 and DATA empty and CRC invalid , not  ACKed and Valid 0. 

TEC increased more than 127 , goes to error passive after a few milliseconds. 

OBD2 request frames.png

 02 01 0C with first byte 02 means it is a request for RPM in live mode (show current data). I don't even flood the bus since my requests are periodic with 1s , and i address it to each physical address from 7E0-7E7 and 7DF(broadcasting to all ECUs)


So you have communication errors!

Frame not acked means, bitrate issue or hardware issue. I'm a bit surprised by this:

"I am able to receive CAN frames and able to log CAN frame frames it is just that frames sent are rejected"

What clock source are you using for FDCAN? HSI or HSE+Crystal?  if HSI, please use HSE + a crystal or any other external precise source.

 

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.

> "I am able to receive CAN frames and able to log CAN frame frames it is just that frames sent are rejected"
> What clock source are you using for FDCAN? HSI or HSE+Crystal?  if HSI, please use HSE + a crystal or any other external precise source.


As I understood it, an attached CAN dongle properly receives and displays those messages. Which does not mean that the OBD counterpart does.
And, having no OBD experience either, have seen that Wikipedia lists either 250 or 500 KBit/s as possible supported bitrates.
The OP can have a mismatch here, I have seen nothing about "auto baud detection".

I’m providing all the sources of issues that can face with the communication and also I cited a possible issue of a bitrate mismatch. But that doesn’t make sense if his can node is receiving well the frames from the car. That seems to be not a baudrate issue but more related to a jitter or something similar.

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.