Gas station without pumps

2012 August 7

Accelerometer for circuits course?

Filed under: Accelerometer,Circuits course — gasstationwithoutpumps @ 11:02
Tags: , , , ,

One of the people that I asked to look over the course notes and give me suggestions suggested another lab that would likely appeal to bioengineers:

another cheap experiment, accelerometers from Sparkfun to measure gait patterns or detect falls.  If really ambitious, you can teach chaos theory here with analyzing chaos levels in gait patterns—they are different for men and women.

I’ve used accelerometers before, both the analog output ADXL335 and the I2C MQA8452Q. The ADXL335 breakout board was from Adafruit Industries, the MQA8452Q from Sparkfun.  Although I personally prefer the I2C interface, since it takes up only 2 Arduino pins, programming is outside the scope of this class.

This lab sounds like fun, and it would be good for the bioengineers to think of accelerometers as cheap sensors that are easily used, rather than as magic that comes in cell phones, I’m not sure how we would get a circuits lab out of this. Even the analog-output accelerometer just needs to have its XYZ pins connected to analog inputs on the Arduino.  Anything interesting you do with the accelerometer is in either the mechanical mounting or in the software analyzing the data, not in electronic circuits.

We have several constraints in selecting labs for this circuits course:

  • Lab must teach something useful to the students.
  • Lab must seem interesting (or at least useful) to bioengineering students.
  • Lab must not be dangerous (either to students or to equipment).
  • Lab must be doable in one 3-hour lab session (we can afford at most 2 labs that are 2-session labs).
  • Lab cannot require students to be able to program computers.
  • Lab cannot require knowledge of electronics beyond what is taught in the course.
  • Lab should support the teaching of traditional linear circuits.
  • Lab should involve student design and not just analysis of existing designs.

The accelerometer lab fails on two points: any design component would have to be software and there is no support for teaching linear circuits in the lab.  That’s too bad, because it is otherwise a cool lab idea.

2012 April 21

Fitting a sphere

Filed under: Accelerometer,magnetometer,Robotics — gasstationwithoutpumps @ 21:19
Tags: , , , , ,

Today I had to write a program to fit a sphere to a bunch of points that were supposedly near the surface of a sphere, but were noisy and sampled in a very biased way.  Since this is obviously not a new problem, I started out doing web research.  but I didn’t look for fitting a sphere, but for fitting a circle, since that is a simpler related problem.

I found a lot of papers, including several review papers, on how to fit a circle to a bunch of points.  The “obvious” method is to  do a least-squares fit to minimize the distance between the points and the circle, minimizing \sum_i (r- \sqrt{ (x_i-a)^2+(y_i-b)^2})^2, where r is the radius and (a,b) is the center of the circle.  Unfortunately, that is a difficult problem to solve, and even numerical methods require a lot of iterations to get decent solutions.  What most people do is to change to a slightly different problem that optimizes a different fitness function.  For example, Kåsa’s method minimizes \sum_i (r^2 - (x_i-a)^2 - (y_i-b)^2)^2.

There is a very nice, but very formal, presentation of the methods in a paper by Vaughn Pratt from 1987: Direct Least-Squares Fitting of Algebraic Surfaces.  This paper introduced Pratt’s method, which was later slightly improved to make Taubin’s method. I did not read these original papers (other than skimming Pratt’s paper).  Kåsa’s paper (A curve fitting procedure and its error analysis. IEEE Trans. Inst. Meas. 25: 8–14) does not seem to be available on-line.  The IEEE digital library is missing the whole 1976 year.

I did find a recent paper that does careful error analysis of both the geometric approach and several of the algebraic approaches (including the most popular ones: Kåsa, Pratt, and Taubin):

Ali Al-Sharadqah and Nikolai Chernov
Error analysis for circle fitting algorithms
Electronic Journal of Statistics
Vol. 3 (2009) 886–911 ISSN: 1935-7524 DOI: 10.1214/09-EJS419

This paper shows that Taubin’s method is theoretically superior to Pratt’s which is theoretically superior to Kåsa’s (having less essential bias), and gives a very weak example showing it is also tru empirically.  More interestingly, it also gives a “hyperaccurate” algorithm that has less bias even than Taubin’s method.  I did not read the error analysis, but I did read the description of their Hyper algorithm and the implementations of it that Chernov has on his website.

