Wednesday, January 28th, 2015 at 11:52 am - - Machining

As I suspected, this is where all my grand designs go completely wrong. Recall that I proudly got the wind speed probe to convert each passing of the fan blade into a square wave voltage spike earlier this month.

Well, the reading of this signal was to be done with the following code:
(more…)

Friday, January 23rd, 2015 at 11:25 pm - - Machining 1 Comment »

After spending a few days with all my bits and break-out boards in a bowl and stirring them around aimlessly, I got all the major SPI components lined up on a breadboard, like so:
breadversion

That’s an SD card writer, an OLED screen display, a bluetooth low energy and a GPS module.

The additional devices are on short 4-wire phone leads in plastic printed boxes of dubious design.

After a great deal of unplanned soldering and the use of header sockets so that none of the bits are permanently stuck in the wrong place, I’ve got a thing that looks like this:

breadversion2

There are issues. The barometer has a separate power supply and now doesn’t communicate, the wind-meter has a degree of noise in its signal, the I2C accelerometer is too complicated, the dallas temperature sensors can only be read one at a time, and all three SPI devices are incompatible with one another.
(more…)

Sunday, January 11th, 2015 at 9:10 pm - - Hang-glide 1 Comment »

By not including a datasheet with their airspeed probe, Brauninger/Flytek gave me the pleasure of two successful days of hacking involving an oscilloscope and much experimentation to work out its parameters and build a circuit to exploit them.

I bought this thing as an optional add-on to the Flytec 6030 (which I’ve never got to grips with) back when I had more money than sense. I wouldn’t have got it for the purpose of reverse engineering like this because I couldn’t do electronics then, and anyway I’d have rated the chances of success as quite low.

Nevertheless, by applying various voltages and different directions and blowing on the propeller to get a response, I established that if you apply a positive current on the tip of about 1Volt (and ground the other connection), the device exhibits a resistance of between 11200 Ohms and 12000 Ohms, depending on the position of the blade.

This was a job for a Wheatstone bridge:
wheatstonebr

You can actually see the voltage differences (in millivolts) over 1/12 of a turn of the propeller:
proplowvolt
prophighvolt
(more…)

Monday, January 5th, 2015 at 9:00 pm - - Machining 1 Comment »

It’s been a lot of work, and I need a break. This has now outperformed my target over New Year period moping around Bull Pot Farm while everyone else goes caving.

I am now able to make numerous slices on this impellor model made of 38474 triangles with an angle change tolerance between contour sample points of 18degrees in about 5 to 10 seconds per slice using Pypy (or 80 seconds in Python3). The code is at bitbucket.org/goatchurch/barmesh. Use it at your peril. It’s just beginning to work, and the next thing I will do is break it.

Here are some pictures of the results of slicing an impellor shape that’s 20mm in diameter with a sphere of radius 0.2 using the command:

pypy -O main.py –stl=stlsamples/impellor1.stl -v -tswapyz -r0.2 -n52

slicer02surf
Slices with ball radius 0.2 with the STL model shown

slicer02nosurf
Offset slices without the STL model so you can see all the internal contours from the ball rolling along the inside surfaces of the model. These internal contours will need to be detected by connectivity and deleted.
slicer02top
View down the top so you can see the inner and outer offset slices of the central cylindrical through-hole.

From my initial profiling, 99% of the time is spent in the two functions MakePointZoneRF() and CutbarRF(). This is fantastic news as this is where all the point-line-triangle distance/offset-intersection calculations are done. And it’s intended to be very GPU-friendly. (I don’t actually have any experience with GPUs yet, but it could happen now I’ve got a real world use case.)
(more…)

Tuesday, December 30th, 2014 at 2:27 pm - - Cave

This trip round the Lleyn followed on from last year’s Avoiding Nadilog by Walking in Wales. In retrospect nothing much happened. But it was exciting at the time due to the lack of planning and the risk of things going wrong.

whistlesands
Our white Xmas on Whistling Sands

Departure was delayed till the morning of the 24th because someone couldn’t possibly miss their 14th digging trip of the year in ODB. Anyway it was raining and we weren’t packed yet.

(more…)

Tuesday, December 23rd, 2014 at 7:39 pm - - Machining

I printed this beautiful box for my speedy accurate barometer at the DoESLiverpool Xmas party designed on Openscad.

greenprinting
(more…)

Friday, December 19th, 2014 at 9:46 pm - - Machining

I’ve been having “fun” trying to deal with the noise on the MS5611 altitude sensor. It’s an extremely accurate piece of kit (detecting approx 10cm of altitude). Last month I discovered that it is very sensitive to its own working temperature, which depends on how frequently it is read. You miss one interrupt and it throws everything out of whack.

So I got one of these Adafruit Trinkets, which is a tiny microcontroller board just to poll the barometer on a timed loop, and attempted to bit-bang the values down one of its output pins to a digital read pin on the main Arduino. Here’s what the the code looks like:

