Wednesday, 12 August 2015

4x4x4 LED Cube

One funny thing to do which uses all 20 pins of an Arduino UNO and a bunch of LEDs is an LED cube. I found it on Instructables and thought it would be a good value addition to my new workplace. I had just quit IISc and was about to join MathWorks in about a week's time then. So, went and bought 70 blue LEDs and spent 2 days wiring them up in layers of 16 LEDs each. Each layer has a common ground.

And there are 4 layers. So, 16 pins are used to index amongst the LEDs in one layer and 4 pins to index the layers themselves. The result is a cube, which needed persistence of vision to index LEDs which have both different layers and different columns within the layers. This requires a bit lesser amount of coding as compared to the 12 pin solution, which requires PoV to make anything glow.


I assembled the layers one on top of the other and soldered them all to a perf board. Hooked it all up to 20 berg connectors (male) and mounted it atop a clear plastic box. Inside the box is a cheap Arduino clone which handles the LED addressing. A cheap L293D motor driver breakout board handles the layer addressing as each layer would output much more current than what an Arduino can safely sink (as it sources from 16 pins of the Arduino). Below are a few images of the build along with a video. The code used in the video is from the Instructable http://www.instructables.com/id/LED-Cube-4x4x4/.









Incidentally, when I visited MathWorks head office at Natick, MA, in march, I found a much bigger version of the LED cube displaying the MATLAB logo at the entrance of the AH1 block.

The Hunt for a Power Supply

One of the most fundamental resources for an electronics hobbyist is a good robust power supply. Short circuit and overload protection and precise linear control of  voltage and possibly load is essential. The only caveat is, it comes at a cost. A DC power supply from Agilent or Tektronix could easily run up to INR 30k. I decided to build my own, last year.

There's this store called 'Universal Transformers' in SP road, who specialize on manufacturing transformers. I got myself a decent 2A transformer. I assumed it would work up to around 1A  or possibly a bit more without any issue. Then got in a bunch of 1N4007 diodes from my stocks and built two bridge rectifiers. The transformer was a center-tap and would give me 15-0-15V. S
o I can output both negative and positive voltages. Smoothened the output with two 1F capacitors and it gave a smooth and steady voltage on the scope.

The actual voltage control is through a LM317 and its complement, LM337. These are controlled via two precision potentiometers stuck on the main panel. A cheap 7 segment display voltmeter from eBay finished the display part. A switch controlled whether the voltmeter was showing the positive voltage or the negative. The only problem: LM317 and LM337 operate from 1.25V and -1.25V respectively. This leaves a comfortable 2.5V blind spot. Useless for playing with diodes or anything which requires sub-1V.

When I finally decided to upgrade from this, I chose the VarTech 2A 0-30V supply. Pretty decent and comes with short circuit and overload protection.

Tuesday, 12 November 2013

My First Desktop Build

 I've always wanted to build a desktop here at my hostel room. After a friend shelled out a huge amount of money to fix his broken laptop, I took the plunge and started the build. The thing was online in less than a week, with almost all interim components. The plan was to upgrade them one by one over the course of a few months as per requirement. The initial build was a uATX case with an AMD Sempron 145, 8GB Transcend RAM, a Seagate Momentus 1TB HDD and a Radeon 6450HD. It made up a a decent browsing station. The following is the story of my departure from this build onto something much more powerful. I'll narrate the story component-by-component, rather than in a chronological order.



Cabinet: After a lot of survey and research into cabinets, I made up my mind to buy the cheapest cabinet that supports 6-7 fans and has a good modular air flow. I wasn't very keen on the tool-less installation of HDDs and transparent panels. The obvious choice was then the Corsair 200R. But, it so happened that during the Diwali festive season, an online store was selling the BitFenix Merc Alpha for a bit less (around 2700 INR). And I grabbed the last piece! AnandTech and other sites rate the Merc Alpha on par with the Corsair 300R and is just simply the best VFM cabinet out there! It supports 6 fans and has modular airflow over the HDDs and the motherboard.


Processor: After the initial decision to stick to AMD (cost reasons mainly), the most important upgrade was that of the obsolete Sempron. I wanted an overclockable, fast multicore with less than 100 W TDP. The constraint on the TDP was to give it some overclocking headroom on a 125 W motherboard. The obvious choice is then the AMD FX 6300. This Piledriver CPU has a stock speed of 3.5 GHz and is a 6-core. The only drawback is the fact that the stock cooler is total nonsense. On an aftermarket cooler, it easily goes up to 4.5 GHz and even upto almost 5 GHz on a liquid cooler. I don't usually do transcoding-like jobs and hence an 8-core would give me no additional benefit. When running at 4.5 GHz it completely maxes out CPU intensive games like FSX. When running at 4.8 GHz on my H60, it completely defeats any i5 and most lower end i7s. Money-to-performance wise, I bet this is the greatest CPU ever built!

