2024-07-26 10:43 AM
I want to control a TRIAC's gate which will be working on 230V AC. I managed to create a one-pulse PWM based on zero-crossing detection. I want to implement a soft start function. To do that, I implemented soft start by controlling the duty cycle. However, the delay is coming from the zero-crossing side, meaning the TRIAC gate will be turned on not immediately after zero-crossing but during some random voltage. How can I solve this? Is there a way to make delay from duty cyle comming from the other side?
As you can see on the photo when rising edge is detected(orange channel) there is a delay after that(blue channel).
2024-07-27 04:17 AM
More info is needed. What MCU/series? How is zero-crossing detection done? Code snippets?
Wild guess: firmware is too slow/using HAL/...
hth
KnarfB
2024-07-27 01:50 PM - edited 2024-07-27 01:52 PM
The board im using is nucleo-f429zi. Since my zero-crossing detection is simulated by TIM14 which is overflowing every 20ms after which pins are toggeled one for timer and one for my scope. Detection is done by trigering TIM1 on second chanel and then single PWM is generated. To change the duty cycle im using simple for loop in while
for(int i=0;i<19960;i=i+33){
TIM1->CCR1=i;
HAL_Delay(20);
}
/* USER CODE END TIM1_Init 1 */
htim1.Instance = TIM1;
htim1.Init.Prescaler = 167;
htim1.Init.CounterMode = TIM_COUNTERMODE_UP;
htim1.Init.Period = 19999;
htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim1.Init.RepetitionCounter = 0;
htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
if (HAL_TIM_Base_Init(&htim1) != HAL_OK)
{
Error_Handler();
}
if (HAL_TIM_OC_Init(&htim1) != HAL_OK)
{
Error_Handler();
}
if (HAL_TIM_OnePulse_Init(&htim1, TIM_OPMODE_SINGLE) != HAL_OK)
{
Error_Handler();
}
sSlaveConfig.SlaveMode = TIM_SLAVEMODE_TRIGGER;
sSlaveConfig.InputTrigger = TIM_TS_TI2FP2;
sSlaveConfig.TriggerPolarity = TIM_TRIGGERPOLARITY_RISING;
sSlaveConfig.TriggerFilter = 0;
if (HAL_TIM_SlaveConfigSynchro(&htim1, &sSlaveConfig) != HAL_OK)
{
Error_Handler();
}
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig) != HAL_OK)
{
Error_Handler();
}
sConfigOC.OCMode = TIM_OCMODE_PWM2;
sConfigOC.Pulse = 1999;
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
sConfigOC.OCNPolarity = TIM_OCNPOLARITY_HIGH;
sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
sConfigOC.OCIdleState = TIM_OCIDLESTATE_RESET;
sConfigOC.OCNIdleState = TIM_OCNIDLESTATE_RESET;
if (HAL_TIM_OC_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
{
Error_Handler();
}
sBreakDeadTimeConfig.OffStateRunMode = TIM_OSSR_DISABLE;
sBreakDeadTimeConfig.OffStateIDLEMode = TIM_OSSI_DISABLE;
sBreakDeadTimeConfig.LockLevel = TIM_LOCKLEVEL_OFF;
sBreakDeadTimeConfig.DeadTime = 0;
sBreakDeadTimeConfig.BreakState = TIM_BREAK_DISABLE;
sBreakDeadTimeConfig.BreakPolarity = TIM_BREAKPOLARITY_HIGH;
sBreakDeadTimeConfig.AutomaticOutput = TIM_AUTOMATICOUTPUT_DISABLE;
if (HAL_TIMEx_ConfigBreakDeadTime(&htim1, &sBreakDeadTimeConfig) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN TIM1_Init 2 */
/* USER CODE END TIM1_Init 2 */
HAL_TIM_MspPostInit(&htim1);
}
/**
* @brief TIM14 Initialization Function
* @param None
* @retval None
*/
static void MX_TIM14_Init(void)
{
/* USER CODE BEGIN TIM14_Init 0 */
/* USER CODE END TIM14_Init 0 */
/* USER CODE BEGIN TIM14_Init 1 */
/* USER CODE END TIM14_Init 1 */
htim14.Instance = TIM14;
htim14.Init.Prescaler = 167;
htim14.Init.CounterMode = TIM_COUNTERMODE_UP;
htim14.Init.Period = 9999;
htim14.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim14.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
if (HAL_TIM_Base_Init(&htim14) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN TIM14_Init 2 */
/* USER CODE END TIM14_Init 2 */
}
void HAL_TIM_PeriodElapsedCallback (TIM_HandleTypeDef *htim)
{
if (htim == &htim14 ) {
HAL_GPIO_TogglePin(GPIOD, GPIO_PIN_15);
HAL_GPIO_TogglePin(GPIOD, GPIO_PIN_14);
}
}