Grbl on Arduino Leonardo? #111

Closed
chamnit opened this Issue Jul 24, 2012 · 32 comments

Comments

Projects
None yet
Owner

chamnit commented Jul 24, 2012

Just noticed that the Arduino Leonardo has been released. So, I'd like to start a discussion on what changes this would entail for Grbl. The main difference is that the Leonardo is based on a Atmega32U4 chip, rather than the Atmega328p with a AtmegaXU2 or FTDI USB-to-serial chip. Here's a short list of the differences between the two.

  • More SRAM memory 2.5K from 2K. This could mean up to 20-25 acceleration planner blocks from 16-18 now. Or larger receive streaming buffers, etc. What's the best way to use the increase in memory?
  • (Possibly) 4 more digital I/O pins. Apparently these maybe inaccessible, since they have been mapped to the ICSP header and another terminated. Haven't played with one, but would like to know if this could be easily hijacked for use. Maybe for 4th axis?
  • More Timers! If I understand this correctly, instead of two 8-bit and one 16-bit timers, the Leonardo has one 8-bit, two 16-bit, and a 10-bit high speed timer on-board. Not exactly sure what this would mean for Grbl. Open to some ideas here.
  • Full-speed USB / No serial chip. This means that the main processor is now handling all communications. I imagine that Grbl will need to include a lot of these drivers into its code-base to support this, but I could be wrong. This also means that the basic serial interface that Grbl uses may be obsolete. One thing for sure is that this could throw a wrench into things on how Grbl communicates and GUIs interact.
  • Separation of serial and USB comm: This means that the digital I/O pins are no longer tied to D0 and D1 and is instead performed through virtualization software unless explicitly compiled-in. Which means there may be an additional two digital I/O pins that can be used for a 4-axis or something else.
  • Reset oddities: When connecting through the serial interface, a sketch is not automatically reset as in previous Arduinos, instead the program continues to run. Also, upon a hard reset of the Leonardo, the device completely disconnects from the host computer and connect must be re-established. Not sure how this will affect 3rd party GUIs but some thought and testing will likely need to be done to see how this works exactly,.

I would think that part of that extra memory would be used for usb buffers

I used USB with st libraries for my stm32 port and I just kept everything the same and from the usb tx/rx interrupt read/wrote to/from the same buffers as the uart used.

the data will tend to come in chunks but I think that is also the case when using an external usb chip, they are both tied to the usb packet size and 1ms interval

Owner

chamnit commented Jul 24, 2012

Good to hear that porting should be relatively straight forward. I'm unfamiliar with the workings of the USB-to-serial conversion process. I do know that the packet delays causes an issue with XON/XOFF flow control, if the converter doesn't manage it somehow.

I'm curious on how much processor time this would take up and would it be necessary to even have a USB-to-serial function. I imagine that given that everything is integrated into one flash, we have the freedom to hack this code to make it more streamlined for Grbl, rather than a catch-all for everything. Do you have an idea on how much memory the USB buffers would required?

@ghost

ghost commented Aug 8, 2012

I've had a go at porting this to the leonardo, but got stuck on the serial. I need to find out how the usb serial is handled.

Another issue you didn't mention above is the current leonardo boot loader takes care of the usb serial stuff but it is also around 4k in size - so it limits the space available for programs.

Is grbl downloadable via a boot loader or does it require an external programmer to load it onto the micro?

Owner

chamnit commented Aug 8, 2012

Thanks for giving it a go! I haven't picked up a Leonardo yet and wasn't sure how they managed the serial USB. It's good to know that it's in the bootloader. This doesn't really give us that great of direct control of it since it is.

Grbl can be flashed either via the bootloader or an external programmer. With the bootloader method, you can go right back to using the Arduino IDE afterwards without needing to re-flash the bootloader on it. We do this because this makes it attractive for new users to just try Grbl out. Flashing with an external programmer does help with eliminating a short 'boot-up' delay that can make Grbl susceptible to electronic noise during it.

