Contact me: hankecnc@gmail.com

方向针延迟 #115

推推 grbl 3年前 (2023-01-29) 269次浏览
关闭
JensHauser 打开了这个问题 2019 年 4 月 4 日 · 9条评论
关闭

方向针延迟#115

JensHauser 打开了这个问题 2019 年 4 月 4 日 · 9条评论

注释

方向针延迟 #115
贡献者

还没有实施,是的。我读了 :-)
我已经买了一些 DM556 步进电机驱动器,它们需要一点延迟。
有没有办法解决这个问题?

方向针延迟 #115
所有者

可能有几种方法可以做到这一点。

Grbl 的方法是使用定时器来延迟。这会耗尽另一个宝贵的计时器,但可能会奏效。

理想的 ESP32 方式是使用RMT 功能。我前段时间写了一篇关于这个的博客文章。这将允许您有一个 OFF_ON_OFF 信号,前 2 个阶段有一个持续时间。不幸的是,我在让 RMT 在 Grbl 中很好地演奏时遇到了很多麻烦。RMT 不喜欢从中断中调用。我认为这可能是由于 RMT 的 API。我在使用 RTOS 和 Grbl 来解决这个问题时也遇到了麻烦。我不是 RTOS 方面的专家,自从我尝试这个以来,API 发生了很多变化,因此 RMT 可能有希望。

在我完成其他一些项目后,我可能会在几周后再看一遍。如果有人认识可以帮助解决此问题的专家,那也很好。

方向针延迟 #115
贡献者作者

是的,会很棒。

由于我有硬件(例如 1200mm X 轴上的 DM556 加 3A 步进器),我可以提供测试编程。同时,我将尝试在 Arduino 上使用 GRBL 进行学习,尽管这不是我的首选解决方案。ESP32 有更多优势:-)

方向针延迟 #115

不是专家,但这似乎对我有用:

void initRMT (settings_t *settings)
{
	rmt_item32_t rmtItem[2];

    rmt_config_t rmtConfig = {
        .rmt_mode = RMT_MODE_TX,
        .clk_div = 20,
        .mem_block_num = 2,
        .tx_config.loop_en = false,
		.tx_config.carrier_en = false,
		.tx_config.carrier_freq_hz = 0,
		.tx_config.carrier_duty_percent = 50,
		.tx_config.carrier_level = 0,
		.tx_config.idle_output_en = true
    };

    rmtItem[0].duration0 = settings->steppers.pulse_delay_microseconds ? 4 * settings->steppers.pulse_delay_microseconds : 1;
    rmtItem[0].duration1 = 4 * settings->steppers.pulse_microseconds;
    rmtItem[1].duration0 = 0;
    rmtItem[1].duration1 = 0;

    uint32_t channel;
    for(channel = 0; channel < N_AXIS; channel++) {

    	rmtConfig.channel = channel;

    	switch(channel) {
			case 0:
				rmtConfig.tx_config.idle_level = settings->steppers.step_invert.x;
				rmtConfig.gpio_num = X_STEP_PIN;
				break;
			case 1:
				rmtConfig.tx_config.idle_level = settings->steppers.step_invert.y;
				rmtConfig.gpio_num = Y_STEP_PIN;
				break;
			case 2:
				rmtConfig.tx_config.idle_level = settings->steppers.step_invert.z;
				rmtConfig.gpio_num = Z_STEP_PIN;
				break;
    	}
    	rmtItem[0].level0 = rmtConfig.tx_config.idle_level;
    	rmtItem[0].level1 = !rmtConfig.tx_config.idle_level;
        rmt_config(&rmtConfig);
        rmt_fill_tx_items(rmtConfig.channel, &rmtItem[0], rmtConfig.mem_block_num, 0);
    }
}

// Set stepper pulse output pins
inline IRAM_ATTR static void stepperSetStepOutputs (axes_signals_t step_outbits)
{
    if(step_outbits.x) {
        RMT.conf_ch[0].conf1.mem_rd_rst = 1;
        RMT.conf_ch[0].conf1.tx_start = 1;
    }

    if(step_outbits.y) {
        RMT.conf_ch[1].conf1.mem_rd_rst = 1;
        RMT.conf_ch[1].conf1.tx_start = 1;
    }

    if(step_outbits.z) {
        RMT.conf_ch[2].conf1.mem_rd_rst = 1;
        RMT.conf_ch[2].conf1.tx_start = 1;
    }
}

我绕过 API 直接写入 ISR 代码中的 RMT 寄存器。代码可以很容易地改回 grbl 中的原始编码风格。

方向针延迟 #115
所有者

@terjeio

看起来不错。我要到本周末才能对其进行测试,但它看起来与我要尝试的非常相似。

API看起来像是假设你打算对传输的数据进行大量更改,需要等待传输完成,并且需要处理多个线程。

我们希望每次都发送完全相同的内容,并且这些步骤的固有时间消除了所有其他问题。

你的方法看起来不错。

方向针延迟 #115
所有者
培养 评论了 2019 年 4 月 11 日  

我创建了一个新分支用于测试。我实施了@terjeio基本代码。正如他发布的那样,我在将它编译成 Grbl 时遇到了一些问题,因此对其进行了调整以使用 Grbl 倾向于使用的全局变量。

谢谢

方向针延迟 #115

@bdring

那很快。您的分支中的一个小问题:由于步进反转是在 RMT init 完成的,因此不应在步进 ISR(第 326 行)中再次完成。此外,我忘记包含一段代码,用于将时钟信号分配给 RMT 外围设备 – 似乎不需要它,因为无论如何你都能正常工作?

    uint32_t channel;
    for(channel = 0; channel < N_AXIS; channel++)
        rmt_set_source_clk(channel, RMT_BASECLK_APB);

我没有将它添加到 initRMT,因为我在更改设置时调用了 initRMT(我在一个单独的函数中执行所有外围设备的基本设置)。

方向针延迟 #115
所有者

谢谢,我的意思是删除那个反转。我还没有测试过任何这些东西。我也会添加那个时钟的东西。

我跳过了联动电机功能以加快基本测试。我需要把它加回去。

bdring 添加了引用此问题的提交 2019 年 4 月 12 日

方向针延迟 #115
所有者
培养 评论了 2019 年 4 月 12 日  

根据您的建议更新。

我当前的 RMT 方法不允许您像以前一样自由定义和/或自由步进 GPIO 引脚。我需要找出一种稳健的设计方法来仅初始化所需的 RMT 通道并在 stepperSetStepOutputs() 中引用它们

也许最好的方法是在 cpu_map.h 中分配通道号?

方向针延迟 #115
所有者

更改代码以允许主分支具有相同的 I/O 和轴灵活性。轴现在配置如下..

#define X_STEP_PIN GPIO_NUM_12
#define X_DIRECTION_PIN GPIO_NUM_26
#define X_RMT_CHANNEL 0

我计划尽快与 master 合并,并在 config.h 中将 RMT 设为可选。这将允许它与 master 一起测试。