gnea / grbl

An open source, embedded, high performance g-code-parser and CNC milling controller written in optimized C that will run on a straight Arduino
https://github.com/gnea/grbl/wiki
Other
4.04k stars 1.61k forks source link

Add support for DC motors/encoders instead of steppers #420

Closed CptanPanic closed 6 years ago

CptanPanic commented 6 years ago

I would like to use grbl for a cnc project that utilizes dc motors with encoders instead of stepper motors. Firstly do you think this is possible, if so how difficult would this be? There might be some arduino libraries already that may implement this closed loop operation such as https://github.com/misan/dcservo but am not sure if it would work as a library, etc, but may be able to use some of the code. I might be able to do this development, so let me know.

109JB commented 6 years ago

What you are talking about is a servo motor. There are many servo motor controllers that close the encoder loop at the motor controller and take step and direction signals just like a stepper. The Gecko servo drives are this way and would work fine with Grbl the way it currently is. There are many many more out there though

https://www.geckodrive.com/g320x.html

CptanPanic commented 6 years ago

Just because something can be done in hardware doesn't mean it shouldn't be done in software, which is much cheaper.

109JB commented 6 years ago

Just because something can be done in software doesn't mean it should be done in software.

Even if you incorporate the encoder feedback and PID loop into Grbl, you still need a "driver" to power the motor since Grbl can't do that itself. For a small motor a simple L298 H-bridge like your link shows would suffice, but when you get to larger servos the L298 just can't cut it which is where the drives like the Geckos come in (up to about 2 horsepower). Then consider that regardless of the motor drive, each encoder needs an additional 2 input pins and each PID loop and each pin interrupt takes time away from other tasks like motion planning, parsing code, etc. On top of all that, it is a much different task to control position of a servo compared to a step/dir signal. This would mean tons of coding time and testing. For a 328p powered Grbl version, there are 3 deal killers. First there aren't enough pins available. Second, there isn't enough computing power available. Third, there isn't enough program memory available. For the Arm version that is being worked, it could be possible, but I personally see no real gain from doing so within Grbl.

So as to which is cheaper? Is it cheaper to spend all the time involved to implement within Grbl, or is the better route to just spend a few dollars on either a pre-made external drive, or make one yourself. The link you posted is for a arduino based external servo control and from the description the parts, not counting motor and encoder, are less than $5 per axis, and $2 of that would have to be spent even if incorporated within Grbl. So, we are talking about $3 or so per axis for external drives, or $9 for a 3-axis machine. I'd say for $9 the external drives you linked are the cheapest route if you count the time involved to do this within Grbl at anything more than about $0.10 per hour.

Yes it would be nice to have servo control with the loop closed within Grbl. Even though the Arm version could be capable of performing this, I would personally rather see many other things implemented within Grbl before this though. Such as: spindle synchronization, backlash compensation, canned cycle implementation, cutter radius compensation, standalone operation (ie: Display and SD card), better laser support, more of the standard g-codes implemented, and the list goes on. If I were in charge of Grbl development, I would add this to the long term list, but it would be way down there below many other things.

chamnit commented 6 years ago

@109JB : Agreed.

davidelang commented 6 years ago

So does this discussion mean that code to support this isn't wanted in grbl? or just that it won't fit on the 328?

the o-drive in an example of a 'cheap' board that can support KW level BLDC motor/encoders (motor drivers included) and present them as a step-dir interface, but it's >$100 for two motors.

I can easily understand the argument that it won't fit on the 328, but as the ARM option becomes more of an option, would you be more open to adding this sort of support?

One advantage of doing this inside grbl rather than simulating a stepper is that the system would be able to detect that it is not keeping up with the desired position/acceleration and be able to adjust to compensate (or return an error message to the user) rather than just cutting wrong.

The ability to have feedback opens up new possibilities.

aprospero commented 6 years ago

@davidelang: I agree.

chamnit commented 6 years ago

@davidelang : Servo/closed loop support has always been on the long term todo list. A large part of what I've been doing recently is breaking up and refactoring the code so that it makes it easier for other contributors to add things without breaking the current, tightly intertwined code (which was necessary to get it to fit and run efficiently on the 328p). Going to ARM allows you to take some code efficiency penalties for things like this. The 328p is barely fast enough for Grbl. It was a miracle that it can do what it does.

davidelang commented 6 years ago

@chamnit Thanks, I thought that it was on your long-term list, but the way the replies were sounding, I wasn't sure.

I agree on the limits of the 328p. In the case of the machine that @CptanPanic and I are looking at, it's limited to ~40ipm, and is using an arduino as the controller now, but with no acceleration planning. We would love to be able to leverage the capabilities of grbl for this project, but it will need the servo support (and then some kinematics changes as well).

I'm eagerly looking forward to the ARM option being available. Is using a highfive or due the same problem as moving to an ARM board?

Is there a 'bug bounty' type of system that grbl developers participate in that I could use to encourage development of specific features?

cri-s commented 6 years ago

