Saturday, August 21, 2010

Mythtv and DVB entertainment.

I just spent a number of hours on a pleasant saturday morning trying to work out exactly why MythTV doesn't get program info for Channel Nine (in Sydney, Australia). I already knew this was because Mythtv was failing to parse the EIT data, and in particular, the SDT wasn't being found.

After a fair bit of poking around, re-learning the fragments of DVB that I have long since forgotten, compiling various hacks into mythbackend, I eventually worked out that it was looking for the SDT in the wrong transport ID.

Because mythtv (being the bastion of stunning design that it is), stores a NIT/TID (network id, transport id) per channel, and _also_ stores a TID into the multiplex table. So the channel table has lots of very fine NIT/TIDs which I checked until the cows came home, before eventually discovering that the code was also reading from the dtv_multiplex table.

One "update dtv_multiplex set transportid = 1056 where mplexid=24;" and I now have program schedules for channel 9. w00t!

Ok, this is a pretty trivial thing, and I don't actually care about the data: It's just that this has been non-working for many months, and every time I noticed it it irritated me that I didn't know why it was broken.

Now I do. So now I'm happy :)

Monday, January 11, 2010

Another thing to add to the list of "Life is too short".

Attempted to add an SVN project from http://code.google.com/p/project into Eclipse using the SVN plugin. Project is an android project.

Total failure. Eventually I got down to errors like:
java.lang.IllegalArgumentException: Path must include project and resource name: /android-l2tp-tether
        at org.eclipse.core.runtime.Assert.isLegal(Assert.java:63)
        at org.eclipse.core.internal.resources.Workspace.newResource(Workspace.java:1628)
        at org.eclipse.core.internal.resources.Container.getFolder(Container.java:137)
        at com.android.ide.eclipse.adt.internal.build.PreCompilerBuilder.buildAidlCompilationList(Unknown Source)
        at com.android.ide.eclipse.adt.internal.build.PreCompilerBuilder.build(Unknown Source)

Noting that there were a project called 'android-l2tp-tether'...
Eclipse is just too big, too clumsy, and too opaque to usefully debug. I wasted an hour wandering around with straces et al, but realized I was just wasting time. Copying the svn directory else, and then doing 'create new project from existing source' was instantly successful. ugh.

Saturday, January 9, 2010

Unit tests

Gradually coming up to speed on gtest (google c++ unit test framework). Yes, I'm know I'm painfully behind...

And retro-fitting unit tests to existing code isn't much fun. However, it is entertaining for the number of latent bugs it finds! There's always something special about output like:
[----------] 2 tests from Image
[ RUN      ] Image.Empty
Segmentation fault (core dumped)

Noting that the unit test in question creates an unparametrised object and inquires as to it's size. :)

Off to fire up a debugger and find out wtf is going on.

Sunday, November 15, 2009

Bayes and models.

This is me talking to the pumpkin (aka thinking aloud).

I have two models.
One is that everything is noise, and has a discrete distribution over a grid.
One is that there's a pattern and predicts the future location of an event.

Bayes says the posterior probability of the model is:
   P(M|E) = P(E|M)P(M) / P(E)
where
   P(E) = P(E)P(M) + P(E)P(!M)

Ahhh. I realise my mistake. P(E) is not the ideal probability of the event, but the much more restricted 'probably of event in the space the P(E|M) is measured '.

In my case, where the distance between the predicted location and a movement event is being considered, the underlying distribution is the expected distance to a movement events, independent of the model.

I.e. Have no model. Just measure the expected distance from random points to movement events to build the model. Then seperately build the same model specifically for known model conforming events. That generates P(E) and P(E|M).

Doh. For some reason that took a very long to sink in.

Thursday, July 30, 2009

HAL sucks

So you have a touchscreen, and a 'modern' X11 installation.

Your 'modern' X11 knows that actually configuring devices is something that people who live in caves do. 'Modern' X11s use HAL!

Unfortunately, the nice 'modern' X11 installation is borked. It's talking to HAL which is telling it to use inputs/event0. Which doesn't actually exist.

So the question is: How do you tell it to use /dev/inputs/event2 which is a working touchscreen?

