December 19, 2010

X-TRONIC 4000 Digital Hot Air Rework & Soldering Station

A little while ago I purchased an X-TRONIC 4000 off ebay to upgrade from my simple craft soldering iron.  Now that I have use it a few times I can properly review it.  First off, after doing my initial research there are far better soldering stations you can purchase, however they will be far more expensive. I was not willing to pay $250+, so I was limited to the this and the Aoyue 906 which did not include as much and was a little more expensive. So with that in mind, for a hobbyist who is looking for something better than your cheap plug in iron, the X-TRONIC 4000 is not a bad choice.  It also includes a very good warranty, and while still being manufactured in China at least it is held up to some level of ISO standards and is sold by a US based company. I was able to grab one for a little over a hundred dollars, so it is not so cheap that you would expect it will break in a few uses.  Plus the included backup heating elements prolong that even further.

The hot air gun works as expected, and was pleasantly quiet.  At worst I was expecting a fish tank pump.  At high air flow, which was way too much for circuit work, you could hear the light hum.  Yet at a normal air flow settings it was rather quiet, at the lowest it was whisper quiet.  I had no problem removing a surface mount chip off an old test board with some careful blowing and medium heat.  I expect any future part removal will now be done with hot air, as it make it very simple, or possible in the case of surface mounted chips which cannot be easily removed with an iron.  I also used it to heat some epoxy for removal and that worked as well.  With the three different air tips that are included, you will be set for basic use, though it does not beat a specialty nozzle for even heating.

The hot air gun is nice, but the main feature is the iron.  After using a craft iron for even delicate work getting a serious one is amazing to use. The soldering iron heats up in about 30 seconds, which is so much faster than the three to five minutes my craft iron would take. Also using the lcd read out and the control dial, the temp is more or less kept constant.  It is important to note that the temp displayed vs what is always applied still depended on the surface area in use . The ten included tips range from tiny to very thick.  For small leads, the small tips worked well, however for a lot of normal use you will need to use a thicker tip which keeps the temp far more even.  I understand this is not so much a flaw, as it is something normal with any iron of this level and power draw.  The included stand is nothing to brag about but it does keep the iron handy and away from burnable objects.  The cleaning sponge is thin and pointless, I will be replacing it with a brass sponge eventually, until then I will stick with a damp paper towel.  In short, this will be the start of many "why did I not do this earlier" life moments.

Overall if you are looking at getting a hot air gun and nice soldering iron this should work for you.  If you do not need the hot air then there are more actuate irons you can get for the same price.

December 14, 2010

Converting an PIR outdoor light circuit for 12v

Being lazy I did not want to turn on and off my circuit tree on my desk at work, so I was just leaving it off.  However, with the Christmas season upon us, people started to bug me about not leaving it on, so I decided to get creative and convert a PIR circuit from an old outdoor motion activated spotlight to run on a safer 12v and control the tree on my desk.

First off, after eagerly prying the circuit from the lamp I quickly realizes that it did not use a transformer like I was expecting.  Most newer lights I looked at did.  So I went out looking for a datasheet on the PIR controller ic, but the one used here is either too old, or is just unlisted. This was not going to be as easy as I was expecting it to be.



This was trouble some as every PIR ic has different pinouts, and some use a first/second amp other do not.  So I went back to the basics and traced out the circuit with my multimeter and carefully sketched out the paths so I could better see what was going on.  The first thing that stood out was the four large diodes which are clearly a rectifier, to convert ac to dc.  After this, it passes through the biggest resister (blue tube) I have ever seen, which drops the voltage down to around 13v for the relay which is switched by a transistor.  From there it is dropped further to 8v and smoothed out by a capacitor for the rest of the circuit. Which is odd as an ic usually takes 5v max, but as it was unlisted I only have the trace readings to go on, so I will assume it was built to handle a larger voltage.



After figuring out this much, it was not hard to see where I would need to apply 12v to have the circuit work exactly the same but at a far safer voltage.  So after removing a small resister to break the original +120v (black) path, I now had an isolated PIR circuit and a separate circuit switched by the relay.  Right now the relay will only deal with 9v, but this leaves it open to once again control higher voltages, for potential use at Halloween.

You can see the final result below.


I am quite happy that my digital/analog circuit skills have not gotten too rusty with all the programing I tend to focus on.

November 16, 2010

Google Voice app on iPod Touch

Today I was pleased to see that Google had released an official Google Voice app, as the GVMobile+ ones from Cydia where somewhat broken.  What I was not happy with was the device not supported message that I got when trying to sync. Apparently this is only for the iPhone... Well that would not last long.  Below are the steps you need to take to get the app working on a jail broken iPod Touch.

  1. Download the ipa from the iTunes store.
  2. Change the .ipa to .zip and extract the Google Voice folder.
  3. Open and find the payload folder and grab the GoogleDialer.app
  4. Drop the GoogleDialer.app into the /Applications folder on the ipod via sftp.
  5. Respring
Interestingly enough the application works great on an iPod Touch, it just will not install via itunes.  I was looking through the ipa plist, but have not quite figured out what setting causes the restriction. Ideally removing the restriction and repacking the ipa would be best, but as I have it working, I will leave that up to someone with a bit more interest.

EDIT: Now that the official iPod version is out, this is no longer needed, unless you want the iPhone version.

October 16, 2010

Apple LaserWriter 12/640 setup with OS X

