Freesteel Blog » Machining

Tuesday, September 8th, 2015 at 4:08 pm - - Flightlogger

The amazingly cheap HC-SR04 ultrasonic sensor works pretty well for what it does, which is measuring distances by echo location, but I wanted to use it for measuring air velocity as my mechanical anemometer is unreliable and of no use for getting the direction.

The sonic anemometer uses the theory that you can measure the time it takes for sound to travel through the air (about 2938.6microseconds to travel one metre) and the delay it would experience if the air was also traveling against the direction of the sound waves (about 8.6 additional microseconds for each metre per second in velocity). These values should be no problem for an Arduino running at 16MHz frequency to detect.

The basic interface code to run the HC-SR04 is as follows:

float speedofsoundmps = 340.29; // metres-per-second
digitalWrite(triggerpin, LOW);  
digitalWrite(triggerpin, HIGH);
digitalWrite(triggerpin, LOW);
long timemicros = pulseIn(echopin, HIGH);
System.out.print("Distance (cm) = ");
                       // factor 2 because distance
                       // is there and back

The basic code for pulseIn() counts processor cycles for the duration of the voltage being HIGH.

Here’s my experimental setup using two such devices, one sending and the other receiving (though you do need to trigger both in order to arm the receiver). Note the desktop fan to generate the wind.

And these are the experimental results plotted over five minutes, making a reading 20 times a second for ten minutes.
The average time of 1545.7microseconds equates to 52cms, which is an under-reading as the actual distance is 60cm, but we’ll ignore that for now.

If we turn the fan on we get an average reading of 1551.7micoseconds with a higher standard deviation of 13.4 (not surprising as the fan air is chopped and turbulent) which is an average difference of 6microseconds amounting to a wind speed of about 2 metres per second, agreeing approximately with the figure from my mechanical anemometer.

I’m not interested in tracking down the source of the error or calibrating this setup while the readings themselves are so darn noisy and in excess of the signal I am attempting to detect.

What is the source of the noise?

Wednesday, August 19th, 2015 at 6:44 pm - - Machining

The limitations of the scipy.optimize.minimize() function has now become apparent. They should have called it localminimize() starting from an “initial guess”.

This follows on from the mess I made out of using this same function to calculate the circumcircle of a triangle.

Here I begin with a STL file of a widget which was then probed from 20 random directions to a distance (ball radius) of 5mm.


This was done using a my barmesh library that I ought to start getting back into as I haven’t touched it since I got distracted by all this arduino electronics.

The barmesh code itself is impenetrable when I looked at it recently, but use of its features is still possible.

Thursday, August 13th, 2015 at 5:27 pm - - Flightlogger

I’ve got a Global Top Inc FGPMMOPA6H GPS module (datasheet) in my hang-glider data logging device. Using the command packet:


I’ve programmed it to give me a GPRMC every 50 cycles, a GPVTG every cycle, GPGGA every cycle and a GPGSA every 10 cycles.

The command $PMTK220, 200 is used to set the length of the cycle at 200ms, so I’m getting a positional and velocity reading 5 times a second.

The code for controlling all this is here. Note that my code does not contain hundreds of lines of #defines of the form:


that you tend to get in other people’s programs for the purpose of referencing the this-will-never-change-hardware-encoded 3-digit string ‘314’ by the arguably more readable (ie I will argue with you) string ‘PMTK_API_SET_NMEA_OUTPUT’ that serves no purpose, isn’t interpreted by anything except the preprocessor, and you have to look it up to get back to the number that is actually documented in the manual. Why is this controversial? </rant>

Monday, August 10th, 2015 at 5:24 pm - - Machining

I failed to take a photo of the experimental set-up which the guy on the Newcastle stand at Manchester Makefest let me shove my airspeed probe into. The airspeed probe is described here and some interrupt timing misery to do with it (which I don’t know was properly solved) is reported here.

This is the track of the windspeed when it’s in the device, and then when we put a card across the air intake that roughly halved the flow.
The time interval is 5 seconds for every green vertical line.

The readings where it is flat and high (off the left of the diagram) have an average of 7.11m/s, standard deviation 0.11 over 60 seconds. The middle low section has average 3.26, sd=0.05 over 35 seconds. The final high value when I took the card off the intake was 6.99m/s, sd=0.077 over 45 seconds.

The tailing off of the wind speed measurements is probably an important factor.
Squashing the graph down the Y-axis and plotting the green lines at one second intervals, we can compare the two incidences where I put a card over the intake and halved the wind flow.

It takes about one second to settle, and the two curves don’t match up.

I can’t tell if this is due to the inertia in the propeller sensor, or inertia in the wind tunnel device when I cover it up making it sound like a blocked vacuum cleaner.

At least half is due to the latter, or the curves would be a better match because they’re smooth enough and the propeller inertia doesn’t change.

We’d need another way to more quickly vary the intake into the wind sensor. For example, we could rotate it slightly so that it picks up less wind. The engineer suggested introducing some controlled friction into the system to dampen the spinning so it responded faster. Alternatively there’s a pitot tube.

Of more immediate concern is the unexplained wandering around of the wind speed sensor by as much as 6% across multiple seconds of time. This can’t be turbulence in the device as it wouldn’t have such lasting effects.

Also, there are short bursts of zig-zagging every half second indicated by the red marks.

I’ve seen these zigzag effects before with the temperature measurements, probably caused by the interference with other devices on the same microcontroller, going into and out of phase with their interrupt cycles.

I don’t know of a mechanism for voltage changes to affect the rotating fan blades (like they did the thermistors), although something could be introducing small delays into the detection of the interrupt signals.

This would take a lot more building of separate interrupt-driven dedicated microcontroller circuits to test the theory. And then that doesn’t answer the 6% wandering.

I got to get back to other parts of the project, and look at this later when I have use for these measurements as well as a test rig.

Maybe there’s other technology, such as a thermal anemometer or a beautiful sonic anemometer that measures windspeed and direction instantaneously for a mere $2700. I haven’t got that kind of money to squander at the moment, but it does show what’s available.

OMG, what’s this publication I’ve just uncovered:

Sonic anemometer and atmospheric flows over complex terrain: measurements of complex flows

Three measurement campaigns and the use of sonic anemometry under specific conditions are described in this work. EBEX2000 was an international energy balance field experiment in San Joaquin Valley USA, were different sonic anemometer types, and heat and momentum flux measurements, were analyzed and compared. The second case was a complex coastal flow at Madeira Island, Portugal. The complexity of the flow compromised the performance of an existing wind farm. The use of post-processing techniques, such as Fourier and wavelet spectral analysis allowed the detection, and unveiled, the existence of coherent structures and other specific features of that wind turbine site. The flow over the mountainous terrain of Madeira Island is also presented for the latter case, where sonic anemometer measurements were executed at wind energy resource assessment phase.

I found some excerpts of the book where they are discussing the instruments. Taking some liberties with the text, there is:

As discussed in chapter 3 the sonic anemometer measurements have to be corrected due to transducer shadow effect and overestimation of measurement due to flow acceleration through the transducer array…

The cup anemometer systematically overestimates the mean wind velocity compared against the sonic… Wyngaard (1981) showed that cup anemometers respond faster to wind speed increases (u > 0) than wind speed decreases causing the anemometer to overspeed.

My anemometer is a propeller, which requires it to be pointed in exactly the right direction. This is not going to help when there is yawing of the glider of up to 80 degrees.

The interesting thing about atmospheric flows over complex terrain is that good glider pilots have the experience to guess the locations of up-currents by visual inspection and from what they know of the wind direction.

In the future the swarms of cooperating autonomous cargo gliders which connect the world together using zero energy (unlike the plans for drones) will be able to not only rely on thermal updrafts, but could also use dynamic lift by reference to weather stations dotted at critical places around the landscape to inform the flow model accurately enough to fly downwind with exactly the right height to clear the next tree line.

I’ve got to climb out of this rabbit hole now before it sucks me in for the rest of the week.

Monday, August 3rd, 2015 at 11:40 am - - Machining 1 Comment »

We will begin today’s rant (following last years post-quitting blog) by turning to Carl Bass’s favourite management consultancy firm, McKinsey&Company, and searching for “Autodesk” through the link:

to get 17 hits — 10 of which are for exactly the same page.

Well done McKinsey. I hope your internal document management system is better than the one on your webpage, given that your only purpose is to write commissioned documents.