Ahh, you might ask. What you really do is spend far too much time searching google and eventually arrive at:

<?xml version="1.0" encoding="ISO-8859-1"?>
<deviceinfo version="0.2">
<device>
  <match key="input.product" contains="Touchscreen">
    <merge key="input.x11_driver" type="string">evdev</merge>
    <merge key="input.x11_options.SwapAxes" type="string">true</merge>
    <merge key="input.x11_options.InvertX" type="string">true</merge>
  </match>
</device>
</deviceinfo>

Which you install in /etc/hal/fdi/policy/touchscreen.fdi

Of course. it was obvious from the very start that this was the thing to do, no? And the documentation has zero mistakes or misspellings in it. A remarkable end it achieves by being non-existant.

Sunday, July 12, 2009

Rust as far as the eye can see.

Having many adventures trying to compile a new kernel for the DevKit8000

embest haven't submitted the board support to mainline and after reverse engineering their patches, it's easy to see why!

The diff is littered with random patches to random files (that aren't used), #if 0'ed code, and cruft like:


 #ifdef CONFIG_OMAP_MUX_DEBUG
-       debug = cfg->debug;
+       //debug = cfg->debug;
+       debug = 1;
 #endif
        warn = (orig != reg);
-       if (debug || warn)
+       //if (debug || warn)
                printk(KERN_WARNING
It's been about  two hours work to separate out the parts that actually do something, and port them forward to a 2.6.30 kernel.

Which brings me to a confession: I just realized it's been something like 3 years since I last ran 'make menuconfig' on a linux kernel. The rust! It burns!!

Saturday, July 11, 2009

DevKit8000


I recently ordered a DevKit8000 development board for use in an embedded image processing project I'm looking at.

My DevKit8000 arrived yesterday. I bought the "yes, I will have fries with that" version, so it has the 7" touchscreen, more cables than you can poke a stick at, 512MB sd card, a USB hub,  and 2 power wall-wart power supplies.

Total cost was $AUD420 including DHL shipping of ~ $AUD80. The price for the board board is comparable with the BeagleBoard, but the shipping was cheaper and easier from China than it would have been from DigiKey! So I'm pretty happy with the price.

One of the power supplies has a USA plug, the other is something European.
The one with the USA plug is apparently the board power supply, the other is probably the USB hub power supply (at least, the plug doesn't fit the board).

The board itself had Windows CE loaded in NAND flash out of the box, which sent me on a 4 hour trail of destruction trying to replace it with linux. This was mostly due to me not realising that the sd-card that comes with the board is junk, and in addition to being unreliable, doesn't function at the 3.3V the OMAP processor requires for it to be booted from.

Not realising that, I thought that I must be doing something wrong (which given the .. umm.. erratic number of the board documentation wasn't unlikely) and so tried all sorts of things in an effort to re-flash the NAND X-loader, cumulating in formatting the NAND flash and rendering the board entirely unbootable. Waving aside the blue air, I finally did what I should have done to start with, and use a known-good SD card. Which instantly booted correctly, taking another 2 minutes for me to reflash the x-loader, u-boot, uImage and filesystem. *&^*&^*&^&*!!!!!!!

With the board actually booting and running linux, it was much more useful. It immediately come up on the ethernet with an ifconfig+route making it a lot faster to move images around than the sd-card sneakernet I had been using.

The CD that comes with it has a port of Android which functions rather well and was useful is checking that the touchscreen actually works.

The hardware appears to be fairly close to the beagleboard, except that it also includes an on-board ethernet, and a ZIF socket for a camera input.

There's a couple of odd things: The host USB port (as opposed to the OTG USB port) appears to be missing a chip. The pattern is there for it on the board, and all the pad have solder on them, just not chip. This is not entirely unexpected: The USB Host port isn't listed in the feature list, and the BeagleBoard people have had trouble getting it reliable.


The more concerning one is that one of the power regulators (TPS73701) has a terrible soldering job done on it. It looks like there may have been a solder mask problem and FAR too much solder paste was dumped on. The tab is swimming in solder, and leads look like they didn't quite reach temperature to fully melt the paste. This is one of a two parallel regulators, and the other one is spotless, so I'm a little puzzled as to what went wrong with this one. Both are running the same temperature so it appears they're both working, it just looks terrible.

Other than that, the rest of the board looks clean and well put together.

Now I'm off to setup a cross compiler environment!

Belated files

Very belatedly getting around to posting these.

The Eagle CAD files for the relay driver board is now posted at https://sites.google.com/a/dgmo.org/home/Home/boards

Friday, April 10, 2009

Noise filter your signals!

Free advice. When there's a 200m loop of wire carrying a low voltage signal, noise filtering is a _very_ good idea.

Otherwise the doorbell may ring at 3am in the morning from induced noise...

Sunday, April 5, 2009

'Fixed' the doorbell today.

The doorbell has been a source of trouble for a while. Mostly because D is in the habit of closing every between where she is and the front door, causing it to be inaudible.

So today, I wired the doorbell between the DCD and DTR lines on the main fileserver and wrote a little C program effectively gets an interrupt when DCD changes. When triggered, this program runs wget to hit a URL on another server, that runs a cgi-bin script, that plays a .wav file through the speaker.

For some reason the name 'Reuben Garret Lucius Goldberg ' kept running through my head...

But the end result is that one can push a door near the front door, and something near the center of the house chimes, so the end goal is fully achieved!

Saturday, April 4, 2009

Clipsal C-Bus

Clipsal have decided to open the C-Bus protocol.

http://www.cbusforums.com/forums/showthread.php?t=5022

Speaking as someone with a C-Bus wired house (for reasons that were never terribly good), this is a very, very good thing.

It's rather unexpected, and I suspect a little late (there's considerably more competition around now), but it's going to make it much easier to do semi-decent integration.

Yay Clipsal!

Monday, March 16, 2009

Adventures in Switzerland.

Currently in Zurich.
R is here for first time, so wanted to do a little wandering around.

Had very vaguely hatched a plan to visit Pilatus, a mountain not too far from Zurich. The plan was to catch a train to Luzern, bus to the cable station, and then cable car up Pilastus.

The morning started off to plan: We managed to leave the hotel vaguely sort of on time, made our way to Zurich HB (Central train station), and found food at McDonalds. (hungry people do desperate things).

The first sign of trouble was attempting to buy a ticket to Luzern. This involved much fighting with the ticket machine. Firstly it didn't like anything. This was solved by actually pressing 'OK' on the screen before attempting to hand over money. Then it refused my visa card many times (in various orientations), then it wanted a pin (which I don't have), then rejected my EFTPOS card as unsupported (the pin for which I did know), R's visa card (it wanted a pin which he didn't know), and various other random pieces of plastic we attempted to feed it. Finally R found some cash and fed it that, which is liked, ate, and dispended tickets. Yay! For a train that was due to leave in 60 seconds. On a platform far, far away.

Sprinting for the platform had us there just in time to see it leaving in the distance. A 30 minute wait...

The trip to Luzern was very pleasant. The trains are very quiet and nice, and the scenery is picturesque. Did a few sudoku puzzles which R had infected me with, and we arrived in Luzern in short order.

Wandering around looking for things bearing the name 'Pilatus' had us finding the S31 bus which ran to Pilatusmarkt. Very promising. So we walked to the 6 blocks to Pilatusplatz, found a bus stop (yay), found the S31 stopped there (yay) and it was due to arrive in 6 mins (yay).

15 mins later, it was pretty clear that the S31 wasn't. The timetable insisted that all was well, but no bus. So we decide to take the S20, change to the S21 and we'd be fine. S20 was good. Actually did arrive, did travel in the right direction. Alas, we fell to talking and missed the stop. So getting off at the next stop decide to 'just walk back. Not far really'. About 15 mins of walking led us back to the stop for the S21. Which was due to arrive in a little over an hour. argh! Ok. Another change of plan. Now we'd take the S16 which looked like it also went to Pilatusmarkt and that one was only 6 mins away.

Bus arrive. We get on bus. Bus travels about 300meters to Pilatusmarkt. We get off. Find we are at deserted shopping center. Close for the sunday. Named 'Pilatus Market'. Doh! Turns that that many random things around Luzern are named after the mountain.

Now very lost, with the next bus not due to 60 mins, we decide to walk back to where we caught the S16. The horrendously unreliable map (scale optional) claimed a nearby train station.

20 mins of walking, we are at train station. We had originally intended to catch the train back toward Luzern, but there timetable had various stations marked with a cable car symbol. How exciting! Which led to R get excited about visiting Engelberg, and maybe wandering up Titlis, a 3000m high mountain.

More tickets, more fighting with ticket machine, eventually discovered that it enjoyed amex cards. Wait for train. Train takes us along a very pretty route. Alongside a lake, wending through valleys. And then turned into a cog-train for a while! Seriously steep assent led us into some stunning scenery (sorry, no photos yet) .

Engelberg was less interesting, but they really did have a cablecar up the mountain (actually, many many cable cars up many slopes). We caught one to Gerschnialp, about 1260m above sea level. Normal hairy cable car ride put us in some fairly serious snow. With us wearing jeans and tennis shoes...

We had a really good time. Walked along a snow trail for about 20 mins a small restaurant in the middle of no-where , had a fairly ordinary lunch (which cummulated with them refusing to accept anything except Amex, where the amex could only be used for bills over 50CHF [ours was 33CHF], and we had no cash left...) we then set off to walk down the mountain.

This was hugely enjoyable. A snow trail wandered down the mountain through forests et al. Most of it was fairly well packed snow so it wasn't that bad to walk on. Most of the other people we saw were wearing snowshoes, but they clearly envied our minimalist approach to snow hiking.

About 1/2 we down, we found a ski-jump! A truly terrifying affair. Seeing them on television can't convey just how insane they are. Standing at (well, near) the lip of the jump, you can't actually see any of the slope below, just the flat field far below. Actually: far, far, far below. I was having trouble with the heights just standing near the edge of the jump. I can't imagine just how certifiable you'd have to be to actually go down it on skis. Simply amazing.

It took a bit over an hour to walk down the mountain. Followed by a sprint to catch the train back to Luzern (more stunning scenery), and then the train back to Zurich, and then another train back to Stadelhofen.

Hugely enjoyable day; Now very, very tired. Goodnight.

PS: No, never did find out what happened to the S31 bus.

Sunday, March 1, 2009

Puzzle Piece


Just spent a few enjoyable hours making this exercise. "How DID the nut get on there?".

It's puzzle piece to which the photo doesn't do full justice. There's a no visible joins in the threaded piece: It looks seamless.

It's a nice exercise in lathe work with a number of tricky bits. The facing needs to be very good, threading interior sections is a generally a bitch to do, especially in stainless steel. And then finishing it all to the mirror polish (which you can somewhat see in the high fidelity reflection at the end).

I'm quite pleased with it because I pretty much got it right first time, it turned out well, and the polish came up far better than I was expecting. I keep underestimating how far the buffing wheel will cut.

Friday, February 13, 2009

Audio over HDMI

Noted here mostly so I can find it later.

I have a Gigabyte motherboard, the GA-G33M-S2H, that I use for a HTPC (home theater pc). It lives under the couch, driving the LCD TV, diskless, quiet, and is generally pretty happy.

I bought it principally because it has on-board video that does HDMI with an intel chipset. The intel graphics chips are pretty well documented and Intel fund development of linux drivers so it was a fairly easy choice at the time.

When I first turned it on about a year ago, the video of HDMI turned up right away. Very easy. 1080P @ 50Hz is very nice.

Alas, the audio didn't work. At the time, there were bugs in the ALSA drivers that prevented the properly detecting the (seperate ATI) chip that handles audio encoding for the HDMI data stream. After mucking around with it for too long, I gave up and ran a DVI cable and an audio cable to the TV instead. Which had it's own mucking around to get 1080P working on a single DVI channel...

Coming back to the present, I had occasion to revisit my MythTV setup, due to the "urgent need" to repaint the wall. This mean the TV cable down briefly, and stirred me to investigate if the audio HDMI is fixed.

Yay! It is, as of ALSA 1.0.17. Which is in Fedora 9 which I upgraded to a while back, so the kernel already knew about the HDMI audio and was ready to use it. Sweeet.

But. There's always a but. Pulseaudio, the apparent audio hub of choice didn't know about it. After poking, peering and prying at the config, it was clear that HAL did know about it, but pulseaudio refused to use more than the first device on any given soundcard.

As the HDMI appears on this motherboard as hw:0,3 (3rd device on card 0), pulseaudio via HAL refused to have any truck with it. This turns out to be a known, very long standing bug in pulseaudio.

My hack solution: Boot the HAL module in pulseaudio out the door, and just hardcode the detection for the device. Which said that it worked, but didn't produce any sound. After even more trawling, it turns out that I needed to unmute the "IEC958" in the ALSA mixer.

And now it all works! HDMI, 1080P and audio over a single cable.

Saturday, February 7, 2009

Tapping ACME nut.

 
 
 


The short story is: I re-tapped the acetal nut for the X axis to an ACME thread.

The longer story involves much pain. :-)