Since I needed Python code, not Matlab code, and I needed spheres rather than circles, I spent a few hours today reimplementing Chernov’s Hyperfit algorithm.  I noticed that the basis suggested by Pratt for spheres, (x^2+y^2+z^2,x,y,z,1), was a simple modification of the one used in both Pratt’s paper and Chernov’s paper for circles, (x^2+y^2,x,y,1).  I decided to generalize to n dimensions, and use the Numpy package in Python for all the matrix stuff.  I hope I got the generalization right!

From starting to look for papers until getting the code working was about 6 hours, but I had lunch in there as well, so this felt like pretty speedy development.  I’ve released the code with a Creative Commons Attribution-ShareAlike 3.0 Unported License, and would welcome corrections and improvments to it.

Of course, after all this buildup, you are probably wondering why I needed to fit a sphere to points—that is not a common problem for a bioinformatician to have.  Well, it is for the robotics club, of course.  They’ve been having a lot of trouble with the magnetometer calibration and heading code, so we decided to try doing an external calibration of the magnetometer, which has an enormous arbitrary 3D offset.  By waving the magnetometer around in different orientations (which means tumbling the ROV once the magnetometer is installed), we can sample the magnetic field in many orientations, though far from uniformly.  The center of  the sphere fitted to the readings gives us the 3D offset for the magnetometer.

My son and I tested it out with Python code and Arduino code that he had written to get the data from the magnetometer to the laptop, and the magnetometer readings do seem to be nicely centered around (0,0,0) after we do the correction.  We’re still having trouble using the accelerometer to get a tilt correction to give us clean compass headings, but that is a problem for tomorrow morning, I think.

2012 March 1

Sensor board for underwater ROV

Since I had bought the robotics club an I2C accelerometer and magnetometer, I decided to make a new PC board for them to mount the accelerometer, the magnetometer, and the pressure gauge on the same board.  I don’t have the SMD soldering skills to solder all the chips onto one board, and I already had breakout boards for the accelerometer and magnetometer from Sparkfun, so I decided just to put connectors for those breakout boards onto the back of the pressure sensor board.  (The back, because the pressure sensor on the front has to be stuck through a hole in the dry box and glued in place.

The new boards are tiny (1.05″ × 1.425″), so I decided to try BatchPCB (which has pricing by the square inch) rather than 4pcb.com (which has fixed pricing per board, up to a fairly large size).  The price from BatchPCB was $10 per order plus $2.50/square inch plus $0.90 for shipping, so ordering 3 copies of the board (though I only needed one), cost me $22.12, substantially less than a single board from 4pcb.com, which is $33 plus $17.30 shipping and handling per board (plus an extra $50 if your board has multiple boards on it).  The 4pcb price is lower if your board is bigger than about 15.76 square inches, so even my HexMotor boards (at 12.44 square inches) would be cheaper from BatchPCB.  If you get multiple boards from 4pcb.com on a single panel and cut them apart yourself, the breakeven point is about 35.76 square inches for a single design (so three HexMotor boards from a single 4pcb.com panel is cheaper than from BatchPCB). For multiple designs on a single panel, the 4pcb.com deal is better: for 3 different designs, a total of 27.04 square inches would make 4pcb.com the cheaper way to go.

If you want a copy of the board, you can order it from BatchPCB, or pick up the Eagle files from my web site and order copies from elsewhere.  I’ve put the HexMotor Eagle files on line also, but not put them on the BatchPCB site.  I should probably upload them there sometime.

Bottom line: BatchPCB is better for small numbers of tiny boards, but 4pcb.com is better for larger boards and multiple designs.

The BatchPCB orders came back quite quickly (12 days from order to delivery by mail), though I had been worried because their design-rule check, which they say takes minutes had taken about 8 hours.  The problem was that each check takes a few minutes, but they had hundreds in the queue over the weekend, and it took a full day to clear the queue.

I had less trouble soldering the pressure gauge this time (this was my second attempt at soldering surface mount devices).  You can see in the pictures above that the results are much cleaner than in my first attempt.

The robotics club has tested the pressure sensor on the new board (using their own code on the Arduino) and it seems to work ok,  have drilled the hole in the dry box for the port, and glued the sensor board in place using superglue.  It seems to be waterproof (at least down to 1 foot—we’ve not tested in deep water yet).

2012 January 30

Magnetometer and accelerometer read simultaneously

In Learning to Use I2C and Magnetometer not fried, I talked about interfacing the MAG3110 magnetometer and MQA8452Q accelerometer to an Arduino.  For both, I’m using breakout boards from Sparkfun Electronics.

I  checked today that there are no problems when I connect both devices to the same I2C bus.

The first test was very simple: I put both the breakout boards into a breadboard and wired them together, then tried running each of the programs I’d written for the chips separately. Result: no problems—worked first time.

I then tried merging the programs (cleaning up any naming conflicts) so that both could be run from the same code.  After a few typo fixes, this also worked fine

I think I’m now ready to hand over the software to the students to use for their robot.

I still need to put the i2c.h, i2c.cpp, and accel_magnet code in some public place for others to use (perhaps on github? maybe on my web pages at work?) [UPDATE 2012-jan-31: I have put the libraries and the sample code for the accelerometer and magnetometer at http://users.soe.ucsc.edu/~karplus/Arduino/]

One thing that is still missing is doing tilt correction for the compass heading.  Since the ROV is not expected to remain level (the accelerometer is intended to be used in a feedback loop to adjust the pitch, with anything from -90° to +90° being reasonable), getting a good compass heading requires rotating the magnetometer readings into the horizontal plane.  Only one of the students in the robotics club has had trigonometry or matrix math, so I’ll have to work with him to get him to figure out how to do the tilt correction. It may be simplest conceptually  to compute pitch and roll angles first, then rotate twice, rather than trying to do the whole tilt correction in one step (especially since the Arduino does not have matrix libraries).

2012 January 22

Learning to use I2C

For the Santa Cruz Robotics Club, I’ve bought three sensors for their underwater ROV: a magnetometer, an accelerometer, and a pressure sensor.

Originally, we were going to an ADXL335 accelerometer (with a breakout board by Adafruit Industries) and an MPXHZ6250A pressure sensor (no magnetometer), for which I designed a small PC board, but once the specs for this year’s mission came out, we saw that they wanted us to determine compass headings for a “sunken ship”, so it seemed a natural thing to add a magnetometer to the hardware.  After looking at what was available, I chose the MAG3110 breakout board from Sparkfun, because it provided a triple-axis magnetometer for only $15.

The MAG3110 is an I2C interface, which means we need only 2 wires to hook it up (and the wires can be shared with other I2C devices).  If we are going to all the trouble of figuring out an I2C interface, I figured we might as well use it for the accelerometer as well, so I got a MMA8452Q breakout board from Sparkfun also.

I decided to do a simple test program for the I2C parts before handing them over to the robotics club, so that they could be sure they had working parts.  It was a good thing I did, because I spent more than an entire day trying to get the parts to work.  I finally gave up on the “Wire” library from the Arduino website, and tried using the i2c.h file from Sparkfun (example code linked to from the accelerometer web page).  I got that working and rewrote the library as a proper .h and .cpp file, so that it could be installed as a normal Arduino library, adding some of the utility calls that had been buried in the MMA8452 demo code.

The MMA8452Q code was working fine, so I tried using the same i2c library for the MAG3110 magnetometer.

I had gotten MAG3110 working with the Wire library, but running at 5v (I’d not noticed that it was a 3.3v part—rather, I thought I’d checked that it was a 5v part, but I was wrong).  I’d left it powered at 5v all night, and I think I burned it out, as it was quite warm in the morning.  Today, I can read and write the registers of the MAG3110, but the xyz values are not coming out reasonable at all—I frequently get the same values (like 0xF9F9)and 0x1DF9), independent of the orientation. If I read all the registers, a lot of them come out as 0xF9 or 0x1D.  Even the WHO_AM_I register (which should be 0xC4) often comes out 0x1D.  I seem to get intermittent correct values for registers, but mostly bogus values.

I’ll feel stupid if I order another part and it turns out to be a software bug, but I’m pretty sure the chip is fried.  But I guess it is time to do another Sparkfun order. (I owe them some business, after calling them for the replacement photointerrupter.)

Incidentally, I tried finding a usable pressure sensor with an I2C interface, but it doesn’t look like anyone is making them except for barometric pressure ranges for dry gases.  I suppose Freescale will eventually come out with a full range of I2C pressure sensors, but my guess is that will be a long time coming, as the automotive and industrial applications have a pretty long product design cycle (unlike consumer electronics, which is driving the barometric pressure sensors).

Next Page »