使用ledc_set_freq()出现丢失脉冲

hhd2018
Posts: 7
Joined: Fri Nov 30, 2018 6:20 am

使用ledc_set_freq()出现丢失脉冲

Postby hhd2018 » Fri Nov 30, 2018 6:27 am

Code: Select all

while (1) {
		switch (sys_state) {
		case SYS_NOR_INFUSE: {
			if (current_frequence < 7)
				current_frequence = 7;
			if (current_frequence > 5000)
				current_frequence = 5000;
			if (target_frequence <= current_frequence)
				current_frequence = target_frequence;
			else
				current_frequence = current_frequence + 1;
			/*the watch got triger may cause losing of step during the changing of frequence*/
			//the frequence shoul  changed smoothly  or it may cause losing step
				current_frequence = st() % 4900 + 8;
				accu_pluse = accu_pluse +current_frequence;
			if (ledc_get_freq(LEDC_HIGH_SPEED_MODE, MOTOR_TIMER)!= target_frequence)
				{
				ledc_set_freq(LEDC_HIGH_SPEED_MODE, MOTOR_TIMER,
						current_frequence);
				}
			break;
		}		
		}
		pre_tick=st();/*updata pre_tick after the loop*/
		vTaskDelay(5);/*to avoid the frequence changing too fast*/
	}
丢失情况稳定出现,丢失时刻随机变化。详见附件的波形图。
Attachments
20181130142532.png
20181130142532.png (103.02 KiB) Viewed 15647 times
Last edited by hhd2018 on Fri Nov 30, 2018 8:17 am, edited 1 time in total.

costaud
Posts: 55
Joined: Wed Dec 30, 2015 5:09 pm

Re: 使用ledc_set_freq()出现丢失脉冲

Postby costaud » Fri Nov 30, 2018 8:17 am

请问是想要控制外部的 步进电机驱动芯片吗?

costaud
Posts: 55
Joined: Wed Dec 30, 2015 5:09 pm

Re: 使用ledc_set_freq()出现丢失脉冲

Postby costaud » Fri Nov 30, 2018 8:26 am

https://github.com/espressif/esp-iot-so ... or/stepper

这里有个实现,ledc输出直接连到pcnt的输入,可以准确控制脉冲个数。

关于变频的问题,我们需要些时间来测试下。

hhd2018
Posts: 7
Joined: Fri Nov 30, 2018 6:20 am

Re: 使用ledc_set_freq()出现丢失脉冲

Postby hhd2018 » Tue Dec 04, 2018 7:08 am

对 需要控制一个连续变频的步进电机

hhd2018
Posts: 7
Joined: Fri Nov 30, 2018 6:20 am

Re: 使用ledc_set_freq()出现丢失脉冲

Postby hhd2018 » Tue Dec 04, 2018 7:16 am

只需控制上升沿的频率,占空比的多少不影响电机转动速度

随着PWM频率的改变,duty resolution的实际有效位数似乎在变化...好像与程序设定的初始值不同。猜的,来不及测试了

ESP_houwenxiang
Posts: 118
Joined: Tue Jun 26, 2018 3:09 am

Re: 使用ledc_set_freq()出现丢失脉冲

Postby ESP_houwenxiang » Tue Dec 04, 2018 9:04 am

hhd2018 wrote:
Tue Dec 04, 2018 7:16 am
只需控制上升沿的频率,占空比的多少不影响电机转动速度

随着PWM频率的改变,duty resolution的实际有效位数似乎在变化...好像与程序设定的初始值不同。猜的,来不及测试了
Hi, 你 LEDC 初始化的参数配置能提供一下吗? 我们好进行调试.

thanks !!
wookooho

hhd2018
Posts: 7
Joined: Fri Nov 30, 2018 6:20 am

Re: 使用ledc_set_freq()出现丢失脉冲

Postby hhd2018 » Mon Dec 10, 2018 11:56 am

Code: Select all

/**
 ******************************************************************************
 * @file    motor.c
 * @author  Huang Handong
 * @brief   This file contains the definitions,variable and functions that
 *          need to control the motor smoothl.
 ******************************************************************************
 *
 *
 *
 ******************************************************************************
 */

#include "motor.h"

/*current pwm frequence of the io port*/
uint32_t current_frequence = 7; /*range 7~5000*/

/*the pwm frequence should change from
 * current frequence to target frequence smoothly*/
