Saturday, November 12, 2011

Binary Protocol Deployed

A month ago I thought I was close to routing my first circuit board. I had some problems with the running of the toolpath. I thought the general problem was noise and I may have been right, I still have more data to collect on that. I found that the spindle motor produces enough noise above 2000 RPM to interfere with things, particularly the E-stop. I was running at full speed, 2500+. Staying under 2000 helped a lot.

Suspecting bad communications, I rewrote the serial protocol. The packet design, bit shifting and checksum all went well. Getting the 2 "nodes" to carry on a dialog proved to be quite a challenge. Clear exchanges were no problem, correcting errors was. A low error rate was easy to deal with. My protocol does not send an Ack, just a Nak. I decided to leave the Ack to the business layer. Higher error rates with back-to-back errors turned out to be difficult to deal with.

Imagine I'm in the back seat giving you driving directions. I say "turn left", you turn left. If you don't understand me you say "say again". Then I repeat what I said. But if I say "turn left", you say "say again" but I don't understand that, I say "say again". The last thing you said was "say again" so you say it again. the last thing I said was "say again" and we are in an active lock.

Another scenario results in you hearing "turn left" twice and we go down the wrong street. I managed to fix the first scenario but not the second. I set up 2 Java threads talking to each other with random error injection. A few errors in a thousand was no problem. 5% errors led to duplicate messages. Around 3% errors the code could handle. I suspect the real error rate will be much, much lower so it should be good enough.

I dropped the new binary protocol into the firmware and ran my circuit board tool path. In addition to the noise problems I had some "transport" problems, meaning the machine didn't move the prescribed distance. Some of the moves seemed rough and there was some stalling too (resonance?). I don't mean the motors weren't strong enough, there's like no resistance here. This is a problem with pulse timing. The motors need to get pulses with timing that is appropriate for the current speed of the motor. I've written about that before.

The question is why is this coming up now after all the programmed paths I've run? The toolpaths generated by the various software tools I've been using that convert SVG and other sources to Gcode have been producing various conditions that reveal flaws in my code. The paths I've been generating from Java are relatively simple. This is the vector that was running rough at best, stalling at worst:


X:1203 Y:260741 Z:0

Since Z is zero, we're not moving vertically. I'm using a Bresenham algorithm (I think) to move the axes in some ratio. Above, the axes move in something like a ratio of 1203:260741. I say "something like" because it's actually the X axis that is longer. I've written about this before, too. I subtract 1203 from both values, X is then zero so I step it and reset. I continue this until the Y value is zero and I step it. If the machine is moving at a constant velocity, the time between pulses is fixed. Each axis that moves should step at a regular interval. With my implementation, I subtract the smallest value from all until one or more is zero. That's X most of the time until Y gets down to 893. Then I subtract 893 from both. Y is now zero but X is 310 so I step Y. Then I subtract 310 from both and step X again. So X and Y are not stepping at the same time. I don't think this is a problem, the problem is that the time between steps is fixed which means we waited twice as long as we were supposed to between X steps while we were stepping Y. At least that's my theory. I changed the Y value to 260744 which is evenly divisible by 1203. This resulted in much smoother motion and no stalling.

At some point early in the process (almost a year ago) I ran across this post by Thomas. He touches on the Bresenham algorithm and some more advanced acceleration algorithms. In the case he gives, a ratio of 3:2 is smooth enough. A ratio of 3:8 should result in the same problem I have above. Thomas talks some serious stuff about stepper motor modeling. I'm still feeling positive that I can keep things pretty simple and still get good performance. 

I'm not quite sure what approach to take to solve this. I could tweak things in the host software so that the axes ratios are such that the longest axis steps every loop. I might lose some accuracy, though. Another idea is to use the axes ratios to drive the timing between steps. I can't really think of a coherent way to describe what I'm thinking off. I'll try to work it out on paper and post it later.

No comments:

Post a Comment