<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Kerry D. Wong</title>
	<atom:link href="http://www.kerrywong.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.kerrywong.com</link>
	<description></description>
	<lastBuildDate>Sat, 13 Mar 2010 01:47:11 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>A Power Inverter with Arduino Pulse Source</title>
		<link>http://www.kerrywong.com/2010/03/12/a-power-inverter-with-arduino-pulse-source/</link>
		<comments>http://www.kerrywong.com/2010/03/12/a-power-inverter-with-arduino-pulse-source/#comments</comments>
		<pubDate>Sat, 13 Mar 2010 01:47:11 +0000</pubDate>
		<dc:creator>kwong</dc:creator>
				<category><![CDATA[AVR/Arduino]]></category>
		<category><![CDATA[Arduino]]></category>
		<category><![CDATA[Atmega328P]]></category>
		<category><![CDATA[AVR]]></category>
		<category><![CDATA[MOSFET]]></category>
		<category><![CDATA[Physical Computing]]></category>

		<guid isPermaLink="false">http://www.kerrywong.com/?p=1702</guid>
		<description><![CDATA[After going through some of the tutorials on Arduino’s site, I really started to appreciate what a powerful platform Arduino really is. A lot of seemingly complex software/hardware interactions can be made quite easy with relatively few components and little coding. As one of my first Arduino based projects, I built a simple power inverter [...]]]></description>
			<content:encoded><![CDATA[<p>After going through some of the tutorials on <a href="http://arduino.cc/">Arduino’s site</a>, I really started to appreciate what a powerful platform Arduino really is. A lot of seemingly complex software/hardware interactions can be made quite easy with relatively few components and little coding. As one of my first Arduino based projects, I built a simple power inverter driven by Arduino.<span id="more-1702"></span></p>
<p>The following is the circuit diagram of this <a href="http://en.wikipedia.org/wiki/Inverter_(electrical)">inverter</a>. As you can see, the two MOSFETs attached to the center-tapped transformer (mine was removed from an old UPS), when driven by a rectangular or sinusoidal wave, will produce alternating current in the primary winding. The pull-down resistors (1M) are necessary to prevent any electrical noise. The 10K resistors are not strictly necessary, but I placed them there to prevent damage to the Arduino board in case of a MOSFET failure.</p>
<div id="attachment_1705" class="wp-caption aligncenter" style="width: 310px"><a href="http://www.kerrywong.com/blog/wp-content/uploads/2010/03/arduinoinverter.png"><img src="http://www.kerrywong.com/blog/wp-content/uploads/2010/03/arduinoinverter-300x180.png" alt="An Inverter using Arduino" title="An Inverter using Arduino" width="300" height="180" class="size-medium wp-image-1705" /></a><p class="wp-caption-text">An Inverter using Arduino</p></div>
<p>The gates of the two MOSFETS are connected to two digital pins of the Arduino board. The following code shows how to use the simple <a href="http://en.wikipedia.org/wiki/Bit-banging">bit-banging</a> technique to generate the 60Hz square wave needed for the inverter.</p>
<pre class="brush: cpp;">
int pin1 =  4;
int pin2 =  5; 

void setup()   {
  pinMode(pin1, OUTPUT);
  pinMode(pin2, OUTPUT);
}

void loop()
{
  digitalWrite(pin1, HIGH);
  digitalWrite(pin2, LOW);
  delay(7);
  digitalWrite(pin1, LOW);
  digitalWrite(pin2, HIGH);
  delay(7);
}
</pre>
<p>The benefit of using an Arduino to control the waveform generation is that the output frequency can be precisely controlled. Of course, if the output waveform accuracy is a concern, <a href="http://arduino.cc/en/Tutorial/SecretsOfArduinoPWM">more advanced PWM signal</a> with a 50% duty cycle should be used to drive the MOSFETs. An <a href="http://en.wikipedia.org/wiki/Inverter_(logic_gate)">inverter gate</a> would be necessary in this case to obtain the opposite phase pulse signal to drive the second MOSFET. We can even <a href="http://interface.khm.de/index.php/lab/experiments/arduino-dds-sinewave-generator/">use Arduino to generate pure sinusoidal wave</a> to drive this inverter. </p>
<p>In my example above, the gate-to-source voltage comes directly from the TTL output of the Arduino digital pin. This voltage is acceptable for a 12V Vcc. If the circuit requires higher DC voltage, the gate-to source-voltage may need to be amplified for the MOSFETS to switch properly. The optimal driven voltage can be found on the datasheet of the particular MOSFET used. In this case, it is <a href="http://www.datasheetcatalog.com/datasheets_pdf/R/F/P/5/RFP50N06.shtml">RFP50N06</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.kerrywong.com/2010/03/12/a-power-inverter-with-arduino-pulse-source/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Hello Arduino</title>
		<link>http://www.kerrywong.com/2010/03/04/hello-arduino/</link>
		<comments>http://www.kerrywong.com/2010/03/04/hello-arduino/#comments</comments>
		<pubDate>Thu, 04 Mar 2010 19:44:59 +0000</pubDate>
		<dc:creator>kwong</dc:creator>
				<category><![CDATA[AVR/Arduino]]></category>
		<category><![CDATA[Arduino]]></category>
		<category><![CDATA[Atmega328P]]></category>
		<category><![CDATA[AVR]]></category>
		<category><![CDATA[Physical Computing]]></category>

		<guid isPermaLink="false">http://www.kerrywong.com/?p=1665</guid>
		<description><![CDATA[When I first started interfacing electronics with computers back in the early 90&#8217;s my hardware choice was an ISA AD/DA card. So when I wanted to experiment with some physical computing stuff recently, I thought of getting an AD/DA card that can be plugged into either a PCI or a PCI Express slot.
But a fairly [...]]]></description>
			<content:encoded><![CDATA[<p>When I first started interfacing electronics with computers back in the early 90&#8217;s my hardware choice was an ISA <a href="http://en.wikipedia.org/wiki/Analog-to-digital_converter">AD</a>/<a href="http://en.wikipedia.org/wiki/Digital-to-analog_converter">DA</a> card. So when I wanted to experiment with some <a href="http://en.wikipedia.org/wiki/Physical_computing">physical computing</a> stuff recently, I thought of getting an AD/DA card that can be plugged into either a <a href="http://en.wikipedia.org/wiki/Conventional_PCI">PCI</a> or a <a href="http://en.wikipedia.org/wiki/PCI_Express">PCI Express</a> slot.<span id="more-1665"></span></p>
<p>But a fairly recent dedicated AD/DA board with a PCI or PCI Express interface is way too expensive for casual hobbyist. So I started researching for alternatives that is both capable and inexpensive and it did not take long for me to come to a rather short list of choices: <a href="http://www.parallax.com/tabid/295/Default.aspx">BASIC Stamp</a> and <a href="http://www.arduino.cc/">Arduino</a>.</p>
<p>Since Arduino is an entirely open sourced platform (both hardware and the software) and is relatively inexpensive, I thought it might be a good starting point. (I got mine from <a href="http://www.nkcelectronics.com/">NCK Electronics</a>)</p>
<p>The latest <a href="http://www.arduino.cc/en/Main/ArduinoBoardDuemilanove">Arduino Duemilanove</a> board comes with an Atmel <a href="http://www.atmel.com/dyn/products/product_card.asp?PN=ATmega328P">ATMega328P</a> microcontroller. Unlike an AD/DA card which is host only, Arduino is capable of running either with host (communicating with computer via USB port) or stand-alone. This feature makes it even more attractive. On the programming side, you can either write code with the Arduino IDE using higher level functions or write against the AVR-GCC libraries directly using lower level primitives. All the coding can be done in the familiar plain-old C/C++. You can also interface the Arduino with <a href="http://processing.org/">Processing</a>.</p>
<p>I setup my Arduino environment (version 18) on Ubuntu 9.10 (64 bit). Please note that if your setup is similar to mine, you might want to update your <a href="http://users.frii.com/jarvi/rxtx/">RXTX libraries</a> (both librxtxSerial.so and RXTXcomm.jar located under Arduino lib folder to the latest version RXTX-2.2pre2) due to bugs in the previous version that cause the serial monitor to crash. Processing also uses these libraries and they need to be replaced as well if you need the serial communication capability.</p>
<p>So far I am very pleased with the Arduino Duemilanove after going through a few examples on the <a href="http://www.arduino.cc/">Arduino site</a> and I am sure I will find something to write about in the near future.<br />
<div id="attachment_1694" class="wp-caption aligncenter" style="width: 310px"><a href="http://www.kerrywong.com/blog/wp-content/uploads/2010/03/myarduino.jpg"><img src="http://www.kerrywong.com/blog/wp-content/uploads/2010/03/myarduino-300x225.jpg" alt="My Arduino" title="My Arduino" width="300" height="225" class="size-medium wp-image-1694" /></a><p class="wp-caption-text">My Arduino</p></div></p>
]]></content:encoded>
			<wfw:commentRss>http://www.kerrywong.com/2010/03/04/hello-arduino/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>A Parallel Port Stepper Motor Driver With Discrete Components</title>
		<link>http://www.kerrywong.com/2010/02/20/a-parallel-port-stepper-motor-driver-with-discrete-components/</link>
		<comments>http://www.kerrywong.com/2010/02/20/a-parallel-port-stepper-motor-driver-with-discrete-components/#comments</comments>
		<pubDate>Sun, 21 Feb 2010 01:31:13 +0000</pubDate>
		<dc:creator>kwong</dc:creator>
				<category><![CDATA[Miscellaneous]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[MOSFET]]></category>
		<category><![CDATA[Parallel Port]]></category>
		<category><![CDATA[Stepper Motor]]></category>

		<guid isPermaLink="false">http://www.kerrywong.com/?p=1636</guid>
		<description><![CDATA[Using PC&#8217;s parallel port is a convenient way to control a stepper motor. For unipolar stepper motors, up to two motors can be controlled with the 8bit data line.
The standard way of connecting a unipolar stepper motor to the parallel port is to use a Darlington driver such as ULN2003 and there are already many [...]]]></description>
			<content:encoded><![CDATA[<p>Using PC&#8217;s <a href="http://en.wikipedia.org/wiki/Parallel_port">parallel port</a> is a convenient way to control a stepper motor. For unipolar stepper motors, up to two motors can be controlled with the 8bit data line.<span id="more-1636"></span></p>
<p>The standard way of connecting a <a href="http://en.wikipedia.org/wiki/Stepper_motor">unipolar stepper motor</a> to the parallel port is to use a <a href="http://en.wikipedia.org/wiki/Darlington_transistor">Darlington</a> driver such as <a href="http://www.st.com/stonline/books/pdf/docs/5279.pdf">ULN2003</a> and there are already <a href="http://www.google.com/#hl=en&#038;q=parallel+port+stepper+motor&#038;aq=f&#038;aqi=g1&#038;oq=&#038;fp=79a46ede2c2a175d">many examples</a> out there on how to do this. In this post, I will show you how to build a simple stepper motor driver using discrete <a href="http://en.wikipedia.org/wiki/MOSFET">MOSFET</a>s.</p>
<p>In the circuit diagram below, you will find that the four power MOSFETs are used as switches for each coil in the stepper motor (the stepper motor I used in this example is a <a href="http://www.mitsumi.co.jp/Catalog/pdf/motor_m35sp_9_e.pdf">MITSUMI M35SP-9</a>. In theory, any uni-polar stepper motors should work with this circuit). A pull-down resistor is attached to the gate of each MOSFET. This is important as otherwise the interference from the port would prevent the MOSFET from switching reliably.<br />
<div id="attachment_1648" class="wp-caption aligncenter" style="width: 310px"><a href="http://www.kerrywong.com/blog/wp-content/uploads/2010/02/controllercircuit.png"><img src="http://www.kerrywong.com/blog/wp-content/uploads/2010/02/controllercircuit-300x145.png" alt="Controller Circuit" title="Controller Circuit" width="300" height="145" class="size-medium wp-image-1648" /></a><p class="wp-caption-text">Controller Circuit</p></div></p>
<p>The benefit of using discrete MOSFET is that they can handle extremely high current loads. Using <a href="http://pdf1.alldatasheet.com/datasheet-pdf/view/96663/IRF/IRFZ22.html">IRFZ22</a>, the coil current can be as high as 10 Amp.<br />
<div id="attachment_1657" class="wp-caption aligncenter" style="width: 310px"><a href="http://www.kerrywong.com/blog/wp-content/uploads/2010/02/steppermotorctrl.jpg"><img src="http://www.kerrywong.com/blog/wp-content/uploads/2010/02/steppermotorctrl-300x225.jpg" alt="Stepper Motor Controller" title="Stepper Motor Controller" width="300" height="225" class="size-medium wp-image-1657" /></a><p class="wp-caption-text">Stepper Motor Controller</p></div></p>
<p>The following C code sets the data port (pin 2, 3, 4, 5) to high in order so that the stepper motor would rotate clockwise. If you want the motor to rotate counter-clockwise, simply change the output order to 8,4,2,1.</p>
<pre class="brush: cpp;">
#include &lt;sys/io.h&gt;

#define PAR_PORT 0x378 

void main()
{
	while (1)
	{
		outb(1, PAR_PORT);
		outb(2, PAR_PORT);
		outb(4, PAR_PORT);
		outb(8, PAR_PORT);
	}
}                                            
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.kerrywong.com/2010/02/20/a-parallel-port-stepper-motor-driver-with-discrete-components/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>An Isolated MOSFET Serial Port Relay Controller</title>
		<link>http://www.kerrywong.com/2010/02/04/an-isolated-mosfet-serial-port-relay-controller/</link>
		<comments>http://www.kerrywong.com/2010/02/04/an-isolated-mosfet-serial-port-relay-controller/#comments</comments>
		<pubDate>Fri, 05 Feb 2010 01:48:26 +0000</pubDate>
		<dc:creator>kwong</dc:creator>
				<category><![CDATA[Miscellaneous]]></category>
		<category><![CDATA[MOSFET]]></category>
		<category><![CDATA[RS232]]></category>
		<category><![CDATA[Serial Port]]></category>

		<guid isPermaLink="false">http://www.kerrywong.com/?p=1618</guid>
		<description><![CDATA[Using DTR (data terminal ready) and RTS (request to send) pins of a PC serial port (RS-232) without actually using the serial data pins, we can interface at least two relay devices with a computer.  Windmeadow Labs has an excellent article on how to achieve this using a bipolar transistor (BJT). Here I will [...]]]></description>
			<content:encoded><![CDATA[<p>Using DTR (data terminal ready) and RTS (request to send) pins of a PC serial port (RS-232) without actually using the serial data pins, we can interface at least two relay devices with a computer.  <a href="http://www.windmeadow.com/node/4">Windmeadow Labs has an excellent article</a> on how to achieve this using a <a href="http://en.wikipedia.org/wiki/Bipolar_junction_transistor">bipolar transistor</a> (BJT). Here I will show you a similar relay control circuit built using an <a href="http://en.wikipedia.org/wiki/Opto-isolator">opto-isolator</a> and a <a href="http://en.wikipedia.org/wiki/MOSFET">MOSFET</a>. <span id="more-1618"></span></p>
<p>Here is the circuit diagram:<br />
<div id="attachment_1624" class="wp-caption aligncenter" style="width: 1023px"><a href="http://www.kerrywong.com/blog/wp-content/uploads/2010/02/serialportctrl.png"><img src="http://www.kerrywong.com/blog/wp-content/uploads/2010/02/serialportctrl.png" alt="" title="An Isolated MOSFET Serial Port Relay Controller" width="1013" height="498" class="size-full wp-image-1624" /></a><p class="wp-caption-text">An Isolated MOSFET Serial Port Relay Controller</p></div></p>
<p>The benefit of using an opto-isolator is that the rest of the controller circuit is totally isolated from the serial port and thus prevents the port from accidentally being damaged by wrong wiring or current surge due to a failed component. And by replacing the drive circuitry from using a BJT to a MOSFET, the switching capability is improved dramatically, making switching higher current load more reliable and more efficient.</p>
<p>Here is a picture of the finished board:<br />
<div id="attachment_1632" class="wp-caption aligncenter" style="width: 810px"><a href="http://www.kerrywong.com/blog/wp-content/uploads/2010/02/serialportctrlboard.jpg"><img src="http://www.kerrywong.com/blog/wp-content/uploads/2010/02/serialportctrlboard.jpg" alt="Circuit Board" title="Circuit Board" width="800" height="600" class="size-full wp-image-1632" /></a><p class="wp-caption-text">Circuit Board</p></div></p>
<p>And here is a simple program that toggles the relay on and off at an interval of 0.5 second. </p>
<pre class="brush: cpp;">
#include &lt;sys/ioctl.h&gt;
#include &lt;fcntl.h&gt;
#include &lt;stdlib.h&gt;

#define _SERIAL_PORT &quot;/dev/ttyS0&quot;

int main(int argc, char **argv)
{
        int fd, status = 0, cmd = 0;

        if ((fd = open(_SERIAL_PORT, O_RDWR | O_NDELAY)) &lt; 0)  exit(1);

        while(1) {
                if (cmd) cmd = 0;  else cmd = TIOCM_DTR;

                ioctl(fd, TIOCMSET, &amp;cmd);
                ioctl(fd, TIOCMGET, &amp;status);

                if (status &amp; TIOCM_DTR) puts(&quot;ON&quot;); else puts(&quot;OFF&quot;);
                usleep(500000l);
        }

        close(fd);
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.kerrywong.com/2010/02/04/an-isolated-mosfet-serial-port-relay-controller/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Building a Degaussing Coil</title>
		<link>http://www.kerrywong.com/2010/01/18/building-a-degaussing-coil/</link>
		<comments>http://www.kerrywong.com/2010/01/18/building-a-degaussing-coil/#comments</comments>
		<pubDate>Tue, 19 Jan 2010 02:27:50 +0000</pubDate>
		<dc:creator>kwong</dc:creator>
				<category><![CDATA[Miscellaneous]]></category>
		<category><![CDATA[Electronics]]></category>

		<guid isPermaLink="false">http://www.kerrywong.com/?p=1605</guid>
		<description><![CDATA[One of my older CRT TVs does not have a built-in degauss button and after sitting in the corner of the basement for a couple of years, it somehow got magnetized pretty badly. The top two-thirds became totally disclorored with the &#8220;rainbow&#8221; effect.Since the TV works excellent otherwise, I decided to fix the screen magnetization [...]]]></description>
			<content:encoded><![CDATA[<p>One of my older CRT TVs does not have a built-in degauss button and after sitting in the corner of the basement for a couple of years, it somehow got magnetized pretty badly. The top two-thirds became totally disclorored with the &#8220;rainbow&#8221; effect.<span id="more-1605"></span>Since the TV works excellent otherwise, I decided to fix the screen magnetization issue with a <a href="http://en.wikipedia.org/wiki/Degaussing">degaussing</a> coil.</p>
<p>The basic operation principal of a degaussing coil is using a strong and gradual fading magnetic field which has an initial magnetic field many times stronger than the magnetization within the tube (typically in the shadow mask or the supporting frame). To produce such a strong magnetic field, we would need a very strong electromagnet. The simplest way is to find a pre-wound spool of <a href="http://en.wikipedia.org/wiki/Magnet_wire">magnetic wire</a> and connect it to an <a href="http://en.wikipedia.org/wiki/Alternating_current">AC</a> source.</p>
<p>I bought a spool of 28 AWG magnetic wire which is roughly 1000ft. The spool has an inner diameter of roughly 1 inch. To increase the inductance of the coil and make it suitable for use with 110V main power, I added a steel rod as the core (the steel rod came from a used printer which was just a tad thinner than 1 inch). Here&#8217;s a picture of the degaussing coil I built:</p>
<div id="attachment_1609" class="wp-caption aligncenter" style="width: 392px"><a href="http://www.kerrywong.com/blog/wp-content/uploads/2010/01/degaussingcoil.jpg"><img src="http://www.kerrywong.com/blog/wp-content/uploads/2010/01/degaussingcoil.jpg" alt="Degaussing Coil" title="Degaussing Coil" width="382" height="237" class="size-full wp-image-1609" /></a><p class="wp-caption-text">Degaussing Coil</p></div>
<p>To test the coil, you will have to be careful about the maximum current the magnetic wire coil can carry. Excessive current can cause the coil to melt and possibly burn! If you are unsure about the inductance of the coil, you probably want to use an <a href="http://en.wikipedia.org/wiki/Autotransformer">autotransformer (Variac)</a> and a AC current meter to determine what is the optimal operation voltage for your coil. Or, if you don&#8217;t have such tools, you will at least want to add a 100W light bulb between the coil and the power to limit the maximum current. If the light is dim when you power on the coil, then it indicates that your coil has sufficient inductance to operate using 110V AC power. If the light is very bright, you will have to adjust your design (i.e., adding a core with higher permissibility or add more turns to the winding).</p>
<p>If your construct is the same as mine, then the coil can operate at 110V AC with no overheating issue (current is at roughly 0.35 A when connected).</p>
<div id="attachment_1612" class="wp-caption aligncenter" style="width: 351px"><a href="http://www.kerrywong.com/blog/wp-content/uploads/2010/01/degaussingcircuit.png"><img src="http://www.kerrywong.com/blog/wp-content/uploads/2010/01/degaussingcircuit.png" alt="Degaussing Circuit" title="Degaussing Circuit" width="341" height="182" class="size-full wp-image-1612" /></a><p class="wp-caption-text">Degaussing Circuit</p></div>
<p>When degaussing, connect the power and move the coil slowly away from the TV screen to a few feet away in a gradual and circular motion. </p>
]]></content:encoded>
			<wfw:commentRss>http://www.kerrywong.com/2010/01/18/building-a-degaussing-coil/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>The Simplest MOSFET On/Off Switch</title>
		<link>http://www.kerrywong.com/2010/01/06/the-simplest-mosfet-onoff-switch/</link>
		<comments>http://www.kerrywong.com/2010/01/06/the-simplest-mosfet-onoff-switch/#comments</comments>
		<pubDate>Wed, 06 Jan 2010 23:46:10 +0000</pubDate>
		<dc:creator>kwong</dc:creator>
				<category><![CDATA[Miscellaneous]]></category>
		<category><![CDATA[MOSFET]]></category>

		<guid isPermaLink="false">http://www.kerrywong.com/?p=1597</guid>
		<description><![CDATA[A touch sensitive on/off switch can be made with a single MOSFET. The following schematics illustrate such a switch using only a power MOSFET (IRFZ22).
In this example, the switching capability is achieved by the dielectric nature of MOSFET&#8217;s gate. Since the gate is insulated from other device regions, the leakage current is relatively small and [...]]]></description>
			<content:encoded><![CDATA[<p>A touch sensitive on/off switch can be made with a single <a href="http://en.wikipedia.org/wiki/MOSFET">MOSFET</a>. The following schematics illustrate such a switch using only a power MOSFET (<a href="http://www.alldatasheet.com/datasheet-pdf/pdf/96663/IRF/IRFZ22.html">IRFZ22</a>).<span id="more-1597"></span></p>
<div id="attachment_1598" class="wp-caption aligncenter" style="width: 507px"><a href="http://www.kerrywong.com/blog/wp-content/uploads/2010/01/mosfetswitch.gif"><img src="http://www.kerrywong.com/blog/wp-content/uploads/2010/01/mosfetswitch.gif" alt="Simplest Switch using MOSFET" title="Simplest Switch using MOSFET" width="497" height="319" class="size-full wp-image-1598" /></a><p class="wp-caption-text">Simplest Switch using MOSFET</p></div>
<p>In this example, the switching capability is achieved by the dielectric nature of MOSFET&#8217;s gate. Since the gate is insulated from other device regions, the leakage current is relatively small and thus the capacitor can hold its charge for a relatively long period of time.</p>
<p>When the gate and the positive lead are touched, the relatively small gate capacitor is rapidly charged (dry skin has a resistance of several mega-ohm) and the switch turns on. And when the gate and the ground are touched the gate capacitor quickly discharges and the switch turns off.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.kerrywong.com/2010/01/06/the-simplest-mosfet-onoff-switch/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>My First Few Days With Chrome for Linux Beta</title>
		<link>http://www.kerrywong.com/2009/12/13/my-first-few-days-with-chrome-for-linux-beta/</link>
		<comments>http://www.kerrywong.com/2009/12/13/my-first-few-days-with-chrome-for-linux-beta/#comments</comments>
		<pubDate>Mon, 14 Dec 2009 02:02:50 +0000</pubDate>
		<dc:creator>kwong</dc:creator>
				<category><![CDATA[Miscellaneous]]></category>

		<guid isPermaLink="false">http://www.kerrywong.com/?p=1584</guid>
		<description><![CDATA[When Google Chrome beta for Windows was first released last September, I tested it briefly on a Windows XP box and was quite impressed by its speed and simplistic user interface.
But it would have been too early to tell how the future lies for Google&#8217;s budding browser platform without first seeing it running on other [...]]]></description>
			<content:encoded><![CDATA[<p>When <a href="http://www.google.com/chrome/">Google Chrome</a> beta for Windows was first released last September, I tested it briefly on a Windows XP box and was quite impressed by its speed and simplistic user interface.<span id="more-1584"></span></p>
<p>But it would have been too early to tell how the future lies for Google&#8217;s budding browser platform without first seeing it running on other platforms, particularly on Linux. Although the market share for Linux has been a distant third comparing to Windows and Mac OS (depending on how the market share is calculated the figure goes anywhere between less than 1% to a few percentages), it is a sign of serious commitment when we see the support for Linux finally comes. To be honest, the developer build Chrome for Linux had been around for a while now, but the release of Beta last week was the first official release from Google.</p>
<p>Before I started using it, I wasn&#8217;t keeping my hopes very high. I was prepared to experience some glitches as after all it is still in its early Beta stage and comparing to Firefox, Chrome is only in its infant stage. But the result is much beyond my expectations.</p>
<p>The installation process was pretty much flawless. Google provides both Debian and RPM packages (Chrome 4.0.249.30) and installing on 64bit Ubuntu (9.10) was as simple as any other Ubuntu packages. And upon starting for the first time, it offered to import my favorites from my current Firefox installations. Unfortunately, I had my Firefox sessions open at the time, and it was unable to import the settings. But it was easy enough to manually import all my favorites ones I started using it.</p>
<p>My first impression is that the user interface is very pleasant. It is clean, minimal and almost barren. Like the simple design of its homepage, Google wanted to emphasize on the content and rather the shell. This clean design is also a necessity given Google&#8217;s intension of a Chrome based web-centric OS. Serving as the desktop surface, every square inch of client usable screen real estate counts. This philosophy virtually dictated every aspect of the Chrome browser. When maximized, borders are gone. The top border was shrunk down further&#8211;an other nice touch&#8211;as users do not need to move the window when the browser is maximized. Even the status area is not permanently utilized. It only appears when there is message to display.<br />
All of these efforts add up to give users the maximum screen space.</p>
<p>Another well thought behavior was the slight delay when closing tabs. When you have dozens of open tabs, the tab sizes were adjusted dynamically to accommodate the limited screen width. If you try to close these tabs one by one, it would be annoying if you had to constantly adjust your mouse to find the &#8220;close&#8221; icon of the tab. Google realized this, and designed Chrome such that as long as mouse remains in the tabbing area, the tab sizes do not change. So that closing multiple consecutive windows is a simple matter of multiple mouse clicks, without the need to move or adjust. The tab sizes are only adjusted after a brief delay when the mouse moves out of the &#8220;tabbing&#8221; area (see screen shot below).</p>
<div id="attachment_1589" class="wp-caption aligncenter" style="width: 310px"><a href="http://www.kerrywong.com/blog/wp-content/uploads/2009/12/chrome_closingtabs.jpg"><img src="http://www.kerrywong.com/blog/wp-content/uploads/2009/12/chrome_closingtabs-300x29.jpg" alt="Tab closing behavior" title="Tab closing behavior" width="300" height="29" class="size-medium wp-image-1589" /></a><p class="wp-caption-text">Tab closing behavior</p></div>
<p>Chrome is also a full-fledged web development environment. It has many handy tools (developer->developer tools menu) you would need to inspect/debug your web pages. It even provides a task manager, listing the resources each web page utilizes. Presumably, being an OS rather than a simple browser means that it has to have a task manager of some sort.</p>
<p>Needless to say, page loading in Chrome is generally noticeably faster than that in Firefox. Fast page loading is extremely important for concurrently loading multiple pages (for example, opening a folder of favorites). If a browser is slow, many pages will time out due to the limited rendering capability of the browser. When I loaded a set of a couple dozen or so sites in both Firefox and Chrome, only a couple of sites failed to load properly in Chrome, where as in Firefox as many as ten sites were timed out.</p>
<p>Sites with Flash also worked flawlessly. While this has less to do with Google than Adobe, supporting Flash out-of-box is certainly a nice thought as users generally assume that a web site should just work, regardless of what plug-in is required.</p>
<p>And of course, Chrome is standard compliant. It passes even the most stringent ACID3 browser test. The only gripe I had was the lack of a bookmark menu icon when bookmark bar is not used. In this case, you will have to open the bookmark manager in order to retrieve bookmarked items.</p>
<p>Remember though, this is only a beta browser and it&#8217;s not near its completion by any means. I am sure there would be more pleasant surprises down the pipeline. </p>
<p>Whether or not the Chrome OS lives up to its hype, Chrome as a browser is certainly a serious and credible challenge to Microsoft Internet Explorer and it is here to stay. </p>
]]></content:encoded>
			<wfw:commentRss>http://www.kerrywong.com/2009/12/13/my-first-few-days-with-chrome-for-linux-beta/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>A Hall Effect Magnetic Field Polarity Detector</title>
		<link>http://www.kerrywong.com/2009/12/05/a-hall-effect-magnetic-field-polarity-detector/</link>
		<comments>http://www.kerrywong.com/2009/12/05/a-hall-effect-magnetic-field-polarity-detector/#comments</comments>
		<pubDate>Sun, 06 Dec 2009 00:42:00 +0000</pubDate>
		<dc:creator>kwong</dc:creator>
				<category><![CDATA[Miscellaneous]]></category>
		<category><![CDATA[Brushless Motor]]></category>
		<category><![CDATA[Hall Effect]]></category>

		<guid isPermaLink="false">http://www.kerrywong.com/?p=1563</guid>
		<description><![CDATA[Hall effect sensors can be found in many common household gadgets. Most brushless DC motors for instance, like those used in computer cooling fans, contain Hall effect sensors in the driving circuits. I recently replaced one of the cooling fans in my computer and decided to do some experiments with the Hall effect sensor in [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://en.wikipedia.org/wiki/Hall_effect">Hall effect</a> sensors can be found in many common household gadgets. Most <a href="(http://en.wikipedia.org/wiki/Brushless_DC_electric_motor">brushless DC motors</a> for instance, like those used in computer cooling fans, contain Hall effect sensors in the driving circuits.<span id="more-1563"></span> I recently replaced one of the cooling fans in my computer and decided to do some experiments with the Hall effect sensor in that old fan.</p>
<p>After removing the fan rotor you can see the stator and the control circuits. This particular fan is driven by a single chip ATS 277<a href="http://www.datasheetcatalog.org/datasheet2/a/0awqfy74tj776gp8g4esy438whwy.pdf">(the data sheet can be found here)</a>, which is a complementary output Hall effect latch. It turns on and off the alternate side of the poles depending on the rotor&#8217;s position. </p>
<div id="attachment_1565" class="wp-caption aligncenter" style="width: 310px"><a href="http://www.kerrywong.com/blog/wp-content/uploads/2009/12/stator.jpg"><img src="http://www.kerrywong.com/blog/wp-content/uploads/2009/12/stator-300x228.jpg" alt="The stator of a cooling fan" title="The stator of a cooling fan" width="300" height="228" class="size-medium wp-image-1565" /></a><p class="wp-caption-text">The stator of a cooling fan</p></div>
<p>So, using this Hall effect latch IC, we can build a simply electronic circuit that can be used to detect the polarity of a magnet (the magnetic field has to be strong enough to trigger the sensor due to its limited sensitivity).  </p>
<p>Here is the schematics I used to build such a detector:</p>
<div id="attachment_1568" class="wp-caption aligncenter" style="width: 291px"><a href="http://www.kerrywong.com/blog/wp-content/uploads/2009/12/PolarityDetector.gif"><img src="http://www.kerrywong.com/blog/wp-content/uploads/2009/12/PolarityDetector-281x300.gif" alt="Magnetic Polarity Detector Schematic" title="Magnetic Polarity Detector Schematic" width="281" height="300" class="size-medium wp-image-1568" /></a><p class="wp-caption-text">Magnetic Polarity Detector Schematic</p></div>
<p>and here is a picture of the detector after it was built.</p>
<div id="attachment_1571" class="wp-caption aligncenter" style="width: 289px"><a href="http://www.kerrywong.com/blog/wp-content/uploads/2009/12/detector.jpg"><img src="http://www.kerrywong.com/blog/wp-content/uploads/2009/12/detector-279x300.jpg" alt="The assembled detector" title="The assembled detector" width="279" height="300" class="size-medium wp-image-1571" /></a><p class="wp-caption-text">The assembled detector</p></div>
<p>When the circuit is powered on, one of the two output will be latched at low and thus the LED connected to that pin will light up: </p>
<div id="attachment_1572" class="wp-caption aligncenter" style="width: 255px"><a href="http://www.kerrywong.com/blog/wp-content/uploads/2009/12/led1on.jpg"><img src="http://www.kerrywong.com/blog/wp-content/uploads/2009/12/led1on-245x300.jpg" alt="Activated with one side of the magnet" title="Activated with one side of the magnet" width="245" height="300" class="size-medium wp-image-1572" /></a><p class="wp-caption-text">Activated with one side of the magnet</p></div>
<p>If the Hall sensor detects a strong enough magnetic field, the original pin with the low output will turn high and the other pin will turn low. Thus the blue LED will be off and the red LED will be turned on (see the picture below, note that the red LED is illuminated albeit it is a little dark compared to the blue one).<br />
<div id="attachment_1573" class="wp-caption aligncenter" style="width: 281px"><a href="http://www.kerrywong.com/blog/wp-content/uploads/2009/12/led2on.jpg"><img src="http://www.kerrywong.com/blog/wp-content/uploads/2009/12/led2on-271x300.jpg" alt="Activated with the other side of the magnet" title="Activated with the other side of the magnet" width="271" height="300" class="size-medium wp-image-1573" /></a><p class="wp-caption-text">Activated with the other side of the magnet</p></div></p>
<p>By alternating the polarity of the magnetic field (e.g. use the opposite side of the magnet), the LEDs will alternate between blue and red, depending on the polarity used.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.kerrywong.com/2009/12/05/a-hall-effect-magnetic-field-polarity-detector/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>A Simple Thread Barrier Implementation</title>
		<link>http://www.kerrywong.com/2009/11/27/a-simple-thread-barrier-implementation/</link>
		<comments>http://www.kerrywong.com/2009/11/27/a-simple-thread-barrier-implementation/#comments</comments>
		<pubDate>Sat, 28 Nov 2009 01:03:38 +0000</pubDate>
		<dc:creator>kwong</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[Barrier]]></category>
		<category><![CDATA[C Sharp (C#)]]></category>
		<category><![CDATA[Multi-threading]]></category>

		<guid isPermaLink="false">http://www.kerrywong.com/?p=1540</guid>
		<description><![CDATA[Sometimes a group of concurrently running threads may need to rendezvous at a certain point in time before they can further proceed. This situation commonly arises in areas like event simulation, where the events are synchronized via a clock event (see illustration below):
In the above example, a number of threads start at different times with [...]]]></description>
			<content:encoded><![CDATA[<p>Sometimes a group of concurrently running threads may need to rendezvous at a certain point in time before they can further proceed. This situation commonly arises in areas like event simulation, where the events are synchronized via a clock event (see illustration below):<span id="more-1540"></span><br />
<div id="attachment_1541" class="wp-caption aligncenter" style="width: 620px"><a href="http://www.kerrywong.com/blog/wp-content/uploads/2009/11/eventbarrier.gif"><img src="http://www.kerrywong.com/blog/wp-content/uploads/2009/11/eventbarrier.gif" alt="Event Barrier" title="Event Barrier" width="610" height="176" class="size-full wp-image-1541" /></a><p class="wp-caption-text">Event Barrier</p></div></p>
<p>In the above example, a number of threads start at different times with the arrival of each clock event and wait till all threads finish running before the next clock event arrives.</p>
<p>Such <a href="http://en.wikipedia.org/wiki/Barrier_%28computer_science%29">barrier</a> can be implemented using various techniques with different level of difficulties. <a href="http://www.albahari.com/threading/part3.aspx#_Thread_Pooling">One possible implementation</a> can be found in  <a href="http://www.albahari.com/threading/">Joseph Albahari&#8217;s Threading in C#</a> where a monitor construct is used to wait on a synchronization object in the main thread after the worker threads are queued. </p>
<pre class="brush: csharp;">
    lock (workerLocker)
    {
      while (runningWorkers &gt; 0)
        Monitor.Wait (workerLocker);
    }
</pre>
<p>In each of the worker thread, the number of running workers is decremented when the thread finishes:</p>
<pre class="brush: csharp;">
    lock (workerLocker)
    {
      runningWorkers--;
      Monitor.Pulse (workerLocker);
    }
</pre>
<p>And when the running number of workers reaches zero, the monitor exist the wait condition and the main thread continues.</p>
<p>The wait on the locker object forms a barrier in the example above. The method illustrated here is simple and elegant. It can be used to create the barriers needed to synchronize the clock event mentioned earlier.</p>
<p>Threadpooling might not always be the optimal solution though. While the number of threads in a thread pool is typically bounded to a few dozens, it may incur excessive context switching penalties if the majority of the threads are CPU bound. In a computation intensive situation, a fixed number of threads approximating the number of computational cores would be more appropriate (for instance, four threads on a four core CPU).</p>
<p>Here I will show another relatively simple way to construct a barrier where only a predetermined maximum number of threads can reach at a given time. To achieve such a ceiling, a global semaphore is used (in this example three concurrent threads can enter the semaphore):</p>
<pre class="brush: csharp;">
public class Global
{
    public static Semaphore sp = new Semaphore(3, 3);
}
</pre>
<p>To simplify coding and shield the programmer from the synchronization mechanism details, I created an <strong>IEvent</strong> interface and an abstract <strong>EventBase</strong> as follows:</p>
<pre class="brush: csharp;">
interface IEvent
{
    void OnEvent(int arg);
}
</pre>
<pre class="brush: csharp;">
public abstract class EventBase : IEvent
{
    #region IEvent Members
    public void OnEvent(int arg)
    {
        Global.sp.WaitOne();
        Run(arg);
        Global.sp.Release();
    }
    #endregion

    public virtual void Run(int arg)
    {
    }
}
</pre>
<p>Users can simply implement their code that needs to block at the barrier by inheriting from <strong>EventBase</strong> and overridding the <strong>Run()</strong> method:</p>
<pre class="brush: csharp;">
public class Event1 : EventBase
{
    public override void Run(int arg)
    {
        Console.WriteLine(&quot;Thread {0}, arg {1}&quot;, Thread.CurrentThread.ManagedThreadId, arg);
        Thread.Sleep(1000);
    }
}
</pre>
<p>To illustrate how this barrier implementation can be used considering the following code:</p>
<pre class="brush: csharp;">
class Program
{
    delegate void MyEvent(int arg);

    static void Main(string[] args)
    {
        IEvent e = new Event1();
        MyEvent m = new MyEvent(e.OnEvent);

        List&lt;IAsyncResult&gt; l = new List&lt;IAsyncResult&gt;();

        for (int i = 0 ; i &lt; 6 ; i++)
        {
          IAsyncResult r = m.BeginInvoke(i, null, null);
          l.Add(r);
        }

        foreach (IAsyncResult r in l)
        {
            m.EndInvoke(r);
        }
    }
}
</pre>
<p>In the code above, we simulate six concurrent threads that need to be synchronized. The multi-threading is achieved via asynchronous invocation. Because the capacity of the semaphore is set to be 3 in this example and if this code is run on a quad-core machine, you will see that the six asynchronous threads are run in two batches, three at a time. And all the threads are synchronized at the end. Here is the sample output:</p>
<blockquote><p>
Thread 10, arg 1<br />
Thread 11, arg 2<br />
Thread 6, arg 0<br />
Thread 13, arg 4<br />
Thread 10, arg 5<br />
Thread 12, arg 3
</p></blockquote>
<p>Using this approach, the number of concurrently running threads can be precisely controlled by the maximum threads allowed in the semaphore.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.kerrywong.com/2009/11/27/a-simple-thread-barrier-implementation/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>A Simple Program for Finding Palindromic Prime Numbers</title>
		<link>http://www.kerrywong.com/2009/11/15/a-simple-program-for-finding-palindromic-prime-numbers/</link>
		<comments>http://www.kerrywong.com/2009/11/15/a-simple-program-for-finding-palindromic-prime-numbers/#comments</comments>
		<pubDate>Mon, 16 Nov 2009 01:49:08 +0000</pubDate>
		<dc:creator>kwong</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[Miscellaneous]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[Palindromic Prime Number]]></category>
		<category><![CDATA[Palprime]]></category>
		<category><![CDATA[Prime Number]]></category>

		<guid isPermaLink="false">http://www.kerrywong.com/?p=1527</guid>
		<description><![CDATA[A palindromic prime (palprime) is a prime number that is also palindromic. So out of curiosity I wrote a simple program a few days ago that can find the palindromic numbers within a given range. Here is the code in C++:

#include &#60;stdio.h&#62;
#include &#60;stdlib.h&#62;
#include &#60;limits.h&#62;
#include &#60;math.h&#62;
#include &#60;iostream&#62;

using namespace std;

bool IsPrime(unsigned long long n) {
	bool r = [...]]]></description>
			<content:encoded><![CDATA[<p>A <a href="http://mathworld.wolfram.com/PalindromicPrime.html">palindromic prime</a> (palprime) is a prime number that is also palindromic. So out of curiosity I wrote a simple program a few days ago that can find the palindromic numbers within a given range. Here is the code in C++:<span id="more-1527"></span></p>
<pre class="brush: cpp;">
#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;limits.h&gt;
#include &lt;math.h&gt;
#include &lt;iostream&gt;

using namespace std;

bool IsPrime(unsigned long long n) {
	bool r = true;

	for (unsigned long long i = 3; i &lt; sqrt((double) n) + 1; i+= 2)
	{
		if (n % i ==0) {
			r = false;
			break;
		}
	}

	return r;
}

bool IsPalindrome(unsigned long long n) {
	bool r = true;
	char s[30];
	int l = sprintf(s, &quot;%llu&quot;, n);

	if (l == 1 &amp;&amp; n != 1) {
		r = true;
	} else	{
		for (int i = 0; i &lt; l/2; i++) {
			if (s[i] != s[l-i-1]) {
				r = false;
				break;
			}
		}
	}

	return r;
}

/*
 * usage: palprime [lbound] [ubound]
 */
int main(int argc, char** argv) {
	unsigned long long beginNum = 3;
	unsigned long long endNum = 3;

	if (argc == 2) { // lbound default to 3
#ifdef _WIN32
		endNum = _strtoui64(argv[1], NULL, 10);
#else
		endNum = strtoull(argv[1], NULL, 10);
#endif

	} else if (argc == 3) {
#ifdef _WIN32
		beginNum = _strtoui64(argv[1], NULL, 10);
		endNum = _strtoui64(argv[2], NULL, 10);
#else
		beginNum = strtoull(argv[1], NULL, 10);
		endNum = strtoull(argv[2], NULL, 10);
#endif
	}

        unsigned long long i = beginNum;

        while (i &lt; endNum) {
                char s[30];
                int l = sprintf(s, &quot;%llu&quot;, i);

		//length cannot be even as even length palindrome numbers
		//can be divided by 11.
                if (l % 2 == 0) {
                    i = ((unsigned long long) (i / 10)) * 100 + 1;
                    continue;
                }

		if (IsPalindrome(i)) {
			if (IsPrime(i)) {
				cout &lt;&lt; i &lt;&lt; endl;
			}
		}

                i+=2;

                if (s[0] % 2 == 0) {
                    i+=pow(10, l-1);

		    //leading/ending number cannot be 5
                    if (((int) (s[0] - '0')) + 1 == 5) {
                        i += 2 * pow(10, l-1);
                    }
                }
	}
	return (EXIT_SUCCESS);
}
</pre>
<p>At first, I was trying to find all the palprimes that can be represented by 64 bit integers. But soon I realized that it would take months to do so using the code above with a quad-core PC (using 4 processes with different ranges). Anyway, here&#8217;s the last few palindromic primes less than 10,000,000,000,000:</p>
<blockquote><p>
9999899989999<br />
9999901099999<br />
9999907099999<br />
9999913199999<br />
9999919199999<br />
9999938399999<br />
9999961699999<br />
9999970799999<br />
9999980899999<br />
9999987899999
</p></blockquote>
<p>And here are a few interesting ones:</p>
<blockquote><p>
11357975311<br />
1112345432111<br />
1300000000031<br />
1700000000071<br />
1900000000091<br />
7900000000097<br />
9200000000029<br />
1357900097531
</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://www.kerrywong.com/2009/11/15/a-simple-program-for-finding-palindromic-prime-numbers/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>CFL Capacitor Problem</title>
		<link>http://www.kerrywong.com/2009/11/08/cfl-capacitor-problem/</link>
		<comments>http://www.kerrywong.com/2009/11/08/cfl-capacitor-problem/#comments</comments>
		<pubDate>Mon, 09 Nov 2009 02:03:01 +0000</pubDate>
		<dc:creator>kwong</dc:creator>
				<category><![CDATA[Miscellaneous]]></category>
		<category><![CDATA[Compact Fluorescent Lamp]]></category>

		<guid isPermaLink="false">http://www.kerrywong.com/?p=1511</guid>
		<description><![CDATA[Many of you may still remember the capacitor plague that caused massive motherboard failures back in the early 2000s. While the practice of using cheap and unreliable electrolytic capacitors in computer components has largely died down nowadays, it seems that the issue has cropped up elsewhere. 
This time,  the issue is with cheap capacitors [...]]]></description>
			<content:encoded><![CDATA[<p>Many of you may still remember the <a href="http://en.wikipedia.org/wiki/Capacitor_plague">capacitor plague</a> that caused massive motherboard failures back in the early 2000s. While the practice of using cheap and unreliable <a href="http://en.wikipedia.org/wiki/Electrolytic_capacitor">electrolytic capacitors</a> in computer components has largely died down nowadays, it seems that the issue has cropped up elsewhere. <span id="more-1511"></span></p>
<p>This time,  the issue is with cheap capacitors used in some compact fluorescent light (CFL) bulbs. The following photo is taken from the electronic ballast of a CFL that failed during the first year of its use:<br />
<div id="attachment_1516" class="wp-caption aligncenter" style="width: 330px"><a href="http://www.kerrywong.com/blog/wp-content/uploads/2009/11/badcap.jpg"><img src="http://www.kerrywong.com/blog/wp-content/uploads/2009/11/badcap.jpg" alt="Bad Capacitor in CFL electronic ballast" title="Bad Capacitor in CFL electronic ballast" width="320" height="398" class="size-full wp-image-1516" /></a><p class="wp-caption-text">Bad Capacitor in CFL electronic ballast</p></div></p>
<p>As you can see that the bulging top clearly shows signs of leakage. The capacitor used in this particular CFL is rated 22uf/200V with a maximum operating temperature of 105 degree (Celsius). Under normal conditions, this capacitor should be fine. But with a lot of interior light fixtures that are recessed into the ceiling, the heat generated during normal operation can easily approach this limit and causes the CFL to fail prematurely. Many failed CFLs I had over the past few years exhibited similar capacitor problems. And apparently, the general quality issue of CFLs <a href="http://www.nytimes.com/2009/03/28/business/energy-environment/28bulbs.html">has been concerning</a>.</p>
<p>It seems to me though that the easiest way to fix this issue is for manufacturers to use electrolytic capacitors with higher operating temperature rating and lower <a href="http://en.wikipedia.org/wiki/Equivalent_series_resistance">ESR</a>. Since the majority of CFL electronic ballasts utilize only one electrolytic capacitor, the increase in cost should be minimum.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.kerrywong.com/2009/11/08/cfl-capacitor-problem/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Weekend Ubuntu Upgrade</title>
		<link>http://www.kerrywong.com/2009/11/01/weekend-ubuntu-upgrade/</link>
		<comments>http://www.kerrywong.com/2009/11/01/weekend-ubuntu-upgrade/#comments</comments>
		<pubDate>Mon, 02 Nov 2009 00:52:16 +0000</pubDate>
		<dc:creator>kwong</dc:creator>
				<category><![CDATA[Linux/BSD]]></category>
		<category><![CDATA[Ubuntu]]></category>

		<guid isPermaLink="false">http://www.kerrywong.com/?p=1504</guid>
		<description><![CDATA[Karmic Koala was released into the wild last Thursday, so naturally I was going to upgrade my desktop installations at home. In this past I had been doing fresh installs whenever there was a new release, since there might be some issues with the new Ext4 file system, I decided to upgrade my current 9.04 [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://releases.ubuntu.com/karmic/">Karmic Koala</a> was released into the wild last Thursday, so naturally I was going to upgrade my desktop installations at home. In this past I had been doing fresh installs whenever there was a new release, since there might be <a href="https://bugs.launchpad.net/ubuntu/+source/linux/+bug/453579">some issues</a> with the new Ext4 file system, I decided to upgrade my current 9.04 installation in place and perform a fresh installation when the Ext4 file system stabilizes.<span id="more-1504"></span></p>
<p>Since I had quite a few unofficial packages installed on my primary PC, I was not quite sure how the upgrade would turn out and I was prepared to see a few gotchas at some point. But the upgrade process was surprisingly smooth (albeit slow since all new versions of the installed packages had to be fetched first), and when the upgrade process is done I was able to boot into the new desktop. The only thing I needed to do was to re-install the <a href="http://www.nvidia.com/object/cuda_get.html">CUDA driver</a> (190.18), but this was to be expected since every major kernel updates would require the CUDA driver to be re-installed. I certainly hope that NVidia would make their proprietary binary drivers  more robust by detecting kernel changes and reinstall automatically if necessary as opposed to require the end user&#8217;s manual intervention. </p>
<p>For my other machine running Ubuntu 9.04, the upgrade was equally smooth. One of the problems I ran into there was due to my VMWare Server installation. As it turned out, there are <a href="http://www.uluga.ubuntuforums.org/showthread.php?t=1305254">some issues</a> with the default installation package that came with VMWare Server 2. The problem however can be resolved with <a href="http://radu.cotescu.com/2009/10/30/how-to-install-vmware-server-2-0-x-on-ubuntu-9-10-karmic-koala/">Radu&#8217;s installation script</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.kerrywong.com/2009/11/01/weekend-ubuntu-upgrade/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Windows Administrative Share With Samba</title>
		<link>http://www.kerrywong.com/2009/10/04/windows-administrative-share-with-samba/</link>
		<comments>http://www.kerrywong.com/2009/10/04/windows-administrative-share-with-samba/#comments</comments>
		<pubDate>Sun, 04 Oct 2009 17:55:33 +0000</pubDate>
		<dc:creator>kwong</dc:creator>
				<category><![CDATA[Linux/BSD]]></category>
		<category><![CDATA[Samba]]></category>

		<guid isPermaLink="false">http://www.kerrywong.com/?p=1482</guid>
		<description><![CDATA[In a heterogeneous computing environment (e.g. Linux and Windows), it is necessary to use Samba to share files between the Linux systems and Windows systems. Due to the security enhancements in Windows XP SP2 and above however, the administrative share access (e.g. \\{computer name}\c$ is disabled by default.
To enable administrative share access from Linux hosts, [...]]]></description>
			<content:encoded><![CDATA[<p>In a heterogeneous computing environment (e.g. Linux and Windows), it is necessary to use <a href="http://samba.org/">Samba</a> to share files between the Linux systems and Windows systems. Due to the security enhancements in Windows XP SP2 and above however, the administrative share access (e.g. \\{<strong><em>computer name</em></strong>}\c$ is disabled by default.<span id="more-1482"></span></p>
<p>To enable administrative share access from Linux hosts, we need to change the Windows machine&#8217;s security policy. My assumption is that you are using Windows XP. You may need to make further changes depending on the version of Windows you are using.</p>
<p>The security policy snap-in is located at </p>
<blockquote><p>c:\windows\system32\secpol.msc</p></blockquote>
<p>Select local policies and then Security Options:<br />
<a href="http://www.kerrywong.com/blog/wp-content/uploads/2009/10/security_setting.gif"><img src="http://www.kerrywong.com/blog/wp-content/uploads/2009/10/security_setting.gif" alt="security_setting" title="security_setting" width="600" height="424" class="aligncenter size-full wp-image-1496" /></a><br />
Then select sharing and security model for local accounts:<br />
<a href="http://www.kerrywong.com/blog/wp-content/uploads/2009/10/security_setting_1.gif"><img src="http://www.kerrywong.com/blog/wp-content/uploads/2009/10/security_setting_1.gif" alt="security_setting_1" title="security_setting_1" width="418" height="505" class="aligncenter size-full wp-image-1495" /></a></p>
<p>Under the enhanced security scheme, &#8220;Guest only: local users authenticate as guests&#8221; is chosen. This policy means that administrative network access is treated as if it was done with a guest account and therefore you would get permission denied error when trying to access an administrative share &#8212; even though your account has administrative rights locally.</p>
<p>To allow administrative share on Samba network, you can simply select the other option &#8220;Classic: local users authenticate as themselves&#8221;.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.kerrywong.com/2009/10/04/windows-administrative-share-with-samba/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>An Alternative Illustration of Prime Number Distribution</title>
		<link>http://www.kerrywong.com/2009/09/06/an-alternative-illustration-of-prime-number-distribution/</link>
		<comments>http://www.kerrywong.com/2009/09/06/an-alternative-illustration-of-prime-number-distribution/#comments</comments>
		<pubDate>Sun, 06 Sep 2009 14:40:04 +0000</pubDate>
		<dc:creator>kwong</dc:creator>
				<category><![CDATA[Miscellaneous]]></category>
		<category><![CDATA[Distribution]]></category>
		<category><![CDATA[Histogram]]></category>
		<category><![CDATA[Prime Number]]></category>

		<guid isPermaLink="false">http://www.kerrywong.com/?p=1441</guid>
		<description><![CDATA[Prime number theorem dictates the asymptotic behavior of prime number distributions. In layman terms, the distance between prime numbers increases at a logarithmic pace. This gives the familiar logarithm figure.
Alternatively, if we “bin” the prime numbers according to the differences (gaps) between two consecutive prime numbers, we would yield another logarithmic distribution: the histogram of [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://en.wikipedia.org/wiki/Prime_number_theorem">Prime number theorem</a> dictates the asymptotic behavior of prime number distributions. In layman terms, the distance between prime numbers increases at a logarithmic pace. This gives the familiar logarithm figure.<span id="more-1441"></span></p>
<p>Alternatively, if we “bin” the prime numbers according to the differences (gaps) between two consecutive prime numbers, we would yield another logarithmic distribution: the histogram of such differences will be logarithmic as well.</p>
<p>So, take the following sequence of prime numbers for example:</p>
<blockquote><p>2, 3, 5, 7, 11, 13, 17, 19, 23, 29&#8230;</p></blockquote>
<p>The distances between the consecutive numbers in the above sequence are:</p>
<blockquote><p>
3-2 = 1<br />
5-3 = 2<br />
7-5 = 2<br />
11-7 = 4<br />
19-17 = 2<br />
23-19 = 4<br />
29-23 = 6
</p></blockquote>
<p>We then calculate the histogram based on the gaps. </p>
<p>Denote the histogram bin index as<br />
\[i = \lfloor\frac{d}{2}\rfloor\]</p>
<p>For the example above, we get the following distributions for H[i]:<br />
\[H[0] = 1, H[1] = 3 H[2]=2, H[3]=1\]</p>
<p>Now we calculate the distribution (H[i]) described above using prime numbers within the following interval (for all prime numbers up to 4,294,967,291):<br />
\[[2^0, 2^{32}]\]</p>
<p>We can obtain the following plot for the histogram (H[i]):<br />
<div id="attachment_1474" class="wp-caption aligncenter" style="width: 610px"><a href="http://www.kerrywong.com/blog/wp-content/uploads/2009/09/hist.jpg"><img src="http://www.kerrywong.com/blog/wp-content/uploads/2009/09/hist.jpg" alt="Prime number distribution" title="Prime number distribution" width="600" height="450" class="size-full wp-image-1474" /></a><p class="wp-caption-text">Prime number distribution</p></div></p>
<p>To illustrate that the distribution is indeed around a logarithm curve, we take the logrithms of the values for each H[i] and get the following figure:</p>
<div id="attachment_1475" class="wp-caption aligncenter" style="width: 610px"><a href="http://www.kerrywong.com/blog/wp-content/uploads/2009/09/hist_log.jpg"><img src="http://www.kerrywong.com/blog/wp-content/uploads/2009/09/hist_log.jpg" alt="Prime number distribution" title="Prime number distribution" width="600" height="450" class="size-full wp-image-1475" /></a><p class="wp-caption-text">Prime number distribution</p></div>
<p>As you can see, the distribution is around a straight line.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.kerrywong.com/2009/09/06/an-alternative-illustration-of-prime-number-distribution/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Why Current EVs Do Not Make Sense From Economical And Environmental View Points</title>
		<link>http://www.kerrywong.com/2009/08/15/why-current-evs-do-not-make-sense-from-economical-and-environmental-view-points/</link>
		<comments>http://www.kerrywong.com/2009/08/15/why-current-evs-do-not-make-sense-from-economical-and-environmental-view-points/#comments</comments>
		<pubDate>Sat, 15 Aug 2009 23:32:49 +0000</pubDate>
		<dc:creator>kwong</dc:creator>
				<category><![CDATA[Miscellaneous]]></category>
		<category><![CDATA[Electric Vehicle]]></category>
		<category><![CDATA[Hybrid Car]]></category>

		<guid isPermaLink="false">http://www.kerrywong.com/?p=1432</guid>
		<description><![CDATA[About two years ago, I blogged about why hybrids were not saving us any energy by taking into consideration the amount of energy needed to produce the vast battery packs and the inherent low efficiencies in battery technologies.
Now, two years later after crude oil price peeked and then stabilized amidst the economic turmoil, the main [...]]]></description>
			<content:encoded><![CDATA[<p>About two years ago, I blogged about <a href="/2007/04/30/do-hybrid-cars-really-save-energy/">why hybrids were not saving us any energy</a> by taking into consideration the amount of energy needed to produce the vast battery packs and the inherent low efficiencies in battery technologies.<span id="more-1432"></span></p>
<p>Now, two years later after crude oil price peeked and then stabilized amidst the economic turmoil, the main reason for companies from Toyota and GM alike to push for new electric and hybrid vehicles seems to me is to show case their technological capabilities and ride along the buzz generated many years ago when the first generation Prius first hit the road. Using the technologies available to us today and in the immediate future, the advantage in terms of environmental impacts of these alternative vehicles such as the hybrid and electric cars remains unclear. And at their current state, it is doubtful that these alternative drivetrains make any economical sense.</p>
<p>Take electric cars for example. From an environmental point of view, while electrical vehicles by themselves do not generate any greenhouse emissions like their gasoline and diesel counterparts, the manufacturing process of the batteries that go into these EVs are likely to have a high environmental impact. The extraction of precious metals and the creation of some of the chemical compounds that used in these high energy density battery packs are likely to consume more energy than the well established process for engine manufacturing. And much of that energy is coming from electrical power plants that use fossil fuel for electricity generation. The “cleaner” nature of EVs is merely because of the redistribution of pollution over different stages of their life cycles and over different geographic areas.</p>
<p>From an economical stand point, today’s manufacturing processes to produce batteries used in the electrical vehicles remain very expensive and the cost of which constitutes a significant portion of the overall cost of the vehicle. And because batteries must be plugged into the grid for charging, it relies on the cost of electricity in order to make economical sense. It seems funny to me that at a time when people prefer natural gas based heating system and shy away from electrical baseboards due to cost considerations, it would somehow be cheaper to charge the EVs off the grid on a daily basis. We know that the power requirement for the electrical vehicles dwarfs some of the most power hungry household electrical systems. Until we are further removed from fossil fuels in our electricity generation process, the cost saving of using EVs is hardly justified. We are having the illusion of savings due to government subsidy and the lower day-to-day operating expenses. The initial investment buying an EV, however, is likely to be much bigger than that of a traditional gasoline counterpart.</p>
<p>Reliability remains a big concern for EVs and hybrids, particularly for EVs. As I discussed <a href="/2007/04/30/do-hybrid-cars-really-save-energy/">before</a>, given the complexity of the hybrid powertrains and the inherent reliability issues of the battery banks, it remains unknown how the long-term reliability (e.g. over a time span of 20 years) of these EVs compare against that of the more traditional vehicles. So even though electric motors are generally much more reliable than gasoline engines, the current state of battery technology significantly limits the overall reliability of these battery powered vehicles.</p>
<p>Another not-so-obvious problem of EVs is related to the power-hungry auxiliary systems (e.g. Heater, air conditioner, audio amplifier, etc). Using these systems will significantly shorten the advertised range and EVs may have to rely on an alternative power-generating unit (e.g. a regular gas powered motor) to generate the additional power needed while using these auxiliary systems. </p>
<p>To improve EV performance, companies have invested heavily and concentrated on reducing the overall weight of the vehicles by using lighter materials such as carbon fibers for the body frames. If we were to adopt a similar approach in today’s gasoline car manufacturing process and reduce the weight of the vehicles, we would significantly reduce the power requirement and thus be able to reduce the engine sizes and ultimately reduce emissions as well.</p>
<p>So, the long term viability of the current electrical vehicles remains to be seen.</p>
<h3>References:</h3>
<ul>
<li>
<a href="http://money.cnn.com/2009/08/11/autos/volt_mpg/index.htm?postversion=2009081108">Chevy volt to get 230 mpg rating</a>
</li>
<li>
<a href="http://tech.slashdot.org/comments.pl?sid=1332901">Slashdot comments</a> on Chevy Volt Rated At 230 mpg In the City
</li>
<li>
<a href="http://www.evworld.com/article.cfm?storyid=1361">Electric Vehicles and the Environment</a>
</li>
<li>
<a href="http://www.typesofenergy.co.uk/electric-vehicles-environment.html">http://www.typesofenergy.co.uk/electric-vehicles-environment.html</a>
</li>
<li>
<a href="http://agmetalminer.com/2009/08/12/a-different-take-on-the-gm-volt-announcement/">A Different Take on the GM Volt Announcement</a>
</li>
<li>
<a href="http://clipmarks.forbes.com/2009/08/11/chevy-volt-part-ii-mileage-but-at-what-cost/">Chevy Volt (part II): 230 MPG, but at what cost?</a>
</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.kerrywong.com/2009/08/15/why-current-evs-do-not-make-sense-from-economical-and-environmental-view-points/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Strange Windows Authentication Behavior</title>
		<link>http://www.kerrywong.com/2009/07/30/strange-windows-authentication-behavior/</link>
		<comments>http://www.kerrywong.com/2009/07/30/strange-windows-authentication-behavior/#comments</comments>
		<pubDate>Thu, 30 Jul 2009 12:13:59 +0000</pubDate>
		<dc:creator>kwong</dc:creator>
				<category><![CDATA[Miscellaneous]]></category>
		<category><![CDATA[SQL Server]]></category>

		<guid isPermaLink="false">http://www.kerrywong.com/?p=1429</guid>
		<description><![CDATA[I was writing an ASP.Net 2.0 web application using Windows authentication (since I needed to capture users’ credentials). The web application saves data into a MS SQL 2005 database using a SQL server account. While developing this application, I ran into a very strange issue.
Since the database access is using a SQL Server account rather [...]]]></description>
			<content:encoded><![CDATA[<p>I was writing an ASP.Net 2.0 web application using Windows authentication (since I needed to capture users’ credentials). The web application saves data into a MS SQL 2005 database using a SQL server account. While developing this application, I ran into a very strange issue.<span id="more-1429"></span></p>
<p>Since the database access is using a SQL Server account rather than integrated authentication, in theory the database access code should not be affected by whether I use Forms authentication or Windows authentication in the web application. </p>
<p>However, the problem I ran into was that if I use Forms authentication mode, everything works fine. But if I switch the authentication mode to Windows, I would get the following error message emitted from the data access layer after the application was deployed to the server:</p>
<blockquote><p>A network-related or instance-specific error occurred while establishing a connection to SQL Server. The server was not found or was not accessible. Verify that the instance name is correct and that SQL Server is configured to allow remote connections. (provider: Named Pipes Provider, error: 40 &#8211; Could not open a connection to SQL Server) </p></blockquote>
<p>What is weirder is that if I tried to use the application locally on the web server after deployment, everything would work fine. And after &#8220;touching&#8221; the deployed website on the server, the web pages can then be remotely accessed via client browser for a while (10 minutes maybe) but after that the same error would occur again.</p>
<p>So I searched many forums but could not find any conclusive explanations or remedies.</p>
<h3>The Not So Satisfying Solution</h3>
<p>One of my coworkers took a look at my code and confirmed that there were no coding errors but noticed that I did not have port information in the connection string (Note, even though we use non-standard ports, this has never been necessary). So as he suggested, I plugged in the port number and it worked!</p>
<p>Clearly, I am still as confused as before. The authentication modes differences must have somehow affected the way the connection string is interpreted&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.kerrywong.com/2009/07/30/strange-windows-authentication-behavior/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Monodevelop on Ubuntu 9.04</title>
		<link>http://www.kerrywong.com/2009/07/22/monodevelop-on-ubuntu-9-04/</link>
		<comments>http://www.kerrywong.com/2009/07/22/monodevelop-on-ubuntu-9-04/#comments</comments>
		<pubDate>Wed, 22 Jul 2009 04:00:04 +0000</pubDate>
		<dc:creator>kwong</dc:creator>
				<category><![CDATA[Linux/BSD]]></category>
		<category><![CDATA[Miscellaneous]]></category>
		<category><![CDATA[C Sharp (C#)]]></category>
		<category><![CDATA[Mono]]></category>
		<category><![CDATA[Ubuntu]]></category>

		<guid isPermaLink="false">http://www.kerrywong.com/?p=1408</guid>
		<description><![CDATA[I am running Ubuntu 9.04 64bit. One thing I noticed is that the integrated debugger is behaving quite flaky for the included Monodevelop 2.0 package. After some research, it turned out that a lot of people are having similar issues.
So I followed the instructions given in these two blogs: Install Mono 2.4 on Ubuntu,
Building Mono [...]]]></description>
			<content:encoded><![CDATA[<p>I am running Ubuntu 9.04 64bit. One thing I noticed is that the integrated debugger is behaving quite flaky for the included <a href="http://monodevelop.com/">Monodevelop 2.0</a> package. After some research, it turned out that a lot of people are having similar issues.<span id="more-1408"></span></p>
<p>So I followed the instructions given in these two blogs: <a href="http://blog.ruski.co.za/page/Install-Mono-on-Ubuntu.aspx">Install Mono 2.4 on Ubuntu</a>,<br />
<a href="http://synpl.blogspot.com/2009/07/building-mono-and-monodevelop-from.html">Building Mono and MonoDevelop from source on Ubuntu 9.04 64bit</a> to re-install Monodevelop 2.0 and its dependencies from the source. </p>
<p>One thing you will need to pay special attention to is that for the monodevelop-debugger-mdb-2.0 to compile successfully, you will need mono-debugger version 2.4, instead of the latest version 2.4.1. Otherwise you will receive an error on <em>Thread.AbortInvocation</em> as there is a breaking change in mono-debugger 2.4.1 which added a parameter to the method (see <a href="http://lists.ximian.com/pipermail/mono-patches/2009-May/149225.html">mono debugger 2.4.1 change log</a>).</p>
]]></content:encoded>
			<wfw:commentRss>http://www.kerrywong.com/2009/07/22/monodevelop-on-ubuntu-9-04/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Poor Man&#8217;s Parallel Task Dispatcher</title>
		<link>http://www.kerrywong.com/2009/07/14/poor-mans-parallel-task-dispatcher/</link>
		<comments>http://www.kerrywong.com/2009/07/14/poor-mans-parallel-task-dispatcher/#comments</comments>
		<pubDate>Wed, 15 Jul 2009 01:55:39 +0000</pubDate>
		<dc:creator>kwong</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[C Sharp (C#)]]></category>
		<category><![CDATA[Mono]]></category>
		<category><![CDATA[Multi-threading]]></category>

		<guid isPermaLink="false">http://www.kerrywong.com/?p=1392</guid>
		<description><![CDATA[Even though multi-core processors are almost ubiquitous nowadays, applications are slow to catch up. Of course, one could always re-write the applications in order to take the full advantages in a multi-core environment. But it is not an easy undertaking. For applications that performs rather repetitive tasks over a well defined set of data (e.g. [...]]]></description>
			<content:encoded><![CDATA[<p>Even though multi-core processors are almost ubiquitous nowadays, applications are slow to catch up. Of course, one could always re-write the applications in order to take the full advantages in a multi-core environment. But it is not an easy undertaking.<span id="more-1392"></span> For applications that performs rather repetitive tasks over a well defined set of data (e.g. image processing) it is relatively easy to utilize multiple cores with some simple modifications to the applications themselves. </p>
<p>For the type of applications that perform the same task over a large dataset for example,</p>
<pre class="brush: csharp;">
for (int i = 0 ; i &lt; num ; i++)
{
    //lengthy tasks
}
</pre>
<p>we could easily break down the <em>for loop</em> evenly into chunks that fit into the number of processors given. And for each of the subsets we could create a new process to perform the desired tasks. For instance, if we were to execute the above <em>for loop</em> in parallel on a duo-core processor, we could re-write each of the loops like the following:</p>
<pre class="brush: csharp;">
//core 1
for (int i = 0 ; i &lt; num ; i+=2)
{
    //lengthy tasks
}
</pre>
<pre class="brush: csharp;">
//core 2
for (int i = 1 ; i &lt; num ; i+=2)
{
    //lengthy tasks
}
</pre>
<p>By executing the application in separate processes, we eliminated certain race conditions that must be properly handled in a multi-threaded process and thus it is far easier to execute multiple processes concurrently when there is no inter-process communications involved than to handle multi-processing within a process via multi-threading. In a multi-process scenario, the operating system handles the concurrency issue behind the scene whereas in the multi-threading case the application developer must ensure the code regions are thread safe.</p>
<p>The following C# code shows how to dispatch tasks among different processes using asynchronous method invocations. Each process being invoked can identify its order by the extra integer parameter (line 36) passed to it. Thus we only needed to modify the target application to take this extra parameter into account (for instance, in a quad-core system, the first process would process items 1,5,9&#8230; and the second process would run items 2,6,10, and so on)</p>
<pre class="brush: csharp;">
using System;
using System.Diagnostics;
using System.Threading;

namespace MPDispatcher
{
    class Program
    {
        public delegate bool CmdDlg(string fn, string args);

        private bool RunCommand(string fn, string args)
        {
            bool r = true;
            Process p = new Process();

            p.StartInfo.FileName = fn;
            p.StartInfo.Arguments = args;

			Console.WriteLine(String.Format(&quot;Starting {0} with arguments {1}. Thread ID: {2}&quot;, fn, args, Thread.CurrentThread.ManagedThreadId));
            r = p.Start();
            p.WaitForExit();

            return r;
        }

		public bool DispatchCommand(int numOfThreads, string args)
        {
            bool r = true;

            IAsyncResult[] ars = new IAsyncResult[numOfThreads];
            CmdDlg[] dlgs = new CmdDlg[numOfThreads];

            for (int i = 0; i &lt; numOfThreads; i++)
            {
                dlgs[i] = new CmdDlg(RunCommand);
                ars[i] = dlgs[i].BeginInvoke(args, i.ToString(), null, null);
				Thread.Sleep(100);
            }

            bool finished = false;

			//wait till all processes are finished.
            while (!finished)
            {
                bool t = true;

                for (int i = 0; i &lt; numOfThreads; i++)
                    t = t &amp;&amp; ars[i].IsCompleted;   

                if (t) finished = true;

                Thread.Sleep(100);
            }

            for (int i = 0; i &lt; numOfThreads; i++)
            {
                r = r &amp;&amp; dlgs[i].EndInvoke(ars[i]);
            }

            return r;
        }

        static void Main(string[] args)
        {
            Program p = new Program();

			if (args.Length &lt; 1 || args[0].ToUpper() == &quot;-H&quot;) {
				Console.WriteLine(&quot;Usage: MPDispatcher {app name} {app args}&quot;);
			} else {
				int numThreads = 4; //use 4 threads
				string argStr = string.Empty;

				for (int i = 1 ; i &lt; args.Length; i++) {
					argStr = String.Format(&quot;{0} {1}&quot;, argStr, args[i]);
				}

            	p.DispatchCommand(numThreads, argStr);
			}
        }
    }
}
</pre>
<p>The above code works under Windows and Linux (Mono). </p>
]]></content:encoded>
			<wfw:commentRss>http://www.kerrywong.com/2009/07/14/poor-mans-parallel-task-dispatcher/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Google Finance Down Earlier Today</title>
		<link>http://www.kerrywong.com/2009/07/06/google-finance-down-earlier-today/</link>
		<comments>http://www.kerrywong.com/2009/07/06/google-finance-down-earlier-today/#comments</comments>
		<pubDate>Tue, 07 Jul 2009 01:43:56 +0000</pubDate>
		<dc:creator>kwong</dc:creator>
				<category><![CDATA[Miscellaneous]]></category>
		<category><![CDATA[Cloud Computing]]></category>

		<guid isPermaLink="false">http://www.kerrywong.com/?p=1368</guid>
		<description><![CDATA[It appeared that Google Finance was down for at least half an hour (from before 9:30 EST till after 10:00 EST) today. I captured this screen-shot during the outage:
This is just the latest one of a string of high-profile outages from large corporations like Google (here&#8217;s an other outage less than two months ago) and [...]]]></description>
			<content:encoded><![CDATA[<p>It appeared that Google Finance was down for at least half an hour (from before 9:30 EST till after 10:00 EST) today. I captured this screen-shot during the outage:<span id="more-1368"></span></p>
<div id="attachment_1369" class="wp-caption aligncenter" style="width: 686px"><a href="http://www.kerrywong.com/blog/wp-content/uploads/2009/07/googlefinanceerror1.gif"><img src="http://www.kerrywong.com/blog/wp-content/uploads/2009/07/googlefinanceerror1.gif" alt="Google Finance Error" title="Google Finance Error" width="676" height="445" class="size-full wp-image-1369" /></a><p class="wp-caption-text">Google Finance Error</p></div>
<p>This is just the latest one of a string of high-profile outages from large corporations like Google (<a href="http://news.cnet.com/widespread-google-outages-rattle-users/">here&#8217;s an other outage less than two months ago</a>) and Microsoft (<a href="http://news.cnet.com/8301-1023_3-10279084-93.html">this outage</a> was on July 3, due to fire at a data center in Seattle).</p>
<p>It certainly does not bode well for those who tout <a href="http://en.wikipedia.org/wiki/Cloud_computing">cloud computing</a>. While in theory, larger cloud service providers like Google and Microsoft have the resources and capabilities to make their cloud services much more reliable. In practice, it doesn&#8217;t help when the services are down at the most unfortunate time when you need them the most.</p>
<p>I could see some benefits of using cloud computing in some non-essential business scenarios, but I doubt that any business would shift its core applications into the cloud. The reason is quite simple: For the bread-and-butter business applications, we need to know with confidence when the system will be down. When you host your own application, even if you don&#8217;t have control over everything (e.g. hardware failure) you at least can control when you implement changes. So while your applications might not be up 99% of the time, you could carefully plan the outage windows for the necessary maintenances to minimize any side effects to the normal business operations. </p>
<p>Of course, there are many other reasons why companies should not en-thrust their core businesses to the cloud. Some of the reasons are physical (e.g. a web service call will always be magnitudes slower than a in-process function call. And Internet speed will always be slower than intranet and significantly slower than memory speed), and some are philosophical. Like <a href="http://en.wikipedia.org/wiki/Richard_Stallman">Richard Stallman</a> once <a href="http://www.guardian.co.uk/technology/2008/sep/29/cloud.computing.richard.stallman">put it</a>:</p>
<blockquote><p>&#8220;One reason you should not use web applications to do your computing is that you lose control. It&#8217;s just as bad as using a proprietary program. Do your own computing on your own computer with your copy of a freedom-respecting program. If you use a proprietary program or somebody else&#8217;s web server, you&#8217;re defenseless. You&#8217;re putty in the hands of whoever developed that software.&#8221;</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://www.kerrywong.com/2009/07/06/google-finance-down-earlier-today/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Image Blur Detection via Hough Transform &#8212; IV</title>
		<link>http://www.kerrywong.com/2009/07/03/image-blur-detection-via-hough-transform-iv/</link>
		<comments>http://www.kerrywong.com/2009/07/03/image-blur-detection-via-hough-transform-iv/#comments</comments>
		<pubDate>Sat, 04 Jul 2009 01:06:30 +0000</pubDate>
		<dc:creator>kwong</dc:creator>
				<category><![CDATA[Miscellaneous]]></category>
		<category><![CDATA[Algorithm]]></category>
		<category><![CDATA[Blur Detection]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[Edge Detection]]></category>
		<category><![CDATA[Hough Transform]]></category>
		<category><![CDATA[Intel IPP]]></category>

		<guid isPermaLink="false">http://www.kerrywong.com/?p=1277</guid>
		<description><![CDATA[In my previous three articles (1,2,3) I discussed how to use Canny edge detection and Hough transform to identify blur images. Here I will show some results from the algorithm discussed before.
Results
When presented with images that are clear, the algorithm correctly identified most of them (see images below):
















The following images illustrate how the original image [...]]]></description>
			<content:encoded><![CDATA[<p>In my previous three articles (<a href="/2009/06/19/image-blur-detection-via-hough-transform-i/">1</a>,<a href="/2009/06/24/image-blur-detection-via-hough-transform-ii/">2</a>,<a href="/2009/06/27/image-blur-detection-via-hough-transform-iii/">3</a>) I discussed how to use Canny edge detection and Hough transform to identify blur images. Here I will show some results from the algorithm discussed before.<span id="more-1277"></span></p>
<h3>Results</h3>
<p>When presented with images that are clear, the algorithm correctly identified most of them (see images below):</p>
<table>
<tr>
<td>
<div id="attachment_1285" class="wp-caption aligncenter" style="width: 330px"><a href="http://www.kerrywong.com/blog/wp-content/uploads/2009/06/c1.jpg"><img src="http://www.kerrywong.com/blog/wp-content/uploads/2009/06/c1.jpg" alt="Building (Microsoft Research Digital Image)" title="Building (Microsoft Research Digital Image)" width="320" height="240" class="size-full wp-image-1285" /></a><p class="wp-caption-text">Building (Microsoft Research Digital Image)</p></div>
</td>
<td>
<div id="attachment_1286" class="wp-caption aligncenter" style="width: 330px"><a href="http://www.kerrywong.com/blog/wp-content/uploads/2009/06/c2.jpg"><img src="http://www.kerrywong.com/blog/wp-content/uploads/2009/06/c2.jpg" alt="Street (Microsoft Research Digital Image)" title="Street (Microsoft Research Digital Image)" width="320" height="240" class="size-full wp-image-1286" /></a><p class="wp-caption-text">Street (Microsoft Research Digital Image)</p></div>
</td>
</tr>
</table>
<table>
<tr>
<td>
<div id="attachment_1289" class="wp-caption aligncenter" style="width: 330px"><a href="http://www.kerrywong.com/blog/wp-content/uploads/2009/06/c5.jpg"><img src="http://www.kerrywong.com/blog/wp-content/uploads/2009/06/c5.jpg" alt="Sky" title="Sky" width="320" height="240" class="size-full wp-image-1289" /></a><p class="wp-caption-text">Sky</p></div>
</td>
<td>
<div id="attachment_1288" class="wp-caption aligncenter" style="width: 330px"><a href="http://www.kerrywong.com/blog/wp-content/uploads/2009/06/c4.jpg"><img src="http://www.kerrywong.com/blog/wp-content/uploads/2009/06/c4.jpg" alt="Flower" title="Flower" width="320" height="240" class="size-full wp-image-1288" /></a><p class="wp-caption-text">Flower</p></div>
</td>
</tr>
</table>
<p>The following images illustrate how the original image (top right) is divided into sub regions. Canny detection is performed on each of the sub images.</p>
<table>
<tr>
<td>
<a href="http://www.kerrywong.com/blog/wp-content/uploads/2009/07/1.jpg"><img src="http://www.kerrywong.com/blog/wp-content/uploads/2009/07/1.jpg" alt="1" title="1" width="214" height="160" class="aligncenter size-full wp-image-1300" /></a>
</td>
<td>
<a href="http://www.kerrywong.com/blog/wp-content/uploads/2009/07/4.jpg"><img src="http://www.kerrywong.com/blog/wp-content/uploads/2009/07/4.jpg" alt="4" title="4" width="214" height="160" class="aligncenter size-full wp-image-1303" /></a>
</td>
<td>
<a href="http://www.kerrywong.com/blog/wp-content/uploads/2009/07/7.jpg"><img src="http://www.kerrywong.com/blog/wp-content/uploads/2009/07/7.jpg" alt="7" title="7" width="214" height="160" class="aligncenter size-full wp-image-1306" /></a>
</td>
</tr>
<tr>
<td>
<a href="http://www.kerrywong.com/blog/wp-content/uploads/2009/07/2.jpg"><img src="http://www.kerrywong.com/blog/wp-content/uploads/2009/07/2.jpg" alt="2" title="2" width="214" height="160" class="aligncenter size-full wp-image-1301" /></a>
</td>
<td>
<a href="http://www.kerrywong.com/blog/wp-content/uploads/2009/07/5.jpg"><img src="http://www.kerrywong.com/blog/wp-content/uploads/2009/07/5.jpg" alt="5" title="5" width="214" height="160" class="aligncenter size-full wp-image-1304" /></a>
</td>
<td>
<a href="http://www.kerrywong.com/blog/wp-content/uploads/2009/07/8.jpg"><img src="http://www.kerrywong.com/blog/wp-content/uploads/2009/07/8.jpg" alt="8" title="8" width="214" height="160" class="aligncenter size-full wp-image-1307" /></a>
</td>
</tr>
<tr>
<td>
<a href="http://www.kerrywong.com/blog/wp-content/uploads/2009/07/3.jpg"><img src="http://www.kerrywong.com/blog/wp-content/uploads/2009/07/3.jpg" alt="3" title="3" width="214" height="160" class="aligncenter size-full wp-image-1302" /></a>
</td>
<td>
<a href="http://www.kerrywong.com/blog/wp-content/uploads/2009/07/6.jpg"><img src="http://www.kerrywong.com/blog/wp-content/uploads/2009/07/6.jpg" alt="6" title="6" width="214" height="160" class="aligncenter size-full wp-image-1305" /></a>
</td>
<td>
<a href="http://www.kerrywong.com/blog/wp-content/uploads/2009/07/9.jpg"><img src="http://www.kerrywong.com/blog/wp-content/uploads/2009/07/9.jpg" alt="9" title="9" width="214" height="160" class="aligncenter size-full wp-image-1331" /></a>
</td>
</tr>
</table>
<p>When performing Hough Transform, I chose to detect up to ten lines in each image, with the following stepping parameter (the detection results are very sensitive to these parameters, the following parameters were chosen based on experiment results):<br />
\[\rho=1, \theta=0.01\]</p>
<p>Out of all the detected lines, a few sections are selected based on line continuity and the calculated average gradients around the detected lines. The following images shows the chosen Hough line segments based on the algorithm. </p>
<table>
<tr>
<td>
<a href="http://www.kerrywong.com/blog/wp-content/uploads/2009/07/1_o.jpg"><img src="http://www.kerrywong.com/blog/wp-content/uploads/2009/07/1_o.jpg" alt="1_o" title="1_o" width="214" height="160" class="aligncenter size-full wp-image-1309" /></a>
</td>
<td>
<a href="http://www.kerrywong.com/blog/wp-content/uploads/2009/07/4_o.jpg"><img src="http://www.kerrywong.com/blog/wp-content/uploads/2009/07/4_o.jpg" alt="4_o" title="4_o" width="214" height="160" class="aligncenter size-full wp-image-1312" /></a>
</td>
<td>
<a href="http://www.kerrywong.com/blog/wp-content/uploads/2009/07/7_o.jpg"><img src="http://www.kerrywong.com/blog/wp-content/uploads/2009/07/7_o.jpg" alt="7_o" title="7_o" width="214" height="160" class="aligncenter size-full wp-image-1315" /></a>
</td>
</tr>
<tr>
<td>
<a href="http://www.kerrywong.com/blog/wp-content/uploads/2009/07/2_o.jpg"><img src="http://www.kerrywong.com/blog/wp-content/uploads/2009/07/2_o.jpg" alt="2_o" title="2_o" width="214" height="160" class="aligncenter size-full wp-image-1310" /></a>
</td>
<td>
<a href="http://www.kerrywong.com/blog/wp-content/uploads/2009/07/5_o.jpg"><img src="http://www.kerrywong.com/blog/wp-content/uploads/2009/07/5_o.jpg" alt="5_o" title="5_o" width="214" height="160" class="aligncenter size-full wp-image-1313" /></a>
</td>
<td>
<a href="http://www.kerrywong.com/blog/wp-content/uploads/2009/07/8_o.jpg"><img src="http://www.kerrywong.com/blog/wp-content/uploads/2009/07/8_o.jpg" alt="8_o" title="8_o" width="214" height="160" class="aligncenter size-full wp-image-1316" /></a>
</td>
</tr>
<tr>
<td>
<a href="http://www.kerrywong.com/blog/wp-content/uploads/2009/07/3_o.jpg"><img src="http://www.kerrywong.com/blog/wp-content/uploads/2009/07/3_o.jpg" alt="3_o" title="3_o" width="214" height="160" class="aligncenter size-full wp-image-1311" /></a>
</td>
<td>
<a href="http://www.kerrywong.com/blog/wp-content/uploads/2009/07/6_o.jpg"><img src="http://www.kerrywong.com/blog/wp-content/uploads/2009/07/6_o.jpg" alt="6_o" title="6_o" width="214" height="160" class="aligncenter size-full wp-image-1314" /></a>
</td>
<td>
<a href="http://www.kerrywong.com/blog/wp-content/uploads/2009/07/9_o.jpg"><img src="http://www.kerrywong.com/blog/wp-content/uploads/2009/07/9_o.jpg" alt="9_o" title="9_o" width="214" height="160" class="aligncenter size-full wp-image-1317" /></a>
</td>
</tr>
</table>
<p>The table below shows the gradient index calculated within each area (the average of the gradients along all the chosen line segments within a sub-image. The result is scaled by 1000, the scale factor is chosen such that for clear images the resulted index is greater than 1 and for blur images the resulted index is less than 1).</p>
<table>
<tr>
<td>1</td>
<td>1.709</td>
</tr>
<tr>
<td>2</td>
<td>2.383</td>
</tr>
<tr>
<td>3</td>
<td>1.012</td>
</tr>
<tr>
<td>4</td>
<td>2.842</td>
</tr>
<tr>
<td>5</td>
<td>3.389</td>
</tr>
<tr>
<td>6</td>
<td>2.419</td>
</tr>
<tr>
<td>7</td>
<td>2.933</td>
</tr>
<tr>
<td>8</td>
<td>2.168</td>
</tr>
<tr>
<td>9</td>
<td>2.534</td>
</tr>
</table>
<p>And the sub images are indexed as follows:</p>
<table>
<tr>
<td>1</td>
<td>4</td>
<td>7</td>
</tr>
<tr>
<td>2</td>
<td>5</td>
<td>8</td>
</tr>
<tr>
<td>3</td>
<td>6</td>
<td>9</td>
</tr>
</table>
<p>The algorithm can also detect images with deliberate blur regions (e.g. <a href="http://en.wikipedia.org/wiki/Bokeh">Bokeh</a>). The results are illustrated below:</p>
<div id="attachment_1287" class="wp-caption aligncenter" style="width: 330px"><a href="http://www.kerrywong.com/blog/wp-content/uploads/2009/06/c3.jpg"><img src="http://www.kerrywong.com/blog/wp-content/uploads/2009/06/c3.jpg" alt="Plant (Microsoft Research Digital Image)" title="Plant (Microsoft Research Digital Image)" width="320" height="240" class="size-full wp-image-1287" /></a><p class="wp-caption-text">Plant (Microsoft Research Digital Image)</p></div>
<table>
<tr>
<td>1</td>
<td><font color="red">0.000</font></td>
</tr>
<tr>
<td>2</td>
<td>1.750</td>
</tr>
<tr>
<td>3</td>
<td>1.973</td>
</tr>
<tr>
<td>4</td>
<td>1.595</td>
</tr>
<tr>
<td>5</td>
<td>2.815</td>
</tr>
<tr>
<td>6</td>
<td>3.188</td>
</tr>
<tr>
<td>7</td>
<td><font color="red">0.000</font></td>
</tr>
<tr>
<td>8</td>
<td>1.204</td>
</tr>
<tr>
<td>9</td>
<td>1.308</td>
</tr>
</table>
<p>Note that the 0&#8217;s in the detection results indicate that within those regions, no lines could be reliably detected and thus those regions are considered blurred.<br />
Generally speaking, when an image contains both blurred and clear regions, some of the indexes will be zero and others will be greater than one.</p>
<p>The following images are detected as blurred, with the detected indexes far less than one.</p>
<table>
<tr>
<td>
<div id="attachment_1294" class="wp-caption aligncenter" style="width: 330px"><a href="http://www.kerrywong.com/blog/wp-content/uploads/2009/06/b3.jpg"><img src="http://www.kerrywong.com/blog/wp-content/uploads/2009/06/b3.jpg" alt="Boat (Microsoft Research Digital Image)" title="Boat (Microsoft Research Digital Image)" width="320" height="240" class="size-full wp-image-1294" /></a><p class="wp-caption-text">Boat (Microsoft Research Digital Image)</p></div>
</td>
<td>
<div id="attachment_1295" class="wp-caption aligncenter" style="width: 330px"><a href="http://www.kerrywong.com/blog/wp-content/uploads/2009/06/b4.jpg"><img src="http://www.kerrywong.com/blog/wp-content/uploads/2009/06/b4.jpg" alt="Candle" title="Candle" width="320" height="427" class="size-full wp-image-1295" /></a><p class="wp-caption-text">Candle</p></div>
</td>
</tr>
</table>
<h3>Limitations</h3>
<p>when image contrast is low, or when objects borders are not clearly defined, the algorithm may have difficulty in distinguishing whether an image is blurred. Take the following two cloud images for instance, the image on the left was correctly classified as a clear image due to the relatively high contrast around the center. But the image to the right was classified as blurred due to its lack of contrast. </p>
<table>
<tr>
<td>
<div id="attachment_1291" class="wp-caption aligncenter" style="width: 330px"><a href="http://www.kerrywong.com/blog/wp-content/uploads/2009/06/b1.jpg"><img src="http://www.kerrywong.com/blog/wp-content/uploads/2009/06/b1.jpg" alt="Cloud" title="Cloud" width="320" height="240" class="size-full wp-image-1291" /></a><p class="wp-caption-text">Cloud</p></div>
</td>
<td>
<div id="attachment_1293" class="wp-caption aligncenter" style="width: 330px"><a href="http://www.kerrywong.com/blog/wp-content/uploads/2009/06/b2.jpg"><img src="http://www.kerrywong.com/blog/wp-content/uploads/2009/06/b2.jpg" alt="Cloud" title="Cloud" width="320" height="240" class="size-full wp-image-1293" /></a><p class="wp-caption-text">Cloud</p></div>
</td>
</tr>
</table>
]]></content:encoded>
			<wfw:commentRss>http://www.kerrywong.com/2009/07/03/image-blur-detection-via-hough-transform-iv/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
