cancel
Showing results for 
Search instead for 
Did you mean: 

I can read CAN-bus signals, but not write CAN-bus signals. Do I have wrong baud rate?

DMårt
Lead

Hi!

I have recently written an SAE J1939 library and it works great to read CAN-bus signals. Check it out.

https://github.com/DanielMartensson/Open-SAE-J1939

I have copy->paste the library into my STM32 and it works great to read the SAE J1939 signals from the ECU unit. But when I'm going to write to the ECU unit, then nothing happens. It's not the librarys fault. It's the CAN-bus settings in STM32CubeIDE.

This is how I have done:

Step 1: I KNOW that the ECU has 250 kb/s baudrate. So I tune that in inside STM32CubeIDE

0693W00000D0FMiQAN.png0693W00000D0FUmQAN.pngStep 2: Then I create my CAN-bus layer code. It's for STM32F3 if you wonder.

/*
 * CAN.c
 *
 *  Created on: Jun 14, 2021
 *      Author: Daniel Mårtensson
 */
 
#include "Functions.h"
 
static CAN_HandleTypeDef *can_handler;
static uint32_t CAN_ID = 0;
static uint8_t RxData[8] = {0};
static bool new_message = false;
static void Create_CAN_Filter(CAN_HandleTypeDef *hcan);
static void Create_CAN_Interrupt(CAN_HandleTypeDef *hcan);
 
void STM32_PLC_Start_CAN(CAN_HandleTypeDef *hcan) {
	can_handler = hcan;
	Create_CAN_Filter(hcan);
	if (HAL_CAN_Start(hcan) != HAL_OK)
		Error_Handler();
	Create_CAN_Interrupt(hcan);
}
 
HAL_StatusTypeDef STM32_PLC_CAN_Transmit(uint8_t TxData[], CAN_TxHeaderTypeDef *TxHeader) {
	uint32_t TxMailbox;
	return HAL_CAN_AddTxMessage(can_handler, TxHeader, TxData, &TxMailbox);
}
 
/* Returns true if the message data is new */
void STM32_PLC_CAN_Get_ID_Data(uint32_t* ID, uint8_t data[], bool* is_new_message) {
	*ID = CAN_ID;
	memcpy(data, RxData, 8);
	*is_new_message = new_message;
	new_message = false;
}
 
/* Interrupt handler that read message */
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan) {
	CAN_RxHeaderTypeDef RxHeader;
	if (HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, &RxHeader, RxData) != HAL_OK)
		Error_Handler();
 
	/* Read ID */
	if(RxHeader.IDE == CAN_ID_STD){
		CAN_ID = RxHeader.StdId;
	}else{
		CAN_ID = RxHeader.ExtId;
	}
	new_message = true;
}
 
static void Create_CAN_Interrupt(CAN_HandleTypeDef *hcan) {
	if (HAL_CAN_ActivateNotification(hcan, CAN_IT_RX_FIFO0_MSG_PENDING) != HAL_OK)
			Error_Handler();
}
 
static void Create_CAN_Filter(CAN_HandleTypeDef *hcan) {
	CAN_FilterTypeDef sFilterConfig;
	sFilterConfig.FilterBank = 0;
	sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;
	sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;
	sFilterConfig.FilterIdHigh = 0x0000;
	sFilterConfig.FilterIdLow = 0x0000;
	sFilterConfig.FilterMaskIdHigh = 0x0000;
	sFilterConfig.FilterMaskIdLow = 0x0000;
	sFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO0;
	sFilterConfig.FilterActivation = ENABLE;
	sFilterConfig.SlaveStartFilterBank = 14;
 
	if (HAL_CAN_ConfigFilter(hcan, &sFilterConfig) != HAL_OK)
		Error_Handler();
}

Step 3: I init the CAN-bus layer.

STM32_PLC_Start_CAN(&hcan);

Step 4: I'm reading the SAE J1939 can bus signals..

Open_SAE_J1939_Listen_For_Messages(&j1939); /* Examples are available in the GitHub repository */

Step 5: Im suing TCAN334 IC chip for transmitt CAN-data.

https://www.ti.com/lit/ds/symlink/tcan334.pdf

All this above works great! I can read messages.

But then when I'm writing to the ECU unit. In this case, the ECU unit have the address 0x80 = 128. Nothing happens.

SAE_J1939_Send_Request_Address_Claimed(&j1939, 0x80);

I hook up an oscilloscope and analysing the signals.

Settings:

1V divider

20 uS sweep time

CAN+ from my STM32 board:

This is a request ID for Address Claimed = 0x00EE00

ID = 0x18EA8022 = 0b00011000 11101010 10000000 00100010

DLC = 3 bytes

DATA = 0x00EE00 = 0b00000000 11101110 00000000

0693W00000D0FWiQAN.pngCAN+ from the ECU:

0693W00000D0FWxQAN.pngQuestion:

Judging by the CAN+ signals, how different they are. Can it be that I have seleted wrong baudrate?

Why can I read the signals from the ECU, but not write to the ECU?

Edit:

Here is more pictures. The same settings as above.

CAN+ and CAN- from ECU

0693W00000D0G8wQAF.png0693W00000D0G9LQAV.pngCAN+ and CAN- from STM32F3:

0693W00000D0G9pQAF.png0693W00000D0G9uQAF.png

STM32MP151AAC3 custom board with STM32-OS as operating system: https://github.com/DanielMartensson/STM32-Computer
4 REPLIES 4

Is the STM32 flagging any error/status?

The CAN+/- look Ok

Have you tried a pair of STM32 talking to each other, or CAN1 to CAN2 out-n-back test?

Perhaps look at what the transceiver is doing.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

I'm only having CAN1 and only one STM32 board.

The transmitt function gives HAL_OK.

Also from the ECU, I get a DM1 message.

FMI = 0 is it. I don't understand it.

"Data Valid But Above Normal Operational Range (Most Severe Level): The signal communicating information is within a defined acceptable and valid range, but the real world condition is above what would be considered normal as determined by the predefined most severe level limits for that particular measure of the real world condition (Region e of the signal range definition). Broadcast of data values is continued as normal."

https://product-help.schneider-electric.com/Machine%20Expert/V1.1/en/IoDrvJ1939/topics/fmi.htm

STM32MP151AAC3 custom board with STM32-OS as operating system: https://github.com/DanielMartensson/STM32-Computer

By the way! I notice something weir.d

This code runs, even if TransmitGlobalTime is DISABLE

      /* Set up the Transmit Global Time mode */
      if (pHeader->TransmitGlobalTime == ENABLE)
      {
        SET_BIT(hcan->Instance->sTxMailBox[transmitmailbox].TDTR, CAN_TDT0R_TGT);
      }

Have a look

0693W00000D0GcNQAV.png

STM32MP151AAC3 custom board with STM32-OS as operating system: https://github.com/DanielMartensson/STM32-Computer

Is there any way I can put CAN- constant low and CAN+ constant high in STM32CubeIDE?

I want to measure the voltage between CAN+ and CAN-. Perhaps the voltage is to low?

Thank you.

STM32MP151AAC3 custom board with STM32-OS as operating system: https://github.com/DanielMartensson/STM32-Computer