STM32F4 ile MPU6050 iletişimi

Başlatan Cemre., 17 Şubat 2016, 23:34:22

Cemre.

Konu hakkında blog sitemde bir videolu yazı yayınladım, belki arkadaşların işlerine yarar.

https://maviled.wordpress.com/2016/02/17/cubemx-ile-i2c-projesi/

Kolay gelsin, iyi akşamlar.

muhittin_kaplan


koray692

bende mikroc ile verileri alıyorum ancak veriyi 10 ms aralıklarla kesme ile almak istiyorum register map e baktım ama pek birşey anlamadım açıkcası ?

Cemre.

Alıntı yapılan: koray692 - 19 Şubat 2016, 13:41:37
bende mikroc ile verileri alıyorum ancak veriyi 10 ms aralıklarla kesme ile almak istiyorum register map e baktım ama pek birşey anlamadım açıkcası ?
Aslında DLPF özelliğini 6.seviye aktif ederek veri sıklığını 40 küsur/saniye'ye düşürebilirsiniz.

Ama ben 10ms.de bir o anki veriyi okuyacağım derseniz paylaştığım örnekte dış kesme kullanarak nasıl yapılacağını anlatmıştım. Siz de bir timer kurup taşma olduğunda yine benim MPU6050_INT_State değişkeni gibi bir değişkeni 1 yapıp ana döngüde okuma yaptırabilirsiniz. Yine INT bacağını da kontrol edebilirsiniz ayrıca.

Kolay gelsin, iyi geceler.

__ozgur

Merhabalar,

Öncelikle blokta paylaştığınız kod için çok teşekkür ederim. Ancak şöyle bir sıkıntım var 6 ile 10 saniye arasında değişen sürelerde kod donuyor ve yeni verileri okumamaya başlıyor. STM32f7 Nucleo board ve GY-87 kullanıyorum imu olarak. Vcc üzerinden 5 voltla besleme yapıyorum. Problem i2c haberleşmesinde midir? Biraz araştırdım power supply la ilgili olabilir demişler benzer bir problem yaşayan olmuş mudur acaba?


__ozgur

Interrupt yapısını kaldırdım ve okumayı RTOS task'ı içine aldım. Ne derece doğru ölçüm yaptığımı bilmiyorum ancak şuan için kod tıkanmadan okuma devam ediyor. Yine de sorunun neyden kaynaklandığı hakkında fikri olan varsa paylaşabilirse çok sevinirim.  :)

Cemre.

Sensor Interrupt ayarlarınızı doğru yaptığınızdan emin misiniz?
Okuma işlemini ext int rutini içerisinde mi yapiyorsunuz? Uzun sürüyorsa işlemci hataya düşüyor olabilir.

Debug yapıyor musunuz?

Int ile okuma bu sorunların önüne geçmek için kullanılıyor zaten...

__ozgur

Blogunuzda yayinladiginiz bacagi degil baska bir external interrupt bacagini kullanmistim ancak problemin orada oldugunu da sanmiyorum. Linux ortaminda calisiyorum malesef keil kullanamadigim icin dongulerin icine ledler printler koyarak verimsiz bir debug yapiyorum. Mbed kutuphanesini, rtos kutuphanesini ve rosserial kutuphanesini de ekleyerek 100 hz rtos taskinin icerisinde okuma ve yazmayi birlikte yapiyorum. Iyi kotu degerler geliyor simdilik, yarin filtre uygulamaya calisacagim o zaman anlasilacak ne kadar duzgun okuyabildigim  :)

Cemre.

Alıntı yapılan: __ozgur - 18 Ocak 2017, 22:43:29
Blogunuzda yayinladiginiz bacagi degil baska bir external interrupt bacagini kullanmistim ancak problemin orada oldugunu da sanmiyorum. Linux ortaminda calisiyorum malesef keil kullanamadigim icin dongulerin icine ledler printler koyarak verimsiz bir debug yapiyorum. Mbed kutuphanesini, rtos kutuphanesini ve rosserial kutuphanesini de ekleyerek 100 hz rtos taskinin icerisinde okuma ve yazmayi birlikte yapiyorum. Iyi kotu degerler geliyor simdilik, yarin filtre uygulamaya calisacagim o zaman anlasilacak ne kadar duzgun okuyabildigim  :)

