cancel
Showing results for 
Search instead for 
Did you mean: 

CAN Bus between STM32F103 and Arduino

chris_daquino
Associate

I have a few arduino boards communicating through each other on a CAN Bus. Arduino is connected to a MCP2515 CAN Bus Module TJA1050.

All arduino are communicating properly between each other. Here is an example of my reader on arduino:

#include "MIDIUSB.h"
#include <SPI.h>          
#include <mcp2515.h>
 
struct can_frame txMsg, rxMsg;
//struct can_frame rxmsg;
 
MCP2515 mcp2515(7);
 
byte chan = 1;
 
void setup() {
    Serial.begin(500000);
    Serial.println("myDrum 2 MIDI");
 
    SPI.begin();
 
    mcp2515.reset();
    mcp2515.setBitrate(CAN_500KBPS,MCP_8MHZ); 
    mcp2515.setNormalMode();
}
 
 
void loop() {
 
    if (mcp2515.readMessage(&rxMsg) == MCP2515::ERROR_OK) {
 
        switch (rxMsg.data[0])
        {
        case 144:
            noteOn(chan, rxMsg.data[1], rxMsg.data[2]);
            break;
        case 178:
            controlChange(chan, rxMsg.data[1], rxMsg.data[2]);
            break;
        default:
            break;
        }
        
        //Serial.print("Received Message: ");
        Serial.print(rxMsg.data[0]); Serial.print(" - ");
        Serial.print(rxMsg.data[1]); Serial.print(" - ");
        Serial.println(rxMsg.data[2]);
    }
}
 
void noteOn(byte channel, byte pitch, byte velocity) {
    midiEventPacket_t noteOn = {0x09, 0x90 | channel, pitch, velocity};
    MidiUSB.sendMIDI(noteOn);
    MidiUSB.flush();
}
 
void controlChange(byte channel, byte control, byte value) {
    midiEventPacket_t event = {0x0B, 0xB0 | channel, control, value};
    MidiUSB.sendMIDI(event);
    MidiUSB.flush();
}

Now I'm trying to add an STM32F103 with a MCP2551 transceiver module but nothing is being received from the STM32F103 on the arduino side. Since the arduino's are talking to each other, I tend to think that the issue is on the STM32F103 side. My code is below. Any thoughts on what I'm missing?

#include "main.h"
ADC_HandleTypeDef hadc1;
ADC_HandleTypeDef hadc2;
 
CAN_HandleTypeDef hcan;
 
I2C_HandleTypeDef hi2c1;
 
UART_HandleTypeDef huart1;
 
/* USER CODE BEGIN PV */
CAN_RxHeaderTypeDef RxHeader;
CAN_TxHeaderTypeDef TxHeader;
uint32_t TxMailbox;
/* USER CODE END PV */
 
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_CAN_Init(void);
static void MX_USART1_UART_Init(void);
static void MX_ADC1_Init(void);
static void MX_ADC2_Init(void);
static void MX_I2C1_Init(void);
/* USER CODE BEGIN PFP */
 
/* USER CODE END PFP */
 
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
 