The truth is, that with cheap microprocessor it is easier to do closed loop DC motors as with arm. There exist some microprocessors with 3 quadrature inputs, that relaxes the need for real time, Microchip (Atmel) have M4 core and Ti have Arm9 chip. Otherwise cheap avr can handle a single axis with 100khz pulses and 5000 ppr encoder. This is 62.5 RPS max (200 steps, 8x microstepping equivalent).

There are hovewer two issues. DC motor require different accerelartion curves. Further speed must slow down if any of the motors trip the ADC current sensor limit or the Error is too big. The requirement is 2 to 10ms for distributed systems, On grbl, don"t remove the code for step/dir, instead use the global step position counters for closed loop pid, the mcu package usually have a lot of pins.

2018-04-25 23:23 GMT+02:00, Sonny Jeon notifications@github.com:

@davidelang : Servo/closed loop support has always been on the long term todo list. A large part of what I've been doing recently is breaking up and refactoring the code so that it makes it easier for other contributors to add things without breaking the current, tightly intertwined code (which was necessary to get it to fit and run efficiently on the 328p). Going to ARM allows you to take some code efficiency penalties for things like this. The 328p is barely fast enough for Grbl. It was a miracle that it can do what it does.

-- You are receiving this because you are subscribed to this thread. Reply to this email directly or view it on GitHub: https://github.com/gnea/grbl/issues/420#issuecomment-384438925

aprospero commented 6 years ago

Agreed that realtime demand of closed loop is hard to accomplish with application ARMs. Especially for multiple axis and other parallel tasks to be computed. However there are plenty HW solutions to feed quadrature outputs into HW counters which would make subsampling a feasible way to go. That would add some cost per axis though. Correct me if I'm wrong but in my understanding is grbl already a 'realtime' application - maybe not as demanding as closed loop, but it still would benefit from tight reaction times. so porting to a realtime capable platform would be another option, methink.

davidelang commented 6 years ago

grbl is a realtime application, and it's running on the bare metal, which is as realtime as you get :-) If it delays and is off on the timing of sending pulses, it will (at best) make the machine shudder, and may cause it to skip of jump steps.

It's not clear to me that running a PID loop would be any worse. Depending on the speed, you may actually be able to run the loop far less frequently than you think. You would have to make sure you detect the encoder pulses 'fast enough', but 'fast enough' is before the next encoder pulse comes in, and before you make a decision based on that pulse (although, depending on the resolution you are aiming for, that may not matter)