void sendbitbangbyte(uint8_t v)
{
    digitalWrite(PinOut, LOW); 
    delayMicroseconds(BITTIME); 
    digitalWrite(PinOut, (v & 0x01 ? HIGH : LOW)); 
    delayMicroseconds(BITTIME); 
    digitalWrite(PinOut, (v & 0x02 ? HIGH : LOW)); 
    delayMicroseconds(BITTIME); 
    digitalWrite(PinOut, (v & 0x04 ? HIGH : LOW)); 
    delayMicroseconds(BITTIME); 
    digitalWrite(PinOut, (v & 0x08 ? HIGH : LOW)); 
    delayMicroseconds(BITTIME); 
    digitalWrite(PinOut, (v & 0x10 ? HIGH : LOW)); 
    delayMicroseconds(BITTIME); 
    digitalWrite(PinOut, (v & 0x20 ? HIGH : LOW)); 
    delayMicroseconds(BITTIME); 
    digitalWrite(PinOut, (v & 0x40 ? HIGH : LOW)); 
    delayMicroseconds(BITTIME); 
    digitalWrite(PinOut, (v & 0x80 ? HIGH : LOW)); 
    delayMicroseconds(BITTIME); 
    if (v & 0x80) {
        digitalWrite(PinOut, LOW);
        delayMicroseconds(BITTIME); 
    }
    digitalWrite(PinOut, HIGH);
}

Sensible programmers wouldn’t do this because they’d use one of the many standard libraries available that operats on a standard protocol. But I wanted to tactically slot this into the main loop that polls and waits (9 milliseconds) for the barometer/thermometer to make its reading with the minimum disturbance possible. It’s important to keep everything regular and synchronized.
(more…)

Friday, December 12th, 2014 at 9:02 pm - - Machining

The fact is that this is probably what most visitors to this blog are going to be most interested in.

I’ve another session hacking the barmesh slicing code, which is now creating these interesting subdivisions:
closeslicesubdiv

It can even generate 17 slices of a part without crashing, though it takes a few minutes:
impslices7

It’s still only testing against the points, and not the edges and faces (hence the arcs), but that will only make it crash less as the shapes will be smoother.

It’s a little unclear what to do next. Maybe I should tidy the code further and clear up all these special cases I’ve been hitting and had to hack in to make it work. When a subdividing line crosses the r=0.5 threshold and I calculate it’s location, I’m setting it back to exactly 0.5. I don’t think this is the most reliable way to make it work.

The crucial functions are:
(more…)

Sunday, December 7th, 2014 at 4:14 pm - - Cave, Kayak Dive, Machining

I’m going to do some other coding, now that I got this result. The code would fall apart if I touched it again.
impslicesubdiv

Next on the list of things to do is clear out the vast quantity of rubbish left in the code, completely redo the subdivision loops and make the logic robust, apply it to multiple z-levels and plot slices, then make it test against edges and faces (not just points), and package it into a self-contained (but very slow) version of the slicer.

I don’t know how long this will take, as there are many other distractions available.
(more…)

Wednesday, December 3rd, 2014 at 7:43 pm - - Machining 1 Comment »

By popular demand, I am working on a new Z-slicing algorithm, which is open source and in Python and can be found here. (My latest parts order is taking too long to be picked and come in the post.)

The code is not in any state to be used by anyone as I conduct some very meandering software development. I am unexpectedly basing everything on these BarMesh structures. This is a neat way to represent a triangulated manifold, such as the STL triangle file that contains the 3D input geometry. But also, instead of basing the slice on a strict XY grid (or weave) as I’ve done before, I’m using a second BarMesh to handle the 2D partitioning of the plane.

impellorslice1

I don’t really know what I am doing, but if it gets messy and results in malformed folded cells, at least I can choose to constrain the BarMesh to conform to an XY grid weave structure, which I know works.

I’m just slicing (with a radius) against the points in the input geometry as this creates a more difficult slice geometry to begin with (here it’s an impeller shape with 38474 triangles, so I’m not starting with a toy example).

When the slicer is working, I can extend the code to test against the edges and faces of the input geometry.

I’m going for simplicity, and not being too constrained by speed or memory useage. There’s a lot more memory available than we need, and I’m counting on investigations into some weird Python compiler systems to provide the performance of C++, without the disadvantages of using C++.

I maintain the fact that if you take away the speed advantage of C++ on a particular platform, it loses its point of existence. Therefore the question of whether you should be using C++ is not to be found by looking at C++ itself, but by trying to beat what it supposedly does best using another language.

I can’t predict what will win. But the experience I am about to have ought to be extremely relevant to a programming team that is starting a new product and is having to choose what language they commit to.

This particular slicer will be for 3D printing and it will not notice the problem of mismatching triangle edges or self intersecting input geometry. (Self-intersecting inputs can come when you throw in some support structures.) It will be optimized for taking hundreds of slices and different Z-levels. It will work by finding the offset surface at a particular radius, and then offsetting back in by that radius to get the “true” surface, after the interior contours have been identified by tracking them up and down in 3D to prove full enclosure.