「加速度センサーで重力の向きを検出する」で使ったプログラム

 /* USER CODE BEGIN Header */

/**

  ******************************************************************************

  * @file           : main.c

  * @brief          : Main program body

  ******************************************************************************

  * @attention

  *

  * Copyright (c) 2023 STMicroelectronics.

  * All rights reserved.

  *

  * This software is licensed under terms that can be found in the LICENSE file

  * in the root directory of this software component.

  * If no LICENSE file comes with this software, it is provided AS-IS.

  *

  ******************************************************************************

  */

/* USER CODE END Header */

/* Includes ------------------------------------------------------------------*/

#include "main.h"


/* Private includes ----------------------------------------------------------*/

/* USER CODE BEGIN Includes */

#include "Bin2Bcd.h"

/* USER CODE END Includes */


/* Private typedef -----------------------------------------------------------*/

/* USER CODE BEGIN PTD */


/* USER CODE END PTD */


/* Private define ------------------------------------------------------------*/

/* USER CODE BEGIN PD */


/* USER CODE END PD */


/* Private macro -------------------------------------------------------------*/

/* USER CODE BEGIN PM */

#define DECEL_TIME 6

#define ACCEL_TIME 6

#define BASE_TIME 60


#define MP_SLAD 0xD0 //MPU-6050のI2Cアドレス 本当は0x68なんだが左に1bitシフト

#define MP_INT_ADR 0x6B //MPU-6050 初期化レジスタアドレス

#define MP_INT_ENABLE 0x00 //MPU-6050 初期化レジスタ値

#define MP_ACC_ADR 0x3B //MPU-6050 加速度レジスタアドレス 2x3バイト

#define MP_CNF_ADR 0x1A //MPU-6050 LPF設定アドレス

#define MP_LPF_5Hz 0x06 //MPU-6050 LPF設定値(5Hz)



/* USER CODE END PM */


/* Private variables ---------------------------------------------------------*/

I2C_HandleTypeDef hi2c1;


UART_HandleTypeDef huart2;


/* USER CODE BEGIN PV */

uint16_t pinNo[4] = {GPIO_PIN_3,GPIO_PIN_4,GPIO_PIN_6,GPIO_PIN_7};

/* USER CODE END PV */


/* Private function prototypes -----------------------------------------------*/

void SystemClock_Config(void);

static void MX_GPIO_Init(void);

static void MX_I2C1_Init(void);

static void MX_USART2_UART_Init(void);

/* USER CODE BEGIN PFP */


/* USER CODE END PFP */


/* Private user code ---------------------------------------------------------*/

/* USER CODE BEGIN 0 */


void softDelayUs(int time){

int n;

n=((time-61)*100)/60;

if(n<0){

n=0;

}


for(int i=0;i<n;i++){

//NOP();

}

}


uint8_t forward8Step(int time){

for(int i=0;i<4;i++){

  HAL_GPIO_WritePin(GPIOA, pinNo[i], 1);

  HAL_Delay(time);

  HAL_GPIO_WritePin(GPIOA, pinNo[(i+4)%4], 0);

  HAL_Delay(time);

}

HAL_GPIO_WritePin(GPIOA,GPIO_PIN_5,HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_1));

return HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_1);

}

uint8_t back8Step(int time){

for(int i=0;i<4;i++){

  HAL_GPIO_WritePin(GPIOA, pinNo[3-i], 1);

  HAL_Delay(time);

  HAL_GPIO_WritePin(GPIOA, pinNo[((3-i)+1)%4], 0);

  HAL_Delay(time);

}

HAL_GPIO_WritePin(GPIOA,GPIO_PIN_5,HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_1));

return HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_1);

}


uint8_t forward2Step(int time){

for(int i=0;i<2;i++){

  HAL_GPIO_WritePin(GPIOA, pinNo[i*2+1], 1);

  HAL_Delay(time);

  HAL_GPIO_WritePin(GPIOA, pinNo[i*2+1], 0);

}

HAL_GPIO_WritePin(GPIOA,GPIO_PIN_5,HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_1));

return HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_1);

}


