Category Archives: electronics


Feather HUZZAH Temperature Monitor

I recently visited the cabin, and it was cold. Like, excessively cold. Like, 37 degrees, which is perilously close to pipes-freezing cold. The thermostat shouldn’t allow that to happen. I hadn’t been there for more than a month, so I don’t know how long there had been a problem, but clearly, the thermostat or furnace wasn’t working. I went into the crawlspace under the house, pulled some panels off the furnace, and did a bit of troubleshooting on my own. Then I did a bit of troubleshooting with an HVAC guy on the phone. Eventually, we determined that something was, indeed, broken. The HVAC guy came out, replaced the controller board on the furnace, and I had heat again.

At the office, I build and maintain complicated software systems. Any sufficiently complicated system is going to have unpredictable failure modes. I accept that I can’t avoid all possible failure modes, but once I recognize a critical failure class, I build monitors to alert me to any failure in that class. It’s what I do in software, so it makes sense to do it in hardware as well. I don’t know all the failure modes of the heating system in the cabin, but failure of the heating system is certainly a failure class that could have very bad (as in, expensive) consequences.

I recently became aware of Adafruit’s new Arduino-compatible line of development boards, Feather. The Feather HUZZAH, is particularly interesting, as it has built-in WiFi (based on the ESP8266 chipset), and costs only $16. With a Feather HUZZAH and a temperature sensor, like the MPC9808 I2C breakout, I could put together an inexpensive monitor. I happened to have a spare, small I2C OLED display that I could add to the mix for a bit of feedback.


The code to initialize and control the temperature sensor and OLED is short and easy. The loop() portion of the sketch reads the temperature, puts it on the display, and if 15 minutes have passed since the last time data was sent to the server, send the temperature to the server and reset timer variable. Finally, shut down the temp sensor and sleep for two seconds. It looks like this:

void loop() {
  float f = tempsensor.readTempF();

  display.print(f, 1);

  if (millis() - send_timer >= 1000 * 60 * 15) {
    WiFiClient client;
    if (!client.connect(host, httpPort)) {
      Serial.println("connection failed");
    else {
      client.print(String("GET ") + url +
        "?code=" + mac + "&tval=" + f + " HTTP/1.1\r\n" +
        "Host: " + host + "\r\n" + 
        "Connection: close\r\n\r\n");
      send_timer = millis();


The only problem I had was that when I tried uploading the sketch to the HUZZAH, I got the error,

warning: espcomm_sync failed
error: espcomm_open failed

A bit of research indicated that to upload a sketch, I’d need to connect Pin 0 to ground and reset the unit (either by power cycling it, or by hitting the reset button).

Pin 0 to Ground

With Pin 0 held to ground, the sketch uploaded. After connecting the temp sensor and OLED, the device seemed to measure the temperature accurately. I took some dimension measurements, and designed an enclosure in TinkerCAD. By the time I had soldered the connections, the two pieces of the enclosure had finished printing.


The last component for this project is a server-side piece that could record the temperature. In the simplest case, I could set up a page that listens for incoming data, and sends me an email or text message when a temperature is posted below some threshold. But I wanted also to be able to see trends over time. So I needed to store readings in a database. Since I might want to have multiple temperature monitors running in several locations, I need to record a source with each temperature reading. To normalize the database, I split the source and measurement into two tables, like this:

mysql> describe sources;
| Field | Type        | Null | Key | Default | Extra          |
| id    | int(11)     | NO   | PRI | NULL    | auto_increment |
| code  | varchar(64) | YES  | MUL | NULL    |                |
| name  | varchar(64) | YES  |     | NULL    |                |
3 rows in set (0.00 sec)
mysql> describe temps;
| Field       | Type         | Null | Key | Default           | Extra                       |
| id          | int(11)      | NO   | PRI | NULL              | auto_increment              |
| source_id   | int(11)      | NO   | MUL | NULL              |                             |
| measured_at | timestamp    | NO   |     | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP |
| temperature | decimal(4,1) | NO   |     | NULL              |                             |
4 rows in set (0.00 sec)

After I had recorded temperature measurements for several days, I had enough data to start putting something on a graph. Rather than building a graphing mechanism from scratch, I repurposed some D3 code that I had written for my UltraSignup Visualizer (which was, at least in part, repurposed from my MMT Graph project). The D3 code pulls data (as JSON) from a PHP script that retrieves temperature measurements and timestamps from some specified source. It then draws the graph, and adds the (slightly smoothed) measurements.

// Smooth temperature readings over avglen measurements
var temperatures = [];
var cur_temp = 0;
var avglen = 8;
var i = 0;
// Seed the running average
while (i < (avglen - 1) && i < results.length) {
  cur_temp += (1.0 * results[i].t);
// Populate the running average (cur_temp) as a FIFO list of avglen length
while (i < results.length) {
  cur_temp += (1.0 * results[i].t);
  temperatures[temperatures.length] = {x: results[i].d, y: (cur_temp / avglen)};
  cur_temp -= (1.0 * results[i - avglen].t);

// Create the SVG line function
var line = d3.svg.line()
   .x(function(d, i) { return xScale(new Date(d.x)); })
   .y(function(d) { return yScale(d.y); });

// Add the data to the graph using the line function defined above
   .attr("d", line(temperatures))
   .attr('class', 'rank_line')
   .style("fill", "transparent")
   .style("stroke", "rgba(71, 153, 31,.8)")
   .style("stroke-width", 1.25);

Temperature Graph

Now that everything works, I’d like to make a few more of these devices. The main costs are $15.95 for the Feather HUZZAH, $4.95 for the temperature sensor, $17.50 for the OLED display, a few dollars for a micro-USB cable and power supply, and some cents for a few inches of wire and a few grams of PLA (for the 3D printed enclosure). For the cost of the device, the display is disproportionately expensive. Once the device is running, the purpose is to record temperature remotely. If I replace the OLED with a single NeoPixel (which’ll run about $1) that flashes some color code to indicate status, I don’t get the onboard temperature readout, but I DO get the entire device for around $23 (plus the micro-USB cable and power supply). So the next iteration will replace the OLED with a NeoPixel. Stay tuned.


Jeep Computer Update

A year and a half ago, I wrote about a spanky little computer I built for my Jeep. It had been working like a boss for a little more than a year before it started to malfunction. Whereas it used to acquire a GPS fix almost instantly, it started to take several minutes to find the satellites. And the “trip timer” function (which measured trip time and average speed) no longer worked correctly. Every time the car was powered on, the clock was reset to 7:59pm or 6:59pm (depending on daylight savings status). After getting a GPS fix, the time would correct itself, but as far as the computer was concerned, the trip started at the pre-fix time, often adding several hours to the actual trip time.

My first suspicion was that the external antenna had gone bad. It’s encased in black plastic, and it sits on top of the dashboard. I imagined that the hot, summer sun baked it somehow, so the computer could only use its internal antenna, tucked (with the rest of the main processing unit) tightly under the dashboard. I ordered a new antenna, and started designing a small, protective case that I could print in white PLA, so the antenna would have some protection from direct sunlight. I decided that it would also make sense to replace the black enclosure that I had printed for the display with a white enclosure, and put a back on it for additional protection from the sun. When I pulled the display out of the car, I realized that the heat had taken a toll. The black enclosure had melted, and was drooping around the display.

Enclosure Before

Before: The enclosure was nice and square when it was first installed.

Enclosure After

After: A year and a half in the sun took its toll.

I literally had to cut away the enclosure to get the display out of it, as the PLA had so tightly molded itself around the back circuit board. Fortunately, I now have my own 3D printer, so I could use the same STL file to print a new copy of the enclosure, and design a cap to provide some shade for the back side of the display circuit board.

Finally, the main processing unit — the Arduino with the GPS shield, and all the assorted connections — was shoehorned into an awkwardly shaped, generic enclosure that I had purchased at Radio Shack [moment of silence, please]. So that was due for a new, custom enclosure. I made a pretty simple box, with some cutouts for the power and USB connectors, and holes where I could mount the GPS antenna connector and temperature sensor plug.

New Enclosure

After putting all of that together, the new antenna I had ordered arrived. I tried it out… And it made no difference. So on to the next step of troubleshooting. I remembered that the GPS shield had a built-in real time clock (RTC). That would have been the module responsible for maintaining the time when the device was powered off. I assumed also that keeping accurate time between power cycles would allow the GPS to establish a faster fix on the satellites. I pulled out the RTC battery (which was a CR1220 form factor). My multimeter happens to be dead now (due to a blown fuse) so I couldn’t test it. Fortunately, batteries are cheap. I got a new battery, and now the time is correct upon powering up, and the unit gets a fix within a few seconds. In the interim, I did make a minor tweak to the Arduino code. Previously, I depended on the unit maintaining the correct time between power cycles, so I started the trip calculation (time and average speed) immediately. Now, I wait until the GPS has a fix to start the calculations. In the normal case, the fix only takes a few seconds. However, the next time the battery dies, it will still affect the time it takes to find the satellites, but it will no longer cause the trip calculations to be totally erroneous.



3D Printing and Custom Enclosures

I finally got around to finishing my Jeep computer project. I had gotten the Arduino and display working, and I had wired everything together. However, as of my previous post about the project, neither the display nor the Arduino were in enclosures, and the cabin of the Jeep was festooned with wires.

The first step in cleaning up the mess was to purchase an inexpensive, generic, plastic, rectangular enclosure from Radio Shack. I drilled some holes to mount the connections for the Arduino/GPS unit. I put it together and tucked it behind the dash, nice and neat. So most of the wires were gone. The only remaining messy part was the display. I still had the bare display nestled e’er so gently in a knit cap that I’d leave on top of the dash as a pillow for my electronics. I wanted an enclosure that would fit snugly around the display, and that I could mount on the dashboard.

At some point along the way, I learned that the Washington DC public library system has a 3D printing service. For a minimal cost, they would make a print of an object. Fantastic! I just needed to figure out how to create a model. I learned that I was going to need to use a CAD program to create an .stl (STereoLithography) file, which seems to be one of the primary file formats in the 3D printing world.

Of course, I didn’t want to spend thousands of dollars on a CAD program that would take years to learn. Fortunately, there are free, easy-to-learn options, such as SketchUp or TinkerCAD. SketchUp is a native program that runs on Macs and Windows computers. While I have a couple of Macs, and I run various versions of Windows in virtual machines for testing purposes, at home, my primary computer is Linux. TinkerCAD is a very simple, web-based CAD program that works well in any modern browser.

After a basic exploration of TinkerCAD, I was ready to go about designing the custom enclosure for my display. The display is a 2.8″ TFT LCD Touchscreen Breakout from Adafruit. I spent some time searching for specs that list the dimensions, but no such specs were to be found. So I pulled a tape measure out of my knitting kit, and built the CAD model as I measured the dimensions.

TinkerCAD and the Display

My first attempt included a back plane. Having no experience with 3D printing, I didn’t realize that in order to support the back plane during the printing process, the printer would have to lay down a grillwork of plastic that I would have to remove after the fact.

3D Grillwork

I attempted to remove the grillwork, but the plastic is surprisingly sturdy. (In fact, I was originally worried that the 2mm walls of my model would be flimsy, but it ended up being rock solid… Err, in a plastic sort of way.) So I removed the back in the CAD file, and resubmitted. I got back an enclosure that fits the display perfectly.





I considered adding grooves to the enclosure so I could print a separate back plane that could be attached and detached. In the end, I went with simplicity, and I just used a bit of Gorilla Tape for the back. I’ve mounted it on the dashboard (again, with Gorilla Tape until I settle on a more permanent solution), and it satisfies all of my greatest hopes and desires (with respect to a 3D printed enclosure anyway).





Jeep Seat Heaters

Once you own a car with seat heaters, it’s hard to go back. The old VW had heated seats; the new Jeep did not. Clearly, this state of affairs could not stand.

I found that I could get some nice, neoprene seat covers with built-in seat heaters made by Wet Okole. The Wet Okoles came with heating elements in both the butt-area and the back-area, whereas some aftermarket heaters only heat the butt. I used Quadratec’s “designer” for Wet Okoles. When the seat covers arrived, I installed them, and there was much rejoicing.

Wet Okole Seat Covers

Each seat had a cigarette lighter plug for power, and a push-button switch that allowed setting the heater element to Off, Low, Medium, or High.

Original Switch

Here we get to the problem: While convenient for a quick connection, I didn’t want wires dangling from the seats to the cigarette lighter. Further, I only had one cigarette lighter. Even splitting the circuit for the cigarette lighter wasn’t a great solution, as each seat could potentially draw a little more than 10 amps, and the lighter was on a 20 amp fuse. Splitting the circuit would mean that I’d risk blowing the fuse each time both seats were on full. The Jeep conveniently has a spare 20 amp circuit on the fuse block behind the dash, but it’s an unswitched circuit. If I used that, it’d only be a matter of time before I’d leave the car with a seat heater on, and I’d come back to a dead battery.

After using the seat heaters for a while, I decided that they were keepers, so it was worth investing in a more permanent solution to the power problem — and a solution that would allow both seats to be heated at the same time. I needed to add at least two new 15 or 20 amp, switched circuits to the car, and I wanted controls that were integrated into the dashboard somehow.

For the controls, I started looking around for switches that could put into some existing blanks on the dash. However, after bashing in a heater vent (by transporting some furniture in the passenger seat), I stumbled upon the perfect solution in a Daystar replacement vent with an integrated switch panel.

Vent Switches

The drawback of the rocker switches is that I would no longer have Low or Medium settings. The seat heaters would either be off, or fully on. But really, who need a “lightly warmed” bum in winter? If it’s cold enough to turn ’em on, turn ’em on ALL THE WAY, I say!

For the circuits, I found that Painless Performance makes three- and seven-circuit add-on fuse blocks. I decided to go with the seven-circuit block to give me room for expansion in future, yet-to-be-conceived projects (such as my Arduino-based trip computer). That gave me four new switched circuits, and three new constant circuits, all at 20 amps.

The parts arrived, and so I got to connecting all the pieces. The trickiest decision was where to mount the new fuse block. I had initially intended to mount it behind the glove compartment, next to the existing internal fuse block, but there wasn’t enough room. Perhaps I could have found another spot behind the dash, but I didn’t want to put it somewhere that would require ripping open the dash to access it (in case I should need to replace a fuse). There was an empty spot in the engine compartment (for a second battery, I suppose, to power a winch that I’m unlikely to add) that seemed like a good candidate. Being in the engine compartment, I wanted to add a bit of protection to the block, as it wasn’t marketed as a weatherproof component. So rather than mounting it directly, I mounted it to the inside of a small tupperware bin. I drilled a few ventilation holes in the bin, and a larger hole to run the wires, then mounted the bin in the engine compartment.

Placement of fuse block

The new fuse block is in a ventilated tupperware bin, mounted near the back-driver-side of the engine compartment.

The fuse block had three sets of wires:

  1. Two wires to connect to the positive and negative poles of the battery to power the circuits.
  2. A single wire that needed to be connected to an existing switched circuit. This wire poweres an internal relay that controlled the switching of the four switched circuits in the fuse block.
  3. Seven hot wires for the seven new circuits.

Since the fuse block was already in the engine compartment, running the first set of wires to the battery was fairly trivial. The rest of the wires, though, had to make it into the cabin, which meant getting them through the firewall. I spent more than a few minutes looking for an accessible, existing run through the firewall, and was met with no success. I refered to Dr. Google, and learned that a hard, rubber plug near the gas pedal is the preferred channel — just make a hole straight through it. I made the hole, and pulled the wires through.

Wires run through the firewall

To get the wires through the firewall, I had to make a hole in a rubber plug that seemed to exist for exactly that purpose.

For the relay wire, I tapped into the hot line for the cigarette lighter — I just cut away a centimeter of insulation, joined the relay wire, and wrapped it up neat and tidy with electrical tape. The remainder of the work consisted of running wires up and down behind the dash: hot circuit wires to switches, switches to positive wires for the seats, switches to ground, seats to ground.

As of this blog post, the seats have been keeping my bum warm for more than two winters. A boy could hardly ask for more.



An Arduino-Based Computer For The Jeep

In my early 20s, I made what, at that point, was the biggest purchase of my life: my little, green Volkswagen. In both a literal and figurative way, it carried me through some formative years. After 11 years, when repair bills were starting to exceed the value of the car, it finally became time to retire The Green Machine. (It wasn’t an easy decision, but I got a very large estimate to weld out a bad catalytic converter, and weld in a new one that would be necessary to get the car to pass its emissions inspection.) In its place, I wanted something that would handle snowy mountains a bit better — that meant four-wheel drive — and something that I could pay for in cash without totally draining the kitty. I ended up with an 11 year old Jeep Wrangler.

The Jeep has several drawbacks over the Volkswagen. It’s loud. It’s a rough ride. Despite seeming to be quite a bit larger, it doesn’t have much carry capacity at all — packing the car for any long trip becomes an exercise in applied geometry and spacial relations. However, it does have one big advantage: it is user serviceable. It’s a great car for modification and personalization. All cars should be so modular. When a side mirror recently broke, my only problem was deciding what kind of mirror I wanted to replace it with. I browsed through the options on Quadratec, picked a set, they arrived two days later, and it took me 20 minutes to replace both mirrors. When I decided that the stock headlights were too dim, I bought new enclosures for a different bulb type, and swapped the old for the new. Busted radiator? Got a new one at the local auto parts store, and swapped it out. Want seat heaters? Add a fuse block, and wire them to switches on the dashboard. (I’m sure I’ll post more about that one later.)

Since I’ve been driving the Jeep, one feature of the VW I have longed for is the little computer that would tell me the temperature outside, how long I have been driving, and my average speed. Maybe I care too much for stats, but I liked to know, eg, This trip was 19 miles, it took 26 minutes, and it is 68° F outside. The Jeep doesn’t even have a clock on the dashboard. No, to be able to see the time, I need to leave the radio (also an aftermarket replacement) on the clock display.

I finally took up the challenge to put together something that would give me the information I so yearned for. I decided to use an Arduino as the microcontroller for the project. I went to my other favorite site, Adafruit, and ordered most of the parts I’d need, such as a digital temperature sensor, a GPS shield, and a touchscreen display. When the parts arrived, it was time to get soldering.

Parts to solder

I had to solder the header pins to the GPS shield, and a set of wires to both the GPS shield and the touchscreen in order to connect them to each other. I didn’t want to connect them directly. The plan was to set it up so the microcontroller/GPS unit would be hidden under the dashboard. The display would be affixed to the top of the dashboard. The temperature sensor would be mounted to the front of a front wheel well, and wires would be run back through the engine compartment, and through a small hole I had drilled in the firewall. But before I could do all of that, I wanted to make sure the basic unit worked. Once I figured out how to interface with the temperature sensor, the touchscreen, and the GPS, it wasn’t particularly challenging to write code to pull data from the sensors, and spit the information to the display. I connected the display to the microcontroller/GPS unit through a breadboard, and plugged a 9V battery into it. It was a self-contained unit that I could plop on top of the dashboard.

Computer on dash

I’m holding the display, which is connected (through the breadboard) to the GPS shield which is plugged in to the Arduino, which is powered by a 9V battery. The display shows the time of day at the top. On the left is the outside temperature (“??? F” since it is not currently connected to the temp sensor), current speed, and altitude above sea level. On the right is current trip information: time, distance, and average speed (“0.0 MPH” because of a bug in my code at that time). At the bottom is the latitude and longitude, and a green dot, indicating that the GPS has a fix.

Once I was generally satisfied with how the device was working, I needed to replace the breadboard with a more convenient connection. I needed to connect nine wires, so I started digging around for a standard RS232 serial cable with a DB9 connector on both ends. Fortunately, I keep around all sorts of old cable that will probably never be useful again. After digging around the box, I found a cable with DB9 connectors. I tested all the pins to make sure that I had a serial cable — where there is a one-to-one connection between pins on each end — and not a null modem cable — where a pin on one end might be connected to multiple pins on the other end. I was in luck; the cable would work. I picked up some solderable DB9 connectors from Radio Shack, and put one end on the display, and the other end on the microcontroller.

For the temperature sensor, I needed to be able to plug in three wires. I like the simplicity of a standard 1/8″ stereo jack, so I soldered a female end to the wires on the microcontroller, and a male end to the wires from the temperature sensor. So that’s an easy-peasy-parcheesi connection! The only trouble I had with the temperature sensor was joining the wires that ran through the engine compartment. The sensor itself is wrapped in a waterproof casing, and is connected to a 1 meter wire. But that wasn’t long enough to make it to the cabin. Joining longer wires to complete the run was not a problem, but securing them from the elements was a concern. So I picked up some dual-layer heat-shrink. Standard heat-shrink will shrink tightly around a join, but it’s still possible that moisture could get in. Dual-layer heat-shrink has an internal layer of adhesive that melts at a temperature lower than the application temperature. The adhesive fills in the gaps, and creates a waterproof layer — it’s preferable to standard heat-shrink for outdoor applications. So I made the joins, heat-shrunk each of the three individual wires, and tested it. Everything worked fine. I added one more layer of heat-shrink around all three wires, and tested again. The sensor no longer worked. I suspect that I over-heated the wires. Rather than using a proper heat gun, I was just waving a lighter under the heat-shrink. I think I was over zealous in my attempts at shrinkage, and I somehow ruined the connections or wires with too much heat. I had to cut out the connection, pull the remaining wires closer together, and start over. Eventually, I got it right.

Temperature Sensor

Clockwise from top left: 1) Under the front, drive-side wheel well. The white wire is connected to the temperature sensor. The sensor itself is on the left, wrapped in black Gorilla Tape, to add extra insulation against the elements. 2) Under the hood, the white temperature sensor wire comes from the bottom left up to the point where it is joined (with a length of black heat-shrink) to red, black, and green wires that run to the back of the engine compartment and through the firewall. 3) The wires from the temperature sensor terminate at a 1/8″ stereo plug.

For the GPS, I needed an external antenna, as the GPS chip would eventually be placed under the dash, where it would have a hard time finding a signal. I got an external, active antenna that I could place someplace where it would have good line-of-sight to the satellites. I found that the best location was on top of the dashboard. That made it easy to run the wire behind the dashboard, down to where the microcontroller would eventually be living. The antenna wire ends in an SMA connection (which is a small coax-type connection), so I us an SMA to uFL adapter to connect it to the uFL connector on the GPS shield.

The antenna is mounted on the dashboard. The wire runs behind the dashboard, and terminates in an SMA connector, which is connected to a uFL adapter.

The antenna is mounted on the dashboard. The wire runs behind the dashboard, and terminates in an SMA connector, which is connected to a uFL adapter.

The final piece of the puzzle was power. Fortunately, for other purposes, I had previously installed an extra fuse box in the Jeep, and I had a few spare switched (ie, on when the car is on; off when the car is off) leads in the cabin. I connected one to a 2.1mm power connector, and that was all I needed to do to power the microcontroller. However, when I took the whole contraption for a ride, I noticed that the Arduino ran very hot. The car provides a fairly dirty 12-14 volts, with possible spikes that could get to 18 or 20 volts. Based on the Arduino specs, the on-board voltage regulator should be able to handle that. But aside from my own observation that the device became worryingly hot, research seemed to indicate that it was only a matter of time before I fried the device. So I decided that I’d try to feed it a clean 7 or 9 volts. (It needed to be at least 7V because the GPS shield required 5V, and the on-board regulator would cause a drop of at least 1.5V from whatever I supplied.) I considered cheaping out, and just adding a standard, 7807 or 7809 voltage regulator. But in case I end up packing everything together in a tight space, I didn’t want to have the heat dissipation issues of a voltage regulator, so I went with a much-more-expensive buck converter. Whereas a voltage regulator reduces voltage by dissipating excess energy as heat, a buck converter is a highly efficient electronic device that will step down voltage with minimal waste. I hunted down a Traco TSR 1-2490 and installed it inline with the power connector.

A Traco TSR 1-2490 buck convert is connected inline with the power connector to supply a clean 9 volts.

A Traco TSR 1-2490 buck convert is connected inline with the power connector to supply a clean 9 volts.

Since I haven’t finalized the installation, the cockpit of the car is a mess of wires that I can connect to the microcontroller when I put it into the car.


And the controller itself is sort of a mess (but somewhat less delicate that you’d think — yay for solid solder joints!).

The Whole Kielbasa

But hey, it works! So the next step is to make some custom enclosures, and tidy everything up. I have some ideas, but I might not get around to it for a few months.



Blinking LED Circuit

As part of a larger project, I needed a circuit to blink an LED. It’s a simple task, and there are plenty of existing designs. But having almost no experience with circuit design, I wanted to make my own. Further, I wanted to make it with basic components — no ICs. An integrated circuit, like a 555, would take the fun out of it!

As is the case with most oscillators of this sort, the charge/discharge cycle of a capacitor acts as a switch to turn the LED on and off. I sketched out a few ideas, and eventually arrived at this:

Blinking LED Circuit

The blinking happens because the circuit oscillates between several states:

  1. Current goes through PNP transistor Q2 to the anode side of capacitor C1. As C1 charges, the cathode side drains through resistor R1 to ground. In doing so, it also puts “pressure” on the base of PNP transistor Q1, preventing current from flowing through it.
  2. After C1 is fully charged, its cathode side will no longer be draining, so there will be nothing preventing flow from the base of Q1 through R1 to ground. At that point, Q1 will start to conduct to the big loop, which will cause three things to happen.
    1. Current will flow to the base of NPN transistor Q3, which will allow C1 to slowly discharge through resistor R3. Also, once Q3 is conducting, the drain on the base of Q1 will increase as current flows to the cathode side of C1.
    2. Current will flow through diode D1, to put “pressure” on the base of Q2, thereby preventing further charging of C1 from the voltage source.
    3. Current will flow through light emitting diode D2, causing it to light up.
  3. Once C1 is fully drained, the base of Q1 will only drain through R1. If R1 has a high enough value, the output of the collector of Q1 will fall below the threshold to block the base of Q2. When that happens, current will once again flow through Q2, C1 will start charging again, Q1 will stop conducting, the LED will turn off, and we return to step 1.

So that was my theory. My next step was to build it, and figure out the right values for all the components. I breadboarded it like this:

Blinking LED Circuit

Voltage: +5
Q1: (PNP) 9015
Q2: (PNP) 9015
Q3: (NPN) PN2222
R1: 10KΩ
R2: 10KΩ
R3: 680Ω
R4: 68Ω
C1: 470µF
D1: 1N4148
D2: Blue, 3.7V, 20mA

That resulted in a flash rate of 1.3Hz. The blinking speed can be adjusted by changing the capacitor and/or changing the values of R1 and R2. I swapped C1 for a 22µF cap, and the flash rate increased dramatically, perhaps to something between 20 and 30Hz. So I swapped R1 and R2 for 100KΩ, and the flash rate returned to something around 1.6Hz. Ideally, the capacitor should be very small, since it is essentially charging, then dumping its charge in every cycle. I’d like to try to use a much smaller capacitor (with larger R1 and R2 values) to see if I can maintain enough current in that part of the circuit to control the functioning of the transistors. I used a blue, 3.7V LED on a 5V circuit. The LED can be changed, as long as R4 is changed as well to ensure the proper current for the LED’s voltage.

It’s not the simplest circuit of this sort, and I’m sure that I’ve screwed up at least part of the analysis. But as someone who only knows as much about circuit design as he could find on the internet, and a couple of books (namely, Getting Started in Electronics by Forrest Mims, and Starting Electronics by Keith Brindley), I was fairly pleased with myself for making this work.