Owning an old networked Apple LaserWriter LS 12/640 is cool, especially as found I can use the waste toner I clean from another printer to fuel this one.  While the result is not amazing print quality, it works well for the occasional print job at home.  The big problem is that setting up the printer is no longer supported in OS X, yet there is some unix and window hackery that will do the trick, the problem was getting them all to work from my Macbook Pro and not having to drag a PC into the mix.

First off you need to setup an IP for the printer, which by default has an IP of 0.0.0.0 and a subnet of 0.0.0.0.  Normally back in the OS 8/9 days you would use the printer utility over appletalk.  Sadly(?) apple talk has been removed as of 10.6.  So time to delve into some unix to fix the issue.

Chapter 4 in the manual for the 12/640 covers setting of the printer for unix. Basically this breaks down into adding an entry to the host file (/etc/hosts) for the printer name and ip address of your choice for the printer.  Then get the mac address for the printer, which is listed on the configuration page it will print out each time it is turned on when in config mode, e.g. little switch on back out, not in.  Then use the following arp command in the terminal "arp    -s    printer_IP_name     printer_Ethernet_address" followed by "ping printer_IP_name".  This will create a link to the printer despite an IP address not being configured.  Use this temporary link to telnet into the printer using the IP address you chose and finish up setting final network settings using the text menu system.

Next you will need to finish setting the other printer configuration items.  However they are missing from the telnet menu.  To gain access to these additional setting, such as turning off config page printing on powerup, you need to grab a copy of the Windows Laserwriter Utility.  This can be run on a pc, through a virtual machine or by using Crossover Mac to simply run it in OS X.  I used Crossover, installed the utility and it connected automatically the first time I ran it.  You can tell the setting have been changed as the printer will be sent a job for each command and then print a wasteful page that confirms each change.  After that the printer will be all set up and ready to be added to your printer list.  The 12/640 driver is pre installed in 10.6, but must be chosen manually.

Once again I am recycling old tech for current use.  Plus it is a pice of Apple history, is your made by Apple, for most that would be a no.

August 12, 2010

Hydro Thunder Hurricane Review

For a couple of months now, I was eagerly awaiting the release of Hydro Thunder Hurricane(HTH), a ten years in the making redesign of the 1999 hit arcade racer Hydro Thunder(HT).  While there are already numerous reviews out about the game I figure I would throw in a little depth  with my 2 cents.

First off, the game carries the HT name quite well, however to fully enjoy it, you have to remember that this is not the same game we know and love.  The boats are back and the race courses are exotic with twists and turns, however gone are the crazy announcer (different less impressive announcer now), mighty hull and a few other small parts, which have been replaced by different and in some case better improvements.  The quick answer to "should I buy it" is YES, the long answer is... well read more to find out.

Controls:
The boat controls are similar to the original HT gas, boost and steer (but oddly no reverse).  However the new wave physics of the water in each course makes the actual overall feel of each race far different from the original game and takes some getting used to. Hydro jumping makes a return, but is (over) simplified down to just a button press removing what was a tricky skill related move and replacing it with something anyone can achieve by pressing x.  Might hull, the move that would smash opponents out of the way has been removed, which is a shame in single player, but makes sense in multiplayer, as it would turn into a complete mess of whoever runs out of boost first gets smashed, and there is already plenty of boat smashing going on.

Boats:
The Boats are back, minus Midway (now named Vector).  Each has two or three unlockable skins to help show off your progress and make you stand out more in races. The boats are ranked novice, pro and expert (complete with the "your crazy"). However the feel of the boats have been altered considerably.  The novice boats are not worth using after unlocking the pro boats, which may put off new players due to initial races being far more difficult to maneuver, however I urge you to keep playing because the pro/expert boat make the game far more enjoyable.  On the other hand, further in the game the expert boats that can be unlocked are way more responsive than their original counter parts, rad hazard being a good example, it is far less prone to spin out on turns, which makes it quite fun to drive now. The down side to this is that in online competition almost every player uses a expert boat, sort of making the rest of the boats pointless (design flaw).  Yet, while experienced players will probably stick with expert boats, I had no problems winning a few online multiplayer races with a Thresher(pro boat), it was just far more challenging than with the faster expert boats.  In conclusion, other than the novice boats the rest are well relatively balanced and fun to race with once you master their quirks.

Tracks:
The tracks in HTH are all new, however they carry over the feel of the classic tracks.  Below are a quick guide to the mix of each track based loosely on the classic ones.

Lake Powell (Lake Powell)
The first track, also making a triumphant return, a lot of different paths to take and a few classic shortcuts to leverage.  All in all a fun track which won't take too long to master.

Storming Asgard (Arctic Circle + Ship Graveyard)
The second track, less light and lots of ice.  A fun track with some cool surprises, though I am a little sad that the ice shortcuts require you to boost unlike the original which was crazy fast before even boosting.

Monster Island = (Jungle Adventure + Catacombs)
Third track, a circuit track with three laps that change what path is available to take due to the water level dropping.  A few too many sharp turns for my tastes, but after getting used to it it is not too bad.

Hydro Dome (Hydro Speedway)
Fourth track, a circuit track with three laps which is very fun and built for speed.  Close quarters so online play will knock you around a lot, however once you figure out the layout and shortcuts it is full throttle all the way to the finish.  I destroy with Rad Hazard on this track!

Lost Babylon (Nile Adventure)
Fifth track, this one takes a lot of play to get used to, but is probably my favorite.  Impressive visuals, lots of tricky shortcuts and quick turns make it very changeling but worth it.

Paris Sewers (New York Disaster)
Sixth track,  a circuit track with three laps, built for speed and turns, not too much else going on, but still a solid track.

