We Have a Winner!

Following on the previous post, I shot a quick video showing some of the new firmware features in action. Most importantly, my suspicion that it was a serial buffer overflow problem seems to have panned out. As this video shows, I can spin the encoder as hard as I can, and nothing weird happens. A more technical explanation after the jump…

The Arduino has two serial buffers, one for input, one for output. Each can hold 64 bytes. With incoming messages taking up 6 bytes per message, it doesn’t take many for it to fill up, and when that happens, a “buffer overflow” occurs. It’s the computer equivalent of trying to stuff ten pounds of $#@! in a five-pound bag. Normally, the buffer is just a staging area, a loading dock where messages coming off the trucks (the wire) are quickly picked up and taken into the warehouse (processed by the main program). So long as they get picked up quick enough, things work fine.

In this case, though, the Arduino has to do more than unpack incoming serial messages, it also has to send messages back out in response to user actions (like spinning the MPG wheel). In order to work properly, the encoder is connected to what are known as Interrupt Service Routines (ISRs). Specifically, any time the value on either of the two encoder signal lines changes, the Arduino will pause whatever it’s doing and process the encoder input to notify the host PC that the encoder has turned one unit clockwise or counter-clockwise.

Under normal circumstances, the Arduino runs fast enough that it can handle a bunch of encoder pulses, process an incoming display update, then a few more encoder pulses, and get back to the display update before the buffer gets too full. But if you spin the encoder fast enough, it basically monopolizes the Arduino’s resources, and boxes start falling off the loading dock.

My solution to this was to put a “choke” on the encoder ISR. When the routine is called, it first checks to see how long it’s been since the last call (i.e. encoder count). If it was less than 5 milliseconds ago, then it ignores the encoder and returns to normal program execution before running most of the ISR. This appears to provide just enough breathing room to keep the incoming buffer from backing up.

EMC2’s halui module supports two modes of jogging: incremental, where each encoder pulse results in a fixed increment of motion (e.g. 0.010″), or velocity, where the axis moves at a rate proportional to the speed of the encoder. I’ve been testing only in incremental mode so far, and it’s not clear whether my solution to this problem would work well in velocity mode, since the behavior of the system is to essentially lock the encoder output when the rate exceeds a certain value. That being said, you have to give the encoder a *really* fast spin before it gets clipped much, so I think it’s a good solution. At the very least, it’s a truly stable solution, which makes me feel a lot better about this than I did earlier today.

At this point, I’ve got pretty much all the core building blocks working. I haven’t wired up the spindle rate override, the velocity or spindle readouts, the coolant relay, etc., but those are just more of the same that’s already seen here. So now it’s time to move on to my next big idea, which if I can get it to work will be absolutely delicious. Stay tuned….


5 responses to “We Have a Winner!

  1. Paulo Martins April 4, 2011 at 6:28 pm

    I have what should be a really simple question for you, and i cant find out for myself because i’m waiting to get my motors, and would be grateful if u could answer (really its just a yes or a no).
    I was planning on using an arduino to control an axis position coupled to a DC servo motor by reading its encoder(don’t know yet how many counts).
    The arduino would have to do some other stuff (serial com, PID and PWM), but from what i read in your post, it wont work ( as the motor will spin very fast, calling the interrupts…is my assumption correct?

    Thanks in advance,
    Paulo Martins

    • Colin April 5, 2011 at 9:49 am


      The simple answer is probably “no.” Servo control algorithms (PID loops, basically), are complex and involve lots of math and engineering. I suspect that you might be able to get an Arduino to work for a single low-speed servo motor and nothing else, but simply counting the encoder lines will keep the CPU very busy, so I doubt you could get anything else in there. There are quadrature counter chips which would do this for you and allow you to read the count via I2C or SPI, but these introduce other problems. If you are trying to control real CNC servos (vs. radio control toy servos), just buy Geckodrives or use EMC all the way.

  2. Paulo Martins April 5, 2011 at 3:50 pm

    thanks for the reply.
    Yes my goal is to use EMC and real servos, but developing the electronics of the power stage and positioning control. I think i’ll have to look into some linux development boards with real time threading capability but i’m not sure and i lack experience in this field. Anyway thanks again.

    I’m looking forward to your work developments.

    Best regards.

    • Colin April 5, 2011 at 5:48 pm

      If your goal is to build a working CNC machine, then contact Mesa Electronics or Pico Systems, both have a variety of fairly inexpensive hardware for EMC to do exactly what you are talking about. There’s no reason to re-invent the wheel, unless you want to learn how to make a wheel šŸ™‚

      • Paulo Martins April 6, 2011 at 6:15 am

        Thanks, i’ll have a look into that but just because since i started to read about CNC i’m getting more and more interested, wanting to know everything about it, in the other hand as you said my goal is to re-invent the wheel although i know for a fact that i will probably end up spending more money to get a lot less quality final product (but this is for a college project).

        Thanks for the tips.

        Best regards.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: