0% found this document useful (0 votes)
230 views

Gyroscope LED Controller STM32F407 Discovery

Using a gyroscope, the MCU will control the 4 LEDs (disposed in a cross formation around the sensor) that are available on the developing board. The light intensity of each LED will be depending on the tilt measurement from the inertial sensor.

Uploaded by

Andrei George
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
230 views

Gyroscope LED Controller STM32F407 Discovery

Using a gyroscope, the MCU will control the 4 LEDs (disposed in a cross formation around the sensor) that are available on the developing board. The light intensity of each LED will be depending on the tilt measurement from the inertial sensor.

Uploaded by

Andrei George
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 21

UNIVERSITY “POLITEHNICA” OF BUCHAREST

Faculty of Electronics, Telecommunications and Information Technology

MES Project
Gyroscope LED Controller

Andrei George-Andrei
ACES Master Program

2021

1
Contents
1. Project description………………………………………………………………………….……3
2. Hardware description………………………………………………………………………….…3
3. Developing tools used……………………………………………………………………….…...5
4. Software description……………………………………………………………………….…….8
5. Conclusions ……………………………………………………………………………………...9
6. Source code………………………………………………………………………………………9

2
1. Project description
Using a gyroscope, the MCU will control the 4 LEDs (disposed in a cross formation around the
sensor) that are available on the developing board. The light intensity of each LED will be
depending on the tilt measurement from the inertial sensor.

For example:
If the board is a little inclined to the south side, the led from that side will light up. The bigger
the tilt angle, the more the light intensity will rise. If the sensor will be tilted both south and
west, two LEDs will start lightning the same way described above.

2. Hardware description
For the project a STM32F407 Discovery board (fig. 2.1) was used. It has an on board soldered
LIS3DSH ST MEMS 3-axis accelerometer (fig. 2.2), 4 LEDs (fig. 2.2).
The accelerometer has an SPI communication interface. Fig. 2.3 describes the circuit schematic of
the tilt device.

3
Fig. 2.1 Discovery board

Fig. 2.2 Accelerometer and LEDs

Fig. 2.3 MCU connections

4
3. Developing tools used
For the project development several software tools were used. The pin allocation (fig. 3.1) and
peripheral configuration (fig. 3.2) was done by STM32CubeMX. It can also ease the clock
configuration (fig. 3.3) and generate code.
The main program was written and debugged in STM32CubeIDE and the data was visualized in
real time with STM Studio app (fig. 3.4).

Fig. 3.1 STM32CubeMX pin allocation

5
Fig. 3.2 STM32CubeMX SPI configuration

6
Fig. 3.3 STM32CubeMX clock configuration

7
Fig. 3.4 STM Studio live data visualization

4. Software description
The code logic is described in fig. 4.1

Fig. 4.1 logic diagram

8
5. Conclusions
In conclusion, we can state that STM32F407 Discovery board is a resourceful device, maybe
overpowered for our project. The multitude of peripherals and the high performance ARM Cortex-M4
microcontroller make the discovery board a great choise for our project and for all sorts of demanding
projects.
The four LEDs light up as we planned: if we tilt the board on one side, the LED on that side will get
brighter and brighter accordingly to the inclination angle.

6. Source code
/* USER CODE BEGIN Header */

/**

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

* @file : main.c

* @brief : Main program body

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

* @attention

* <h2><center>&copy; Copyright (c) 2020 STMicroelectronics.

* All rights reserved.</center></h2>

* This software component is licensed by ST under BSD 3-Clause license,

* the "License"; You may not use this file except in compliance with the

* License. You may obtain a copy of the License at:

* opensource.org/licenses/BSD-3-Clause

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

*/

/* USER CODE END Header */

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

#include "main.h"

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

/* USER CODE BEGIN Includes */

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

/* USER CODE END PM */

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

SPI_HandleTypeDef hspi1;

TIM_HandleTypeDef htim4;

/* USER CODE BEGIN PV */

uint8_t spiTxBuf[2];

uint8_t spiRxBuf[2];

int8_t x_data;

int8_t y_data;

//int8_t dutyCycleCH1 = 0;

//int8_t dutyCycleCH2 = 0;

10
//int8_t dutyCycleCH3 = 0;

//int8_t dutyCycleCH4 = 0;

/* USER CODE END PV */

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

void SystemClock_Config(void);

static void MX_GPIO_Init(void);

