Thursday, August 6, 2015

LinuxCNC/Machinekit, BBB, and Python

Background

My original computer controlled microscope ran LinuxCNC on an old laptop:


You can see AXIS running on the laptop to the left along with a scan pattern.

Unfortunately, it was difficult to make this system compact and reliable.  Laptops aren't really that great to run real time software because ACPI gets in the way.  Desktops can work but they are bulky and still need to be somewhat carefully selected.  My Sherline mill compromises by using a mini ATX motherboard connected to a laptop.  That way the laptop does all the display, keyboard, and mouse in a compact form factor while running all the real time tasks on a purpose built PC.

But this was still too big and costly to generally deploy.  Instead, I made "pr0ndexer" which runs on inexpensive STM32 dev boards.  The firmware was written in an afternoon and seemed to work well to get the job done.

Or did it?

After a while one of my motors started to slip.  Evidently lack of acceleration was wearing out gears in the linear stage.

Oops.

So I patched up the software with some crude acceleration and production continued to hum along.  But still it was still pretty crusty:
  • Pulses are generated with sleep statements instead of timer ISRs.  Receiving serial characters (or other tasks) messes up the timing
  • Only one axis can be moved at a time

Towards the BBB

While this was happening it was brought to my attention that LinuxCNC had been ported to run on Beagle Bone Black (BBB) by the Machinekit.  At this point though things were working well enough that I decided not to pursue that.

Fast forward to 2015.  I'm building more robots and need to decide what the next control system will look like.  I decided to revisit Machinekit/BBB which I'm just going to loosely call BBB.

For most of these systems I'm moving some number of stages and doing some sort of image capture.  There are two ways the system could be used:
  • Run LinuxCNC on the BBB and also do image capture (ie through the USB port)
  • Use BBB as a remote control drone and run image capture on a laptop
For a variety of small reasons  I decided to continue controlling the setup on laptops and use BBB's as control drones.

linuxcncrsh/emcrsh API

When you start LinuxCNC there are a variety of frontends you can use to interact with it with AXIS probably being the most common.  One alternative is the rsh frontend which launches a sort of telnet command server instead of a GUI.  The developers make no claim that its a robust interface but note that it may be good enough for quick and dirty projects.

Seeming to be the easiest way to use in a drone fashion, I started with this.  I ran into a few snags though:
  • Axis homing takes a long time.  My theory is that this has something to do with the way that poll() works (see later) but I'm not really sure
  • No position feedback: a command is either running or completed
Still, I was able to control things and get running pretty quickly using pyexpect.  Here is my python interface to it.

Python API

Unfortunately while I could get a quick PoC, rsh didn't seem to give enough control for what I wanted to do.  So next I tried the python API which is considerably more powerful.

Although this API is much more complex, it is well documented and I was able to get it working reasonably quickly.  The API is much richer and allowed me to do everything I wanted to (ex: getting position feedback). For example, the Python API is aware of fine points like the target position vs the actual position from servo feedback.

Remote python API

Unfortunately above only works locally (at least as far as I can tell).  To use the BBB from a remote system I decided to use XML-RPC since I've used it before and its pretty easy to use.  I instantiate a linuxcnc object that looks just like the linuxcnc module.  This allows programs written against the normal Python module to nearly seamlessly my remote version.

To make it run smoothly I do the following:
  • Copy LinuxCNC .ini file to BBB (SFTP)
  • Launch LinuxCNC on BBB using .ini file (SSH)
  • Copy XML-RPC server to BBB (SFTP)
  • Launch XML-RPC server on BBB (SSH)
  • Create SSH tunnel from BBB to localhost
  • Connect to BBB using XML-RPC client
I'm using the paramiko API to copy files over and launch remove processes.  Although I'm not using rsh, its still convenient as I can wait for the rsh port to open to know that linuxcnc is ready.  There might be better ways but this was easy and seems to work.

The core linuxcnc remote interface client and server are here.  The wrapper to remotely deploy it can be found here.   Here's an example program using the wrapper.

Polishing

I'm using the  CRAMPS configuration as a base.  This unfortunately has a lot of stuff I don't need and causes it to take a long time to start up.  I've started stripping down the config but there's still a lot to strip out (ex: thermal management).

I'd also like linuxcnc to launch automatically at start up which probably isn't too hard.  I'd also like my config files to get versioned which may just mean I check out the uvscada git repo to the BBB.  This eliminates most of the above steps.

XML-RPC has a lot of overhead: it creates a connection for every function call and XML isn't terribly efficient.  Fortunately I'm not doing anything super performant so this is probably okay.

Applications

I have several new imaging systems coming online.  This project was primary driven by my x-ray scanner:


which I'll do a post on in the near future.  I'm also planning on deploying this to existing systems like pr0nscope and k2scope.