Seoul Stream (The Far East)
Seventh track, night track with lots of fancy lighted waterfalls and fountains. After the initial oohs and awes, not much going for this track beyond a few interesting but hard to activate/use water powered shortcuts.

Area 51 (Greek Isles + Ship Graveyard)
The eight and last track, a lot of people love this track, I like it but it is not my favorite. Includes a lot of interesting events going on in the background to keep you entertained. Otherwise a balanced track with emphasis on speed in the later half.  Listen closely to what is said in the background during the race to get a few laughs.

Unlike the original HT, the track design in HTH are about the same in difficulty. Yep, sadly no Venice Canals successor to challenge our reflexes. Instead the difficulty of each track is controlled by what class of boat you use. Racing with a novice vs pro vs expert causes the other boats to adjust speed, use boost and take shortcuts. The expert racing is, as expected, the hardest as other boats are always at top speed.  I prefer the pro races over all.

Secrets:
Secrets on each track are back, this time in abundance, with most tracks offering several routes to choose from, ranching from normal to secrets that have to be landed in from a high drop. This is fine, however I have a minor complaint with how a lot of the secrets are set up.  A few have the classic feel, and if not taken only slow you down, however a lot of the extra paths are pointless to take. While even worse some important ones do not provide enough of a boost aid even after being extremely hard to access.  Namely, that in the original HT taking shortcuts would normal fill your boost quit well, most in HTH do not, or even waste boost to access.  This is not ruin the overall play experience, but you will occasional find your self thinking, "why did I even take this shortcut?"

Online Play:
Of all the features in HTH the one that I was looking forward to most is the online play.  Races pit you against 1-7 other players with the host of each game choosing what map is played.  I must say that the developers could have taken a cue from the Halo series and added a count down to each lobby, as I am always kicking out people who sit in a not ready state for over 20 seconds while every other player is ready to go.  Beyond that the races are as expected, far different and more challenging than with humans vs the game AI.  You tend to get knocked around far more as experienced players try to prevent others from getting boosts and accessing shortcuts.  To make things more even in races, boost is adjusted based on position, so first gets normal while 8th place gets 8X as much ofter filling the gauge, this is both annoying if you are in first and very helpful when your boat explodes from a small mistake, so I am listing it as a moot point, though in the end it does not do much to help new players win, and would have been nice to be able to disable. In the end a ranking system would have been more fair for new players; I hit the game running, but new younger players must be feeling some frustration being constantly pitted against veteran players with no chance of winning till they get used to the track and unlock better boats.  I have had a few races where I am against only one person in a novice boat, I had a good 60sec lead by the end, which is just not fair for them, but an easy win for me.  Beyond the online races the leader board keeps track of your overall rank on each track, but due to some glitch problems on tracks allowing players to achieve impossible times, the leader boards are somewhat pointless, nothing like seeing 1:20 at the top where I can only get close to 2:00 on a race with an expert boat.

Down loadable content:
While rumors are flying, it is mostly confirmed that two more tracks should be available at some point.

That about covers the game, so if you like what you have seen go buy the game, if anything go grab the demo and check it out, however be ready for the novice boats to be very lame to drive.

July 30, 2010

Install Microsoft SDK in Visual C++ 6

A recent project required me to work with the JobObject feature of the Microsoft API, this worked fine with VC++9 however when it came time to re-try it in VC++6, I quickly became aware of the fact that the base SDK that comes with VC++6 did not have a definition for the JOBOBJECT_EXTENDED_LIMIT_INFORMATION struct or the enum needed to attach it to a precess in order use it.  Sadly I needed this for a "kill at end of job command", where as other more basic JobObject features did work with the base SDK. So while I could re implement the struct I was stuck beyond that.  Lucky a SDK update fixed the issue.  But like so many other things getting the update working was not quite that easy.

VC++6 will only work with Windows Server 2003 SP1 SDK as the latest update, be careful not to grab anything newer than that. Get it Here (bottom of page) Next let it install, which will take a good ten minutes.  After it has installed then launch VC++6 and go to Tools > Options and click the Directory tab.  Now in each of the correct lists (drop down option) add an entry for either the include, bin or lib folders that are located in C:\Program Files\Microsoft Platform SDK\. Finally, the last important step is to move the new SDK items up to the top of each of these lists, if you do not the order will cause issues and the SDK files will not be used or will have errors.

Now JobObjects work as expected.

June 27, 2010

Adding an AUX to a Clarion PF-2597A-B

Originally I had planned to just buy a new after market head unit for my car, do to its lack of an AXU input for my iPod, however after seeing nothing within my price range that was decent looking, I realized that I may have been on the wrong track.  While doing some research, I stumbled upon this forum posting about adding an AUX input to an old car tape deck.  After digging some more on this topic I found that people have been successful with hijacking both the AM/FM and CD input on stereo circuits.  The CD methods seemed like a bad idea due to needing a silent cd to play constantly, which is just asking to wear out the stereo cd drive.  So I went with hijacking the FM audio out pins of the stereo.  The interesting part about using the AM/FM method is that due to the Auto Gain Control built in, when a MP3 player is connected, its stronger signal seems to overrides the AM/FM on the board and effectively shuts it off without any extra effort on your part. From what I have read, this seems to be the case with most car stereos, however your results may vary.

Here is a good place for the standard warning:  I did this project knowing it could potentially destroy the stereo and/or the mp3 player, if you attempt the same thing or something similar you face the same risks.  Do not blame me if you break anything by following my information or pictures, I express no warrantee on this information's correctness or usability.

