cancel
Showing results for 
Search instead for 
Did you mean: 

3V motor control with PWM

Matija1
Visitor

Hi everyone,

I'm currently working on a project where I'm controlling a small DC motor using a PWM signal, based on the temperature read from an LM35DZ temperature sensor. I'm using an STM32 microcontroller, and generating the PWM signal with Timer2, Channel 2 (on pin PB3).

The PWM signal is working correctIy, I tested it using an LED, which lights up fully at higher temperatures, confirming that the PWM output is active. The ADC readings and temperature conversion are working fine. I'm printing the raw ADC value, voltage, and calculated temperature via UART, and everything looks correct. The calculated PWM duty cycle is also being set properly using __HAL_TIM_SET_COMPARE(...).

The problem is that the motor never spins.

I'm using a 2N2222 NPN transistor as a switch, and a 1N4148 diode for flyback protection (cathode connected to +5 V, anode to the transistor’s collector). The motor is powered from a 5 V power bank, and I’ve made sure that the GND of the STM32 and the GND of the power bank are connected together.

What I’ve tried so far:

  • Connecting the transistor’s base through a 1 kΩ resistor directly to 3.3 V (bypassing PWM), and the motor still doesn't work

  • Replacing the 2N2222A transistor with another one

  • Double-checking the diode orientation

  • Swapping collector and emitter pins, in case I had them reversed

I’ve confirmed that the motor works fine when connected directly to 5 V and GND.
The PWM signal is present.

Despite all of this, the motor just won't turn.

If anyone has any suggestions, experience with similar setups, or sees what I might be missing, I’d be very grateful for your help. I can also share a schematic if needed.

Thanks in advance!

  WhatsApp Image 2025-07-01 at 11.23.18.jpeg

MX_GPIO_Init();
  MX_ADC1_Init();
  MX_TIM2_Init();
  MX_USART2_UART_Init();
  /* USER CODE BEGIN 2 */
  uint16_t rawValue;
  float temperatura;
  float voltage;
  HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_2);
 while (1)
  {
	  HAL_ADC_Start(&hadc1);
	  HAL_ADC_PollForConversion(&hadc1, HAL_MAX_DELAY);
	  rawValue = HAL_ADC_GetValue(&hadc1);
	  voltage = ((float)rawValue) / 4095 * 3300;
	  temperatura=voltage/10;
	  printf("ADC rawValue: %d\r\n", rawValue);
	  printf("Voltage: %.2f mV\r\n\n", voltage);
	  printf("Temperatura: %.2f\r\n", temperatura);
	  HAL_Delay(1000);
	  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_6, GPIO_PIN_RESET);  // Plava
	  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_7, GPIO_PIN_RESET);  // Zelena
	  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_RESET);  // Crvena

	  if (temperatura <= 21) {
	      HAL_GPIO_WritePin(GPIOA, GPIO_PIN_6, GPIO_PIN_SET);  // Plava
	  }
	  else if (temperatura >= 23) {
	      HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_SET);  // Crvena
	  }
	  else {
	      HAL_GPIO_WritePin(GPIOA, GPIO_PIN_7, GPIO_PIN_SET);  // Zelena
	  }
	  uint32_t pwmMax = __HAL_TIM_GET_AUTORELOAD(&htim2);
	 	         uint32_t pwmValue;

	 	         if (temperatura < 21.0f)
	 	         {
	 	             pwmValue = 0;
	 	         }
	 	         else if (temperatura <= 30.0f)
	 	         {
	 	             pwmValue = (uint32_t)(((temperatura - 21.0f) / 9.0f) * pwmMax);
	 	         }
	 	         else
	 	         {
	 	             pwmValue = pwmMax;
	 	         }

	 	         __HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_2, pwmValue);
	 	         char msg[50];
	 	         float duty_percent = ((float)pwmValue / pwmMax) * 100.0f;
	 	         sprintf(msg, "Duty cycle: %.1f %%\r\n", duty_percent);
	 	         HAL_UART_Transmit(&huart2, (uint8_t*)msg, strlen(msg), HAL_MAX_DELAY);

	 	         HAL_Delay(1000);
	     }

 

3 REPLIES 3
Andrew Neil
Super User

What current does your motor draw?

In particular, what is its stall current ?

Maybe it's blown the transistor ... ?

 

PS:


@Matija1 wrote:

The motor is powered from a 5 V power bank,

:

I’ve confirmed that the motor works fine when connected directly to 5 V and GND.


Your title says it's a 3V motor - so that well over its rated voltage (167%) ...

A complex system that works is invariably found to have evolved from a simple system that worked.
A complex system designed from scratch never works and cannot be patched up to make it work.

It's stall currrent is <0.98 mA. Do you think i should replace 2N2222 with maybe IRLZ44N? IRLZ44N can handle higher current.

Where/how  did you get that figure?

Definitely worth trying a higher-rated transistor.

Have you tested the transistors you've used? are they still working?

A complex system that works is invariably found to have evolved from a simple system that worked.
A complex system designed from scratch never works and cannot be patched up to make it work.