-
Success!
10/12/2015 at 20:39 • 0 commentsI finally got the drifting problems sorted out! I added a lot of data logging to the code and spotted the switch bouncing when I ran it drawing circles over and over.
[(98)=100][(82)=84][(101)=204][(116)=118] [(103)<104>=105] [(0)=183] [(40)=42][(133)=214][(87)=89][(103)=150]
Its not terribly easy to read as I needed the data compact so I could scan through large amounts of it. What is happening though is that each step is taking anywhere from 40-130ms to complete, but then there is a point where the switch fires at 103ms 104ms 105ms after receiving an instruction to move. This means the switch is closing, but then opening and closing again within 2ms.I added some simple code to reject any switch changes that happen too quickly to the Arduino Sketch:
if(millis()-lastclick_millis[axis]<20){ // De bouncing } lastclick_millis[axis] = millis();
Since the normal switch changes were happening at around 40ms and up, and the bounces were all 2ms and less I figured rejecting anything below 20ms was a fairly safe boundary.Then I set my H shape test cutting, and it worked perfectly! Here it is after a quick light sand and a coat of mineral oil, with a 9v battery for scale:
Now on to getting the auto start/stop working and cutting more things!
-
The Debugging Adventures Continue
09/22/2015 at 22:27 • 0 commentsIt turns out that leaving debugging code in your project can sometimes be a really great thing. I was going to video the axis mechanism and see if I could spot anything odd happening that might explain the drift, when suddenly during moving it into position I got a couple of these though the serial port:
[rogue axis 1 ]
This was the warning I put in to check if the servo was overshooting at all (axis 1 is the X axis). It turns out it does overshoot, and my limited earlier tests didn't pick it up because it doesn't happen that often.I got all excited and put code into the Arduino sketch to track the movement past when it is supposed to be moving, and adjust the internally recorded position accordingly. Then I tried to cut another shape, and there was still drift.
Once I got over the disappointment I decided to record the axis anyway to see what happens in more detail when it drifts. I marked the side of the linkage with a black dot so that I could easily spot when it went out of alignment. Then I set the video recorder going and had it move in tiny circles (2.4mm or 2 complete turns in diameter) over and over again until I spotted the black dot lose alignment. Then I stepped through the frames trying to count along the steps taken and see what happened:
There is this interesting little bit where it backtracks as if it thinks it has overshot by one (when it hasn't). The problem is though that the count on the left and the count on the right should match up and they don't. Even if the extra tick from thinking it has overshot is added it ends up one short. Without it ends up two short (which is the actual physical amount it ends up off by).
The debugging trace for the red bit looks normal, but the blue bit looks like this:--curved line--- from x: -24 y: 0 z: 0 to x: 0 y: 0 z: 0 center x: -12 y: 0 z: 0 steps 34 c1-132 c0 -100 c0 -117 c1 -173 c1 -129 c0 -98 c0 -113 c0 -155 c1 -152 c1 -112 c0 -75 c1 -143 c0 -62 c0 -120 c1 -75 c0 -93 c0 -83 c1 -107 c1 -60 c1 -103 c1 -111 c1 -90 c1 -124 c0[rogue axis 1 ] -82 c1[rogue axis 1 ]-171 c0 -167 c0 -167 c0 -185 c0 -139 c0 -128 c1 -131 c0 -124 c0 -101 c1 -107 ENDED AT: 0 y: 0 z: 0 DONE
Which is interesting because there are two points where it thought that the servo had overshot (the ones that say "[rogue axis 1]"). I only see one spot where it backtracks on the video though. If the backtrack was the first point we see in the data, the second would be during the backtrack which would put the count off by two. If however the first point it overshoots doesn't backtrack and the second does, that makes the count correct, so is the only theory that makes sense to me unless there is a software bug somewhere.What is clear from all this though is that the switch is detecting extra presses where none are happening. I think my next step is going to be programming in a way to measure more precisely the interval between switch clicks on a specific axis and when they happen related to servo commands so I can get a better idea exactly what is happening.
-
More drift debugging
09/20/2015 at 11:09 • 0 commentsI had an idea as to why the X axis might be drifting. Because it is moving faster than the other two axes, I thought that if the code was operating slowly enough it might be clicking the switch in and back out before I could check for a change of state. Then if calculating the curve was taking longer than a straight line that would explain the drift getting worse during curves.
curve calculation: 0ms --- operation 117ms curve calculation: 1ms --- operation 149ms straight line calculation: 1ms ---- operation 151ms straight line calculation: 0ms ---- operation 178ms
Unfortunately the data doesn't back that lovely elegant theory up at all. The time it takes to move 0.1mm and click the switch is 117ms and above, and the time it takes my completely unoptimized code to do all the calculations in between is somewhere between 0ms and 1ms. That is nowhere near enough time for an extra click to slip through. Foiled by the marvels of modern microcontrollers!I also added code to the Arduino Sketch to check if the switch was being clicked whilst the servo was supposed to be turned off, in case the motor wasn't stopping right away when it was told to, but got no results.
Back to deep thought on the matter. At least I'm finding lots of things that aren't wrong with my project!
-
Drift debugging
09/19/2015 at 21:59 • 0 commentsI've been trying to figure out why the X axis drifts over time, and its a tricky problem. To try and understand what is going on I added some data logging code to the Arduino sketch, and plotted out how many cycles the code waits for each axis to step forward one place (0.1mm), as it moves back and forth from X0 to X10 a few times. The results have been a bit confusing. Here is the X axis:
Looks surprisingly regular. I'd expect to see spikes of double time if it was missing a count, or spikes down to a very low number if the switch was bouncing or something. The servo takes a bit longer to do the first step after you send it a command, so I guess there is a little delay between turning it on and the motor getting up to speed.
In comparison the Y axis (which keeps position perfectly) is way more messy.
It is running slower than the X axis, which explains why the servo sounds different. I'm guessing all the parts don't line up quite as perfectly on this axis so it has to work a bit harder. There are also spikes that look like it occasionally loses a count, or gets stuck. This axis stays in perfect alignment so maybe it is sticking briefly for some reason.
The Z axis also looks bad:
When lowering the cutter (the red and purple lines) the switch seems to occasionally count twice very quickly, and when raising it (green and blue) it occasionally sticks or misses a count like the Y axis does. Drift on this axis is less critical because typically there is a lot less up/down movement when cutting stuff, so there isn't time for it to add up to disastrous levels. I should probably de-bounce this switch and then test for drift though.
To make sure I hadn't made a mistake with the data I recorded some more X axis:
Yep, still looks pretty good.I also did some more test cutting and the X axis seems to lose tracking faster if I am cutting circles. Clearly something more complex is going on here that a dodgy switch, so I think I'll have to give it some more thought before I try anything else.
-
Source code update
09/17/2015 at 21:47 • 0 commentsI've fixed some issues with the source code relating to the problems from my last tests. To see if there was any improvement I threw the Fusion 360 G-Code on there and this happened:
Complex shape cutting success! On the third pass down into the wood I noticed the Y axis had drifted by maybe half a millimeter though, so I stopped it there. This has happened on some of the other tests too, but the other two axes seem to be perfect. I'm guessing this must be some sort of mechanical issue, so I'll need to try and figure out what is happening there.
The Arduino is also stopping to have a little think in between commands also, which is a problem when the program generates lots of little curves like on this model. There is probably a little optimisation to be done there.
Super happy to be finally cutting out exciting things though, I'm starting to feel very close to having an actual useful machine!
-
Testing
09/16/2015 at 13:39 • 0 commentsI seem to have some small issues with reliability at the moment that I am trying to sort out. I cut a little scale on a piece of scrap to check that the proportions are correct on my axes, which came out perfectly:
But the rest of my testing was a bit hit and miss:
I initially tried to feed it some G-Code generated from Fusion 360 (top right) but it got a bit confused on one of the curves and started wandering off.
I then did a few curve tests feeding instructions one at a time(top left), which seemed to work fine, so I then decided to test the repeatability by cutting the shape on the bottom left all the way through in 1mm increments. I got 7mm in when suddenly it started to go off script and cut diagonally into the material. At that point I shut it down.
I think I'm going to need better methods to debug what is happening in the Arduino when something weird happens. I'm also going to check my parsing code with a wider range of data to see what happened with the Fusion 360 G-Code.
-
Source code is up on GitHub
09/13/2015 at 16:03 • 0 commentsI finally got the curve calculating code working on the machine, so everything is now up on GitHub!
https://github.com/penleeki/Shed-CNC/
I got the straight line code (G-Code command 1) working quite quickly, but the curve code (G-Code commands 2 and 3) took quite a while to get sorted. I started off with a little Flash prototype as that was quickest and simplest to debug:
Then converted it into C, and tested it with a little console test program. This had quite a few problems I needed to fix before it would work, as my C is rather rusty:
And then duck taped a felt tip pen to the CNC machine for a quick test on the hardware:
Success! Can't wait to try it on some wood now! For the moment it only works on the XY axis, but the vast majority of curves would be on that plane anyway, so I'm not super keen to add support for the other axes just yet.
I would probably advise against trying to use the code as is since I wrote it for my specific machine and don't really want to develop it further than that (that's not really the fun bit for me). It is also still a work in progress and largely untested. It may come in handy to pick through for anyone else building something similar though, as I couldn't find many resources when I was writing it. The curves and lines and servo switching all took a fair amount of hunting around for ideas and trying things, since I wanted to do it without storing huge amounts of data in the Arduino memory.The repository also includes my Unity scripts for generating G-Code and transmitting it to the Arduino:
These are very early versions and pretty rough around the edges but I plan to develop them a bit more to be more robust and useful as more than just testing tools.I think before that though I need to make sure the hardware is reliable, and cut some more stuff to get more familiar with how to use the machine best.
-
Heat is the enemy! (also vice)
09/12/2015 at 19:58 • 0 commentsI've been doing some reading up on how to CNC, and I think I've figured out why the end mill from my first tests went blunt. I was worried about breaking the end mill or the CNC machine by running the Dremel too slow so I had it on max speed. It turns out though that the Dremel runs very fast for a typical CNC machine, and when you spin the end mill too fast it heats up more as it cuts. When it heats up too much the metal gets buggered up and goes blunt very fast. As a result for future tests I plan to run the Dremel on the slowest setting, and program in frequent breaks to give the end mill a break in which to cool down.
I also made a vice platform to hold the wood more securely as I cut. I started out making a copy of the existing plywood platform, and cutting bits off and screwing bits on:
Then I made a sliding jaw that is held in place by the slot. it has a bit of metal ruler at the bottom as I wasn't sure I'd have enough clearance for a wooden piece.
Then I put the two together and added a bit of threaded rod, and fitted it onto the rails:
The threaded rod is short because a long one would interfere with the bed moving back and forth. If I need to cut something small though I can just put a bit of scrap wood between the threaded rod and the jaw. I also cut a bevel into the inner side of the jaws using the CNC machine, which I managed to do without overheating the router bit.
I also made a little knob for the threaded rod with my drill and some scrap aluminium tapped for a screw:
It holds whatever I put in there nice and securely with no wiggle in any direction, success!