I've been trying to get grbl to run on teensy which is also an Atmega32u4, I got the serial working pretty easily by using the pjrc serial library http://www.pjrc.com/teensy/usb_serial.html, I can communicate with grbl and dump the settings, but when I try to send any G code it seems to hang. I suspect it is a timer interrupt issue, but I haven't tried to debug it yet.
The serial was trivial to rewrite to use the USB, and it can wait until a terminal is attached before going too far in the setup process. I'll fork the grbl code and post my patches to date.

Ok I gave up, no easy way to debug where it was hanging, so I just bought an Uno instead :)

Contributor

tmpvar commented Sep 22, 2012

Hello folks!

I spent a bit of time messing with this tonight and got pretty far! Here's my branch: https://github.com/tmpvar/grbl/commits/atmega32u4-support

Basically I've started the process of integrating LUFA as a dependency which adds about 4k to the flash size (no biggie right?)

I'm using an atmega32u4 breakout board from adafruit against the aforementioned branch. Everything seems to be in working order except actual stepper movement. Sending G1 X100 locks the device up. After some tracing and debugging, I've narrowed the root down to these lines. If I comment them out, the device doesn't freeze.. but it also doesn't work!

My understanding is that LUFA doesn't use interrupts for communication, which frees the implementor up to use all of them. In our case I think think this is a problem. Perhaps forcing the grbl USB_Task() and friends into an interrupt would fix this issue. I'll try it shortly, I just wanted to share before running completely out of steam!

Hello! I've been trying to piece together this line of inquiry for potential use on a 32u4 based board of my own. It seems like good progress was being made by Mr. tmpvar, but the above sounds like a bit of a road block was encountered. Is this to be viewed as an inconvenience or absolute show-stopper?

If it's the former, I'd be keen to dig a bit deeper, but wouldn't want to waste time if it's known to be intractable.

Oh, and huge fan of all the work done here. GRBL is excellent and you all deserve the highest praise.

Contributor

tmpvar commented Jan 31, 2013

@rdpowers I certainly think it's worth a bit of digging. I remember there being more to this thread (or another?) which amounted to "not possible", but I honestly think that depends on how much time it takes to manage the usb interface on the 32u4.

I'm going to guess there is more "stuff" to handle there than just talking to the serial chip that's between usb and atmega328p on an uno. If you figure anything out, let us know!

@tmpvar I think I've sorted your issue : )

It turns out that the 32u4 doesn't have a Timer2! The line here were the issue: https://github.com/grbl/grbl/blob/edge/stepper.c#L151-152

sei() a few lines later looked to be the issue, but that's only because that's when the non-existent Timer2 ISR finally triggered for the first time.

I'm guessing that when the Timer2 interrupt fired (incorrectly and even though it was defined) it set off ISR(BADISR_vect) which resets the micro when it is unhandled. This is a complete guess, I might check it later to see if that's the case.

Changing to use Timer3 seems work pretty well. Although I haven't completely got my device working (nor checked that the timing doesn't fundamentally change and break things), the steppers move and nothing seems terminally broken - just need to tweak to get things fully sorted and then merged to the current version of grbl.
https://github.com/rdpowers/grbl/tree/atmega32u4-support

Thanks heaps for putting me on the right track!

Let's make that Timer0 instead of Timer3 - turns out Timer3 on the 32u4 is 16-bit and overflowing 0xFFFF takes a fair bit more time than overflowing 0xFF. Working well after that!

chamnit closed this Apr 9, 2013

FYI, I've brought my branch of Leonardo/32u4 support up to the current version of grbl - 0.8c. You can find it here:
https://github.com/rdpowers/grbl/tree/atmega32u4-support-8c

It's getting close to the maximum size due to the LUFA dependencies and I had to remove several features just to get it to fit on the micro, including Coolant, Spindle Control, and Homing. One could fit them back in by removing the Catalina bootloader and using a dedicated programmer... exercise left to the reader.

Not tested on an actual machine yet, but appears to do all the right things.

The 32u4 is really turning out to be a poor choice of target and I doubt I'll continue to try to keep up given the constraints on program memory : (