uint8_t forward4Step(int time){

for(int i=0;i<4;i++){

  HAL_GPIO_WritePin(GPIOA, pinNo[i], 1);

  HAL_Delay(time);

  //softDelayUs(4000);

  HAL_GPIO_WritePin(GPIOA, pinNo[i], 0);

}

HAL_GPIO_WritePin(GPIOA,GPIO_PIN_5,HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_1));

return HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_1);

}

uint8_t back4Step(int time){


for(int i=0;i<4;i++){

  HAL_GPIO_WritePin(GPIOA, pinNo[3-i], 1);

  HAL_Delay(time);

  //softDelayUs(4000);

  HAL_GPIO_WritePin(GPIOA, pinNo[3-i], 0);

}

HAL_GPIO_WritePin(GPIOA,GPIO_PIN_5,HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_1));

return HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_1);

}


void forwardStart(){

//87stepつかう

uint16_t n=ACCEL_TIME;

uint16_t m=BASE_TIME;

for(int i=0;i<(n-1);i++){

for(int j=0;j<(m/(n-i));j++){

  forward4Step(n-i);

}

}

}

void forwardStop(){

//87stepつかう

uint16_t n=ACCEL_TIME;

uint16_t m=BASE_TIME;

for(int i=0;i<(n-1);i++){

for(int j=0;j<(m/(i+2));j++){

  forward4Step(i+2);

}

}

}

void backStart(){

uint16_t n=ACCEL_TIME;

uint16_t m=BASE_TIME;

for(int i=0;i<(n-1);i++){

for(int j=0;j<(m/(n-i));j++){

  back4Step(n-i);

}

}

}

void backStop(){

uint16_t n=DECEL_TIME;

uint16_t m=BASE_TIME;

for(int i=0;i<(n-1);i++){

for(int j=0;j<(m/(i+2));j++){

  back4Step(i+2);

}

}

}


void searchForward(){

uint8_t countN=0;

while(back4Step(4)==1){ //もしもセンサに引っかかっていたら引っかからないところまで動かす

}

HAL_Delay(500);

while(forward4Step(4)==0){//センサに引っかかるまで進める

}

HAL_Delay(500);

while(forward4Step(8)==1){//センサに引っかかる範囲を数える

countN++;

}

HAL_Delay(500);


countN /=2; //引っかかる範囲の半分を求める


for(int i=0;i<countN;i++){//引っかかる範囲の真ん中まで戻す

back4Step(8);

}

HAL_Delay(500);

}


int16_t absN(int16_t num){

int16_t ret;

if(num<0){

ret = -num;

}else{

ret = num;

}

return ret;

}


int16_t _atan2(int16_t _y, int16_t _x) {

  int16_t x = absN(_x);

  int16_t y = absN(_y);

  float   z;

  uint8_t    c;


  c = y < x;

  if (c)z = (float)y / x;

  else  z = (float)x / y;


  int16_t a;


  a = z * (z * (z * (829 * z - 2011) - 58) + 5741); //4次曲線近似


  if (c) {

    if (_x > 0) {

      if (_y < 0)a *= -1;

    }

    if (_x < 0) {

      if (_y > 0)a = 18000 - a;

      if (_y < 0)a = a - 18000;

    }

  }


  if (!c) {

    if (_x > 0) {

      if (_y > 0) a = 9000 - a;

      if (_y < 0) a = a - 9000;

    }

    if (_x < 0) {

      if (_y > 0) a = a + 9000;

      if (_y < 0) a = -a - 9000;

    }

  }


  return a;

}


/* USER CODE END 0 */