The McKinsey article begins:

How big companies can innovate
Who says innovation is only for start-ups? In these interviews, the heads of three large, established companies — Intuit, Idealab, and Autodesk — argue there’s no reason big players can’t develop the next big thing.

First up is Carl Bass. What’s he got to say?

Monday, July 13th, 2015 at 7:05 pm - - Machining

Just how bad are these minimization algorithms

I’ve been caught short trusting these classical numerical recipes, packaged up in scipy.optimize.minimize and failing to get an adequate result in the case of the triangular machine tool calibration and its nine unknowns.

So here’s a simple example for finding the circumcircle radius of a triangle whose sides have lengths a, b, c.

Thursday, July 9th, 2015 at 1:45 pm - - Machining


Little to report from Austria. Shoddy internet over the road that cuts out after 2 minutes. Eight minute flight straight down (with cavers watching, wondering what’s the point). Days of rain when I worked on my electronic logging devices, all of which were broken in various ways, from short circuits (caught in time before the Teensy boiled its plastic off), broken I2C connections, a completely bricked BNO055 orientation sensor, and a slightly folded micro-USB card probably from when I accidentally drop-kicked the device on my way out the door which was causing of the short circuit. I debugged for six straight hours like a machine, and still it wasn’t enough.

There’s something making the microcontroller crash after eight minutes whenever the Serial1 connection to the GPS is opened, but it doesn’t happen when you run a program that just listens to the GPS only.

I’ve also done two carries up to top camp of rope and metalwork and my soles are now sore. Now I’m worried that I’m coming down with the lurgi just before I strike camp and head for better air at Greifenburg.

I think I’d better go jump in the river to chill everything out while it’s still hot.

Wednesday, July 1st, 2015 at 5:17 pm - - Machining

Over the last few months, well, since December, I’ve been producing an awful lot of plastic scrap from the UP! 3d printer we have here.

We had better find a way of recycling this soon. I’ve got my eye on the plastic injection moulding machine as a potential consumer.

Here’s the work bench of chaotic iterations of circuitry and boxes to contain the circuits.
To be clear, none of it does anything, except get data and log data to an SD card.

Occasionally it gets a short-circuit which crashes the microcontroller.

I now have two data logging devices. I am busy printing off further legs and hooks to glue onto the second black one on the right so it can be strapped onto another hang-glider, or to my hang-glider beside the primary device, which will mean that I have two sensor boxes measuring the same factors and coming up with wildly different results, thus proving that this kit isn’t as great as it appears.

Building stuff is a great way of putting off actually doing anything with the data. But once I am in Austria in a campsitte and away from DoESLiverpool and its tempting 3D printers, I won’t have the option to put it off anymore.

Friday, June 5th, 2015 at 3:39 pm - - Machining

This BNO055 absolute orientation sensor is just the thing I’ve been after for logging the hang-glider direction and heading. It combines the compass and accelerometer sensors into a single package with its own co-processor running proprietary sensor fusion software, so I don’t need to get into the business of decoding making sense of this sensor data.

The theory for calculating absolute orientation is as follows.

Absolute orientation is represented by three degrees of freedom: horizontal heading, roll and pitch. At rest (held within a particular orientation), there are two absolute vectors which can be sensed: the gravitational force (downwards) and the earth’s magnetic flux (about 23degrees off the down vector towards the north, if you are in the UK).

Knowing an absolute unit vector relative to your oriented frame constrains two degrees of freedom. Think of this as a fixed pin passing through your object like it’s a beetle on a specimen tray: the bug can only spin its body around the pin. Two such pins could nail down four degrees of freedom, but there’s only three, so the extra information is redundant and can be used to estimate the accuracy of the measurement.

Each of the sensors on the BNO055 device requires calibration, according to the datasheet:

3.10 Though the sensor fusion software runs the calibration algorithm of all the three sensors (accelerometer, gyroscope and magnetometer) in the background to remove the offsets, some preliminary steps had to be ensured for this automatic calibration to take place. The accelerometer and the gyroscope are relatively less susceptible to external disturbances, as a result of which the offset is negligible. Whereas the magnetometer is susceptible to external magnetic field and therefore to ensure proper heading accuracy, the calibration steps described below have to be taken.