Still happy to take any questions. Hope someone else finds this useful! : )

Owner

chamnit commented May 31, 2013

@rdpowers : Sweet! Thanks for taking a stab at this. I've been very curious of what it would take to support the Leonardo. One of the main potential issues that users have brought up is the USB handling and how it would effect the step pulses and other real-time operations. For example, if you get any jitter or skipped steps. It's hard to test for this type of thing.

The other was the space involved, which you seemed to have figured out. One of the things that we did for the 328p version was to strip out very large chunks of the Arduino libraries we didn't need and only retained things that we did. For the most part, we ended up re-writing most of them to be more efficient in both size and speed. Something like this could be done too for the Leonardo, but I'm thinking that it's probably not worth the effort, as the cost difference in minimal between the Uno and Leonardo.

kitizz commented May 31, 2013

I think technically you can pump a pretty high baud rate into those things
through the USB. A friend of mine said she was getting well over 115200
quite comfortably =) Can't remember the exact baud rate quoted, but I
definitely thought I'd misheard it.

But yeah, a bit tricky with that bootloader. I wonder how much of the
bootloader could be stripped...
On 01/06/2013 1:08 AM, "Sonny Jeon" notifications@github.com wrote:

@rdpowers https://github.com/rdpowers : Sweet! Thanks for taking a stab
at this. I've been very curious of what it would take to support the
Leonardo. One of the main potential issues that users have brought up is
the USB handling and how it would effect the step pulses and other
real-time operations. For example, if you get any jitter or skipped steps.
It's hard to test for this type of thing.

The other was the space involved, which you seemed to have figured out.
One of the things that we did for the 328p version was to strip out very
large chunks of the Arduino libraries we didn't need and only retained
things that we did. For the most part, we ended up re-writing most of them
to be more efficient in both size and speed. Something like this could be
done too for the Leonardo, but I'm thinking that it's probably not worth
the effort, as the cost difference in minimal between the Uno and Leonardo.


Reply to this email directly or view it on GitHubhttps://github.com/grbl/grbl/issues/111#issuecomment-18750595
.

@chamnit, Yeah, it is certainly hard to test for jitter or skipped steps. The best answer I've got is anecdotal; I've been running the 0.8a version mentioned above for quite a while with reasonable results. It's only a small machine doing small jobs, but they come out pretty well and look to run smoothly. It also doesn't run all that fast, which could help in both departments.

I'm not really up to date on AT chips. I guess I'm just hoping that a similarly architectured, bigger version of the 32u4 might be available some day and this could then be more valuable. It could at least help prevent someone from having to sort out the serial (thanks again @tmpvar, great stuff!) and minor issues like which timers are supported.

@kitizz : I haven't really done any testing, but in this setup, you pretty much just ignore the baud - there's a few too many variables and no telling what part is talking to it's abstraction at what speed... I've punched in everything from 250000 to 9600 and been able to talk to the 32u4 just fine. I use clients that connect at 115200 because that seems reasonable, but, again, that's not supported by anything other than feeling. When I have a bigger job with loads of small G0,G1 commands, it still doesn't seem to affect the smoothness of the operation, but that could be more to do with effective buffering within grbl and the machine speed than the transfer rate. Or not. shrugs : )

cody82 commented Jun 1, 2013

How are you testing the USB speed? The baud rate setting of the virtual serial port does not mean anything to the 32u4. It will run at the same speed no matter if it is 9600 or 250000.

rdpowers commented Jun 2, 2013

@cody82 : I'm not testing the speed, but I assume that setting the speed in the script or program I use to stream G-Code would affect the rate at which information is put on the pipe, but the multiple software layers between there and the micro mean I haven't got much of an idea how quickly anything is ending up there.

The Linux version of Wireshark supports usb monitoring, so there might be some way of telling, but as it hasn't been detrimental to my limited milling, I'm not too inclined to chase it up.

Contributor

tmpvar commented Jun 2, 2013

