2025-07-01 2:30 AM
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!
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);
}
2025-07-01 2:35 AM - edited 2025-07-01 2:40 AM
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%) ...
2025-07-01 2:47 AM
It's stall currrent is <0.98 mA. Do you think i should replace 2N2222 with maybe IRLZ44N? IRLZ44N can handle higher current.
2025-07-01 2:53 AM
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?