I’ve been logging the quaternion heading from this sensor and then trying to relate it to the motions I was making. Unfortunately, sometimes there was a complete sudden reversal of the orientation mid-flow, even though I wasn’t making any sudden motions:

Here’s the log from this moment that occurred at the timestamp=61350

tstamp  qw  qx    qy   qz     mag calibration status
61050 15158 336   41   6208   1
61150 15419 431   103  5522   1
61250 15664 510   164  4774   1
61350 722   234   -654 -16353 2
61450 244   -530  777  16355  2
61550 1460  -929  852  16270  2
61650 2277  -1019 921  16167  2
61750 3023  -1249 1137 16014  2
61850 3509  -1358 1335 15890  2
61950 4023  -1386 1477 15753  2

Funnily enough, for such a complicated packaged system, there are absolutely no configuration settings at all — except for one option known as NDOF_FMC_OFF, which is “the same as NDOF mode, but with the Fast Magnetometer Calibration turned OFF”. (NDOF stands for “9 Degrees of Freedom”, which I guess refers to the fusion of 3 magnetic flux axes, 3 accelerometer axes, 3 gyro axes into a single measurement.)

The fact that you can turn off the so-called “Fast Magnetometer Calibration” mode suggests there is something special about it: ie it might be buggy.

Anyway, I don’t have time to check out what this does otherwise. I’ve wasted enough on this already. I should go look at something else.

Which of course means I’m just putting this off till I have some logged flight data. Which might be complete junk.

Wednesday, June 3rd, 2015 at 12:33 pm - - Machining

This diagram is for reference, made using the 2D constraint editor in OnShape and then annotated with gimp, which I really cannot get along with.


Origin at O with y-axis along Y being the side of the table, because we want to solve this by fixing the job to be machined in the fixed coordinate frame and pretend that the machine and tool are swinging all around it.

The blue lines represent the triangular main frame (with three approximately known lengths of about 745mm), the green lines the arm (with two lengths and an angle). This carries the cutter at point P and its triangle pivots at the movable point A1 due to changes in the length of J1 representing the linear position of the ballscrew.

The entire blue triangular frame pivots around the fixed point A0 due to changes in the length of J0. The absolute offsets on J0 and J1 from their connection to the common vertex are also unknown, which means we have a total of 2+3+3+1=9 dimensions which we can vary in our calculation to calibrate. (That last dimension is the length of the fixed edge between O and A0.)

Given these numbers, the conversion code that is inserted into the controller LinuxCNC is here.

def abanglefromtriangleabc(a, b, c):
    return acos((a*a + b*b - c*c)/(2*a*b)) 

a = 743.5035783400  # sides of mainframe triangle
b = 754.8024952389 
c = 745.4991150306 

d = 697.7062405262  # length of O->A0
e = 695.5193939239  # length A0->"arm" 
f = 583.6487506837  # length A0->P
ah = 0.0764480526      # angle in arm 
tblx = 525.4558306022  # offset in j0 
armx = 396.1544040232  # offset in j1 

ab = abanglefromtriangleabc(a, b, c) 
ac = abanglefromtriangleabc(a, c, b) 

def convertJ0J1toXY(j0, j1):
    tbl = j0 + tblx
    arm = j1 + armx

    aTBL = abanglefromtriangleabc(b, d, tbl)
    aARM = abanglefromtriangleabc(c, e, arm) 
    avec = ab - aTBL; 
    pvec = avec + ac - aARM + ah 

    return (0 - a*sin(avec) + f*sin(pvec),  
            d - a*cos(avec) + f*cos(pvec))

The game we’ve been playing for the last few weeks is to probe a perfectly circular disk mounted on the table with a known diameter, read out a series of joint values J0 and J1 from about 60 different positions, write a function that uses the 9 unknowns to project these measurements into cartesian space relative to O and the axis Y and provide a value of how close we are to having the right circle, and then use scipy.optimize.minimize to pick the values which minimizes this geometric constraint.

Unfortunately, this doesn’t seem to constrain it well enough, for we are getting good fitting solutions where the lengths of the main frame triangle are far from 745mm.

So that’s where we are at this week. I think we’re going to sod the calibration for a little while and just machine some stuff anyway, even if it isn’t perfectly right.