My experiment was to simply test whether it was possible to run grbl on a 32u4. LUFA is probably not the best bet as we've been getting closer and closer to the 32k limit. I bet we could work squash this down, similar to what @chamnit mentioned, but without losing features in the default build.

@rdpowers awesome! where is your code?

@chamnit the benefit I see of using a avr that has usb support is the lack of a secondary chip to do usb operations, which for people like myself would allow for custom controllers which are not necessarily arduino based. I would agree though, that this is not a huge priority.

There is also another thing that I saw just a couple days ago at a conference where a guy flashed the atmega8 that does the usb comm on the arduino to register as a joystick. While I knew this was possible, I had never seen it. It is really easy with a dfu programmer! Although it is not immediately applicable, it may be an option for people completely running out of space on their arduino. Funny to think that there are actually two processors on an arduino uno class board.

FYI The teensy2 http://www.pjrc.com/store/teensy.html is also a 32U4, very cheap. I tried a while back to get GRBL to run on it, but ran into timer issues. This port should help me fix that.

prusnak commented Apr 1, 2014

Why is this closed even though the issue is not resolved yet?

Owner

chamnit commented Apr 1, 2014

@prusnak : There is no plan to officially support the Leonardo. That is why this issue is closed.

prusnak commented Apr 1, 2014

@chamnit Fair enough. It was not clear from discussion, that's why I was confused.

imyu37 commented Apr 7, 2014

Well,it's late tonight.It seems that the issues about GRBL running on LEONARDO is unsolved perfectly.Maybe i should give grbl - 0.8c a try mentioned by @rdpowers.

imyu37 commented Apr 13, 2014

I upload a HEX file which compiled from grbl-atmega32u4-support-8c. Additionally,a virtual USB driver is need,which who can download one here.

I was able to compile and upload the branch by @rdpowers without issue to an Arduino Yun. On OSX, no virtual USB driver is required.

It's worth noting that a few features had to be removed - notably, homing. I'll see if it might be possible to include homing since it's a pretty important feature (for me at least).

Hey, everyone. I really wish I'd found this thread a while ago...

I've been porting grbl0.9j to the Leonardo/32u4 over the last week, mostly because I didn't realize it had already been tried... (yes, I did search, but apparently not hard enough.) And in many ways the port is actually done and working... I can control it with "Grbl Controller" just fine and get moving axis feedback. And I haven't had to drop any features, just turn GUI_REPORTING on. (0.9j has AMASS, Spindle PWM and other improvements) Yes, I remapped Timer2 -> Timer4, and I've been using the Teensy USB lib and stock bootloader. (no LUFA)

However, while doing the 'clean up' of assigning ports and pins and timers, I ran into the (well known here, apparently) problem with the USB interrupt vectors being higher priority than the Timer interrupts. I was wondering if anyone had come up with a solution to that, or tried any of the following:

  1. Poll-driven USB driver - who knows, there might be a rewrite of the USB/CDC routines to be polling rather than interrupt driven. That could also be a pit of despair from which no soul returns.
  2. Re-enable interrupts early in USB vector - don't know if this one works on atmegas, but on most processors you can re-enable the global interrupt while masking out the current interrupt (to prevent re-entrance) and then re-enable the local interrupt at the end. That way lower priority interrupts still happen with slight latency.
  3. Hardware Interrupt Escalation - If a timer output signal was routed to the INT0 pin, then it would be able to interrupt the USB vector. In fact, OC0B comes out on that pin. Perhaps we can use one (unconnected) pin to 'escalate' the interrupt to INT0 - assuming we can make it an output while simultaneously being 'input' enough to cause hardware interrupts. Worst case, two pins need to be jumpered to connect a timer output like OC4A to INT0. There might be extra cycles of latency, though, and weird co-timing issues.
  4. Ignore It. - If the USB interrupt routine is fast enough, then the jitter will be minimal on slow systems - and perhaps driving steppers won't be the purpose of the device. (just spindle/coolant control or similar.)

I'll take a look through the "rdpowers/grbl" repo in case there's something useful in there, but any suggestions would be great. I'm sooo close.