/**

  * @brief  The application entry point.

  * @retval int

  */

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 */

  //unsigned char data;

  //HAL_I2C_Mem_Read(&hi2c1, MP_SLAD, MP_INT_ENABLE, 1, &data, 1, 1000);


  /* 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_I2C1_Init();

  MX_USART2_UART_Init();

  /* USER CODE BEGIN 2 */

  unsigned char rdata[6];

  int16_t accX,accY,accZ;

  unsigned char wdata;

  const uint8_t crBuff[] = "\n\r";

  const uint8_t strX[] = "accX = ";

  const uint8_t strY[] = "accY = ";

  const uint8_t strZ[] = "accZ = ";

  const uint8_t strR[] = "Rad = ";

  uint8_t numDatBuff[8];

  int16_t rad;

  int16_t radOffset;

  int16_t stepNum; //現在位置

  int16_t stepTarget; //目標位置

  int16_t stepDelta;


  //MPU6050の初期 ?

  HAL_I2C_Mem_Read(&hi2c1, MP_SLAD, MP_INT_ADR, 1, rdata, 1, 1000);

  HAL_Delay(100);

  wdata = MP_INT_ENABLE;

  HAL_I2C_Mem_Write(&hi2c1, MP_SLAD, MP_INT_ADR, 1, &wdata, 1, 1000);

  HAL_Delay(100);

  wdata = MP_LPF_5Hz;

  HAL_I2C_Mem_Write(&hi2c1, MP_SLAD, MP_CNF_ADR, 1, &wdata, 1, 1000);

  HAL_Delay(1000);

  radOffset = 0;

  for(int  i=0;i<2;i++){

  HAL_I2C_Mem_Read(&hi2c1, MP_SLAD, MP_ACC_ADR, 1, rdata, 6, 1000);

  HAL_Delay(100);

  accX = (rdata[0]<<8)+rdata[1];

  accY = (rdata[2]<<8)+rdata[3];

  accZ = (rdata[4]<<8)+rdata[5];

  radOffset += _atan2(accZ,accY);

  }

  radOffset /= 2;


  /* USER CODE END 2 */


  /* Infinite loop */

  /* USER CODE BEGIN WHILE */


  uint8_t dd=3;

  searchForward();

  stepNum = 0;


  while (1)

  {

  //MPU6050から加速度を読みだす

  HAL_I2C_Mem_Read(&hi2c1, MP_SLAD, MP_ACC_ADR, 1, rdata, 6, 1000);

  accX = (rdata[0]<<8)+rdata[1];

  accY = (rdata[2]<<8)+rdata[3];

  accZ = (rdata[4]<<8)+rdata[5];


  //角度を計算

  rad = _atan2(accZ,accY) - radOffset;

  //目標STEPを計算

  stepTarget = rad*10/703;

  //現在のSTEPとの差を計算

  stepDelta = stepTarget - stepNum;


  //差分STEP分回転させる

  if(stepDelta>0){

for(int i=0;i<stepDelta;i++){

  forward4Step(dd);

}

stepNum += stepDelta;

  }

  if(stepDelta<0){

for(int i=0;i<(-stepDelta);i++){

  back4Step(dd);

}

stepNum += stepDelta;

  }




HAL_Delay(50);


    /* USER CODE END WHILE */


    /* USER CODE BEGIN 3 */

  }

  /* USER CODE END 3 */

}


/**

  * @brief System Clock Configuration

  * @retval None

  */

void SystemClock_Config(void)

{

  RCC_OscInitTypeDef RCC_OscInitStruct = {0};

  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};


  /** Configure the main internal regulator output voltage

  */

  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);


  /** Initializes the RCC Oscillators according to the specified parameters

  * in the RCC_OscInitTypeDef structure.

  */

  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;

  RCC_OscInitStruct.HSIState = RCC_HSI_ON;

  RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;

  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;

  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;

  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLLMUL_4;

  RCC_OscInitStruct.PLL.PLLDIV = RCC_PLLDIV_2;

  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)

  {

    Error_Handler();

  }


  /** Initializes the CPU, AHB and APB buses 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_DIV1;

  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;


  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK)

  {

    Error_Handler();

  }

  PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART2|RCC_PERIPHCLK_I2C1;

  PeriphClkInit.Usart2ClockSelection = RCC_USART2CLKSOURCE_PCLK1;

  PeriphClkInit.I2c1ClockSelection = RCC_I2C1CLKSOURCE_PCLK1;

  if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)

  {

    Error_Handler();

  }

}


/**

  * @brief I2C1 Initialization Function

  * @param None

  * @retval None

  */

static void MX_I2C1_Init(void)