I started off my taking the stereo apart and looking up the chips on the reverse side of the board shown here.  There is a lot of mixed opinion on where the best place to connect to is, and it seems to vary from different stereos, so it is best to see what you are working with first. While this gave me some good extra info, I quickly realized that this was not necessary, due to the pinout being printed on the back of the board.  I did some voltage checks while the stereo was plugged in and running, the FM outs gave a normal voltage variation between 0v and 3.6v, which means that I would not overload anything with a mp3 player's small voltage output. After figuring out on paper what I wanted to do and finishing my voltage checks, I did a quick test run with a temporary 1/8 inch plug connected and an older expendable mp3 player.  While I was expecting this to work out, it was exciting to hear it function, when the player was plugged in, the FM cut out and the mp3 was clearly playing unplug it and the FM comes back as normal.  While the signal is stronger, the max voltage from the mp3 player is lower than the FM, so the mp3 player needs to be set to at least half volume to be heard well, not bad, but definitely not perfect.  There may be a better connect point that uses a lesser voltage, however I am sticking to the ones on the edge due to it being easy to access and solder.

After testing and finding out that this did indeed work, I drilled a hole in the back of the stereo and added a 1/8 inch plug and then ran a short shielded audio cable to the pins I used in my test.  The board picture above has the final wiring, which pokes out of the side and is soldered to the correct pins coming from the separate AM/FM board and ground which is a larger solder point connecting to the metal housing.  By using a shielded cable inside the radio, it will prevent any extra interference due to the wire stretching across the board from the back panel. After doing one final check, I reassembled the stereo, now with its new AUX plug.  Finally, I put together a separate cable to plug into this AUX port and run it to a more convent location in the center console.

The wire runs down from the back of the stereo and connects to another 1/8 inch plug from which I can easily plug in an mp3 player or another other audio device. After making sure everything was in order I snapped all the console panels back into place leaving just the new 1/8 inch port left in view.  This is nice, because it means that there is no obvious indication that the stereo is no longer stock, making it a far less likely target for theft, not that the radio is easy to get out to begin with.

After doing some actual road testing and letting it run for a while using my expendable mp3 player, I am quite satisfied as well as confident that there is no chance it will harm my iPod, so now I am ready for the commute on monday morning.  I must say that the only down side to this setup is that the mp3 volume needs to be over 50% and the stereo volume ends up being about 12 higher than cd or radio (25-30 vs 10-15 out of 40).  Not that this is a problem, it is just the only flaw to the design and may be fixed by using a closer point to the volume control chip.  Either way, I am happy and my car now has a handy AUX port, all at the cost of $3 for 1/8 inch plugs.

Other possible options instead of this and costs...
DIY AUX ($0-$50 depending on your extra parts supply)
Clarion CeNET adaptor EA1251B ($99 and cannot have CD Changer option installed)
New separate head unit with AUX ($60-$500)

May 15, 2010

Reading plist files

When developing for the mac platform, app preferences are supposed to be stored in ~/Library/Preferences/.  While finding and reading a preference file is easy enough, reading usable information from it is another matter.  This is because in the last couple of system updates (10.5+) the xml based plist files used for preferences are now saved in a binary format, not the UTF-8 format you would suspect.  The tricky part of this is that if you are using the NSDictonary class in Objective-C you will not encounter any problems, but when using any other programing language you suddenly get a mess of garbage text.  Luckily OSX had a built in command to help remedy the issue.  The plutil command converts plists between the text based XML and binary based.

As an example in Java you can use the Runtime class to invoke the command on the fly.