@unorthodox-engineers so, did you managed to solve interrupt priority issue? Can you share your modifications?

Yup. The problems turned out to be non-existant... the USB interrupts all occur during the setup/handshaking stage, and once the endpoints are established everything is handled by the u32's hardware FIFO buffers and polled calls. It's actually quite neat in there. I can confirm that the Leonardo is perfectly capable of running grbl glitch-free at quite high speeds.

In fact, the USB link is technically superior to the serial link or USB converter on the UNO... due to the hardware-level checksum / retransmission / flow control. (The equivalent of XON/XOFF is built in) You can get right up into the stack, on the 32u4, and do all kinds of fun things.

There was a lot of messing around with the Timer and GPIO pins though... pretty much everything got reassigned, making GrblShields useless which I wasn't happy with, and I'm still looking to ameliorate.

There's also an issue with USB "HIDS" (Hardware ID's) which turned out to be a rabbit hole of astonishing proportions. Basically, The "USB Implementers Forum" (The USB equivalent of the MPAA) collects licencing fees for handing out hardware IDs. Unsurprisingly, there are no "class IDs" for generic serial ports. Every USB device manufacturer is supposed to drop $4k on getting a HID, and allowing other people to use your HID is legal grounds for having your keys revoked.

Technically, the HIDs on your Arduino are only licenced for the Arduino LLC firmware. To do things properly, we should get an "Official" grbl HID from OpenMoko (who, due to a licencing glitch, has one of the few re-assignable HID blocks that exists, and gives out ID's to open source projects.) and then write a Windows .inf driver that uses that ID. (Yes, really. This is why every damn serial port device seems to have it's own driver files and the Cypress chip is so popular. The makers have little choice. Just feel glad that Microsoft/Linux/Apple ignored the spec and don't require one for each individual USB Flash drive / mouse / webcam.)

If we got a HID and compiled in unique/random product serial IDs, then grbl devices could be explicitly identified as such by the OS. They'd always get assigned the same COM port. And you could even add linux udev entries that detect the connection and run programs. I think that's a level of reliability that might be worth the trouble, but it's still an effort.

I've been in (extensive!) communication with Sungeun and he's got big chunks of the code I developed, especially the USB driver, but because I made so many other changes as well (replaced stepper output with DAC code for galvos, etc) it's a little difficult to just drag those changes in without at least one of us having access to both platforms. He's only got Unos, and I've only got Leonardos, and that raises the difficulty level to 'hard'. Also, I broke my laser, so I can't test at all right now :-(

It's tempting to just branch and publish, but that's probably a great way to cause a fork, and we've got enough of those already.

If you have a desperate need, let me know and I'll send you the code I have. It will need changes for your platform (especially if you're using steppers again) and you might need to debug a few features like limit switches. I won't be getting back to this until after Christmas at least.

What we really need is someone who has a good testing setup with both platforms, and can verify our builds. Then Sungeun and I can hack on the code, and get told when we've broken the other branch.

cri-s commented Nov 28, 2015

You surely don't want having own HID/VID for open source project.
The driver needs signed, that is yearly fee, for Micro$oft at least.
Even on apple needs to
be signed, but because it's very old requirement, it is possible that is free.
And running Win7-8 without sign necessary is possible for nerd, not
really for real users,
but win10 don't allow that anymore.
You can use VID decimal 5824 (hexadecimal 0x16C0) and range VID
decimal 1000-1009
for testing with this restrictions:
the gadgets in which you use those PIDs do not leave your desk, and
you won't complain to me if you get in trouble with duplicate PIDs
(for instance because someone else did not follow the previous rule).

2015-11-28 1:43 GMT, Jeremy Lee notifications@github.com:

Yup. The problems turned out to be non-existant... the USB interrupts all
occur during the setup/handshaking stage, and once the endpoints are
established everything is handled by the u32's hardware FIFO buffers and
polled calls. It's actually quite neat in there. I can confirm that the
Leonardo is perfectly capable of running grbl glitch-free at quite high
speeds.

In fact, the USB link is technically superior to the serial link or USB
converter on the UNO... due to the hardware-level checksum / retransmission
/ flow control. (The equivalent of XON/XOFF is built in) You can get right
up into the stack, on the 32u4, and do all kinds of fun things.

There was a lot of messing around with the Timer and GPIO pins though...
pretty much everything got reassigned, making GrblShields useless which I
wasn't happy with, and I'm still looking to ameliorate.

There's also an issue with USB "HIDS" (Hardware ID's) which turned out to be
a rabbit hole of astonishing proportions. Basically, The "USB Implementers
Forum" (The USB equivalent of the MPAA) collects licencing fees for handing
out hardware IDs. Unsurprisingly, there are no "class IDs" for generic
serial ports. Every USB device manufacturer is supposed to drop $4k on
getting a HID, and allowing other people to use your HID is legal grounds
for having your keys revoked.