Summary

The Beagle Bone Black is a very compact platform to run LinuxCNC from.  The rsh API is good for very simple remote control applications but you should use the Python API (or C API) if you need better control.  I've provided some wrappers to use the API remotely almost as easily as the local API.

For the amount of work put into this it came out pretty good.  There's still a lot of room for improvement but its mostly better than my pr0ndexer board.  The main disadvantage so far is that the BBB takes several minutes to start up where my board was ready in under a second.  For most of my applications this isn't a big deal.  That said, I'm eventually going to look into ways to cut down startup time.

Wednesday, June 10, 2015

RECON N64 CIC talk

The con is already sold out, but better late than never...

Will be co-presenting a talk on the Nintendo 64 CIC at RECON 2015: https://recon.cx/2015/schedule/

Enjoy the talk and pop by to say hi!

Saturday, May 23, 2015

Dexis/Gendex GXS700 driver released

Source code

Instructions

Run capture.py

Used to create the CBCT and other posts earlier.  I was hoping to release this in exchange for some junk but that didn't pan out.  So after holding onto it for a while decided it was time to let it loose in the world.  Enjoy...

Friday, May 15, 2015

Fruit exploder at Marker's Faire




I'll be blowing up tomatoes, smartphones, and anything else that catches my fancy.   Also someone has offered a brand new Arduino Uno that we are going to raffle off for free (probably at 3:30).  Tentative showtimes at the Cupertinker booth in the main hall:

Saturday
  • 11:30 am
  • 1:30 pm
  • 3:30 pm
  • 5:30 pm
Sunday
  • 4:30 pm

Friday, April 3, 2015

Cone Beam Computed Tomography (CBCT) test shot

I've been playing with a dental x-ray sensor and getting some pretty good results.  Ultimately I'd like it to help reverse engineer PCBs and related security modules.  Here is a shot where you can clearly see bond wires:






This is still relatively early in my testing and I can probably still do a lot more to get better resolution.


With basic imaging working, I'm trying to take it a step further and do CBCT.  Sneak peak at setup:


 I made some test shots into a video but I'm still in the process of trying to stitch them into a proper 3d model.  I'm likely going to use plastimatch and/or RTK.

Once I get that working I'd like to try to laminography ("5DX").  Although I haven't looked too hard, I get the impression there might not be a lot of FOSS software to do this and so might require a bit more effort.

EDIT: slides from a presentation I did

Monday, March 9, 2015

80kV fruit exploding machine

About 5 years ago when I was in college at RPI I used a half ton capacitor bank to blow up apples and other meals.  I'm not in this particular video (stupid test) but this gives you an idea:https://www.youtube.com/watch?v=2EhuHs7IdM0

It was a lot of fun and I've wanted to do something like it again for a while.  I have a large number of ~400V rated pulse capacitors:


that I've used before to blow up wire, small railguns, etc with good success.  However, I also have an 80 kV death capacitor that I've always wanted to use:


The death part is pretty literal:


"WARNING: THE ENERGY STORED IN THIS CAPACITOR IS LETHAL".  Not "may be"...*IS*.  And they are probably right: don't touch it while its live.

But the capacitor is pretty boring without a way to power it.  4 years or so ago I used a 5kV capillary electrophoresis power supply to give it a token charge:


This made a reasonably large snap but, because capacitor energy is 0.5 C V^2 was only 0.4 % of the max energy.  After that it was put into storage and didn't see any use for some time due to lack of a large power supply.  I bought some capacitors and diodes to make a CW multiplier for my neon sign transformer but never built it.

Roll forward to present day.  This capacitor came out of an x-ray (diffraction or crystallography IIRC) system at RPI.  Somewhat related, I've been doing some x-ray work and had a unit fail (more on that in another post).  I opened it up and found I was able to salvage the high voltage (100kV) transformer:


For the following I'm currently only using the left half which seems to give about 60kV DC max.   Worth mentioning I could have grabbed the transformer but it was very heavy/large and left behind.

Started with some spark testing to verify the transformer worked.  The transformer must be submerged in oil to work properly:







About a gallon of oil in there and the box was tipped to one side that it fully covered.  Then I made some arcs:


The gap in the above picture is about 2"

But this is AC and to fully charge the capacitor I need DC.  I still had the original full wave rectifier that powered the capacitor but, for reasons I don't recall, I only have the bare diodes and not a rectifier assembly.  So next step was to assemble them into a rectifier module.  Originally I did a classic rectifier square design:


But then realized this required crossing an output high voltage line over an input source, potentially leading to a breakdown.  So redesigned int in an x pattern so that the polycarbonate sheet provided insulation between the two halves:


Per the labels, AC comes in on the left and DC exits on the right.