static void MX_SPI1_Init(void);

static void MX_TIM4_Init(void);

/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

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

/* USER CODE BEGIN 0 */

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

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

MX_TIM4_Init();

/* USER CODE BEGIN 2 */

HAL_GPIO_WritePin(GPIOE, GPIO_PIN_3, GPIO_PIN_RESET); // Slave select enable

spiTxBuf[0] = 0x20;
// acc CTRL_REG4 address

spiTxBuf[1] = 0x13;
// (0x10 - speed) + (0x03 - Xen, Yen)

HAL_SPI_Transmit(&hspi1, spiTxBuf, 2, 10); // Send config to acc

HAL_GPIO_WritePin(GPIOE, GPIO_PIN_3, GPIO_PIN_SET); // Slave select disable

// HAL_GPIO_WritePin(GPIOE, GPIO_PIN_3, GPIO_PIN_RESET);

// spiTxBuf[0] = 0x23;

// spiTxBuf[1] = 0xC8;

// HAL_SPI_Transmit(&hspi1, spiTxBuf, 2, 10);

// HAL_GPIO_WritePin(GPIOE, GPIO_PIN_3, GPIO_PIN_SET);

HAL_TIM_PWM_Start(&htim4, TIM_CHANNEL_1); // Enable timer1


with 4 channels for PWM output

12
HAL_TIM_PWM_Start(&htim4, TIM_CHANNEL_2);

HAL_TIM_PWM_Start(&htim4, TIM_CHANNEL_3);

HAL_TIM_PWM_Start(&htim4, TIM_CHANNEL_4);

HAL_Delay(2000);

/* USER CODE END 2 */

/* Infinite loop */

/* USER CODE BEGIN WHILE */

while (1)

/* USER CODE END WHILE */

HAL_GPIO_WritePin(GPIOE, GPIO_PIN_3, GPIO_PIN_RESET);

spiTxBuf[0] = 0x29 | 0x80; // acc read (0x80)


from OUT_X_L register (0x29)

HAL_SPI_Transmit(&hspi1, spiTxBuf, 1, 1);

HAL_SPI_Receive(&hspi1, spiRxBuf, 2, 1);

x_data = spiRxBuf[0];
// store X axis data

HAL_GPIO_WritePin(GPIOE, GPIO_PIN_3, GPIO_PIN_SET);

if(x_data > -3 && x_data < 3)

htim4.Instance->CCR1 = 0; // CCRx -
PWM value %

htim4.Instance->CCR3 = 0;

else if(x_data < -3)

htim4.Instance->CCR1 = -(x_data);

htim4.Instance->CCR3 = 0;

else if(x_data > 3)

13
{

htim4.Instance->CCR3 = x_data;

htim4.Instance->CCR1 = 0;

HAL_GPIO_WritePin(GPIOE, GPIO_PIN_3, GPIO_PIN_RESET);

spiTxBuf[0] = 0x2B | 0x80; // acc read (0x80)


from OUT_Y_L register (0x2B)

HAL_SPI_Transmit(&hspi1, spiTxBuf, 1, 1);

HAL_SPI_Receive(&hspi1, spiRxBuf, 2, 1);

y_data = spiRxBuf[0];

HAL_GPIO_WritePin(GPIOE, GPIO_PIN_3, GPIO_PIN_SET);

if(y_data > -3 && y_data < 3)

htim4.Instance->CCR2 = 0;

htim4.Instance->CCR4 = 0;

else if(y_data < -3)

htim4.Instance->CCR4 = -(y_data);

htim4.Instance->CCR2 = 0;

else if(y_data > 3)

htim4.Instance->CCR2 = y_data;

htim4.Instance->CCR4 = 0;

// htim4.Instance->CCR1 = -(x_data);

// htim4.Instance->CCR2 = y_data;

// htim4.Instance->CCR3 = x_data;

14
// htim4.Instance->CCR4 = -(y_data);

HAL_Delay(5);

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

/** Configure the main internal regulator output voltage

*/

__HAL_RCC_PWR_CLK_ENABLE();

__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_NONE;

if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)

Error_Handler();

15
/** 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_HSI;

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_0) != HAL_OK)

Error_Handler();

/**

* @brief SPI1 Initialization Function

* @param None

* @retval None

*/

static void MX_SPI1_Init(void)

/* USER CODE BEGIN SPI1_Init 0 */

