Tuesday 2 September 2014

LTP 750 Pump bearing replacement

Leisure Time Pump repair - LTP 750

A while back I scored a nice second hand pool pump courtesy of a friend that sensibly recovers gems like this from the local council roadside collection (thanks Mark). Anyway, it found a new life as part of my cobbled together pool filtering system along with a number of other second hand pvc pipes, connectors and valves.

The arrangement has been running well for a couple of years now keeping our $200 kmart kids pool nice and clean, however, recently it started making an ever increasing whine that eventually got to the point where I could hear the resonant frequency from the front street.

Not normally being one to delve outside the realms of computer software and electronics, I decided I'd take a shot at fixing it. Maybe it was something simple I could squirt some oil into. (Ha Ha)

pump assembly removal

Ok a few bolts and the pump assembly separated from the motor body, so far so good.

Now to remove the impeller... hang on no nuts, bolts, screw heads... Hmm if I force this thing I'm likely to break something and then I need a new pump.

impeller removal


A quick search on YouTube and I discover these The amazing Pump Guys and six or seven instructional videos later I found myself educated enough to get down to the rotor. At this point the source of the noise became apparent. A 6202 bearing on the front side. Ok time to invest in a bearing puller and a new bearing from my local BSC bearings

Getting the bearing back on the shaft was nice and easy using a bit of old pipe that Dad turned up on the lathe for me. A few careful taps of the hammer moved the bearing nicely down to its seat.

bearing pipe press


Now for the re-assembly. There are four long "through bolts" that hold the ends on the pump and keep the armature centred, the bearings press fit into recesses in these pieces of cast metal. I first tried pulling it together by assembling and then tightening the bolts, however, the armature was binding so I loosened and started again, this time tapping with a rubber mallet.

Weirdly, each time I got the case back together it would spin freely until I tightened, and then it would bind. I tried rotating the back and it improved slightly. (The front has a drain hole that needs to point downwards so it has only one way it can go on)

Time to spin it up (fingers crossed).

Bench test


You can see the through bolts in this shot. Initially I left them loose, ran it for a while and slowly tightened it. Each time I ran it and then tightened, the armature seems to spin more freely as it bedded into position... And the great part about this bench test was the uncanny silence.. Ok, not quite silent, but sounding more like it should and less like a banshee.

Time for the final reassembly:

alignment slot

This bit is easy thanks to alignment slots and helpful arrows in the plastic to remind me which way is up.

Ok, now where did all those rubber seals go?


Nearly there, just have to add the o-ring in front of the seal

Fitting the o-ring

By pressing the spring loaded seal back the small o-ring can then be seated in the shaft groove. After this, there is one more large o-ring that goes around the impeller assembly and makes a seal when the plastic pump body slides on.

Reassembled and Fitted


Finally, the new improved almost silent version... 

Cost was $20 for the bearing puller and $10 for the bearing. (3 times the price from an online pool parts place)

Now that the "Banshee" is gone from the pool filter, maybe I'm feeling game enough to have a go at removing the "Freight Train" from the washing machine spin dry cycle.

Wednesday 5 February 2014

Simple fix for Sticky keys on wired Apple Keyboard

Having recently been given an old iMac to refurbish, I have ended up with a nice wide wired Apple keyboard. (excuse the stock photo)