Motherboard: As I'd mostly never use an SLI/Crossfire setup in the near future, a full ATX board is nothing but an overkill. So I opted for a uATX ASUS M5A78M-LX motherboard to replace the initial build's ECS A960M-MV. I've no intentions of adding 6 Gbps SSDs and have no USB 3 devices yet. This board basically gives me the 125 W TDP limit that I need to revv up the processor. The 6300 rarely hits even 100 W while stress-testing at 4.2 GHz. The only drawback is the lack of the 9-series chipset, which would make things a little faster. This little mobo even comes with ASUS's EPU, which they claim, will make the system a little quieter and cooler, though this is yet to be tested out.


Memory: Not much thought went into choosing the memory. I just wanted a 16 GB DDR3. So simply got a Transcend 8GB DDR3 running at 1600 MHz. Will add another 8GB soon!


Hard Disks: I don't really buy the idea of having an SSD boot disk. The speed-up achieved doesn't matter much to me. I'd rather use that SATA port to hook up a terabyte HDD to create an information blackhole. Data can only come in, never out! So, hacked two 1TB external harddisks and set them up. Later, I added a 3.5 inch 400 GB HDD, which was lying around at home.

PSU: A build is only as good as the PSU that powers it. I replaced the initial Zebronics 450W PSU with a CoolerMaster Thunder 500W. This is the absolute minimum if I ever upgraded to a decent GPU in the future. This is supposed to have been specifically designed for the turbulent conditions of the Indian electricity grid. Nothing eventful has yet happened with it and I don't know whom to thank for it. If not the SPU, it might even be due to the fact that IISc has a pretty stable power supply.


Graphics: I'm still sticking on to the initial build's 6450. I'm basically not much of a gamer. I do play a lot of games, but most of them are strategy games or flight simulators. And hilariously, Microsoft's FSX is a completely CPU bound game, even rendering graphics using the CPU. Strategy games, except a chosen few (such as Civilization V), use low end graphics and the all-time classics (read Age of Empires) even run on 8MB of VRAM. So, the 6450 is serving me pretty well. For my games, its 1 GB of DDR3 memory is more than sufficient to max out all settings. I might go for a better GPU if I happen to graduate onto the modern resource-intensive games.



CPU Cooler: The upgrade which sought the most study was the CPU cooler. This is the most crucial component of an overclocker's build. The 212 EVO echoes through every blog and forum as the amateur overclocker's delight. But I wanted to spend a bit more to get something which is a bit more serious. Air coolers were ruled out almost instantly. I just didn't want a kilogram of aluminum sticking out of my motherboard. That ruled out the monsters from Thermalright, Noctua and other reputed brands. So, liquid cooler it will be! Given their expertise in the area, Corsair was the obvious choice. The 2013 version of the Corsair H60 completely outperforms the comparable Seidon 120M and Antec Kuhler 620. This is due to the fan that the H60 sports, which is specially designed for radiators. H60 is simply the best single layered radiator based cooler available. I got my H60 delivered last tuesday. Even after an hour of Prime95, the temperature remains sub-40 on my 6300 at 4.2 GHz. The maxed out FSX took the temperature to 41-42 degrees. Even at 4.5 GHz, stress testing barely managed to reach 45 degrees.


Cabinet Cooler: Maintaining airflow is crucial to a number cruncher. And fans were the main criteria in choosing the cabinet, in the first place. So, I got 5 fans stuffed in there, apart from the H60's stock fan. These were two CoolerMaster SickleFlow 120s, two DeepCool Wind Blade 120s and a stock fan from BitFenix. The SickleFlows were a bit noisy but could move around 90CFM of air, as compared to the Wind Blades, which moved around just 53 CFM but were much quieter. So a SickleFlow went into the HDD bay and another was the cabinet's floor exhaust. These would be enabled only when required. The Wind Blades went on the cabinet's roof, cooling the entire motherboard. A fan controller from the market costs a bit too much for the features. And I didn't want a mini-keyboard on my front panel to control these fans. So I made my own fan controller with an Arduino UNO. The interface is through a 2-axis joystick and a 16x2 LCD displays which fan is being controlled.


Tuesday, 6 August 2013

Simple Echo using WebSockets through Node.js

WebSockets constitute one of the most useful features of HTML5. The protocol, standardized in RFC 6455, has come to dominate the web of today. It has been designed to be used by web servers and browsers. As of today, almost all major browsers support it. WebSockets' handshakes are interpreted by HTTP servers as an Upgrade request.