/* USER CODE END SPI1_Init 0 */

/* USER CODE BEGIN SPI1_Init 1 */

/* USER CODE END SPI1_Init 1 */

/* SPI1 parameter configuration*/

hspi1.Instance = SPI1;

16
hspi1.Init.Mode = SPI_MODE_MASTER;

hspi1.Init.Direction = SPI_DIRECTION_2LINES;

hspi1.Init.DataSize = SPI_DATASIZE_8BIT;

hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;

hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;

hspi1.Init.NSS = SPI_NSS_SOFT;

hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_16;

hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;

hspi1.Init.TIMode = SPI_TIMODE_DISABLE;

hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;

hspi1.Init.CRCPolynomial = 10;

if (HAL_SPI_Init(&hspi1) != HAL_OK)

Error_Handler();

/* USER CODE BEGIN SPI1_Init 2 */

/* USER CODE END SPI1_Init 2 */

/**

* @brief TIM4 Initialization Function

* @param None

* @retval None

*/

static void MX_TIM4_Init(void)

/* USER CODE BEGIN TIM4_Init 0 */

/* USER CODE END TIM4_Init 0 */

17
TIM_ClockConfigTypeDef sClockSourceConfig = {0};

TIM_MasterConfigTypeDef sMasterConfig = {0};

TIM_OC_InitTypeDef sConfigOC = {0};

/* USER CODE BEGIN TIM4_Init 1 */

/* USER CODE END TIM4_Init 1 */

htim4.Instance = TIM4;

htim4.Init.Prescaler = 16;

htim4.Init.CounterMode = TIM_COUNTERMODE_UP;

htim4.Init.Period = 100;

htim4.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;

htim4.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;

if (HAL_TIM_Base_Init(&htim4) != HAL_OK)

Error_Handler();

sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;

if (HAL_TIM_ConfigClockSource(&htim4, &sClockSourceConfig) != HAL_OK)

Error_Handler();

if (HAL_TIM_PWM_Init(&htim4) != HAL_OK)

Error_Handler();

sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;

sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;

if (HAL_TIMEx_MasterConfigSynchronization(&htim4, &sMasterConfig) != HAL_OK)

Error_Handler();

18
}

sConfigOC.OCMode = TIM_OCMODE_PWM1;

sConfigOC.Pulse = 50;

sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;

sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;

if (HAL_TIM_PWM_ConfigChannel(&htim4, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)

Error_Handler();

if (HAL_TIM_PWM_ConfigChannel(&htim4, &sConfigOC, TIM_CHANNEL_2) != HAL_OK)

Error_Handler();

if (HAL_TIM_PWM_ConfigChannel(&htim4, &sConfigOC, TIM_CHANNEL_3) != HAL_OK)

Error_Handler();

if (HAL_TIM_PWM_ConfigChannel(&htim4, &sConfigOC, TIM_CHANNEL_4) != HAL_OK)

Error_Handler();

/* USER CODE BEGIN TIM4_Init 2 */

/* USER CODE END TIM4_Init 2 */

HAL_TIM_MspPostInit(&htim4);

/**

* @brief GPIO Initialization Function

* @param None

* @retval None

19
*/

static void MX_GPIO_Init(void)

GPIO_InitTypeDef GPIO_InitStruct = {0};

/* GPIO Ports Clock Enable */

__HAL_RCC_GPIOE_CLK_ENABLE();

__HAL_RCC_GPIOA_CLK_ENABLE();

__HAL_RCC_GPIOD_CLK_ENABLE();

/*Configure GPIO pin Output Level */

HAL_GPIO_WritePin(GPIOE, GPIO_PIN_3, GPIO_PIN_SET);

/*Configure GPIO pin : PE3 */

GPIO_InitStruct.Pin = GPIO_PIN_3;

GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;

GPIO_InitStruct.Pull = GPIO_NOPULL;

GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;

HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);

/*Configure GPIO pin : PE0 */

GPIO_InitStruct.Pin = GPIO_PIN_0;

GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;

GPIO_InitStruct.Pull = GPIO_NOPULL;

HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);

/* EXTI interrupt init*/

HAL_NVIC_SetPriority(EXTI0_IRQn, 0, 0);

HAL_NVIC_EnableIRQ(EXTI0_IRQn);

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

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

tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */

/* USER CODE END 6 */

#endif /* USE_FULL_ASSERT */

21

You might also like