Linux ortamında debug yapamayacağınızı nereden çıkardınız?

SW4STM32 IDE'sini ve OpenOCD'yi araştırabilirsiniz.

Bahsettiğiniz kütüphanelere vs aşina değilim maalesef. Çipin başka bir int bacağı olduğunu da bilmiyordum...

Bu arada, HMC'nin veri yenileme sıklığı yanlış hatırlamıyorsam max 30Hz gibi birşeydi, oralarda takılıyor da olabilirsiniz...
Kolay gelsin.

Sya

@Cemre. Hocam sitenizdeki kodların aynısını sensörü deneme amaçlı kopyala yapıştır yaptım fakat çalışmadı. Bi kodlara bakar mısınız ? Cube kısmınıda videodaki gibi yaptım.

#include "main.h"
#include "stm32f4xx_hal.h"
#include "mpu6050_map.h"

/* USER CODE BEGIN Includes */

/* USER CODE END Includes */

/* Private variables ---------------------------------------------------------*/
I2C_HandleTypeDef hi2c1;

/* USER CODE BEGIN PV */
/* Private variables ---------------------------------------------------------*/

uint8_t TxBuffer[2];
uint8_t RxBuffer[7];
uint8_t DataBuffer[14];
int16_t DataBuffer16[7];
uint8_t MPU6050_INT_State = 0;

int16_t gyro_x_temp, gyro_y_temp, gyro_z_temp, accel_x_temp, accel_y_temp, accel_z_temp, temp_raw;
float temp, gyro_x, gyro_y, gyro_z, accel_x, accel_y, accel_z;

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
void Error_Handler(void);
static void MX_GPIO_Init(void);
static void MX_I2C1_Init(void);
static void MPU6050_Extract_Readings(void);