Node.js is a software platform used to build scalable network applications. It uses javascript as it's scripting language and is built around Google V8 Javascript engine. It contains a built-in HTTP server library and hence can be used to build web servers without the use of any additional software. Node.js also comes with a very useful package manager called 'npm'. 

In this post, I present a simple echo server using Node.js and a client using WebSockets and make them communicate. This is presented using the Mac OS X 10.8 operating system, but it should work without issues on any other operating systems as well. 

Step 1: Make sure that Node.js is installed. It can be found at http://nodejs.org/download/.

Step 2: Install the websocket package using npm. Open the terminal and type

$sudo npm install websocket

This installs the websocket package. The result should correspond to the following screenshot.


Step 3: Now implement the web server. Copy paste the following code into a file called 'ws_server.js'.

#!/usr/bin/env node
var WebSocketServer = require('websocket').server;
var http = require('http');

var server = http.createServer(function(request, response) {
    console.log((new Date()) + ' Received request for ' + request.url);
    response.writeHead(404);
    response.end();
});
server.listen(8080, function() {
    console.log((new Date()) + ' Server is listening on port 8080');
});

wsServer = new WebSocketServer({
    httpServer: server,
    // You should not use autoAcceptConnections for production
    // applications, as it defeats all standard cross-origin protection
    // facilities built into the protocol and the browser.  You should
    // *always* verify the connection's origin and decide whether or not
    // to accept it.
    autoAcceptConnections: false
});

function originIsAllowed(origin) {
  // put logic here to detect whether the specified origin is allowed.
  return true;
}

wsServer.on('request', function(request) {
    if (!originIsAllowed(request.origin)) {
      // Make sure we only accept requests from an allowed origin
      request.reject();
      console.log((new Date()) + ' Connection from origin ' + request.origin + ' rejected.');
      return;
    }

    var connection = request.accept('echo-protocol', request.origin);
    console.log((new Date()) + ' Connection accepted.');
    connection.on('message', function(message) {
        if (message.type === 'utf8') {
            console.log('Received Message: ' + message.utf8Data);
            connection.sendUTF(message.utf8Data);
        }
        else if (message.type === 'binary') {
            console.log('Received Binary Message of ' + message.binaryData.length + ' bytes');
            connection.sendBytes(message.binaryData);
        }
    });
    connection.on('close', function(reasonCode, description) {
        console.log((new Date()) + ' Peer ' + connection.remoteAddress + ' disconnected.');
    });
});


Step 4: Run the server using the command

$node ws_server.js

The server should be running and listening on port 8080 and the result should correspond to the screenshot below.


Step 5: It's time to write the client! We use HTML and javascript to write the client. Copy the following HTML code into a file called 'client.html'.

<!DOCTYPE html>
<html lang="en">
<head>
  <title>WebSocket Echo Client</title>
  <meta charset="UTF-8" />
  <script>
    "use strict";
    // Initialize everything when the window finishes loading
    window.addEventListener("load", function(event) {
      var status = document.getElementById("status");
      var url = document.getElementById("url");
      var open = document.getElementById("open");
      var close = document.getElementById("close");
      var send = document.getElementById("send");
      var text = document.getElementById("text");
      var message = document.getElementById("message");
      var socket;

      status.textContent = "Not Connected";
      url.value = "ws://localhost:8080";
      close.disabled = true;
      send.disabled = true;

      // Create a new connection when the Connect button is clicked
      open.addEventListener("click", function(event) {
        open.disabled = true;
        socket = new WebSocket(url.value, "echo-protocol");

        socket.addEventListener("open", function(event) {
          close.disabled = false;
          send.disabled = false;
          status.textContent = "Connected";
        });

        // Display messages received from the server
        socket.addEventListener("message", function(event) {
          message.textContent = "Server Says: " + event.data;
        });

        // Display any errors that occur
        socket.addEventListener("error", function(event) {
          message.textContent = "Error: " + event;
        });

        socket.addEventListener("close", function(event) {
          open.disabled = false;
          status.textContent = "Not Connected";
        });
      });

      // Close the connection when the Disconnect button is clicked
      close.addEventListener("click", function(event) {
        close.disabled = true;
        send.disabled = true;
        message.textContent = "";
        socket.close();
      });

      // Send text to the server when the Send button is clicked
      send.addEventListener("click", function(event) {
        socket.send(text.value);
        text.value = "";
      });
    });
  </script>