Next, we need a trigger.  In the simplest tests its fine to set a spark gap and let it automatically trigger but longer term   In the past I used a pneumatic switch to trigger a spark gap which worked pretty well.  I had some 2" stroke solenoids which aren't ideal (remember I said I could jump 2" above?) but was good for a first test.  Setup:


Note on the right you can see 40kV probe for "low voltage" tests.  The blue silicone tube goes to a compressor on the right.  I simply open up the regulator to close the switch.  I also built a polycarbonate platform that you can see in the above picture.

This system needs a way to safely discharge.  Long term I want an emergency stop, but short term I'm fine with simply bleeding off charge.  My goal is to have the system safely discharged (50V) within about 10 seconds.  I think this didn't work out in the end, but in theory this should be V = e^(-t /(RC)) where:
  • V = 50V
  • t = 10 s
  • R = ?
  • C = 0.25 uF
Solving for R gives you about  5.4M.  That was my original goal, for reasons I don't recall I instead did 800M (too high current draw?).  This discharges to 50V instead in about 185 seconds which still isn't too bad.

Putting it all together, this is what the prototype schematic looked like:


Some artistic license on the schematic: I loosely interchanged electrical paths with pneumatic paths.

Time for results.  The first victim was a galaxy 2 phone donated by a coworker.  Couple minute video of the test process here: https://www.youtube.com/watch?v=Q-sTKhyaM3Y

The phone wasn't blown in half but was a good start: the screen was cracked and burned.  Ultimately the phone succumbed though so I call it a success.

But the goal was to blow up some fruit.  First I tried placing a tomato directly inside the gap: https://www.youtube.com/watch?v=CgCAwcUGMeg&list=UUq3z1paLNFugoH3yTYokMIg

But this didn't work so well: a tomato has a lot of water that serves to nicely absorb the energy.  Next idea: put the electrodes inside the tomato and separate by 0.25".  This focuses the energy into a small space and forms a proper explosion.

This worked great: https://www.youtube.com/watch?v=E4cW6JSh3lc

Mission success!  There is one less tomato in the world.  I also decreased the camera ISO from auto to fixed 400 ISO to get better explosion coverage.  I also upped the frame rate from 30 fps to 60 fps to catch more gore.  I have a 1000 fps Casio that I'll try to use in the near future.

Finally, how to blow the phone in half?  I have a tenative agreement to upgrade the system from 800J to 12-13 kJ.  More to come


(note the ruler for scale)

Wednesday, February 11, 2015

Drying transformer oil

I acquired an x-ray head a bit back off of Craigslist:


and was experimenting with some screens:


to produce some images.  The setup is remotely switched and uses a webcam to view the intensifying screens meaning I don't have to be in the room while it runs.  I started to do some "low voltage" tests (maybe 50kV?) but didn't see any images.  I'm not sure what range the screens are sensitive to so I decided to crank up the voltage some.

In the past I had ran my head at 100kV for a number of experiments with no issue.  Unfortunately, as I turned up the voltage this time it generated an internal short a few seconds after turning it on.  Drat!  I had been warned these old GE heads can suck in moisture and its possible that's what happened

Fortunately, I drained the oil and it was still pretty clear indicating *potentially* no major damage.  So I'm taking two paths to get the system back online.

First, some cheap GE x-ray heads showed up on eBay so I picked up a few:




The bottom left unit is my original Craigslist special.  I have need of some high voltage DC supplies so I should be able to make use of  the lot even if they are excess to my x-ray needs.

However, these heads can still develop the same short if the oil has moisture.  I picked up some mineral oil and tried to dry it out under vacuum in a 2L reactor.  Unfortunately, it seemed to steadily bubble for some hours.

I talked to someone and they suggested that the trick is to get a lot of surface area to let the water out quicker.  So I tried to setup something resembling a vacuum distillation rig:


At the bottom is the 2L reactor with 24/40 joints.  The red hose is the vacuum feed.  The bottom hose has a siphon (like you'd find in a vacuum trap) that leads to a peristaltic pump (not shown) and then recirculates to the top.  From there it feeds a Vigreux condenser to give it lots of surface area to outgas.

I knew that the pump wouldn't prime under vacuum but figured it could be primed under atmosphere and then would circulate.  Unfortunately, the oil outgases heavily under vacuum, causing the pump to de-prime.

To solve this, the next step is to try to gravity feed the reactor into the pump.  Thus, even if it outgases, gravity will feed oil into the pump and cause it to prime under vacuum.  I'll likely have to put the reactor partly on its side which means that it could come apart and make a huge mess.  Most of the work will be trying to ensure this doesn't happen.  I have a clamp for the reactor lid and can tape the rest of the ports in.  Under normal circumstances, vacuum should hold everything together but it must be able to prime as well as survive returning to atmospheric pressure.