Friday, April 27, 2012

Android CNC App

I got the whole toolchain working today!  Android app to tgFX, to TinyG, to JGRO CNC.  See the video for a sense of how it currently works.  I hope to have the configuration settings exposed to the UI tonight, so that you don't have to edit the code to change the link to the server.

While the current version relies on tgFX to talk to the hardware (TinyG), that isn't strictly necessary.  I put together a simple serial to network java program which will serve a similar purpose.  I may put that up on github soon too.

Once I get the basics working fairly well, I'll move on to phase 2, which is using my ICS tablet to talk directly to the TinyG vis host USB support.  That will be very nice, and will get me to my main goal - use of the CNC system without a PC being required.

The write code is fairly pedestrian, but the read code from the network took a little work to sort out.  I'm using an AsyncTask to do the blocking reads, and after each line it parses the JSON and updates the necessary state info. 
private class ListenerTask extends AsyncTask {

  @Override
  protected Void doInBackground(InputStream... params) {
    byte[] buffer = new byte[1024];
    InputStream is = params[0];
    int b;
    int idx=0;
    try {
      while (!isCancelled()) {
        if ((b = is.read()) == -1) {
          break;
        }
      buffer[idx++] = (byte) b;
      if (b == '\n') {
        publishProgress(new String(buffer,0,idx));
        idx = 0;
      }
    }
   } catch (IOException e) {
     Log.e(TAG, "listener read: " + e.getMessage());
   }
   return null;
  }

  @Override
  protected void onProgressUpdate(String... values) {
    if (values.length > 0) {
      Log.i(TAG, "onProgressUpdate: " + values[0].length() + " bytes received.");
      if (machine.processJSON(values[0])) {
        ((TextView)findViewById(R.id.xloc)).setText(Double.toString(machine.getX()));
        ((TextView)findViewById(R.id.yloc)).setText(Double.toString(machine.getY()));
        ((TextView)findViewById(R.id.zloc)).setText(Double.toString(machine.getZ()));
      }
    }
  }

  @Override
  protected void onCancelled() {
    Log.i(TAG, "ListenerTask cancelled");
    mConnect.setVisibility(View.VISIBLE);
  }
}

Thursday, April 26, 2012

Android CNC code published

I finally setup a github repo for my CNC jogger application.  It's still very much a work in progress, but it's working!  I'm going to be spending some time adding some configuration controls next, and hope to have some additional features and a better control layout by the end of the week.

Code is in Github.  Will post a video of the whole things working on Friday!


Thursday, April 12, 2012

Android CNC Controller Progress

I'm making progress.

I've been discussing some of the controller options with the guys at Synthetos, looking for smart ways to collaborate.  Riley is working on a GUI called tgFX, and while it doesn't meet my needs, I didn't want to duplicate a lot of work either.  The outcome of that discussion means I've added one large new feature to the project, which is the ability to talk to TinyG via the network in addition to direct USB.  tgFX has a network port that it is happy to use as a network to serial gateway, and I've written a simple java program which does the same job without all of the GUI-ness.  What this means is that I've been able to spend more of my time recently working out the architecture in my app and less on the specifics of handling USB host on Android.

At the moment, I have a basic jog interface on the Android, and it is able to connect, get status information from the network port, and send commands.  Still left to do is to have the jog buttons actually send the right commands (easy enough now that I have the basic messaging working) and to have the status information from the device update the axis information/state on the device.  Hopefully it will all be up and working in the next few days.

I will have code posted up soon.

Saturday, March 31, 2012

Android tablet as CNC controller

It's been a while since my last post, and wanted to provide an update on my software exploits this month.  Lots of trial and error, but only limited progress.  I spent a couple of weeks trying to get the Chumby to work as a CNC controller.  I actually got it talking with the TinyG unit, had status data, used the touchscreen, etc, but I decided that to move it further would be counterproductive.

The first problem was the particular Chumby I was using - it seems to have a problem with the power regulator or the power connector, since it flakes out when the cable is moved around even a small amount.  After trying a few different ways to try to feed the thing power, I decided it was going to be dicey.  The other reason is the age of the Chumby internals - the ARM system it is using is old enough where many of the tools I wanted to use were simply not available.  I could get a version of java for example, but the standard Oracle JRE wouldn't work because it was ARM v7.  To top it all off, since the Chumby doesn't have any native framebuffer libraries, I ended up spending more time than I wanted simply developing methods to write to the raw framebuffer.

It's been a LONG time since I've implemented a line drawing algorithm.  Or writing out a bitmapped font one bit at a time.  Or double buffering.

So for all of these reasons, I've dropped the Chumby.

I do have a backup plan however, and that's to use my Viewsonic Gtablet.  It's a great little Android-based unit.  It's bigger than the Chumby, which for my purposes is fine.  With the help of the clever people at Team DRH, I have Android "Ice Cream Sandwich" installed, and the kernel understands USB serial IO!  While I have started to work on a UI and plan to use the Java RXTX serial communication classes, I may find a way to team up with the Synthetos folks with the UI system.  It's JavaFX-based, which isn't available on Android so far as I can see.  Hopefully I'll know more soon.

If an Android-based CNC controller is of interest to you, please let me know!

Sunday, March 11, 2012

Chumby One as CNC controller

Well, after a fair bit of fussing to get a decent development environment setup, I finally have the start to my Chumby CNC controller.  So far I only have the manual jog and status screens done, but I expect I'll soon put together a basic gcode streamer to go along with it.  Since I know the audience for this particular mod is fairly small, I'm going to talk in general terms about what I did.  If you want source or have additional questions, please comment.

First, I selected the Chumby for a few reasons, not the least of which is because it was handy.  It runs Linux and has a fairly complete development system.  It also has a nice 3" LCD touchscreen that I wanted to take advantage of and wireless connectivity to the rest of my house.  It runs off of 5v, so I plan to wire it directly to the same supply as the TinyG when I'm done.

I generated a fairly simple control panel using Inkscape.  I then took the coordinates for the various button boxes, and defined them in my program to spit out the button release when the touchscreen is pressed.  The touchscreen is accessed via the Linux input event system, and so most of this is fairly standard and easily portable.

Since the program has to pay attention to events from the TinyG as well as the touchscreen, I'm using select() to block until something is ready and then do the necessary read and parse.  I'm using Perl since that's my programming language of choice after years of sysadmin work, and so I was also able to use the JSON parser module to read the status into from the TinyG.  At the moment, the status output is just being written to standard out, but the next step is to write code to push text out to the yellow status info box.  Since I have to drive the framebuffer directly, I wanted to wait until I had some of the basics working first.

An issue I've run into with the TinyG is that it will happily take (and echo) input while it is in the process of moving and dumping out status info.  That seems to make the parser pretty unhappy.  I'm going to try to shut off character echo on the TinyG end and see if that addresses the issue.

I'm also working to parse the output of ? on startup, so that I can initialize the program's understanding of the coordinates correctly.  Still debugging that part.

At the moment, the jog and update steps seems to be working fairly well, as long as you don't press the buttons too quickly in sequence.  Hoping the echo takes care of that.

I have a USB joystick...  I wonder if I should try to make that a jog input as well...

Sunday, March 4, 2012

Success!

Had some time today, and so I finished putting together the bed support and worked on tramming the bed and aligning all of the axis.  I still need to work on the Z, however I was able to get the X and Y square to the bed within about .03" which isn't too bad.  To do the alignment, I clamped a small bit of steel to my toolhead, and then attached a magnetic base dial indicator.  As I moved the X and Y position, the dial indicator swept the bed, and I was able to watch for height fluctuations.  Picture forthcoming.

I'm going to write some test G code to help ensure that the X and Y are perpendicular later this week.  it should be fairly easy to draw a couple of lines and measure with a square.  For Z, I'm going to use a square relative to the tool frame.  Since I know the bed is good, that should be a fairly simple solution.

I'm working on a better loading solution for the G code.  Since all TinyG needs is to have a streaming program that knows software flow control (Xon/Xoff), there's really no need to have a full-blown PC attached to the unit when milling.  Since I'd rather not burn the workspace space (and power) if I don't have to, I've been thinking about other options.  I've decided to take a Chumby One that I had lying around and use it as the serial link to the TinyG.  At the moment, I have minicom running on the Chumby, and I'm feeding it instructions manually.  My hope is to write a simple menu and status program to take advantage of the Chumby color LCD touchscreen, rotary encoder and button.

Saturday, March 3, 2012

First test of CNC plotter

Pretty exciting today, since I was able to get the system functioning for the first time.  Since I haven't decided what kind of cutting head I want to use, and I haven't finished all of the alignment steps, I wanted to start with a simple 2d plotter test.  I mocked up a simple pen holder, and put a handy whiteboard grid I had on the bed to use as a worksurface.

I decided to use Inkscape, and to treat the plotter head as an engraver.  Inkscape has a nice extension called Gcodetools that will allow you to export paths to G-code.  I used the text function to type a few simple words in, broke them down into paths, and exported the file.  I used the serial terminal I had on my Ubuntu test system to send the file to the TinyG board.  After a couple of issues tweaking the feed rates, homing the pen, and inverting the X axis, I was able to get a pretty nice first result!





 I still have several small tweaks to do to the system, including tramming, getting the bed support attached to the bed, routing the hold down channels, and bolting/screwing the base to the sides.  Right now I'm just using a couple of pipe clamps to hold everything in alignment as I tweaked various things.  I'm pretty surprised about the amount of parallelism I have even without tramming - the pen didn't really drift much.


I also don't seem to have any issues with backlash or overheating, at least for now.  I rewired all of the steppers to be in parallel mode, which theoretically draws 2.8A, over the 2.5A the tinyG drivers can support.  I should be able to manage that using the current pots on the board however, and even in my current configuration I see the benefit.  I'm looking to get another power supply from Jameco, which I think will also allow me to run at higher seek rates - right now I'm running about 225 mm/min max.

Before I move on, I'm going to play with this setup for a bit.  I believe I can take a photo, run some edge detection, then have Inkscpae build me a vector path to plot the image.