</head>
<body>
  Status: <span id="status"></span><br />
  URL: <input id="url" /><br />
  <input id="open" type="button" value="Connect" />&nbsp;
  <input id="close" type="button" value="Disconnect" /><br />
  <input id="send" type="button" value="Send" />&nbsp;
  <input id="text" /><br />
  <span id="message"></span>
</body>
</html>



Step 6: Open 'client.html' using the browser and click on 'connect'. A connection would be established with the running server. Type a message and click on 'send' to send it to the server. The result should be as in the screenshot below.




References:

1. Colin Ihrig's blogs on the same topic.
2. Github repositories of WebSocket-related stuff.
3. Wikipedia.




Thursday, 25 July 2013

My Obsession with Flight

I've always been fascinated by flight. One of my first books ever was a picture book of the Mirage series of fighters by Dassault. The first things I built with Lego blocks were machines and aircraft and my first science experiments were on airfoils. I tried building powered aircraft for several years in my early childhood but never succeeded. When I was 10, my uncle bought me a Guillow's rubber band powered model of the T-6 Trojan. I began playing with flight simulators when I was 9, my first sim being Microsoft FS 98. Over the next decade and half I ended up spending countless hours immersed in virtual flight on FS 98, FS 2000, FS 2002 and FS X.


AH-64A Apache, US Army
A-10A Warthog, USAF

The next three years were spent fiddling around with my own designs using balsa wood sheets. I experimented with vertical take- off designs, tailless deltas, forward swept wings, canards, glider-like configurations, swept wings with various degrees of sweep, etc . Later, I built a Messerschmitt Bf-109 with a kit, which eventually disappeared with time. Then entered the mammoth B-17 project . It had thousands of parts and was never completed . A four engined bomber was just too much!



MiG-21M, Indian Airforce


MiG-29A, Indian Airforce
CVN-70 USS Carl Vinson
aircraft carrier, US Navy


Then entered a phase of kit-building. I was building Academy scale display models, Guillow's powered models, Megatech's R/C choppers and my own DIY designs. One of the Megatech choppers crashed from three storeys and disintegrated. I began loving the scale and detail of the Academy models, eventually building five of them. They were the Soviet Sukhoi Su-27UB Flanker, Indian MiG-29A and MiG-21M, A-10A Warthog of the USAF and the USS Carl Vinson aircraft carrier. They took the punishment of time but were finally repaired to the original state. Other static models in the collection included a Russian Ka-52 Alligator, Chinese MiG-17 and an AH-64A Apache.


Cessna 170





P-51D Mustang, USAAF
P-40 Warhawk, US Navy
A6M Zero,
Imperial Japanese Navy












The powered aircraft fleet consisted primarily of Guillow's models. German Bf-109G, Japanese A6M Zero, Canadian DHC-1 Chipmunk, Cessna 170, P-40 of the US Navy, P-51D Mustang of the USAAF and a Guillow's own  1960s design, the Lancer. The static models from Guillow's consisted of the F-16 and the F-14. The F-16 bore some damage with time. The Zero and P-40 have torn tissues and the Bf-109 was completely lost . The DHC-1 had been gifted to a friend about 4 years ago. The main star of my fleet was (and still is) the Megatech Housefly II. It was one of the first models featuring a coaxial counter-rotating rotor system and was thus capable of indoor flight. This was the state-of-the-art in 2006. Flying this was a charm at Indira park in those days. It was even capable of table-top operations. 


F-14A, US Navy
The photo collection













Its not just modelling that interested me. I was a keen collector of aircraft photos. I personally shot almost every aircraft in IAF inventory; Su-30, the MiG series, Hawk, An-32, Il-76, Suryakiran team, Chetaks and Mi-17s, Dorniers, Maruts, Hunters and Seakings. My collection also included every aircraft in the Boeing and Airbus line and from every major airline; Air India, Thai, Singapore, United, Emirates, Air Canada  to name a few. Being a biker at IISc helped me this way and I often ride up to the runway of the Yelahanka airforce base to shoot the landing Dorniers, Ilyushins and Avros. Transport aircraft of German, Soviet and British origins operating in the same base!


Antonov An-32, Indian Airforce. Shot moments from take off at Yelahanka.



At the helm of a chopper


Megatech


I've always resisted being an aerospace engineer, preferring to study my own designs at my own pace and for its own sake. I'd prefer to be a hobbyist, rather than a professional when it comes to aviation. Perhaps thats one of the charms of flight. Its captivating and truly inspirational in its own way, exerting its undulating influence on many a creative mind. And this might be the reason why most pioneers of aviation were hobbyists to start with. 

Monday, 22 July 2013

Chevalier XIX - The Bike Headlight