/* USER CODE END 0 */
 
 
int main(void)
{
  /* USER CODE BEGIN 1 */
 
  /* USER CODE END 1 */
  
 
  /* MCU Configuration--------------------------------------------------------*/
 
  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();
 
  /* USER CODE BEGIN Init */
 
  /* USER CODE END Init */
 
  /* Configure the system clock */
  SystemClock_Config();
 
  /* USER CODE BEGIN SysInit */
 
  /* USER CODE END SysInit */
 
  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_CAN_Init();
  MX_USART1_UART_Init();
  MX_ADC1_Init();
  MX_ADC2_Init();
  MX_I2C1_Init();
  /* USER CODE BEGIN 2 */
 
  /* USER CODE END 2 */
 
  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
 
 
		uint8_t message[3];
		message[0] = 144;
		message[1] = 38;
		message[2] = 127;
 
		TxHeader.DLC = 3;
		TxHeader.StdId = 0x221;
		TxHeader.IDE   = CAN_ID_STD;
		TxHeader.RTR = CAN_RTR_DATA;
 
 
		if( HAL_CAN_AddTxMessage(&hcan, &TxHeader, &message, &TxMailbox) != HAL_OK)
		{
			Error_Handler();
		}
 
	  HAL_Delay(1000);
    /* USER CODE END WHILE */
 
    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}
 
 
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
  RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
 
  /** Initializes the CPU, AHB and APB busses clocks 
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }
  /** Initializes the CPU, AHB and APB busses clocks 
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
 
  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
  {
    Error_Handler();
  }
  PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_ADC;
  PeriphClkInit.AdcClockSelection = RCC_ADCPCLK2_DIV6;
  if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
  {
    Error_Handler();
  }
}
 
 
static void MX_CAN_Init(void)
{
 
  /* USER CODE BEGIN CAN_Init 0 */
 
  /* USER CODE END CAN_Init 0 */
 
  /* USER CODE BEGIN CAN_Init 1 */
 
  /* USER CODE END CAN_Init 1 */
  hcan.Instance = CAN1;
  hcan.Init.Prescaler = 9;
  hcan.Init.Mode = CAN_MODE_NORMAL;
  hcan.Init.SyncJumpWidth = CAN_SJW_1TQ;
  hcan.Init.TimeSeg1 = CAN_BS1_13TQ;
  hcan.Init.TimeSeg2 = CAN_BS2_2TQ;
  hcan.Init.TimeTriggeredMode = DISABLE;
  hcan.Init.AutoBusOff = DISABLE;
  hcan.Init.AutoWakeUp = DISABLE;
  hcan.Init.AutoRetransmission = DISABLE;
  hcan.Init.ReceiveFifoLocked = DISABLE;
  hcan.Init.TransmitFifoPriority = DISABLE;
  if (HAL_CAN_Init(&hcan) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN CAN_Init 2 */
  CAN_FilterTypeDef can_filter_init;
  can_filter_init.FilterActivation = CAN_FILTER_ENABLE;
  can_filter_init.FilterBank  = 0;
  can_filter_init.FilterFIFOAssignment = CAN_RX_FIFO0;
  can_filter_init.FilterIdHigh = 0x9999;
  can_filter_init.FilterIdLow = 0x0000;
  can_filter_init.FilterMaskIdHigh = 0x9999;
  can_filter_init.FilterMaskIdLow = 0x0000;
  can_filter_init.FilterMode = CAN_FILTERMODE_IDMASK;
  can_filter_init.FilterScale = CAN_FILTERSCALE_32BIT;
 
  if( HAL_CAN_ConfigFilter(&hcan,&can_filter_init) != HAL_OK)
  	{
	  Error_Handler();
  	}
 
  if( HAL_CAN_Start(&hcan) != HAL_OK)
  	{
	  Error_Handler();
  	}
 
//  if(HAL_CAN_ActivateNotification(&hcan,CAN_IT_TX_MAILBOX_EMPTY|CAN_IT_BUSOFF)!= HAL_OK)
//  	{
//  			Error_Handler();
//  	}
 
  /* USER CODE END CAN_Init 2 */
 
}
 
static void MX_GPIO_Init(void)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};
 
  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOC_CLK_ENABLE();
  __HAL_RCC_GPIOD_CLK_ENABLE();
  __HAL_RCC_GPIOA_CLK_ENABLE();
  __HAL_RCC_GPIOB_CLK_ENABLE();
 
  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_SET);
 
  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(drain1_GPIO_Port, drain1_Pin, GPIO_PIN_RESET);
 
  /*Configure GPIO pin : LED_Pin */
  GPIO_InitStruct.Pin = LED_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_MEDIUM;
  HAL_GPIO_Init(LED_GPIO_Port, &GPIO_InitStruct);
 
  /*Configure GPIO pins : pad1_Pin pad2_Pin */
  GPIO_InitStruct.Pin = pad1_Pin|pad2_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
 
  /*Configure GPIO pins : PA5 trigger1_Pin trigger2_Pin */
  GPIO_InitStruct.Pin = GPIO_PIN_5|trigger1_Pin|trigger2_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
 
  /*Configure GPIO pin : drain1_Pin */
  GPIO_InitStruct.Pin = drain1_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
  HAL_GPIO_Init(drain1_GPIO_Port, &GPIO_InitStruct);
 
}
 

5 REPLIES 5
JoniS
Senior

is it possible some of the arduinos always try transmit same time as the STM? If multiple devices transmit same time the one with lowest message ID gets its message sent, and since you have not configured AutoRetransmission, your stm would not try transmit again, well atleast before you call transmit again.

What is the clock speed for your CAN?( just to make sure its configured to that 500kbits baud)

A.MUHENDIS
Associate

I think MCP2515 needs to be connected with stm32f103 via SPI interface, which is not configured from stm32 side !

APatel1
Associate

Hey @chris_daquino​ 

Have you found any solution on this post?

I'm trying the same connection b/w Arduino and STM32F753 and facing the same issue.

I hope I can find solution from you.

BEmad.1
Associate

I'm facing the same problem

Does anyone got the solution for it ?

jvasq.1
Associate

Hi, I solved this problem by using a logic analyzer to check CAN data frame from arduino, then I found CAN baud rate from arduino is not the same I configured in my code (500 KBPS is actually 250 KBPS). In summary, change stm32 CAN baud rate to 250 KBPS to match with arduino and this will solve your problems.

I used arduino uno with MCP2515 and STM32 blue pill with MCP2551.