int main(void)
{

  /* USER CODE BEGIN 1 */
	
TxBuffer[0] = 0x80;
HAL_I2C_Mem_Write(&hi2c1, MPU6050_DEFAULT_ADDRESS, MPU6050_RA_PWR_MGMT_1, 1, TxBuffer, 1, 1000);
HAL_Delay(200);

TxBuffer[0] = 0x00;
HAL_I2C_Mem_Write(&hi2c1, MPU6050_DEFAULT_ADDRESS, MPU6050_RA_PWR_MGMT_1, 1, TxBuffer, 1, 1000);
HAL_Delay(200);

TxBuffer[0] = 0xF8;
HAL_I2C_Mem_Write(&hi2c1, MPU6050_DEFAULT_ADDRESS, MPU6050_RA_FIFO_EN, 1, TxBuffer, 1, 1000);
HAL_Delay(200);

TxBuffer[0] = 0x10;
HAL_I2C_Mem_Write(&hi2c1, MPU6050_DEFAULT_ADDRESS, MPU6050_RA_FIFO_EN, 1, TxBuffer, 1, 1000);
HAL_Delay(200);

HAL_I2C_Mem_Read(&hi2c1, MPU6050_DEFAULT_ADDRESS, MPU6050_RA_ACCEL_CONFIG, I2C_MEMADD_SIZE_8BIT, RxBuffer, 1, 1000);
HAL_Delay(200);
RxBuffer[0] |= 0x18;
HAL_I2C_Mem_Write(&hi2c1, MPU6050_DEFAULT_ADDRESS, MPU6050_RA_ACCEL_CONFIG, 1, RxBuffer, 1, 1000);

HAL_I2C_Mem_Read(&hi2c1, MPU6050_DEFAULT_ADDRESS, MPU6050_RA_INT_ENABLE, I2C_MEMADD_SIZE_8BIT, RxBuffer, 1, 1000);
HAL_Delay(200);
RxBuffer[0] |= 0x11;
HAL_I2C_Mem_Write(&hi2c1, MPU6050_DEFAULT_ADDRESS, MPU6050_RA_INT_ENABLE, 1, RxBuffer, 1, 1000);

HAL_I2C_Mem_Read(&hi2c1, MPU6050_DEFAULT_ADDRESS, MPU6050_RA_INT_PIN_CFG, I2C_MEMADD_SIZE_8BIT, RxBuffer, 1, 1000);
HAL_Delay(200);
RxBuffer[0] |= 0x30;
HAL_I2C_Mem_Write(&hi2c1, MPU6050_DEFAULT_ADDRESS, MPU6050_RA_INT_PIN_CFG, 1, RxBuffer, 1, 1000);

HAL_I2C_Mem_Read(&hi2c1, MPU6050_DEFAULT_ADDRESS, MPU6050_RA_CONFIG, I2C_MEMADD_SIZE_8BIT, RxBuffer, 1, 1000);
HAL_Delay(200);
RxBuffer[0] |= 0x06;
HAL_I2C_Mem_Write(&hi2c1, MPU6050_DEFAULT_ADDRESS, MPU6050_RA_CONFIG, 1, RxBuffer, 1, 1000);

  /* USER CODE END 1 */

  /* MCU Configuration----------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* Configure the system clock */
  SystemClock_Config();

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_I2C1_Init();

  /* USER CODE BEGIN 2 */

  /* USER CODE END 2 */

  /* Infinite loop */
  while (1)
{
while(MPU6050_INT_State == 1)
{
HAL_GPIO_WritePin(GPIOD, LED1_Pin, GPIO_PIN_SET);
//MPU6050_I2C_Mem_Read_Multi(MPU6050_DEFAULT_ADDRESS, MPU6050_RA_ACCEL_XOUT_H, DataBuffer, 14);
HAL_I2C_Mem_Read(&hi2c1, MPU6050_DEFAULT_ADDRESS, MPU6050_RA_ACCEL_XOUT_H, I2C_MEMADD_SIZE_8BIT, DataBuffer, 14, 10000);
for(int i=0;i<7;i++)
{
DataBuffer16[i] = (int16_t)(((uint16_t)DataBuffer[2*i]<<8) | DataBuffer[2*i + 1]);
}
MPU6050_Extract_Readings();
MPU6050_INT_State = 0;
}
HAL_GPIO_WritePin(GPIOD, LED1_Pin, GPIO_PIN_RESET);
}
/* USER CODE END WHILE */

  /* USER CODE BEGIN 3 */

  }
  /* USER CODE END 3 */



/** System Clock Configuration
*/
void SystemClock_Config(void)
{

  RCC_OscInitTypeDef RCC_OscInitStruct;
  RCC_ClkInitTypeDef RCC_ClkInitStruct;

    /**Configure the main internal regulator output voltage 
    */
  __HAL_RCC_PWR_CLK_ENABLE();

  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);

    /**Initializes the CPU, AHB and APB busses clocks 
    */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLM = 8;
  RCC_OscInitStruct.PLL.PLLN = 336;
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
  RCC_OscInitStruct.PLL.PLLQ = 7;
  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_DIV4;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK)
  {
    Error_Handler();
  }

    /**Configure the Systick interrupt time 
    */
  HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);

    /**Configure the Systick 
    */
  HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);

  /* SysTick_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
}

/* I2C1 init function */
static void MX_I2C1_Init(void)
{

  hi2c1.Instance = I2C1;
  hi2c1.Init.ClockSpeed = 400000;
  hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2;
  hi2c1.Init.OwnAddress1 = 0;
  hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
  hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
  hi2c1.Init.OwnAddress2 = 0;
  hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
  hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
  if (HAL_I2C_Init(&hi2c1) != HAL_OK)
  {
    Error_Handler();
  }

}