I've always wanted those extra function keys and page up and page down, since I do a lot of work with other OS's via remote control or VMware. (and the two handy USB ports don't go astray)

Anyway, the problem was sticky keys. Some over them felt quite squishy, some of them crackled and some of them just didn't want to move..

A bit of research on this model revealed a number really well documented but unsuccessful disassemblies and having recently disassembled an older MacBook Air attempting to fix dead keys, I wasn't jumping at the opportunity to start potentially a destructive operation with screwdrivers and heat guns:

Anyway after a few experiments it turns out these older keyboards are quite open in terms of liquid flow through.  (Probably a bad thing when coffee hits it, but a good thing if you are going to try flushing it with solvent)

The solution was as simple as spraying around each bad key with an excess of Isopropyl Alcohol, letting it trickle inside the keyboard and then repeatedly pushing the offending key until it came good..

Now the keyboard works perfectly.. No doubt the coffee or whatever has just moved further into the works, but hey, who am I to complain.

Hero for the day


Sunday 26 January 2014

Curiosity killed the Thread

I've recently been intrigued by David Beazley's introduction to coroutines entitled "A Curious Course on Coroutines and Concurrency" and have had a go at taking his 'Operating System' a little further.

Having programmed some generators previously, I find the whole way of thinking quite interesting.

Basically the concept is that instead of relying on the OS to pre-emptively interrupt running tasks, we program them in such a way that they periodically hand back control to a scheduler. Ok this is actually an old idea, however achieving it using co-routines in python makes it all new again :-) Any tasks that require IO use select and are taken out of the sequential execution loop until ready to continue. I've added some intertask messaging and sleep system calls.

Using coroutines we end up with an operating system that runs tasks consecutively in a loop without the context switching penalties imposed by threading or multi processing.

Admittedly there are some limitations on what you can do, but rather than running thousands of tasks we can now run millions. We can still increase processing efficiency using threads or processes but we can do it via task pools and exercise some control over how this happens.

Spawning a million tasks with pyos coroutines takes around 32 seconds on my i5-3427U 16 Gig Mem Intel NUC. However attempting to spawn a million threads bombs out at < 32,000. The difference is that we are just instantiating a class with the former. Taking the two systems into even ground and attempting to spawn only 31,000 tasks each gives me the following:


  • Coroutines:  1.1 seconds and 40 MB of memory
  • Threads: 28 seconds and 369 MB of memory

The test code looks something like this: (pyos9 is my modified version of David's pyos8)

#!/usr/bin/python2
# Perf and Unit tests
#
# Test what happens with large numbers of tasks
# Simon Ryan 2014

from pyos9 import *
import sys,random,time,threading

mode = sys.argv[1]

try:
    num = int(sys.argv[2])
except:
    num = 1000
now = time.time()

def readhellos():
    yield SubscribeMessage('hello')
    while 1:
        # We need to go idle in order to listen for the message
        yield Idle()
        message = (yield)
        if message and message[2] == 'quit':
            break

def spawninator():
    print('spawninator starting')
    for i in xrange(num):
        yield NewTask(readhellos())
    print('spawninator finishing spawning %d tasks in %2.2f seconds' % (num,time.time() - now))
    print('sending quit message')
    yield Message('hello','quit')

class globs:
    # Poor mans messaging for threads
    timetodie = False

def simpletask():
    # Something we can launch as a thread
    while 1:
        time.sleep(1)
        if globs.timetodie:
            break

if mode == 'pyos':
    sched = Scheduler()
    sched.new(spawninator())
    sched.mainloop()

else:
    # Do approximately the same but with threads
    threadlist = []
    for i in range(num):
         try:
             testthread = threading.Thread(target=simpletask)
             testthread.start()
         except:
             print('Thread create error at thread number %d' % (i+1))
             break
         threadlist.append(testthread)
    elapsed = time.time() - now

    print('spawninator finishing spawning %d tasks in %2.2f seconds' % (num,elapsed))

    globs.timetodie = True
    for task in threadlist:
        task.join()

    elapsed = time.time() - now

print('Finished in %2.2f seconds' % (time.time() - now))

Here is what the output looks like when I ask for 10 Million tasks (this consumed 9.7Gigs of resident memory)

# ./unittest1.py pyos 10000000
spawninator starting

spawninator finishing spawning 10000000 tasks in 367.74 seconds
sending quit message
no more tasks
Finished in 586.68 seconds

Why is this interesting? Being able to spawn this many tasks changes the way we can think about certain types of problems. The first one that comes to mind is large scale simulations. Being able to write the simulated components as programs to be run rather than trying to model them as arrays of parameters opens up all sorts of interesting possibilities particularly where component behaviour is complex, such as automobile traffic around Hong Kong or asteroid/ship collisions in a space game :-)


Check out the code on GitHub