To re-tap the nut to ACME thread involved making an ACME tap. (off-the-shelf ACME taps cost ~ $400 which is a bit much for a one-off). Making an ACME tap seemed very simple: Just cut a piece of thread rod, grind a taper onto it, and then grind an edge. No worries, right?

So being a doofus, I actually did grind the taper, but in a way that involves destroying my finger tips along the way. I made a simple jig with bearings that allow me to rotate the rod against the grinder. The idea was to let the rod spin against the grinder, ensuring that it would be ground evenly and giving an accurate taper.

In practise, the rod spun much too fast, and in reaching out to slow the spinning rod, I found out that rolled ACME thread has fine burs along the thread edges. Some of them relatively large. As I can measure by the many fine cuts in my finger tips....

I started grinding an edge on the rod as well, but I really need a diamond cup grinder to do the postive rake. After mulling it over, I slapped myself upside the head, and just milled the edge onto it. The ACME rod I have isn't ground, nor hardened, so milling it is fine. I just used a carbide boring tool to cut the postive rake.

Once I'd actually managed to wake to using the mill, it all went fairly fast; Just cut the edge, polish it up a bit with the diamond lap, then bung it on the lathe and it's done.

Well, almost. The amount of plastic being removed is fairly large and the taper on the acme isn't as shallow as it should be, so machine tapping it mostly out. I used lathe power to get the tap started, but then using a spanner to turn the nut by hand to cut the thread.

The end result is fairly good. It's a relatively loose fit, so I'll need to add an anti-backlash nut at some point, but the tap itself worked well.

Thursday, February 5, 2009

Bearing mounts





Last night I made the two new bearing mounts. These are brackets that hold the angular contact bearings for the ACME rod. The task was to bore a 16mm hole for the rod, and then a blind 30mm hole for the bearing. The 16mm through hole had no real accuracy considerations, but the 30mm needed to be 29.99mm so as to ensure that the 30.00mm bearing were a press fit.

I had originally planned to do this using the boring bar, but on reflection realized that that would make it difficult to do the accurate flat base required to support the bearing.

So I got out the rotary table. Now normally the rotary table is a pain in the butt to use. Partly because it's difficult to clamp things on my relatively small table, but mostly because I'm terribly slow at indicating the part to be aligned with the table center. I'm just awful; it normally takes me more than an hour to get terrible accuracy. And thus I avoid it like the plague.

My brain wave was to use the lathe to made a trivial jig; The table has a 17.50mm hole in the center, and my part already had a milled 16mm hole in the center. So I made a piece of delrin (plastic) that was just a short section of 17.5mm dia, stepping down to 16mm dia.

A few taps with the mallet inserted it into the table, and then the blanks were a press fit onto the 16mm section. Instant alignment. Yay!