Runtime.getRuntime().exec(new String[]{plutil", "-convert", "xml1", filepath});

To convert a file back once you have read or edited it use this.
Runtime.getRuntime().exec(new String[]{plutil", "-convert", "binary1", filepath});

It is also good check for the lastIndexOf("bplist") as it will alert you if the file is currently in binary form.

April 23, 2010

Powering an Xbox 360 dvd drive

While I was waiting to be able to power my experimental/half working xbox 360 I decided to see if I could easily get the firmware keys off the drive (Note: this not for piracy, the dvd drive is not working and I would like to replace it at some point.) First off, the dvd drive is a sata drive, however it does not run off of a sata power connector, instead it has a 12 pin connector where 10 of the pins are used. Pins 1-2 are not used on the connector, pins 3-4 & 6 are +3.3v, pins 5,7,9,11 are ground, pin 8 is +5v and finally pins 10 & 12 are +12v. I was able to figure out this pinout using the post here.


Sadly, I was not able to get the key off the drive this time, however I was able to create a simple xbox 360 dvd power adaptor which was powered by a standard computer power supply, or in my case a power adaptor for powering a single computer drive. In the picture you can see my simple power supply on a breadboard, most of this is straight forward, the only tricky part is you need a 3.3v regulator to drop the +5v line down to the 3.3v the drive needs. You can see the regulator at the top of the board with two capacitors keeping the output clean at a stable +3.3v.  I did not use a switch to eject the drive, because from what I can tell, the drive motor controller is damaged and will only make a minor movement before freezing and not responding again.

While an interesting side project, it was somewhat pointless as now I can just use the 360 to power it. However it was convent to move this smaller adaptor vs a whole opened 360. Eventually I will take another stab at getting the key off, but not till I have had my fill of xbl arcade.

April 20, 2010

XBox 360 Cooling Experiments



I have an older xbox 360 that a friend had given me a while ago, it had no power brick, controller or av, and I was told that the DVD drive was not working.  As I have limited expendable money right now, it sat in storage for a few months waiting for a time where I had extra money or a reason to get it up and running again.  However, with the upcoming summer release of Hydro Thunder Hurricane I decided it would be worth finally getting the 360 ready.


I was able to snag a used power brick off bay for around $10 with shipping, so all that was left was to check out the guts while I was waiting for snail mail to arrive. First off I quickly released why the GPU overheats in 360's, the DVD drive sits on top of it, and the front has no air vents what so ever to let in fresh air.  Second the fans in the back have a single shroud instead of separate channels for the CPS and GPU, so most of the air is just pulled from just the larger CPU heat sink. I remedied this by building a wall to separate the shroud into two separate paths, forcing the right side fan to pull as much air as possible from the GPS heat sink.  Next, I add a third fan as an air intake, this was placed over the open area inside the case in front of the CPU heat sink.  I also added a plastic wall the cuts the fan air intake into two parts, half is blown into the CPU heat sink, while the other half is blown under the DVD drive so fresh cool air is available to the GPU intake. It was easy to mount a fan that fits the space, as the thin metal shield cover for the 360 has holes already drilled in an attempt to allow a pitiful amount of air to be drawn in, the holes will fit two normal sized fan screws and holds it nicely against the top of the side wall.  I removed the extra metal around the fan intake and then drilled a same sized hole into the white plastic cover above this.  Screen mesh was added to cover the fan intake and protect it. Finally, I used metal heating duct foil tape to cover the fan sides as well as do some plugging of gaps in the heat sink shroud connections.
I have never owned a 360 before, so I will have to do some heat comparisons, but it does not feel like an excessive amount of heat is being blown out the back, so I am assuming this does work to cool the insides better, or at least that is the standard thinking as I have seen that many other people have added an intake fan in this location.

March 29, 2010

DIY Fog Chiller

I have owned a fog machine for many years now, but I had always wanted to make a fog chiller to get a crawling fog effect. However, due to the wind around my house in the fall, it makes it usually pointless for halloween, so until now I had held off on spending any money on it. But when low lying fog was needed for a youth play I was helping setup and run lighting for, I finally had the excuse I needed.

So before any details, a bit of physics… A simple fog machine works by vaporizing a fluid (usually made of mineral oil, glycol, or glycol and water mixture) into a heat exchanger, where the fluid is quickly vaporized. This means that fog is usually somewhat warm, as it does cool down quickly as it expands, similar to compressed air. However it is still warm enough that it always rises as it is released. To remedy this, a fog chiller is used to cool down the fog faster so it lays low and clings to the ground. Some simple examples can be found on youtube that use a metal pipe or plate and ice to cool down the fog, which to my surprise does not need a lot of ice to achieve the task. Though watching expensive professional fog machines run is rather impressive. [Check it out]


Still I wanted to do something more than a simple metal tube, so after purchasing the cheapest plastic bin I could find ($5) I gathered up some PVC tube, mesh window screen, a 120mm computer fan and a plastic sandwich bag.

As you can see from my pictures the mesh is bent and woven into a wave shape for a clear path the smoke can move through, this ensures maximum exposure to the ice is possible and allows the fog to fill the container. Next the mesh smoke path is placed between the PVC inlet and the outlet fan using the lip in the container to to hold it up. Ice is filled all around the mesh as well as in between the gaps between the smoke path. A variable voltage transformer and a remote controlled outlet is used to control power and the speed of the fan. It is pointless to leave the fan running all the time as it will melt the ice faster. Finally a plastic bag with a stiff edge is used as a simple laminar to help smooth and direct the fog to the ground for a gentle rolling effect. While I did not get a chance to take a video of it in action I have included a video of another person's fog chiller which produced the same effect. (AKA, It is not my home, and I do not own such a sketchy rug...)



I was quite happy with the results, the ice lasted and with plenty to spare, while sitting in-between uses for a good hour. And produced a good layer of fog for the two scenes that needed it. Interestingly enough a chiller seems to works better in cold air than warm, due to it keeping the fog cool longer, which is the opposite of what I assumed, as I thought it would be better to have warm ambient air to keep the fog as the cooler sinking air. Also the slower the fog is, the lower it will stay, so if you have a container to pump it into first before cooling it will help slow it, but I will save that for the v2. As you can see from my results, if you own or want a standard fog machine (quite cheap now a-days) you need to make a fog chiller, also don't buy a combined model as they only produce a slow steady output of fog, which is only is useful for an small indoor room.

March 24, 2010

Poking with ajax

I have played with Ajax before and even used it in a few projects, but never in a way that it was obvious.  With the next round of CADY site updates I have finally had a chance to put ajax to some real use. For the upcoming parent network, which is more or less a very simplified forum I am coding from scratch, I needed a simple and easy to use registration page for parents. Setting up a page is easy, making it point out peoples mistakes in a dynamic non refresh ways is not.

It is good HCI practice to limit any screen refreshes to just when locations are actually changing, it is what people expect. Where as if a user submit a form only to have it return and to say you missed something is not as intuitive, because the user has already moved on in their thought process.  This is where javascript and ajax usually come in.  By allowing the page to call remote content you can check form fields on changes and then update the user to missed fields or issues before they submit. You could extend the process and prevent even the submit if things are not correct, however this falls outside my current beliefs on how applications should handle user control.  If the user wants to submit the page with missing items even after being notified, let them, however have it fail the submit on the server side and then bring them back to the restored page with a notice of what they missed.  This forces the user to learn that finishing a form properly the first time is worth not having to remember what they where filling out.

You can check out the CADY Parent Network Registration Page to see my progress and fancy ajax trimmings, however please do not sign up unless you are actually a parent who is interested.

March 9, 2010

Growth Issues,SN Java BufferedImage Transition

With my SN Project slowly coming closer to completion, I decided that I would try out making a simple game to see what needs work, however like always, my plans where derailed quite quickly. I had a small library of images that was working quite well at the time, however after increasing the library to a couple thousand images, I quickly noticed that things where not working quite right, well… actually not at all, it was throwing a java.lang.OutOfMemoryError and crashing. The memory error that as an easy fix, adding a VMOptions tag to the info.plist with -Xmx1024m allowed for me to set the max memory to a much greater amount, however this was nothing more than a temporary fix, I knew there was a much greater issue behind this problem.

The size of the image library was around 150Mb, which when loaded to memory would be larger due to it being uncompressed, however it should not have been much larger than 2X the base size or 300Mb as an upper limit. I was shocked when memory needed skyrocketed to well over 700 Mb, whereas the standard max for the Java VM is around 100Mb. So I went looking for a memory leak. Java handles most memory issues, but it still can have problems with large collections of data gathered in a short period of time, due to the built in garbage collection running only occasionally as needed. After doing some research via Google, I stumbled upon a complaint about the MediaTracker keeping references to the images it tracks, which while in small numbers is not an issue, but can quickly build up as more images are tracked. This was exactly what I was doing wrong.

The standard Image class in java does not load the image into memory right away, instead it acts as a reference until it is needed. This behavior could be seen when removing the method calls to add images to a MediaTracker, the memory used would only increase to around 50Mb and slowly grow as images where loaded when needed. The problem with this is that it causes an issues with flickering in animations. When each frame is used for the first time, it actually draws it on the second call after the first call forces it to be loaded into memory. The standard practice at the time of Java 1.3 to 1.4 was to use a MediaTracker to force the images to load and for my initial use worked quite well. However my project has finally grown beyond the simple use of a MediaTracker. The next step I took was to try some suggestions on limiting the memory retention by removing images from the tracker when they are loaded, or by using separate trackers for each image as well as forcing garbage collection with System.gc(). A mix of these solutions did lower my memory use, however as usual the trade off for space was time and this setup slowed my image loading algorithm to a crawl.

It was quite apparent that I needed something better, and after a bit more research I decided to transition my SN Project from using the base Image class to the improved BufferedImage class available in Java 1.5+. I had actually been using the BufferedImage class for a few things already, but a total transition was not a simple matter. For the most part you can use BufferedImage anywhere you are already using Image, due to the BufferedImage extending the Image class. One huge benefit was that the ImageIO class, instead of the awt Toolkit, loaded the whole image to memory so a MediaTracker is not needed and this sped things up greatly and removed my memory leak. Compared to before, now it only was using around 230Mb, which was well inside my expected limits.

The big problem that I ran into while changing over my code was that the sneaky way I was loading my animation class into my image array on the engine side would no longer be feasible. Originally, I had found a nifty solution to my space problem, with a bit of tweaking my animation class could extend the Image class and then be inserted into my image array for quickly accessing both the game animations and images through one simple method call. It also only needed minimal conditional checks which I already had in place. While this worked well with Image, there is no such luck with BufferedImage. You can serialize a class that extends BufferedImage, but you cannot deserialize it, because as it lacks the "no argument" constructor needed to reconstruct the base class. This left me frustrated and quite annoyed, by this point the editor was ready and working, but the engine would not accept the image data.

A few hours later, I had separated the animations from the image array and while I was sad that I had to abandon my unique solution, it was probably for the best as it is easier to figure out what the code is doing now. This is where big problem two popped up. I was using a PixelGrabber to export my images to an int array and then reconstructing them with MemoryImageSource and the awt Toolkit to load them back into an Image and then forcing them into memory with a MediaTracker. This was not going to work as I was now avoiding the Toolkit and MediaTracker classes. With some more research I finally pieced together that I could do a similar process but this time to a byte array. A simple example of what I am doing is listed below.

Exporting is the same as saving the image, but to a byte stream instead of a file.

ByteArrayOutputStream bstream = new ByteArrayOutputStream();
ImageIO.write(img, "png", bstream);
byte bytearray[] = bstream.toByteArray();

To convert the image back you can read the byte array using a ByteArrayInputStream.
BufferedImage image = ImageIO.read(new ByteArrayInputStream(bytearray));

At this point, around ten hours after I started, I now had a working engine and editor again, however it was rendering slower than before. I commented out a most of the drawing and logic method calls and found that the engine would run around 50 FPS with minimal drawing, on the other hand, with all calls back on it ran around 8 FPS. Interestingly enough, the logic was the issue, instead drawing a single large transparent image of the GUI was causing a 40 FPS reduction. I was aware that transparency always causes a speed reduction due to increased processes needed to render it, but not by that much!

It took some more searching to figure out what was wrong. In Java images come in a few different types running in different modes, examples of these would be Image, VolatileImage and BufferedImage. I found VolatileImage quite fascinating as it is the fastest since it is always stored in the graphics hardware memory, but the trade off is that it always may or may not be available due to the possibility of it being overwritten by something else in the limited space of video memory. You must repeatedly check to see if it is still there, the descriptions of this made me think of trying to arrange a large group of very hyper children into a pattern, but at any point they may scatter. Luckily, with new changes in the BufferedImage class it too tries to run in video memory if possible, but only if it is setup to be compatible with the current video configuration. Apparently, using the ImageIO read method does not always create the fastest images, it was suggested that you create a more compatible image using the current graphics configuration and draw the image onto that. This also seems to only cause a minimal increase in processing that is easily outweighed by the huge increase of rendering speed. After converting all the SNEngine's BufferedImage objects with the GraphicsConfiguration createCompatibleImage() method a huge increase could be seen, going from 8FPS to around 35FPS, my target being 30FPS.

I still have some more work to do on increasing efficiency, but this tedious transition was an eye opening experience. As usual I have learned more than I expected, but this new information on Java graphics will probably come in handy later. (NOTE: This was found to be true on OSX 10.6 compiling for Java 1.5+, while most things would be similar on other platforms, the low level hardware acceleration for graphics does slightly differ on each operation system and JDK.)

March 1, 2010

Java JNI Custom About Box

It is silly just how long it took me to figure out this one line of code... A few months ago, I had finished porting over my SN Project from standard Java to then new JNI Library in Xcode 3.2. However, no matter how much I poked and prodded and searched, I could not figure out how to override the simple About Box I am assuming is provided by the JavaApplicationStub.

Luckily, today I finally stumbled on the answer in an obscure thread on the Apple Mailing List. The short answer is that I was not telling the event that it was already handled before letting the method end, the default box was called as a result of this.

You can see below that you need to add setHandled(true); to the handleAbout ApplicationEvent that is in the OSXAppAdaptor class provided with the JNI Template, or where ever you are handling the EAWT action calls.

public void handleAbout(final ApplicationEvent e)
{
   e.setHandled(true);

I actually feel a bit stupid for not noticing this sooner as a few of the other action call methods already are setting handleAbout but it was not that clear what it was doing so I completely over looked it. Well, with this fixed I now have all the kinks worked out, now on to finishing up the features and finally hitting a stable 1.0 release, though it may take another year.

February 13, 2010

You should have seen it coming! EpicGame on iPhone!


Well, after a few days of learning the ins and outs of UIView and the CGContext classes in Objective C, I went to work porting the classes from the original VB EpicGame to iPhone friendly Objective C classes. This was rather straight forward and other than changing the method formatting almost all the logic was still sound. The big difference that did require some tweaking was that Quartz or CoreImage uses a diffrent orgin point, it is the bottom left, not top left as almost everything else. Oddly enough all the images just needed to be flipped in PhotoShop and all was fine, with little to no code change.

What is different is that there are no keys, you move left and right by holding the left or right edges of the screen. A tap will shoot, and a swipe up makes epic box jump. Pritty niffty I must say.

I quickly found out that the drawing class CGContext was annoying near the end, as you are forced to rely of the Touch OS to draw when it is ready, vs forcing a redraw when needed as I am used to. This takes a huge hit on speed, but I am lazy and do not want to spend an entire extra week of studying just to use OpenGL ES instead. It is large complex and annoying, plus way too much for a simple game like this. Oh, and thanks Apple for not making the iPhone simulator actually match the real speed of an iPhone, for others as a warning, the simulator runs graphic calls around 100 times faster than a real iPod 1G, don't be fooled!

You can grab a copy here, sorry non JailBreakers no portable EpicGame for you, as I am not paying $99 to Apple to distribute a free app, plus the music would most likely prevent it from being approved anyway, as it is used without permission, but without it, it just would not be the same.

Other then the code and the can monster art, I claim no ownership of the rest of the art and music, and as such I am posting the App as free for use as is, enjoy.

January 25, 2010

Coinco 9300-CL Reverse Engineering Part 1


A while back I was able to get several parts to a vending system off of school surplus. Which I was quite excited about, because it was something I had always wanted to be able to play with. However I quickly ran into problems in trying to use it as there was nothing online to help. But, finally with the arduino that I now have, I believe I can make it all work. So I started out by seeing if I can get just the coin changer to interface with my computer via the arduino.

The coin changer is a coinco 9300-CL which from what I can tell is the same as the 9300-L model, but with it requiring 117 instead of a lower voltage. Both seem to have the option of a 15 pin or 12 pin plus, the CL has a 12 pin plug. Using the service manual found here. It explains the pinout and basic operation of the coin changer. However the image for any details of the communication is rather blurry and almost impossible to understand, so I had to do some poking to figure out what was what. To start out the 12 pin plug has 6 vertical pins and then 6 more pins that alternate vertical and horizontal. Pin 1 is the first vertical pin of the all vertical group, starting on the left and then 2 in the middle and finally pin 3 on the right. The rest of the pins follow suit in numbering from left to right on each row. Luckily I had a connector that came from the vending device, so I simple had to use my multimeter to find the connected point on the female connector for the main board. Which was nice as it had the two 117 volt pins removed so I could not accidentally destroy anything!

Using the service manual I have compiled a much easier to read version for the pinout as it was on the female header end of the plug.  You will notice pin 10 and 12 are missing as there is no need for them because another pair of separate wires run to my power supply for those pins.  For basic use it looks like you simple need pin 1 and 2 hooked up to +5 and ground on the arduino and then 3 to a digital output pin and 4 and 5 to digital input pins.  Pin 3 is your TX pin for the serial communication where pin 5 is the RX.  However pin 4 is used as an interrupt that signals when data is going to be sent.  Sadly the service manual only covers a single example of when a coin is used.  This states that when a coin is entered it will send an interrupt to the controller via pin 4 and then wait for a signal on pin 3, which after receiving it will finally send a message with information on the coin and other states.  This is nice, but what I needed is how to connect to it at startup as well. It looks like when the coin changer is first turned on it sends a status request to the controller and will not fully activate until the request is answered.  This is preventing me from actually using it in any way.

So to get around this I hooked everything up to the controller board I already have, that came with the parts, and started intercepting the communication between the coin changer and the controller, using my simple oscilloscope and the arduino to read the serial communication.  For the most part the serial communication is simple enough, however I have yet to figure out the actual protocol used.  From what I have seen online I believe the 9300-CL uses some form of the MDB protocol however I have not been able to quite narrow it down to the 9 bits it should be using if that is the case.  I have tried many different timing setups in order to catch the correct bits, 2400 and 3300 microsecond delays between bits seem to get the best results so far, which I would happily use, if not for the fact that I also need to talk to the coin changer, not just read what it spits out.  So I am now waiting for a reply from coinco tech support to see if they can shed some light on the matter, otherwise it will be a slow process of trial and error till I get the right timing and figure out the correct protocol.

January 18, 2010

SSH Messenger


As a request, I have finished my second full Objective C project. If someone is on a computer wearing headphones and is not in convenient shouting range this app makes it simple to still get their attention.  It would also make a good admin tool, or a awesome way to prank/annoy someone. It is a simple application that will connect to a remote computer via SSH and then use the built in osascript libraries to cause a dialog prompt to appear. However instead of requiring some terminal skills, instead just enter the IP, username and password of the remote computer and then type your message. A handy shell script takes care of all the rest. Click here to check it out. (Universal Binary, Mac OS X 10.5+)

This was an interesting project, not so much on the Objective C side, which I am getting quite good at, instead the shell scripting was a challenge this time. In order to have the SSH command work without setting up key pairs, I needed to delve into the world of Expect. Expect is a handy command set that allows you to set up automation of terminal entry. In short you can have it "expect" some input and then after finding it, send some output to the terminal, which in my case was the password entry for ssh. The ssh command does not have a password argument, so it needed expect to look for the password prompt and then enter a password for the user.  It also led to a nice way to do some general result checking in the case of a prompt with two or more button options.

Expect while a little strange at first was not that hard to figure out and only took about an hour and a half to have down pat and working the way I wanted it to.  Sadly as it is based out of /usr/bin/expect you cannot use echo command, which made it slightly harder to learn when something was not working.

Check out the base script I came up with below...

#!/usr/bin/expect -f
#log_user 0
set addr [lindex $argv 0]
set usr [lindex $argv 1]
set pas [lindex $argv 2]
set message [lindex $argv 3]
set from [lindex $argv 4]
# now connect to remote UNIX box (addr) with given script to execute
spawn ssh $usr@$addr -o StrictHostKeyChecking=no
match_max 100000
# Look for any ssh issue that needs exit
set timeout 4
expect "ssh:" {exit 2}
# Look for password prompt(s)
expect "*?assword:*" {send "$pas\r"}
# Look for password rejection and exit
expect "*?assword:*" {exit 1}
set timeout 10
# send osascript commands for popup
send "osascript -e 'tell application \"Finder\" to activate'\r"
#send "osascript -e 'tell application \"Finder\" to display dialog \"$message\"'\r"
send "osascript -e 'tell app \"Finder\" to display dialog \"$message\" buttons \"Ok\" default button 1 with title \"Message From $from\" with icon caution'\r"
# Look for reply
expect "button returned:Ok" {
 send "logout\r"
 exit 0
}
send "logout\r"
exit;

Another important thing to note is that I was rather annoyed to find out it required the curly braces to be placed how they are, due to it being based on Tcl. However it was only a minor inconvenience until I realized that is why if kept having errors.  The script above takes 5 arguments Address, User, Password, Message and From, and is the general Alert script used in the SSH Messenger.

This makes the first Objective C and Shell combo app that I have done, which is a nice change from the Java Shell combo I am more used to working with.  That and it was a good refresher in shell scripting.

January 1, 2010

A look back before a step forward...

With the passing of Dec 31, it is now 2010 and I have been think back on the past year.  All and all it was not too bad a year, although not exactly perfect either.  Looking back...

GOOD...
Graduated from College (with, in my opinion, flying colors)
Caught up on some good reading
Spent time with family
Had fun with friends
Could actually enjoy the full Christmas Season
Finished some very cool projects

BAD...
Still no full time job, (but part time is better than nothing)
No personal car (not huge, but annoying at times)
Paying back school loans (easy to do, but I hate seeing the money leave)

As you can see, the good easily outweighed the bad, which hopefully in this next year will be finish off completely.  Because, all and all, other than the lack of full time job, life is not too bad. Thus, I do not think I have much of a right to complain.

After looking at the past year, I got to thinking back on the fact that ten years have passed from the year 2000, and all the changes that have happened in the last ten years.  Some of the things I realized where quite amusing.

10 Years ago...
I was happy using dial up (3.5 Kb/s!)
Had never formally programed (but was used to html!)
Used a black & white powerbook duo (system 6.5)
Listened to all my music on cd/cassette player
Never put up a halloween display
Had only hiked one mountain
Lived in a different house
Had a small messy room
Watched way more tv
Could not drive

However a few things have not changed even after ten years...
Still put up a Christmas tree in my room each year
Still chase and poke crabs each summer
Still working with circuits (but much better at it)
Still get along well with my parents
Still fixing things
Still use a Mac

Looking at just these changes over a decade of my life, I have to wonder what will the next ten years bring!