{


  /* USER CODE BEGIN I2C1_Init 0 */


  /* USER CODE END I2C1_Init 0 */


  /* USER CODE BEGIN I2C1_Init 1 */


  /* USER CODE END I2C1_Init 1 */

  hi2c1.Instance = I2C1;

  hi2c1.Init.Timing = 0x00300F38;

  hi2c1.Init.OwnAddress1 = 0;

  hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;

  hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;

  hi2c1.Init.OwnAddress2 = 0;

  hi2c1.Init.OwnAddress2Masks = I2C_OA2_NOMASK;

  hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;

  hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;

  if (HAL_I2C_Init(&hi2c1) != HAL_OK)

  {

    Error_Handler();

  }


  /** Configure Analogue filter

  */

  if (HAL_I2CEx_ConfigAnalogFilter(&hi2c1, I2C_ANALOGFILTER_ENABLE) != HAL_OK)

  {

    Error_Handler();

  }


  /** Configure Digital filter

  */

  if (HAL_I2CEx_ConfigDigitalFilter(&hi2c1, 0) != HAL_OK)

  {

    Error_Handler();

  }

  /* USER CODE BEGIN I2C1_Init 2 */


  /* USER CODE END I2C1_Init 2 */


}


/**

  * @brief USART2 Initialization Function

  * @param None

  * @retval None

  */

static void MX_USART2_UART_Init(void)

{


  /* USER CODE BEGIN USART2_Init 0 */


  /* USER CODE END USART2_Init 0 */


  /* USER CODE BEGIN USART2_Init 1 */


  /* USER CODE END USART2_Init 1 */

  huart2.Instance = USART2;

  huart2.Init.BaudRate = 115200;

  huart2.Init.WordLength = UART_WORDLENGTH_8B;

  huart2.Init.StopBits = UART_STOPBITS_1;

  huart2.Init.Parity = UART_PARITY_NONE;

  huart2.Init.Mode = UART_MODE_TX_RX;

  huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;

  huart2.Init.OverSampling = UART_OVERSAMPLING_16;

  huart2.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;

  huart2.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;

  if (HAL_UART_Init(&huart2) != HAL_OK)

  {

    Error_Handler();

  }

  /* USER CODE BEGIN USART2_Init 2 */


  /* USER CODE END USART2_Init 2 */


}


/**

  * @brief GPIO Initialization Function

  * @param None

  * @retval None

  */

static void MX_GPIO_Init(void)

{

  GPIO_InitTypeDef GPIO_InitStruct = {0};

/* USER CODE BEGIN MX_GPIO_Init_1 */

/* USER CODE END MX_GPIO_Init_1 */


  /* GPIO Ports Clock Enable */

  __HAL_RCC_GPIOA_CLK_ENABLE();

  __HAL_RCC_GPIOB_CLK_ENABLE();


  /*Configure GPIO pin Output Level */

  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3|GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6

                          |GPIO_PIN_7, GPIO_PIN_RESET);


  /*Configure GPIO pins : PA3 PA4 PA5 PA6

                           PA7 */

  GPIO_InitStruct.Pin = GPIO_PIN_3|GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6

                          |GPIO_PIN_7;

  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;

  GPIO_InitStruct.Pull = GPIO_NOPULL;

  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;

  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);


  /*Configure GPIO pin : PB1 */

  GPIO_InitStruct.Pin = GPIO_PIN_1;

  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;

  GPIO_InitStruct.Pull = GPIO_PULLUP;

  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);


/* USER CODE BEGIN MX_GPIO_Init_2 */

/* USER CODE END MX_GPIO_Init_2 */

}


/* USER CODE BEGIN 4 */


/* USER CODE END 4 */


/**

  * @brief  This function is executed in case of error occurrence.

  * @retval None

  */

void Error_Handler(void)

{

  /* USER CODE BEGIN Error_Handler_Debug */

  /* User can add his own implementation to report the HAL error return state */

  __disable_irq();

  while (1)

  {

  }

  /* USER CODE END Error_Handler_Debug */

}


#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 /* USE_FULL_ASSERT */


コメント