So I'm still continuing to name my DIY stuff as Chevalier. The previous Chevalier was an autonomous feeder for my fish tank. The story of my lights is far fetched. When I came to know that I'd soon be riding in the dark, I went to Pedals n Wheels and bought myself a Sigma Illux safety light. I had no clue about what a safety light was. When it proved to be of no use, I bought two cheap BSA headlights, which hardly lasted 3 hours. I got marooned on a night ride on Tumkur road with them.

Since then, I was on a lookout for lights. My crash in october kept me out of action long enough that I founded a Robotics Club in IISc and restarted my erstwhile hobby. Purchasing a headlight worth thousands of rupees is simply preposterous now! This link by Gokul reminded me that a headlight was pending. His was a more temporary-style setup and without any weatherproofing or any solid clamp to his bike.

I began by asking him a demo of his light, which he gladly gave. He filed off the lens to fit a square aluminum tube, which created an amoeba-shaped light beam. Also, I didn't want any focussed light beam. I just want light. Lots of it. It should all be lit. The ground, the trees, everything! And it should hurt motorists the way their high beams hurt us! I'm ready to compensate for the energy consumption with D cells.

Gokul said he used a 555-based timer for doing pulse width modulation to control the current in the circuit. This has a fundamental flaw: versatility. The astable multivibrator made with a 555 can generate only a limited range of duty cycles and frequencies using a single potentiometer. And the number of modes he can have in his light is very limited. And if he desires something extra, he needs to add circuitry. I got a normal 1/4 watt LED working with a 555 based oscillator but soon abandoned the scheme.

I substituted all this circuitry with a time-tested and reliable companion: Arduino UNO. It's already a part of my bike and I had already made a weatherproof mount for it on my handlebar. So I hooked up a pin of the Arduino to a driver IC and connected the driver to the 3 watt LED. It consumed about 70 milli amps at around 30% duty cycle and about 300 milli amps at around 80% duty cycle.

I mounted the LED onto a heatsink and fixed it to a circular lens. The result: A bright light that scatters everywhere. Just the way I wanted it! I drilled a nice circular hole in the cap of an old film cannister using the dremel and fixed the lens to it with Araldite. The battery holder could not be fixed anywhere. A screw through it was dislodging the batteries. So I wrapped it in bubblewrap and put it in the Arduino box. Neither is it fixed, nor is it movable!

Final step: weatherproofing. I poured generous amounts of hot glue on every hole that exists. As a final check, I immersed my light into my fish tank.

The blinding 3 watt LED!

Let there be light! Lighting up the S-Block hostel

Up close and personal!

The beamshot. The distance between two consecutive white blobs is 2 meters.

Apache Cordova 3.0, Mac OS X and iOS Development: Part I - Installation

I've been interested in developing for iOS for quite some time, but the necessity to learn Objective C has postponed by efforts till now. A while back, Ramnath from our IISc Robotics Club mentioned about PhoneGap and the possibility to develop iOS and Android apps using nothing more than HTML/CSS and Javascript. My journey into mobile development begins here.

As a follower of the Apple-cult, I wanted to begin with iOS development and decided to install Apache Cordova/PhoneGap on my MacBook Air.

I used XCode 4.7 on Mac OS X 10.8 Mountain Lion and Cordova 3.0.0. The new rules set by Apple in May 2013 require apps to support iPhone 5 and retina displays. This means, anything created with versions prior to Cordova 2.5.0 would not be published to the App Store. I encountered several issues with this and finally was able to get it working. The following steps worked well for me. Please feel free to contact me for comments or clarifications.

Step 1: Install XCode from the App Store or from the Apple Developer Portals.

Step 2: Make sure that the Locations tab in XCode Preferences looks like this:


Step 3: Launch Terminal.app and enter the following to create a new app called HelloWorld. This is created in the folder iOSApps.


Step 4: Use XCode to open the .xcodeproj file from the directory that was created when the previous step was executed.


Step 5: After it opens with XCode, add $(OBJROOT)/UninstalledProducts/include  to Build Settings -> Header Search Paths in the Target. Choose the iPhone simulator and click on 'Run' at the top left corner to build and launch the simulator.


Step 6: If everything has gone well till now, the iPhone simulator launches with the sample app. 



References:

I found the following resources to be the most helpful.

1. Apache's documentation - The standard resource!
2. Ranjeet's blog - Though it's for Cordova 1.7 and is no longer completely valid, it provided clear insights.
3. Stackoverflow - 1Stackoverflow - 2Stackoverflow - 3 - Addresses a problem that I faced
4. PhoneGap Docs - Valuable info!
5. Wikipedia - The source of all human knowledge :P