uint32_t target_frequence = 8000;/*range 7~5000*/

/*current_timer,the current control timer handle*/
ledc_timer_config_t current_timer;

/*current_channel,the current control channel handle*/
ledc_channel_config_t current_channel;

/*motor_timer,the motor speed control timer handle*/
ledc_timer_config_t motor_timer;

/*motor_channel,the motor speed control channel handle*/
ledc_channel_config_t motor_channel;

/**
 * @brief  translate speed to frequence.
 * @param  speed:the speed need to be translated
 * @retval
 */
int speed2frequence(int speed) {
	int fre; /*the frequence to be caculated and return*/
	fre = 0;
	return fre;
}

/**
 * @brief  initial the motor related gpio and pwm,include:
 *         Q27:motor enable
 *         Q26:PWM that control the motor step
 *         Q21:PWM that chotrol the motor current
 * @param
 * @retval
 */
void motor_ini() {
	gpio_config_t io_conf;
	//disable interrupt
	io_conf.intr_type = GPIO_PIN_INTR_DISABLE;
	//set as output mode
	io_conf.mode = GPIO_MODE_OUTPUT;
	//bit mask of the pins that you want to set,e.g.GPIO18/19
	io_conf.pin_bit_mask = ((1 << CURRENT_PWM) | (1 << MOTOR_PWM)
			| (1 << MOTOR_SLEEP));
	//disable pull-down mode
	io_conf.pull_down_en = 1;
	//disable pull-up mode
	io_conf.pull_up_en = 1;
	//configure GPIO with the given settings
	gpio_config(&io_conf);

	gpio_set_level(CURRENT_PWM, 0);/*this pin will initial as pwm output follow on*/
	gpio_set_level(MOTOR_PWM, 0); /*this pin will initial as pwm output follow on*/
	/*this pin connect to the A4988 /sleep pin,set it on high level to
	 * avoid the motor turn on at the begin of the system */
//	gpio_set_level(MOTOR_SLEEP, 0);
	gpio_set_level(MOTOR_SLEEP, 1);/*this line is just for test,it should be deleted immediately*/

	/*current_timer,the current control timer handle*/
	current_timer.duty_resolution = 7; // resolution of PWM duty
	current_timer.freq_hz = 10000;                     // frequency of PWM signal
	current_timer.speed_mode = LEDC_HIGH_SPEED_MODE; // timer mode,high speed mode,the frequence can be changed on the fly
	current_timer.timer_num = CURRENT_TIMER;            // timer index
	// Set configuration of timer0 for high speed channels
	ledc_timer_config(&current_timer);

	/*current_channel,the current control channel handle*/
	current_channel.channel = CURRENT_CHANNEL;
	current_channel.duty = 6;
	current_channel.gpio_num = CURRENT_PWM;
	current_channel.speed_mode = LEDC_HIGH_SPEED_MODE;
	current_channel.timer_sel = CURRENT_TIMER;
	ledc_channel_config(&current_channel);

	/*current_timer,the current control timer handle*/
	/*resolution of PWM duty
	 * this parameter afect the range of the frequence directly
	 * with the resolution equal 7 the range is 7~5000+Hz
	 * as the resolution is bigger the lower bound of
	 * the frequence range is bigger*/
	/*the watch got triger may cause losing of step during the changing of frequence*/
	/*losing step happen occasionally,have not been completed avoid
	 * luckly it happen only during frequence changing period
	 * when the frequence is stable ,it will not happen*/
	motor_timer.duty_resolution = 7;                // resolution of PWM duty
	motor_timer.freq_hz = 7;                        // frequency of PWM signal
	motor_timer.speed_mode = LEDC_HIGH_SPEED_MODE; // timer mode,high speed mode,the frequence can be changed on the fly
	motor_timer.timer_num = MOTOR_TIMER;             // timer index
	// Set configuration of timer0 for high speed channels
	ledc_timer_config(&motor_timer);

	/*current_channel,the current control channel handle*/
	motor_channel.channel = MOTOR_CHANNEL;
	motor_channel.duty = 5; /*this parametr should not be too small or to big, appropriate value can help to avoid too much losing step*/
	motor_channel.gpio_num = MOTOR_PWM;
	motor_channel.speed_mode = LEDC_HIGH_SPEED_MODE;
	motor_channel.timer_sel = MOTOR_TIMER;
	ledc_channel_config(&motor_channel);

}

/**
 * @brief the aduion driver run in rtos task in an infinit loop.
 * @param arg:system variable,unused
 * @retval
 */
void step_motor(void*arg) {

	double plus_temp;  /*save temporary plus count data*/
	printf("abcdefghijk\n");
	fflush(stdout);

	while (1) {
		sys_state=SYS_NOR_INFUSE;/*this line should be deleted after test immediataly*/
		switch (sys_state) {
		case SYS_NOR_INFUSE: {
			if (current_frequence < 7)
				current_frequence = 7;
			if (current_frequence > 5000)
				current_frequence = 5000;
			if (target_frequence <= current_frequence)
				current_frequence = target_frequence;
			else
				current_frequence = current_frequence + 1;
			/*the watch got triger may cause losing of step during the changing of frequence*/
			//the frequence shoul  changed smoothly  and can not be too fast or it may cause losing step
				current_frequence = st()/10 % 4900 + 1000;
				plus_temp=(double)current_frequence*(double)(st()-pre_tick);/*if the right expression is too long it will cause un except result*/
				plus_temp=plus_temp/1000.0;
				accu_pluse = accu_pluse +plus_temp;
				printf("%d\n",current_frequence);
			    fflush(stdout);
			if (ledc_get_freq(LEDC_HIGH_SPEED_MODE, MOTOR_TIMER)!= target_frequence)
				{
				ledc_set_freq(LEDC_HIGH_SPEED_MODE, MOTOR_TIMER,
						current_frequence);
				}
			break;
		}
		}
		pre_tick=st();/*updata pre_tick after the loop*/
		vTaskDelay(5);/*to avoid the frequence changing too fast*/
	}
}

/**
 * @brief update the remain time and accumulated infusion volum.
 * @param
 * @retval
 */
void update_remain_time_and_accu_infusion_volum()
{
;
}

ESP_houwenxiang
Posts: 118
Joined: Tue Jun 26, 2018 3:09 am

Re: 使用ledc_set_freq()出现丢失脉冲

Postby ESP_houwenxiang » Tue Dec 11, 2018 6:19 am

Hi, 你程序运行的时候应该会有下面类似的打印吧?

Code: Select all

<0x1b>[0;31mE (2324) ledc: div param err,div_param=395061<0x1b>[0m
<0x1b>[0;31mE (2374) ledc: div param err,div_param=385542<0x1b>[0m
<0x1b>[0;31mE (2424) ledc: div param err,div_param=376470<0x1b>[0m
<0x1b>[0;31mE (2474) ledc: div param err,div_param=367816<0x1b>[0m
<0x1b>[0;31mE (2524) ledc: div param err,div_param=359550<0x1b>[0m
<0x1b>[0;31mE (2574) ledc: div param err,div_param=351648<0x1b>[0m
<0x1b>[0;31mE (2624) ledc: div param err,div_param=344086<0x1b>[0m
<0x1b>[0;31mE (2674) ledc: div param err,div_param=336842<0x1b>[0m
<0x1b>[0;31mE (2724) ledc: div param err,div_param=329896<0x1b>[0m
你的控制里面最小频率必须是 7Hz 吗, 10Hz 是否接受, 最高频率 5kHz 是否接受? 如果可以接受,初始化的时候可以按照下面的代码来进行,看看是否能解决你的问题:

Code: Select all

ledc_timer_config_t ledc_timer = {
    .duty_resolution = LEDC_TIMER_7_BIT,
    .freq_hz = 10,
    .speed_mode = LEDC_HS_MODE,
    .timer_num = LEDC_HS_TIMER
};
ledc_timer_config(&ledc_timer);
ledc_channel_config_t ledc_channel = {
    .channel    = LEDC_HS_CH0_CHANNEL,
    .duty       = 64,
    .gpio_num   = LEDC_HS_CH0_GPIO,
    .speed_mode = LEDC_HS_MODE,
    .hpoint     = 0,
    .timer_sel  = LEDC_HS_TIMER
};
ledc_channel_config(&ledc_channel);
以上配置与你的配置的区别是初始化的频率是 5Hz, 这样驱动在选择时钟源时选择的是 1MHz. 按照你的配置选择的是 80MHz, 无法在 10Hz ~ 5kHz之间进行调节.
wookooho

Who is online

Users browsing this forum: Google [Bot] and 225 guests