Even better, this made clamping much easier as I just needed to clamp at one point. Much win all around.

Actually milling the blind 30mm hole was then pretty simple. Just offset a 12mm end mill 8.950mm from the center, mill 5mm into the blank, and run the table around a full 360 degrees. Easy.

The slow bit was getting the hole to be a solid press fit for the bearings, and 29.950mm is much too small. So I increased the hole size in 10 micron increment thru to 29.990. At which point the bearings went in with about 200 newtons of force. Perfect!

I think this is some of the more accurate milling I've done. I'm pretty happy with how it turned out.

Sunday, February 1, 2009

Bearing jig



Dichro milled this up from a scrap piece of aluminium bar. 10x50mm flat bar, drilled with 16mm hole, then added 4 x 7mm holes on a 25x25mm square. M6 bolts, some washers, some skate bearing.

Ta-dah!

Worked extremely well. Should have done it sooner :)

Maching ACME threaded rod


ACME threaded rod, cut to 1150mm long, first end machined.

The 0.5 inch ACME was turned down to 10mm to match the inner diameter of the bearing. It was then threaded to M10 for ~ 30mm to allow for the lock nuts to go on, and then turned down to 4.75mm for the last 10mm to match the coupling for the motor shaft.

The metal was a serious pain to machine. Owing to the length (> 1 meter) I was running the lathe at fairly low speed. The steel work hardened VERY easily, and it's very flexible steel. This meant that it was just as easily bent away from the lathe cutting tool as cut. And it was threaded to boot, which mean highly variable loads on the initial cuts...

I ended up using the live center to attempt to hold it in place which improved matters a little, but not much.

Eventually, I used a handful of skate bearing to make up a jig to support the other end, which let me run the lathe much faster, which made the whole thing easier to do. I was initially turning it at 220 rpm with HSS cutting tool. Running it at ~ 480 rpm was dramatically easier.

The threading was done with a 60degree lathe tool, mounted upside down, with the lathe running backwards. I threaded it in until it "looked done", and then cleaned up by running an M10 x 1.5 die over it. Worked very nicely as I didn't need to try to fight workhardening steel with the die getting an initial thread.

Now to make the bearing brackets...

Saturday, January 31, 2009

ACME threaded rod.

I bought it from

Bomond Trading Co Pty Ltd
49 Orchard Rd, Brookvale, NSW 2100
p: (02) 99391344


1/2 inch (12.7mm) ACME threaded rod (aka leadscrew), 10 tpi (10 turns per inch). This is rolled rather than ground so it's less accurate.

The chap at Bomond was very helpful; I phone up on thursday, he said it was a speciality item, but he could get next day. I went this on saturday (this morning), and picked it up. The length of leadscrew and a handful of M10 nuts was under $AUD100 so I was pretty happy. It was the closet place in Sydney I could find to supply it. There's a number of other places I'd found, but they were a long drive away.

The only fly in the ointment was that I was expecting it to be a 3 meter length, but it was actually 12 foot. For some mad reason I'd heard "12 foot" and mentally translated that to "about 3 meters". Of course, it's actually about 3.7 meters, which is longer than will fit in the car.

Bomond didn't have cutting facilities, but I was on my way to Edcon Steel to pick up some aluminium flat bar, so I just left it poking out of the boot of the car a bit while I drove around the corner and asked the chap at Edcon to snip 1150mm off one end for me. Nice and easy.

Wednesday, January 28, 2009

Stepper motors

The stepper motors I have are Linengineering 4118S-62-07 motors. They were a surplus item, so unfortunately the datasheet doesn't seem to be a very common.

My motors are rated for 2.5A per phase, and a resistance of ~1 ohm is cited in a catalogue with a ~3.6Kg-cm torque.

Looking at http://www.linengineering.com/site/products/4118.html and extrapolating a bit, my motor would be something like the 4118S-04V, or having approx the same torque the 4118S-04P does, just at twice the rpm.

So when I'm running my mill at 2000mm/sec on a 1.25mm pitch, that's about 26 revs/sec. Which would be something like 1600g-cm of torque from my wild guessing and eyeballing the graph. Which, frankly, isn't too bad at all at all!

If I get this ACME at 10tpi (or 2.54mm pitch), I should be able to run a similar speed, but at 13 revs/sec and ~ 2200g-cm of torque. When is very reasonable indeed. Ok, I'm sold.

Now I'm off to buy some 3 meters of ACME threaded rod.