Technically, the HIDs on your Arduino are only licenced for the Arduino LLC
firmware. To do things properly, we should get an "Official" grbl HID from
OpenMoko (who, due to a licencing glitch, has one of the few re-assignable
HID blocks that exists, and gives out ID's to open source projects.) and
then write a Windows .inf driver that uses that ID. (Yes, really. This is
why every damn serial port device seems to have it's own driver files and
the Cypress chip is so popular. The makers have little choice. Just feel
glad that Microsoft/Linux/Apple ignored the spec and don't require one for
each individual USB Flash drive / mouse / webcam.)

If we got a HID and compiled in unique/random product serial IDs, then grbl
devices could be explicitly identified as such by the OS. They'd always get
assigned the same COM port. And you could even add linux udev entries that
detect the connection and run programs. I think that's a level of
reliability that might be worth the trouble, but it's still an effort.

I've been in (extensive!) communication with Sungeun and he's got big chunks
of the code I developed, especially the USB driver, but because I made so
many other changes as well (replaced stepper output with DAC code for
galvos, etc) it's a little difficult to just drag those changes in without
at least one of us having access to both platforms. He's only got Unos, and
I've only got Leonardos, and that raises the difficulty level to 'hard'.
Also, I broke my laser, so I can't test at all right now :-(

It's tempting to just branch and publish, but that's probably a great way to
cause a fork, and we've got enough of those already.

If you have a desperate need, let me know and I'll send you the code I have.
It will need changes for your platform (especially if you're using steppers
again) and you might need to debug a few features like limit switches. I
won't be getting back to this until after Christmas at least.

What we really need is someone who has a good testing setup with both
platforms, and can verify our builds. Then Sungeun and I can hack on the
code, and get told when we've broken the other branch.


Reply to this email directly or view it on GitHub:
#111 (comment)

mimsou commented Mar 30, 2016

Hi everyone '
Let me say that you all are achived a great job , i uploaded the 0.8 c grbl version in my leonardo and until now it works for me

I was asking if the 0.9 vertion for the 32u4 is availble as well i want to do pcb probing but it apear that s Impossible with the 0.8c thx for your help

My email souheyeb@gmail.com

Just saw this today: http://www.arduino.org/products/boards/arduino-industrial-101 along with this paper: http://www.rs-online.com/designspark/electronics/eng/blog/getting-arduino-industrial-101, and I wondered if this could make you, @chamnit, reconsider an official port to the 32u4?

Looks like this board would allow relatively easily yo have both GRBL and the GRBL controller on the same board (or a website), maybe allowing to do a few things with the GCode outside of GRBL, like controlling spindle RPM.

Owner

chamnit commented Jun 13, 2016

@BernardG : No. Not at the moment. After v1.0 is released, I'll be more open to accepting pull requests, which up to this point, I haven't at all due to the 328p's constraints. IMHO, 328 (and the 32U4) are nearing the end of its capability. I'm not sure it's worth the effort to support the 32U4, when I'll personally be ceasing development on the 328p version of Grbl after v1.0 and investing all of my time in the ARM version.

Thanks for your answer, it make sense. Great to know there is a future on ARM for GRBL.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment