Friday, December 23, 2011

Dear youtube...

I would not give you my mobile phone number, even if I had one. So stop asking.

Thursday, December 22, 2011

BAD power supply.

I'm trying to build a 9V power supply for a camcorder, and after seeing Dave Jones' EEVblog #110, I decided to try using the MC34063 switching power controller.

The circuit I built up on a breadboard produces 9V (well, something like 8.88V really) just fine, but my camera would not turn on! Naturally I went in to diagnostics mode (i.e. I started hunting for the cause by trial and error) and found that I was getting ... well, I'm not entirely sure what to call it. A glitch? Anyway, the voltage would occasionally pulse away from its steady state, anywhere from +/-200mV to over 1V!

After poking around a bit I finally tried hooking the scope up directly to the power output terminals of the BK Precision 1665 power supply I was using to drive my own power supply, and the same glitch was showing up even there, whether there was any load on the terminals or not. Here's the trace on my scope:

It looks absolutely terrible, however I don't think it's the root cause of the camera refusing to power on. I had tested the camera directly connected to the BK and was able to turn it on. It seems like the only remaining candidate is current, though I designed the power supply to be able to handle more than the 560mA that the camera pulls when powered on. More diagnostics are required.

Wednesday, December 21, 2011

Jaerb Creators

Just when I thought that the whole mythos surrounding the fictional "Job Creators" had pretty much died out, some twatwaffle whines on PBS Newshour that EPA regulations to keep power companies from poisoning everything will have an undue burden on these fictional job creators. The twatwaffle in question was Scott Segal, director of the Electric Reliability Coordinating Council. Supposedly their mission is to coordinate power generation and transmission across North America but really they just come off looking like lobbyists for power companies.

You didn't even pull the "job creators" card in an even remotely convincing fashion there, guy. Maybe you could dig up some Reagan-era anti-EPA rhetoric that's long since been discredited to along with it.

Who is it that you're actually trying to convince that you'll go out and hire a mess of workers but only if the EPA doesn't tell you to keep your toxins under control? What sort of bullshit blackmail are you trying to pull, here? "You need to let us dump mercury into the atmosphere or we're just going to stop hiring people" (in case it's not patently obvious, not an actual quote, but that's an interpretation).

I must confess I didn't watch the entire interview (or whatever it was supposed to be, despite Jim Lehrer's insistence that opinion, analysis, etc. etc. be readily distinguishable on the NewsHour, it really wasn't clear here), as pulling the "job creator" card pretty much made me not want to hear anything else Segal had to say. Maybe he had some decent points after that, but when you start out regurgitating last year's rhetoric, you don't deserve my ears for the 5 or so minutes you were on.

Phew. Time for some Oedipal Zen.

Saturday, October 29, 2011

Arduino, Wire, and I2C part 5b: Data Analysis and gnuplot

I've been using a feature of gnuplot lately that until yesterday I hadn't really given much thought to its potential. Gnuplot has a curve fitting tool which can be used to come up with those parameters to the sinusoidal functions in the previous post. It's not magic in that it won't necessarily always give you the right answer every time, but it can help with cleaning up estimates. Here's an example. First, define the function you're trying to fit to. In this case, I'm trying to fit to a simple sinusoidal function:
gnuplot> f(x)=a2*sin(omega*x+phi)+d2
This is the function described in the previous post, in gnuplot syntax. Now, you can try and fit the data to the function. The total data set isn't a consistent wave form so I'm going to reduce the data set to points between 150 and 250.
gnuplot> fit [150:250] f(x) "spin.dat" using 0:7 via a2,omega,phi,d2
The above instructs gnuplot to execute an iterative process, attempting to derive the values for a2, omega, phi, and d2 in the function defined as f(x). Gnuplot will output the results in various stages of the process. The most critical results are the final ones of course, which I reprint here:
Final set of parameters            Asymptotic Standard Error
=======================            ==========================

a2              = 0.774445         +/- 11.02        (1423%)
omega           = 0.973404         +/- 0.4104       (42.16%)
phi             = 6.881            +/- 82.27        (1196%)
d2              = -66.2102         +/- 6.535        (9.871%)
You may notice two things:
  1. The equation parameters are quite different from those that I posted previously, and
  2. The standard error percentage of the parameters is quite high (even the lowest, 9% is pretty significant).
You can "prime" the fit algorithm by seeding the parameter to reasonable approximations, i.e. give the fit a good starting point (there's probably a mathematical term for this but I'm not a mathematician). Using the parameters guessed at in the last post:
gnuplot> a2=93.5
gnuplot> d2=-75.6
gnuplot> omega=1/4.6
gnuplot> phi=-6
gnuplot> fit [150:250] f(x) "spin.dat" using 0:7 via a2,omega,phi,d2
Which ultimately resulted in:
Final set of parameters            Asymptotic Standard Error
=======================            ==========================

a2              = 90.8588          +/- 1.735        (1.909%)
omega           = 0.220797         +/- 0.0006131    (0.2777%)
phi             = -8.0615          +/- 0.1239       (1.537%)
d2              = -74.2817         +/- 1.185        (1.596%)

gnuplot> plot "spin.dat" using 7 axes x1y1 t "mag y" with lines, a2*sin(omega*x+phi)+d2

Which looks like a fairly good fit, with less than 2% error. A better fit could be made using equations with more independent variables, however, gnuplot's curve fit feature is limited to 5, of which the above already was using 4. I don't think there is much chance of refining this estimation any further using the fit feature of gnuplot.

Saturday, October 15, 2011

Arduino, Wire, and I2C part 5: Data Analysis and Modeling

Now that I've managed to reduce noise levels in the sensors to a mostly manageable level, it's time to record some data and try and model the board. It's worth reiterating what it is I'm attempting to achieve here: a hand-held underwater metal detector. Magnetometers can be a great way to achieve this, but this particular device is measuring the strength of the magnetic field.

I'm fairly confident that linear movement of the magnetometer is not going to significantly change the sensor measurements. This is because Earth's magnetic "lines of force" don't change particularly rapidly. You would probably have to move hundreds of miles to be able to see any significant change in the magnetometer's measurements, and can you really say you've moved in a "straight line" by then? More than likely you'll have been moving in an arc relative to gravitational center of the earth, which would be even less likely to show a significant change in measurement. Therefore, I'm going to ignore ADXL measurements.

The drawing above shows the board and the axes of measurement for each device. Unfortunately, sparkfun mounted the magnetometer such that it is 90° out of phase with the other devices. This means that the positive X axis of the accelerometer and gyro is the positive Y axis of the magnetometer, and the positive Y axis of the accelerometer and gyro is the negative X axis of the magnetometer. An inconvenience, but hopefully just a minor one.

Data capture was achieved using a common spice rack. I wanted something that didn't have much, if any, metal in it, while having sufficient space to throw the entire test apparatus on. The sensor board is roughly centered (it's a little hard to see given that the tape holding it down is a similar color to the spice rack, but you can see the connector to it above the battery pack), with the power pack and the Arduino UNO, XBee shield and XBee around the edges. Data was transferred via the XBee radio to a PC running Linux. Data loss made it necessary to make the data processing software a bit more robust.

Data capture was successful, and the graph to the right is a plot of the gyro measurements. As you can see in the graph, the rotation was primarily occurring around the Z axis, which matches the diagram of the axes and the picture of the apparatus. What you can't really see very well in the graph is that the Y and X axes were also showing measurable rotation. Those measurements show the same oscillation that can be seen on the Z-axis measurements. This is always going to be the case in any real-world measurements. You're simply never going to be able to get all the axes completely lined up and the axis of rotation perfectly aligned with the Z-axis (or whichever axis you're picking as "up"). You might get a lot closer than what I achieved with some really expensive lab equipment. The Z rotation is negative, indicating that the rotation was in a counter-clockwise direction around the Z axis.

Before looking at the magnetometer data, it's time to take a quick excursion back (for me at least) to Euclid and his geometry, though for the sake of simplicity, I'm going to stick with a 2-dimensional geometry for now. When translating between polar coordinates (angle and radius) and Euclidian coordinates, the following formulae apply:
$\begin{array}{rcl}x_{1} & = & r \cos \alpha,\\y_{1} & = & r \sin \alpha.\end{array}$

where r is the radius and α is the angle. In Euclidian geometry, your axes are always orthogonal, meaning they're at angles of 90° to each other. As such, the trigonometric operations sine and cosine are also 90° out of phase with each other. This phase offset shows up clearly in the recorded data. Given that the experiment was intended to rotate the board at a reasonably constant rate around the Z axis, the X and Y magnetometer measurements will look like sinusoidal waves 90° out of phase with each other. The following two graphs demonstrate. The first graph is the actual data, while the second graph is a simulation of the data set using only cos and sin functions, which are scaled to the appropriate mean and amplitude.
Recorded Measurements
Simulated with Trig functions


The "simulation" in the second plot is of the following functions in standard form:
$\begin{array}{rcl}y_{1}(t) & = & A_{1}\cdot \cos (\omega t + \varphi ) + D_{1},\\y_{2}(t) & = & A_{2}\cdot \sin (\omega t + \varphi ) + D_{2},\\A_{1} & = & 82,\\D_{1} & = & 15.73,\\A_{2} & = & 93.5,\\D_{2} & = & -75.6,\\\omega & = & \frac{1}{4.6},\\\varphi & = & -6.\end{array}$
Note that the frequency (ω) and phase (φ) are the same for both equations. Only the amplitude (A) and center amplitude (D) are different.

One important thing to note (in fact, pretty much the whole point of this post) is that ω is almost certainly a function of the Z-measurement of the gyro. In the simplified environment of a perfect rotation about a co-axial Z axis for the two sensors, this might be expressed as:
$\omega = \gamma z_{g}$
where γ is some constant. The reason for this is that the gyro is measuring some Δα, that is, the rotation rate around a given axis. This is, in fact, the frequency ω. It only needs some scale factor applied to it to match the measurements to the model. The value of that constant scale factor can probably be derived from the data, but I probably need to take a few more sample runs at various speeds of rotation before I can feel comfortable quantifying it.

More to come...

Thursday, October 6, 2011

Arduino, Wire, and I2C Part 4b: Noise reduction

Following the manufacturer's recommendations, I put a 1μF capacitor in the circuit to decouple power supply noise at VS. This meant replacing the .1μF capacitor that sparkfun had put there. Not a particularly big deal, and well worth it as you can see in the attached graph.

The down side is that the vertical axis, whatever that happens to be, remains fairly noisy on the accelerometer and to a lesser extent, on the magnetometer, but clearly the non-vertical axes have had significant reductions of noise. For the purposes of comparison, I did offset the 1μF data set so that the two sets of data shared a common mean value. The 1-sigma error shading is computed solely from the .1μF data set, however.

Sunday, October 2, 2011

Arduino, Wire, and I2C Part 4: Noise and analysis

These weekend I spent some time recording sample data sets from the sparkfun SEN-10724 and looking at it. I'd say I was analyzing the data, except that might give the impression that I actually have a good idea what I'm doing.

The recording of data, I actually set up using the sparkfun "ethernet pro" board, which is basically an Arduino with built-in ethernet and seemingly poorly designed voltage regulation (it gets pretty hot if you power it with the intended voltage levels). I felt more comfortable using the ethernet rather than serial-over-USB since I would be sending more data than was reasonable for the 9600bps that the Arduino UNO is fixed at (over USB - the firmware for the atmega8u2 that handles the USB-to-serial interface is programmed such that it will only operate at 9600bps).

After finding a few errors with decoding the data (mostly in the PC side, the microcontroller was programmed to send the raw measurements as-is), I found that the ADXL345 accelerometer has noise levels way out of spec. I've plotted the measurements and attached images of said plots at the end of this post. The XYZ measurements of the ADXL345 all had significant levels of noise (RMSD 5-12 LSBs) and the magnetometer had noise on the X-axis only (RMSD 9 LSBs). During the test data recording, the sensor board was in a breadboard sitting on my desk with no significant sources of vibration.

One concern I had is that the schematic for the SEN-10724 had two .1μF capacitors "near" the ADXL345. The datasheet calls for a single .1μF capacitor between ground and VDDI/O, and for a 1μF tantalum capacitor at VS, with an optional 10μF tantalum capacitor in parallel.

If the circuit instead only has a .1μF capacitor at VS, that might explain why the measurements look so noisy. In-circuit measurement of the capacitors is impossible, and I don't have a stockpile of SMD capacitors (strangely enough, after the 3 separate LED cube builds) to replace it with. Time to email customer support.

Tuesday, September 27, 2011

Arduino, Wire, and I2C Part 3: gyro

The SEN-10724 board includes three distinct sensors on it. The linear accelerometer and magnetometer were covered in previous posts. The experience gained in working with those two sensors made it a relatively trivial matter to implement an Arduino sketch to get measurements from the 3-axis gyro.

Set-up of the IC is relatively straight-forward. The defaults are fine in most cases. Because my intent is to eventually couple the measurements from each sensor (the first being the magnetometer and gyro), I configured the data rate to be the same as the magnetometer's default. There is a single register that sets that, the sample rate divisor (SMPLRT_DIV). The datasheet provides a formula (in section 8.2) to derive the desired output rate:
Fsample=Finternal/(divider+1)
F is the frequency (sample rate) in Hz. The internal sample frequency can be either 1kHz or 8kHz. I chose an internal sample frequency of 1kHz to start with, and with the desired 15Hz output rate, that resulted in:
15Hz=1000Hz/(divider+1)
divider+1=1000Hz/15Hz
divider=65

One other piece of initialization needs to be done to take measurements, and that is to set the DLPF_FS (digital low-pass filter/full-scale) register. The "full-scale" part of the register has only one valid value, which is to set the full sale range of the gyros to ±2000°/s. The DLPF portion of the register sets the bandwidth of the filter in conjunction with the internal sample rate. For this test, I picked the value that had the most bandwidth in the 1kHz sample rate. I honestly don't understand what the low-pass filter is being used for, but that's not important right now.

I've made the Arduino sketch available. There's no self-test available, but I can get an idea as to whether the data makes any sense by picking up the board and rotating it around. It seems to work. Also, I can look at the temperature sensor measurements and do a quick sanity check.

According to the table in section 3.1, the reference point for the temperature sensor is -13200LSB=35°C, with 1°C=280LSB (i.e. each bit in the temperature measurement is 1/280°C). The measurements looked fairly stable so I just picked one at random: -15106:
(-15106+13200)/280=-6.8°C + 35°C = 28.2°C = 82.75°F
This seems a tad warm to me, but it's not completely unbelievable.

Now that I've gotten measurements (or at least test measurements) out of each device, it's time to start aggregating the data...

Monday, September 26, 2011

9DOF/SEN-10724: corrections


Looking at the schematic more closely this evening I noticed I'd made a couple of (apparently inconsequential) mistakes. First, the SEN-10724 board has built-in pull-up resistors on the SDA and SCL lines, so those in my circuit were redundant. Second, the board has a voltage regulator to keep the voltage between gnd and Vcc on the devices at 3.3V, so you can actually hook it up to your 5V source and it should still work.

The updated (and simpler) circuit diagram is on the right.

Also, I've attached my (currently very sloppy) Fritzing part to the "code" base, so you can download it.

Edit: Reading the source for the Arduino Wire library, it appears that the library activates the AVR-internal pull-ups for the pins being used to connect to SCL and SDL, apparently making even the resistors on the SEN-10724 board redundant.

Sunday, September 25, 2011

Arduino, Wire, and I2C Part 2: RTFDS

In my last post, I wrote a simple Arduino sketch that would get data from the ADXL345 accelerometer, but the "data" was all zeroes. This time around, I actually go about looking at the data sheet in more detail to learn how to properly get measurements from the accelerometer.

The first mention of enabling measurements is in the "Power Sequencing" section of the datasheet. The second paragraph indicates that to enter measurement mode, you must set the measurement bit in the POWER_CTL register at 0x2D. Another statement worth noting is that the manufacturer recommends configuring the device in standby mode and then enabling measurements. The datasheet also states that the device is in standby mode on start-up. The final bit of important information (for this project) in this section of the datasheet is tables 6 and 7, which contain the bit codes for data output rates.

The next section of the datasheet discusses power consumption as it relates to the data rate of the device. For this project, I'm not going to concern myself with how much power is being used as it's all being powered through the Arduino via USB (note that the Arduino does have a limited amount of supply current, as does USB, but this is in the mA range, where this device is at most using 1/10th of 1mA - 145μA).

Page 10 of the datasheet is where the I2C documentation starts, and that's more or less where I left off previously. Moving forward from here, we reach the section on interrupts. The SEN-10724 board does not have the interrupt pins (8 and 9) connected, so interrupts are not available. That said, the interrupt section does contain interesting information about what you could do with the sensor, if you chose to "wire up" your own board.

Page 13 is the first significant discussion of self-test mode for this device. This seems like a good place to start in terms of learning about the sensor and making sure the board and sensor are both functional. Clearly, there are a number of things to pay attention to. Enabling self-test involves setting a bit in the DATA_FORMAT register (0x31), but based on prior experience, I think it's safe to assume that more is involved than that. The next seven pages of the datasheet cover the details of each individual register, followed by even more information about self-test mode. A fair number of these registers are intended to set thresholds for interrupt functions and can therefore be ignored for any application involving the SEN-10724. For implementing a rudimentary test of the sensor using the Arduino, we need to look at:
  1. DATA_FORMAT - register for enabling self-test mode
  2. BW_RATE - register for defining the data output rate
  3. POWER_CTL - register for turning measurements on
The datasheet curiously enough does not mention sample rate, so it's my assumption that the data rate and sample rate are the same, and it's entirely up to the user to implement any data conditioning.

With the above information in hand, I added the following constants to the previously posted Arduino sketch:
static const uint8_t ADXL345 = 0x53;
static const uint8_t BW_RATE = 0x2C;
static const uint8_t POWER_CTL = 0x2D;
static   const uint8_t BIT_MEASURE = 0x08;
static const uint8_t DATA_FORMAT = 0x31;
static   const uint8_t BIT_SELF_TEST = (1 << 7);
static   const uint8_t BIT_RANGE_2G = 0x00;
static   const uint8_t BIT_RANGE_4G = 0x01;
static   const uint8_t BIT_RANGE_8G = 0x02;
static   const uint8_t BIT_RANGE_16G = 0x03;
static   const uint8_t BIT_FULL_RES = 0x08;
static const uint8_t DATAX0 = 0x32;
The data rate must be at least 100Hz for proper self-test function, according to the datasheet, but the datasheet also indicates that this is the default data rate on power-up, and that low-power mode (which trades cleaner measurements for power levels) is not selected. As such, I'll leave the BW_RATE register alone for now. The datasheet also states that the measurement range be set to the full resolution 16g mode. Note that "full resolution" is a separate configuration bit in of itself. The bits for self-test mode and for the measurement range all reside in the DATA_FORMAT register, so updating that one register should be enough. The datasheet also recommends averaging samples. For this stage of the process, I'm not going to do that, for two reasons: 1) I'm a bit lazy, and 2) the atmega328 chip on which the Arduino UNO is based doesn't even have a divide instruction, so averaging would have to be done using a software implementation of add and sub instructions on the chip. Finally, as far as code changes for this stage of effort, I'm going to cut the delay between reading samples down to match the 100Hz sample rate. The sample rate of 100Hz means that there is an accelerometer measurement every 1/100th of a second, or every 10 ms.

The resulting Arduino sketch, which is also available for direct download, executes and reports on a self-test of the ADXL345 accelerometer. If you open the serial monitor (set to 9600 baud) in the Arduino software, it will show the progress of the register settings (helpful debugging, and left-over from the HMC5883L version of the same, which has a slightly better datasheet IMO) and if the device pasts the tests (measurements are within ranges described in table 2 of the datasheet), it will print the measurements, followed by "OK", then turn off measurement and test mode. Otherwise, it will continue to show measurements and indicate which axis is reading out of spec.

... And that's it. Self test for the ADXL345 (and HMC5883L). The ITG-3200 does not have a self-test mode, so there won't be a follow-up for that.

Friday, September 23, 2011

Arduino, Wire, and I2C

In previous postings, I described connecting a sparkfun.com sensor board to the Arduino and getting magnetometer readings from it.  In this post, I intend to go into a little more detail about how I2C works, while providing similar functionality using the accelerometer on the same board.

The first thing to understand is that I2C is a completely 8-bit bus protocol, which means that all addresses and all data are 8-bit quantities (0-255).  The bus consists of a single "master" with up to 112 unique "slave" devices.  The limit of 112 is due to the fact that a device address is actually a 7-bit quantity (more on this later), and 16 addresses are reserved.  Multiple masters are apparently possible, but aren't relevant for this project.  Slave devices can't talk to other slave devices.  Off-the-shelf devices, like the three on the SEN-10724 board, have pre-assigned addresses managed by a central authority.

Devices have a 7-bit address.  This 7-bit address is stored in the 7 MSB (most significant bits) of an 8-bit quantity when sequenced on the bus, with the least significant bit indicating whether the operation is a read or a write (1 or set being "read").  As an example, the HMC5883L datasheet lists 8-bit addresses 0x3D for read, and 0x3C for write.  Convert these to binary and you'll find a 7-bit address of 0x1E followed by a binary 1 for read or 0 for write.  Some manufacturers will list only a 7-bit address in their data sheet, some will list 8-bit addresses, some will do both.

The datasheet for the Analog Devices ADXL345 lists both - 0x1D is the 7-bit address, which results in 0x3A for writes and 0x3B for reads.  However, it also supports an alternate addressing of 0x53/0xA6/0xA7 if pin 12 is tied to ground. The schematic for the sparkfun board indicates that pin 12 is indeed tied to ground, so let's assume that we're going to be using alternate addressing for that device.

Each I2C device will also have a number of registers that are readable and/or writable.  Table 16 on page 14 of the ADXL345 datasheet lists this device's register map.  For this project, we're most interested in registers 0x32-0x37.  If you look at the table, you'll see how manufacturers design for 16-bit quantities, which is (at least in this case and in the case of the HMC5883L) to have adjacent 8-bit registers containing the most significant and least significant bytes of a 16-bit quantity.

Let's start with the X axis on the accelerometer, which according to the board's silkscreen is the side-to-side direction (along the short edge of the board).  The following Arduino sketch implements a simple program that prints out the X axis acceleration once a second.
#include <Wire.h>
// Wire library uses 7-bit addresses and automatically
// sets the r/w bit
static const uint8_t ADXL345 = 0x53;
static const uint8_t DATAX0 = 0x32;

void setup()
{
  Wire.begin();
  Serial.begin(9600);
}

void loop()
{
  // Put the read address on the bus
  Wire.beginTransmission(ADXL345);
  Wire.send(DATAX0);
  Wire.endTransmission();
  // Request data starting with the X register
  Wire.beginTransmission(ADXL345);
  // 2 bytes gets us the LSB and MSB of the X data
  Wire.requestFrom(ADXL345, (uint8_t)2);
  // store the data in a signed integer quantity
  int16_t x;
  // pointer to use to store the data
  byte *p = (byte*)&x;
  // wait for 2 bytes to be available
  while (Wire.available() < 2) {}
  *p = Wire.receive();
  p++; // advance the pointer to the next 8 bits
  *p = Wire.receive();
  Wire.endTransmission();
  Serial.println(x); // finally, print the quantity
  delay(1000); // delay a bit to avoid flooding
}

If you upload this sketch to your Arduino, with the IMU connected as described in the earlier post, you'll probably get a sequence of zeroes in the serial monitor. If, for example, you tried to change the address in the above code to the primary (0x1D), you probably wouldn't see anything at all. So why is it only showing zeroes, even if I shake the heck out of the board? My guess is that the device doesn't start up in a mode where continuous measurements are taken (which is how the HMC5883L operates), and that to get these measurements, other registers must be manipulated...

To be continued...

Sunday, September 18, 2011

Magnetometer Metal Detection

Part of what motivated me to start playing with the magnetometer was an episode of Deep Sea Detectives I had recently watched on Netflix.  I believe it was the "Damn the Torpedoes" episode, where they used a magnetometer to find a ship that presumably had been buried by silt in a hurricane.  The magnetometer used in DSD was a cesium magnetometer, which is more sensitive, but probably a lot more expensive, even if it were a simple matter for an ordinary person to get their hands on cesium.  The HMC5883L that I'm using has a resolution of 2 milli Gauss, or 200nT (nanotesla).  A cesium magnetometer is probably several orders of magnitude more sensitive.

The plot shows "detection" of metal.  In this case, I moved the remains of my old internal Zip drive (which I had disassembled after viewing a "maker" youtube video along those lines) between the sensor and ground (as in the stuff beneath your feet, not the electrical sense in this case).  The off-scale measurements in the chart are probably an implementation error in the HMC5883L library mentioned in my previous post.  The maximum range of the measurements is -2047 - 2048, so I suspect that the values are being incorrectly converted from the 12-bit measurements to a 16-bit quantity.

The following list, which I unabashedly stole from geometrics.com, should give you an idea of how that rates in a real situation where a marine magnetometer is employed:
Objectflux densitymeasurement range
Ship 1000 tons0.5 to 1 nT800 ft (244 m)
Anchor 20 tons0.8 to 1.25 nT400 ft (120 m)
Automobile1 to 2 nT100 ft (30 m)
Light Aircraft0.5 to 2 nT40 ft (12 m)
Pipeline (12 inch)1 to 2 nT200 ft (60 m)
Pipeline (6 inch)1 to 2 nT100 ft (30 m )
100 kg of iron1 to 2 nT50 ft (15 m)
100 lbs of iron0.5 to 1 nT30 ft (9 m)
10 lbs of iron0.5 to 1 nT20 ft (6 m)
1 lb of iron0.5 to 1 nT10 ft (3 m)
Screwdriver 5 inch0.5 to 2 nT12 ft (4 m)
1000 lb bomb1 to 5 nT100 ft (30 m)
500 lb bomb0.5 to 5 nT50 ft (16 m )
Grenade0.5 to 2 nT10 ft (3 m )
20 mm shell0.5 to 2 nT5 ft (1.8 m)
Of course, their product is trying to do a high-level survey, where the magnetometer is tethered to a ship and is well into the water column.  In my application, I intend to have a hand-held device that I'm moving along the sea/lake bed, so I'm not going to be trying to detect a screwdriver from 4 meters, I'm going to be trying to detect a screwdriver from, maybe 1m.

I have no idea how much one would have to pay for the geometrics magnetometer, but I figure it's one of those situations where "if you have to ask...".

There is still plenty to do to even approach a usable metal detector.  Unlike traditional inductive detectors, magnetometers are measuring minute changes in the magnetic field flux density (no, really, I'm not trying to go all technobabble).  Inductive detectors can detect non-ferrous metals, but have a much lower sensitivity and therefore lower range than a magnetometer.  Obviously, then, the magnetometer is restricted to ferrous (iron-based) metals but can have a significantly higher range of detection.  The other issue, and probably the one more significant, is that any rotation of the sensor along any axis will show up in the data.  The trick will be to distinguish between movement of the detector and actual metal.

Monday, September 12, 2011

"9" degrees of freedom IMU on Arduino

This past weekend I finally got around to playing with the "9 degrees of freedom" sensor board (SEN-10724) I'd purchased from sparkfun.com.  I'm not sure if it makes sense to call it that, but what you get is a 3-axis gyro, a 3-axis accelerometer and a 3-axis magnetometer.  The gyros give you information about rotational acceleration, the accelerometer measures linear acceleration, and the magnetometer works like a 3-axis compass.

The circuit off to the side there shows how I managed to get it hooked up and talking through my Arduino UNO.  The short of it is this: it's a 3.3V device (well, 3 devices) and it needs pull-up resistors (I used 4.7K) on the data and clock lines in order to function.  It's wired up to the analog inputs 4 and 5 on the Arduino board, which is what the provided "Wire" library uses to talk to devices like this, that use the I2C protocol.

Honestly, I'm a little bit unclear as to how it's actually able to talk to the sensor stick/IMU (inertial measurement unit) without doing level conversion between the 5V Arduino and the 3.3V IMU, but it does seem to work reliably in this configuration.  If I were doing something more significant (a production board, for example) I'd probably be a bit more careful about matching the signal levels.

The Wire library for Arduino is just a basic library for talking to I2C devices.  Getting into the specific interfaces is another matter, though for a quick start, I used the HMC588L compass library provided by Love Electronics in the UK.  This was enough to get me started and verify that I was able to communicate with the magnetometer.  There's a pretty decent tutorial on that page on how to use the library, though the sample works pretty well as-is.  If you have trouble compiling the sample code, I found that for some reason it has a period (".") at the very beginning of the file - remove that period to make it compile.

Quick update - looking at the example .pde file in linux using hd (hex dump), it turned out there were three unprintable characters at the beginning of the file.  The easiest way I found to fix the problem was to remove any odd characters before the /* at the start of the file, then save it as a new sketch.  That new .pde file can then be used to replace the original example .pde file in the library, or you can just use the fixed version in your sketchbook.

Sunday, September 11, 2011

George Lucas is one stupid mother fucker.

Just can't leave well enough alone, can you George?  New release, new changes.  Guess I'll be keeping my laser discs and ignoring this new pile of shit: http://www.blu-ray.com/news/?id=7234

Can't fix shitty dialogue or bad acting in episodes 1-3, so let's just fuck everything up with CGI.. oh, and add even more stupid dialogue to the original 3.

Hey George:

Wednesday, September 7, 2011

a whole bunch of leagues...

Digging through Netflix streaming selections this evening, I ran across a movie called "30,000 Leagues Under the Sea"... I had to wonder about that, so I did a bit of research and math.

A "league" is an ill-defined measurement term, but it varies from 3 miles, or 15,840 feet, to 18,240 feet, or in nautical terms, which would make more sense in this context, 1 mile is 6000ft, so a league would be 18,000 ft.

The deepest part of the ocean is 35,838 feet, which is slightly less than *two* leagues.  The original Jules Verne tale was only 20,000 league, but the Earth's diameter is still only about 8000 miles, about 1/7th of the "20,000 leagues"... The circumference of the Earth (and the fact that it was round) had been known since around 200B.C. to be around 25,000 miles, or around 8000 leagues.  Even if the value of pi hadn't been known nor the exact relationship between a radius and circumference, just looking at a circle will tell you that the length of a circle's circumference can't possibly be smaller than its diameter... Which begs the question "what was Jules Verne thinking?"

The director of "30,000 Leagues..." (aptly named Bologna) most likely was thinking "here's an old idea we can recycle and make some money with"...

Thursday, September 1, 2011

"I can't find a pulse!"

"Well dammit, keep looking!"

(this post brought to you by Tired Clichés, Inc.)

Saturday, August 20, 2011

GPS receiver

I spent a chunk of today implementing tools to capture and examine the data from a Trimble Copernicus GPS receiver chip.  Unfortunately, even though it supports the output of "raw" measurements, the pseudorange (in meters) can't be derived easily (if at all), and the Doppler measurements appear to be an order of magnitude larger than they should be.  The SNR measurements look appropriate (in dB*Hz), but I'm uncertain about the phase measurements.  It may turn out to be totally useless for science, which would be disappointing.

I'll have to look into this further next week.

Thursday, August 18, 2011

Damn, it's hot.

The American Coal Mining lobby says global warming is a hoax, and that's good enough for me.  Now if you'll excuse me, I need to put on some spf 83 before going out to mow the charred remnants of my lawn.

The above is a lie, of course.  It's actually 10pm and the sun has set.  But it's still 96 degrees Fahrenheit according to intellicast, 101 according to my phone.  That doesn't say anything about global warming.  The extraordinarily long period of heat we've been experiencing doesn't say anything about global warming.  At least, not by itself.  It's the aggregation of weather conditions around the globe over longer periods of time.  Those average temperatures are climbing, thus, "global warming".

Still, global warming or no, it's freaking hot outside and I'd very much like to get a break from it for a while.

Tuesday, August 16, 2011

AVR programming

Today marked a bit of progress on a couple of my microcontroller projects.  First, I discovered the reason that my LED cube controller board wasn't working.  It turned out to be because I had swapped two control lines on the schematic.  Unfortunately, it's not something I can fix in software.  The swapped lines are a clock pulse line and an output enable line, going to each of eight '574 8-bit flip-flop chips.  The two lines work in completely different ways (clock pulse latches the flip-flop outputs on low-to-high transition, and output enable is active low), and are being driven in completely different ways (output enable is supposed to be a shared signal driven by a single pin from the microcontroller, while the clock pulse is supposed to be individually selected one at a time from a 3-to-8 multiplexer chip's output).  So there really isn't a clean (or perhaps even viable) solution to fix this in software.  As a result, I made a revision "C" of the board design and submitted it for manufacture.  The LED cube is getting pretty expensive at this point.

The other bit of success I've had was in hooking up a Trimble Copernicus GPS receiver-on-a-chip that's mounted on a Sparkfun breakout board, through a logic level converter to an atmega8u2 breakout which is programmed to be a USB-to-serial device.  It.. sort of worked, in that I could see bits of data being sent from the receiver, but the firmware on the atmega8u2 would only work at 9600 bps, while the Copernicus talks at 38400 bps or 4800 bps, depending on which interface you chose to use.

The bad news is that the tool chain provided by Ubuntu is way out of date and I can't really compile for the atmega8u2 with what's been provided.  Newer versions of the tool chain can, in theory, be built, but the instructions as listed in that link don't actually work.

After much hair pulling, I managed to find this sticky thread on avrfreaks.net.  I had to do a little bit of tweaking to get the scripts to download the source files to use a site that was actually up in a couple of instances, but the level of hassle to get that tool chain built and installed was far less than what I was going through with the others.  I was able to build LUFA.  I did not, however, install any of the LUFA bootloaders onto the sparkfun device, opting instead to reinstall the original sparkfun firmware to see if it was capable of switching baud rates.  It was, and I was able to confirm NMEA messages coming out of the Trimble receiver chip.  Progress.

I'm still 6 days away from having the Rev. C LED cube controller boards in my hands, but I'm hopeful that when I get that put together, I'll finally have that working as well.

Thursday, August 11, 2011

Making Sense of it all

People who don't live in the US may not get it, but if you want a reasonably accurate depiction of evangelical Christianity in the US, have a look at Jake Busey's character in the movie "Contact" and that character's followers.

For those who don't live in Texas, that's also a pretty decent depiction of the Rick Perry approach to governing.  If you're one of those Americans that believes that the country would be better off making evangelical Christianity the center of all things, then by all means, support Rick Perry in his presidential bid.  If, on the other hand, you think children should be given the opportunity for education rather than indoctrination, that people should be allowed to determine their own faith, or lack thereof (insofar as it isn't at the expense of others), or that prayers for rain is not an effective governing strategy, you might want to look elsewhere.

Perry is right that the nation is in trouble, but I'm reasonably certain he hasn't the slightest clue how to "fix" any of it.  But I'm sure that in his mind it'll involve a lot of prayer.

Monday, July 11, 2011

Today's Rhetoric Buzzword/phrase

"Job Creators" (N) - a fictional group of people fabricated by the Republican political party in the USA for the purposes of arguing against an increase in taxation of the wealthy.  The phrase is used to create the illusion that if taxes on the wealthy are increased, job creation in the US will go stagnant or even reverse (i.e. cause an increase in unemployment).  This is, of course, based on the largely incorrect assertion that personal tax rates have anything at all to do with hiring practices.  It might be more correct to refer to this group as the "election buyers", as the wealthy, if taxed more heavily, would have that much less discretionary income to spend "supporting" their political candidate(s) of choice.

Saturday, June 11, 2011

LED Controller board, rev. B

I tried checking out the new (rev. A) controller board earlier this week, with no success.  A bit of diagnostics showed that the ground layers weren't switching and further research provided the reason: the SOT-89 package for the transistors didn't match the pins of other packages for the same device.

I'm not sure how I ended up making this mistake, though I suspect what happened is that I originally did the schematic assuming a different package, and failed to verify the pinning after making the change.

The picture shows the cube with the prototype boards (brown), with the SMT rev. A board behind (green).  Mostly for a size comparison.  Unfortunately, there probably aren't any packages of similar size and matching pinning that I could use to replace what I have.  This means that I'll have to make another order of boards, which will at least have all the tweaks I've done since learning from my mistakes on the rev. A board.  Hopefully, there won't be further mistakes requiring new boards as at $100 per run, the cost adds up in a hurry.

Sunday, June 5, 2011

Mad "Scientists"

I think I now know why the "mad scientist" archetype in movies and such always has a maniacal laugh when they achieve their goal.  It's almost compelling, really, and it has little to do with madness.  That sense of accomplishment at having achieved a goal towards which a great amount of effort has been put is quite an emotional rush.  Last night, I populated my LED cube controller board as much as I could.  Today, I turned it on for the first time.  While it didn't work 100% perfectly, I was at least able to program the microcontroller and verify that the start-up sequence was working properly.  This is a bit like building a computer from scratch (and I don't mean by ordering a motherboard and such, I mean by building the motherboard yourself) and turning it on and seeing it go through its boot sequence for the first time.

For me, it was a major accomplishment.

The project is far from done.  The empty spots visible on the card need to be filled.  In fact, that's one of the first of several mistakes that have been uncovered in the design.  The original parts meant to go in those locations turned out to be too large to fit.  I've since found a suitable replacement which I should be receiving tomorrow.  Before that, I received the parts kit only to find that the black switches were not, as I'd inferred from the data sheet, illuminated (the white button is, however, a nifty but expensive control).  I've also found that I drew the traces to the ISP (programming) connector incorrectly (which I worked around by running wires from the connector to the right pins on the programmer), the pads that I drew for the filter capacitor (bottom right, glared out orange piece next to the power connector) were less-than-ideal, and there wasn't quite enough physical space between the switches.  Also, I didn't quite solder one of the components to the white push-button well enough but that was very easy to fix.

If I do end up having a second revision of the board made, I'll almost certainly replace the 0402 devices (mentioned in an earlier post) with larger, easier to see, easier to manipulate, and harder to lose 0603 devices.  I can now say "I did it!" (WRT those tiny devices), but I can also say "I don't want to have to do it again!"

Friday, June 3, 2011

The Realm of the Tiny

I've been working for the past few weeks on a surface mount version of the controller circuit described in this instructable for an LED cube.  "Surface Mount" means that the electronic components are soldered directly onto copper "pads" on a printed circuit board, as opposed to "through hole" devices, where a wire or lead goes through a hole that goes all the way through the board.

I've just soldered (properly, this time) two "0402" package capacitors onto the board.  This package size describes devices that are 1mm x 0.5mm (0.04" × 0.02").  After finishing those two pieces, I kinda stared, wide-eyed, at it all.  The accompanying picture shows the result.  I left a needle on the board for size reference.  The needle is 1.5" long, and it was really too big to be of much use holding the component in place.  The components in question are actually probably pretty hard to see, even in this close-up picture.  The needle point is close to the center, just above the label "C5", and the component is just below that.  The two silver dots are the pads and the little brown bit in the middle is the capacitor.  The second one is just above the "C4" label.

Work is still progressing on populating the board.  I'm probably not going to do any more on it for a few days as one of the parts I ordered turned out to be too big to fit on the board the way I designed it.  I've ordered a smaller replacement that should fit, but the uncertainty keeps me from doing much more work.  If I do get the urge to work on it more, I'll definitely check the pad layout very carefully against the specs for the new chip.

Wednesday, June 1, 2011

Congressional Science Policy

Step 1: Cut funding to scientific research
Step 2: Cut funding to scientific research
Step 3: Cut funding to scientific research
....
Step 15: Eviscerate scientists when they fail to predict destructive weather.
Step 16: Get reelected thanks to your tough stance on.... whatever.

Monday, May 30, 2011

Beanworld on Egg-Bot

Early in the year, I ran across the Egg-Bot on sparkfun.com.  The Egg-Bot is basically a tool that's somewhere between a lathe and a plotter, in short, it lets you draw on round objects like eggs or spheres.  Being the geek that I am, I purchased the kit with the intent of making decorations for the spring holiday festivities (well, for office decorations anyway).  Some of the results were simple, classic decorations, but I wanted something a bit more interesting, so I chose to draw some of the characters from Larry Marder's Beanworld.  I only managed to get about half of the drawings done in time, though Larry was kind enough to post what I'd done to his blog.  Having long since finished, I thought I should go ahead and post a picture of the remaining work.

 

Thursday, May 26, 2011

Are you fucking serious?

While the local school district is struggling to have sufficient funds to keep schools open, the city government is planning to spend millions of dollars to make a few highway overpasses look pretty.  I realize that taxes for the city and the school district are assessed separately, even though they both appear on the property tax bills, but surely you can come up with a better way to spend taxpayer money.

Saturday, May 21, 2011

The apocalypse

Oh, hey, the world ended ~13 minutes ago, but I was too busy playing Portal 2 to notice.  They're still playing baseball on TV, Lawrence Welk is on and so on and so forth.  Nothing significant on the news, though there's a thunderstorm raging to the north.  Well, thank god for his messenger Rick Perry and his call for prayers for rain several weeks ago, or the rain would never have come.  This is absolute proof of God's existence!

Well that's enough snark for now.  It's a beautiful day for an apocalypse and I'm going to enjoy it as much as I can.

Edit: Actually the prediction was that "the rapture" would occur at 6pm local on this day.  The world isn't supposed to end until October, apparently.  Nevertheless, nothing eventful on the news.  It's worth mentioning this isn't Harold Camping's first unfulfilled prophecy, though I suspect the prophecies, failed or not, have probably netted him more money than his civil engineering bachelor's degree ever did.

Friday, May 20, 2011

Bad Science and You

I just finished watching a documentary on Netflix "Watch Instantly" called "Under Our Skin", which was about Lyme disease in the Americas (focusing on the USA).  In the documentary, it was suggested that the group of doctors involved in the Infectious Diseases Society of America had one or many conflicts of interest when producing their recommended practices for the diagnosis and treatment of Lyme disease.  These same doctors have subsequently been involved in litigation against other doctors who have (apparently successfully) treated supposed sufferers of the disease using methods beyond those recommended in the IDSA paper.  The conflicts of interest included having 1) patents on the genetic structure of the bacteria involved in the disease (Borrelia burgdorferi), 2) receiving funds from makers of Lyme disease test kits, 3) receiving money from insurance companies for drawing up said guidelines,  4) citing mostly their own prior work on the topic, and other issues I'm unable to recall at the moment.

Several things bothered me about this.  The obvious conflicts of interest, of course, but also the stubborn insistence that, not that "I'm right and the rest of the world is wrong", but more that the rest of the world doesn't even exist in their minds.  One IDSA doctor interviewed for the documentary would say something to the effect that the disease can not be congenital, while in a later scene, a woman with (allegedly non-existent) chronic Lyme disease gives birth to a boy who (again allegedly) has tested positive for the antibodies for Lyme disease.  One of them is almost certainly wrong.

These doctors apparently often insist that the symptoms presented by the (allegedly non-existent) chronic Lyme disease sufferers is psychosomatic.  This reminded me of a similar documentary I listened to from This American Life, called "81 Words".  In that particular documentary, it was discussed how the American Psychiatric Association defined homosexuality as a disease, in particular a mental one.  One of the particular points that was brought up was that the evidence that led to that conclusion/definition (the 81 words) was a skewed gathering of data.  The point being that the psychologically healthy homosexuals weren't actually spending a lot of time associating with the psychiatrists gathering the data, only those with other problems.  One might also make the conclusion, as an ENT doctor, that all homosexuals must get a lot of ear infections, though that's not the best analogy.

Here's a better one, and supposedly a true story though I'm too lazy to google it right now.  This is one that was relayed to me from someone I knew a few years ago that had worked for Northrup-Grumman (which of course would have been a competitor with McDonnell-Douglas, the contractor responsible for the plane at the center of this anecdote, so take it with a grain of salt).  The story (as well as I can remember it) was that in the Vietnam war, the F4 Phantom-II aircraft, used heavily in that conflict, was to be audited by inspectors.  The auditors went around inspecting the planes after combat, looking at the damage to the aircraft and so on.  The damage on returning planes eventually started to show a pattern, and there was an area of the plane that rarely showed any damage.  The auditors came to the conclusion that this part of the plane was well armored against attacks from ground fire (as most of the damage seen to the planes was apparently caused from ground fire, and less so from other aircraft).  Unfortunately, the conclusion was completely wrong.  The area that rarely showed any damage was in fact a weak spot in the design of the plane - small caliber bullets would be enough, if that spot was hit, to take that plane out of commission.  Planes that had taken damage there simply wouldn't make it home.

The auditors had come to precisely the wrong conclusion because they weren't seeing all the data.  Just like the psychiatrists had come to the wrong conclusion about the nature of homosexuality based on their decidedly skewed data set.  Just like the IDSA authors are making conclusions based on the evidence that they want to see (seemingly not simply failing to see evidence to the contrary of their conclusions, but actively refusing to see it).

My conclusion: things probably aren't going to change anytime soon.  In the "81 words" saga, it ultimately required that "secretly" homosexual doctors of the APA to essentially enact a quiet "coup d'etat" among the organization to slowly phase out that, for a while, was the in vogue excuse to brutalize a segment of our population (though make no mistake, there will always be such a segment, though what that segment is will change from time to time).

Sunday, May 15, 2011

Ignorance IS painful... to watch.

A local church has a vacation bible school program going on this summer they've chosen to name "Pandamonia!".  I'm uncertain as to whether the name was chosen in ignorance of the word's origin/meaning, or if it's simply that they hate their children.  I'd like to think the former is more likely, but I have a long history of misreading people.

Happy, fuzzy (sexual harassment?) pandas... from the capitol city of hell.