There is this library ( https://www.pjrc.com/teensy/td_libs_Encoder.html ) that handles reading encoders well at pretty high rates.

In the existing maslow code, it's handling two motors with 8K pulses/rev at 20 rpm with a PID loop running every 50 ms or so to adjust the speeds. We are not seeing the sorts of errors that would be caused by missed pulses.

Now, that's without acceleration planning, etc. but it's a real-world example of what can be done on an 8MHz arduino.

aprospero commented 6 years ago

No intent to start an argument... maslow encoder evaluation uses interrupts which are on the mega2560 with a min. overhead of 10 cycles (5 to push to the stack, 5 to pop) which means an ISR is theoretically capable of 800kHz sample rate, or 1,25µs per ISR call. Calculation errors are my second hobby, so please check the math yourself to be sure. An application ARM can have (depending on the chip layout) an overhead of several hundred µs. Eg. Zynq arm cortex-A9 cores which use an ARM based generic interrupt controller can have 500µs Interrupt latency. See here. The difference between an application and a realtime MCU is exactly these timings and if we all agree in grbl being a realtime application it would be of value to port it to a realtime capable core. If that's not an option out of other reasons, a HW counter approach could loosen the realtime demands of the encoder evaluation. This would certainly go on cost of accuracy regarding acceleration/deceleration since we would have less sampling points. Just my 2cents.

cri-s commented 6 years ago

I should have 6 axis controller for ATSAM4E16E on 144 pin device from 0.9 codebase derived from ramps codebase where the first 3 motors can be driven by servos or steppers. Compiled with atmel eeprom emulation library and arduino backend (CMSIS). The 100pin device allows only one encoder to be connected, the 144 pin allows 3 encoders.

No Usb or ethernet connection, because i have used isolated rs232. just the bare minimum with some additions like additional io pins, support for external i2c attiny (45 or 85) used as pwm and eeprom storage for G54 and as external wdt circuit.

2018-04-26 11:11 GMT+02:00, aprospero notifications@github.com:

No intent to start an argument... maslow encoder evaluation uses interrupts which are on the mega2560 with a min. overhead of 10 cycles (5 to push to the stack, 5 to pop) which means an ISR is theoretically capable of 800kHz sample rate, or 1,25µs per ISR call. Calculation errors are my second hobby, so please check the math yourself to be sure. An application ARM can have (depending on the chip layout) an overhead of several hundred µs. Eg. Zynq arm cortex-A9 cores which use an ARM based generic interrupt controller can have 500µs Interrupt latency. See here. The difference between an application and a realtime MCU is exactly these timings and if we all agree in grbl being a realtime application it would be of value to port it to a realtime capable core. If that's not an option out of other reasons, a HW counter approach could loosen the realtime demands of the encoder evaluation. This would certainly go on cost of accuracy regarding acceleration/deceleration since we would have less sampling points. Just my 2cents.

-- You are receiving this because you commented. Reply to this email directly or view it on GitHub: https://github.com/gnea/grbl/issues/420#issuecomment-384570211

109JB commented 6 years ago

I don't think anyone is saying that it wouldn't be nice to have closed loop servo functionality within Grbl. I understand that you have a strong desire for this, but not many others do, especially considering that there are low cost hardware workarounds. In my opinion, the feature priorities should lie with what will benefit the most users, and with functions that don't have an acceptable work around. My personal opinion is that Grbl does very well for what it is and for what it is intended to do. Alterations in terms of added features are fine, expected and welcome, but need to be weighed in terms of essentially a cost-benefit relationship. If the cost is many many hours to satisfy only a handful of users, especially when an alternate method exists, then that particular feature may not be a good idea. This of course is for Sonny to decide.

As for positional following error tracking allowing the controller (Grbl) to halt motion if the commanded position gets off more allowable, this is easily accomplished even with external hardware and a single digital input to Grbl. Most commercial external servo drives have internal following error tracking and the capability to send an error/fault signal to whatever system is controlling it. Sometimes this pin on the servo drive is hooked up, sometimes not. If hooked up, the motion control software can shut down the motion on all axes if any drive sends an error signal. Grbl can essentially do this now and it has been discussed. The error output from a drive could be sent to the reset pin or the feed hold pin on the arduino to stop motion.

I performed testing myself on my stepper driven machine using a rotary encoder mounted on a dual shaft stepper and a separate Arduino. The separate arduino used one interrupt to sniff the step pulses from Grbl, a digital pin to get the direction info from Grbl, and the second interrupt and a digital pin for the encoder. When a step pulse was sniffed, the direction pin was polled and an internal "step count" variable appropriately incremented. The encoder interrupt resulted in a similar "encoder count" variable being incremented. Any time either interrupt triggered a comparison routine compared step count to encoder count taking into account encoder PPR and stepper microstepping to see if the motor was off more than a certain amount from commanded. Tests went well and I think it cost me about $15 to do for one axis including the price of the encoder and Arduino. Whenever I get time, I plan to fully implement this on my machine using the reset pin of Grbl to do it. This is something that would be nice to have internally in Grbl, but I would definitely not request it at this time because other features are more beneficial to myself and to others.

Having said that, Grbl is open source and many have forked Grbl for their own desires and purposes. Some of those things have made it back into the Grbl core. If I am not mistaken, coreXY kinematics, servo control (model RC servos), and a bunch of the laser stuff started this way.

davidelang commented 6 years ago

The reason I've been pushing a bit here isn't to demand that the core team implement this (it would be fantastic if you did), but rather to understand if the pushback against this feature was cost/benefit/too busy or if it was "we don't think this feature matches the goals of the project, and would reject a PR that implemented it"

Some of the early replies seemed to be implying that you did not want the feature at all. Wanting it, but it not being high enough priority to be on anybody's to-do list is something very different.

Yes I want it quite a bit, but unfortunately I do not have the time (and may not have the skill) to implement it myself, which is why I asked about 'bug bounty' type programs where I could encourage someone to spend time on the feature with cash. I would rather pay someone who is already part of the project rather than just go to an external bug bounty site, because the people who are already part of the project are FAR more likely to end up with a result that's acceptable to the rest of the project (and it's a way to reward the people who have contributed already)

Thanks for taking your time to explain your positions, and I look forward to the ARM branch getting stabilized as that will make it easier to implement many of these new features.

langwadt commented 6 years ago

I've hacked it together on my STM32F4 port of grbl, though I haven't tried on and actual machine just motors on the table. GRBL runs like normal but doesn't toggle any pins it just maintains a position variable for each axis. a PID loop for each axis using the timer hardware quadrature decoding tracks the position

aprospero commented 6 years ago

@langwadt: That sounds cool! Do you mean your nucleo_grbl repo? The grbl_stm32 seems to be a stepper variant, or am I wrong? Can you give a hint?

I personally am more familiar with ti processors, namely C6600 DSPs and am572X SoCs, the latter has two M4 cores but is kind of a beast. It could inhabit Linux with graphical frontend AND grbl running on a M4 core. But I haven't checked if its connectivity is suited for this purpose. If there is anybody who has grbl on a Ti running I would be more than excited to step in and help where I can!

langwadt commented 6 years ago

@aprospero it isn't on github, I never got any further than two motors with encoders running on the table

aprospero commented 6 years ago

@langwadt ...a pity... :)

davidelang commented 6 years ago

can you make the code available?

On Mon, 30 Apr 2018, langwadt wrote:

@aprospero it isn't on github, I never got any further than two motors with encoders running on the table

langwadt commented 6 years ago

@davidelang I'll see if I can dig it out from the empire of dirt

aprospero commented 6 years ago

@langwadt That would be great! In the long term some kind of hardware abstraction would come in handy but i for one would benefit from a real world example approach.

davidlang-openx commented 6 years ago

@langwadt did you have any success in digging up the code?