[Grbl_Esp32 Issue#115] Direction pin delay

未分类 bolang 3个月前 (10-14) 36次浏览

Issue #115 | 状态: 已关闭 | 作者: JensHauser | 创建时间: 2019-04-03


Not implemented yet, yes. I read it :-)
I already bought some DM556 step motor drivers and they require a little delay.
Is there any option to work around this issue?


评论 (9)

#1 – bdring 于 2019-04-03

There are probably several ways to do this.

The Grbl way is to use a timer for the delay. That uses up another precious timer, but would probably work.

The ideal ESP32 way is to use the RMT feature. I wrote a blog post on this a while ago. This would allow you to have an OFFONOFF signal with the first 2 stages having a duration. Unfortunately I had a ton of trouble getting the RMT to play nicely in Grbl. The RMT does not like to be called from interrupts. I think this might be due to the API for the RMT. I also had trouble using the RTOS with Grbl to get around that issue. I am not an expert in the RTOS and a lot has changed in the API since I tried this, so there may be hope for the RMT.

I could probably give this another look in a couple weeks after I wrap up some other projects. If anyone knows any experts that could help with this, that would be great too.


#2 – JensHauser 于 2019-04-09

Yes, would be great.

As I have the hardware (DM556 plus 3A stepper on e.g. 1200mm X axis), I can offer to test the programming. Meanwhile I’ll try learning with GRBL on Arduino, although it’s not my preferred solution. ESP32 has much more advantages :-)


#3 – terjeio 于 2019-04-10

Not an expert, however this seems to be working for me:


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

rmtconfigt rmtConfig = {
.rmtmode = RMTMODE_TX,
.clk_div = 20,
.memblocknum = 2,
.txconfig.loopen = false,
.txconfig.carrieren = false,
.txconfig.carrierfreq_hz = 0,
.txconfig.carrierduty_percent = 50,
.txconfig.carrierlevel = 0,
.txconfig.idleoutput_en = true
};

rmtItem[0].duration0 = settings->steppers.pulsedelaymicroseconds ? 4 * settings->steppers.pulsedelaymicroseconds : 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.txconfig.idlelevel = settings->steppers.step_invert.x;
rmtConfig.gpionum = XSTEP_PIN;
break;
case 1:
rmtConfig.txconfig.idlelevel = settings->steppers.step_invert.y;
rmtConfig.gpionum = YSTEP_PIN;
break;
case 2:
rmtConfig.txconfig.idlelevel = settings->steppers.step_invert.z;
rmtConfig.gpionum = ZSTEP_PIN;
break;
}
rmtItem[0].level0 = rmtConfig.txconfig.idlelevel;
rmtItem[0].level1 = !rmtConfig.txconfig.idlelevel;
rmt_config(&rmtConfig);
rmtfilltxitems(rmtConfig.channel, &rmtItem[0], rmtConfig.memblock_num, 0);
}
}
`
and
`
// Set stepper pulse output pins
inline IRAMATTR static void stepperSetStepOutputs (axessignalst stepoutbits)
{
if(step_outbits.x) {
RMT.confch[0].conf1.memrd_rst = 1;
RMT.confch[0].conf1.txstart = 1;
}

if(step_outbits.y) {
RMT.confch[1].conf1.memrd_rst = 1;
RMT.confch[1].conf1.txstart = 1;
}

if(step_outbits.z) {
RMT.confch[2].conf1.memrd_rst = 1;
RMT.confch[2].conf1.txstart = 1;
}
}

I write directly to the RMT registers in ISR code, bypassing the API. The code can easily be changed back to the original coding style in grbl.


#4 – bdring 于 2019-04-10

@terjeio

That looks great. I won’t be able to test it until the end of the week, but it looks very similar to what I was going to try.

The API looks like it assumes you intend to change the transmitted data a lot, need to wait for the transmission to complete, and deal with multiple threads.

We want to send the exact same thing each time and the inherent timing of the steps removes all of the other issues.

Your method looks great.



#7 – bdring 于 2019-04-11

Thanks, I meant to remove that inversion. I have not tested any of that stuff yet. I’ll add that clock stuff too.

I skipped the ganged motor features to speed up basic testing. I’ll need to add that back in.


#8 – bdring 于 2019-04-11

Updated per your suggestions.

My current RMT method does not allow you to freely define and/or free step GPIO pins like before. I need to figure out a robust design method to only init needed RMT channels and refer to them in stepperSetStepOutputs()

Maybe the best way is to assign channel numbers in cpu_map.h?


#9 – bdring 于 2019-04-24

Changed the code to allow the same I/O and axis flexibility the master branch has. Axes are now configured like this..

#define XSTEPPIN GPIONUM12
#define XDIRECTIONPIN GPIONUM26
#define XRMTCHANNEL 0

I plan to merge with master soon and have RMT be optional in config.h. This will allow it to be tested with master.


原始Issue: https://github.com/bdring/Grbl_Esp32/issues/115

喜欢 (0)