/** Configure pins as 
        * Analog 
        * Input 
        * Output
        * EVENT_OUT
        * EXTI
*/
static void MX_GPIO_Init(void)
{

  GPIO_InitTypeDef GPIO_InitStruct;

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOH_CLK_ENABLE();
  __HAL_RCC_GPIOA_CLK_ENABLE();
  __HAL_RCC_GPIOG_CLK_ENABLE();
  __HAL_RCC_GPIOB_CLK_ENABLE();

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOG, LED1_Pin|LED2_Pin, GPIO_PIN_RESET);

  /*Configure GPIO pins : LED1_Pin LED2_Pin */
  GPIO_InitStruct.Pin = LED1_Pin|LED2_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOG, &GPIO_InitStruct);

  /*Configure GPIO pin : MPU6050_INT_Pin */
  GPIO_InitStruct.Pin = MPU6050_INT_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(MPU6050_INT_GPIO_Port, &GPIO_InitStruct);

  /* EXTI interrupt init*/
  HAL_NVIC_SetPriority(EXTI9_5_IRQn, 2, 0);
  HAL_NVIC_EnableIRQ(EXTI9_5_IRQn);

}

/* USER CODE BEGIN 4 */

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
if(GPIO_Pin == GPIO_PIN_5)
{
MPU6050_INT_State = 1;
}
}

void MPU6050_Extract_Readings()
{
// Extract accel readings
accel_x_temp = DataBuffer16[0];
accel_x = (float)accel_x_temp / 2048.0F;
accel_y_temp = DataBuffer16[1];
accel_y = (float)accel_y_temp / 2048.0F;
accel_z_temp = DataBuffer16[2];
accel_z = (float)accel_z_temp / 2048.0F;

// Extract temperature readings
temp_raw = DataBuffer16[3];
temp = temp_raw / 340.0F;

// Extract gyro readings
gyro_x_temp = DataBuffer16[4];
gyro_x = (float)gyro_x_temp / 131.0F;
gyro_y_temp = DataBuffer16[5];
gyro_y = (float)gyro_y_temp / 131.0F;
gyro_z_temp = DataBuffer16[6];
gyro_z = (float)gyro_z_temp / 131.0F;

// Set accel offset
accel_x += Accelx_offset;
accel_y += Accely_offset;
accel_z += Accelz_offset;

// Set temp offset
temp += Temp_offset;

// Set gyro offset
gyro_x += Gyrox_offset;
gyro_y += Gyroy_offset;
gyro_z += Gyroz_offset;
}

/* USER CODE END 4 */

/**
  * @brief  This function is executed in case of error occurrence.
  * @param  None
  * @retval None
  */
void Error_Handler(void)
{
  /* USER CODE BEGIN Error_Handler */
	
  /* User can add his own implementation to report the HAL error return state */
  while(1) 
  {
		HAL_GPIO_TogglePin(GPIOD, LED2_Pin);
		HAL_Delay(250);
  }
  /* USER CODE END Error_Handler */ 
}

#ifdef USE_FULL_ASSERT

/**
   * @brief Reports the name of the source file and the source line number
   * where the assert_param error has occurred.
   * @param file: pointer to the source file name
   * @param line: assert_param error line source number
   * @retval None
   */
void assert_failed(uint8_t* file, uint32_t line)
{
  /* USER CODE BEGIN 6 */
  /* User can add his own implementation to report the file name and line number,
    ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  /* USER CODE END 6 */

}

#endif

Cemre.

"Çalışmıyor"dan ne anlamam gerekiyor bilmiyorum. Sanırım biraz daha ayrıntı vermeniz gerekiyor. Görünürde kodlarda bir sorun yok. Donanımınızı bir kontrol edin isterseniz.

Kolay gelsin.

Sya

Logic analyzerdan baktım hiçbir sinyal göremiyorum. Bir de debug yaparken watch kısmından değerleri okumaya çalıştım ama hep 0 gösteriyordu.

muhittin_kaplan


Sya

Harici bir pull up koymadım hocam.

Cemre.

Error Handler'a düşüyor olabilir mi? Led2 yanıp sönüyor mu?