Saturday, December 28, 2013

YouTube Videos of some awesome IoT and M2M Products

The best way to introduce some one to a newly emerging technology is to show them short (about 2 minutes) but well shot videos of some new products and applications enabled by that technology. Here is a short compilation of awesome videos of awesome Internet of Things (IoT) and Machine to Machine (M2M) products.
IoT and M2M both make use of the same building blocks of technology, the only difference is that IoT products are developed within the context of home use where is M2M refers to products developed for industrial use.

  1. Internet of Things
    1. Nest Thermostat - The learning thermostat - YouTube Video 00:01:12
    2. Nest Protect - Smoke and carbon monoxide alarm - YouTube Video 00:01:37
    3. Tile - The world's largest lost and found - YouTube Video 00:02:00
    4. Egg Minder - The smart egg tray - YouTube Video 00:00:57
    5. Electric IMP -The Egg Minder is based on this - YouTube Video 00:02:00
    6. WunderBar! - Starter kit for the Internet of Things - YouTube Video 00:03:01
  2. M2M
    1. Sierra Wireless AirLink - Intelligent Gateways - YouTube Video 00:03:09
    2. Flutura Decision Sciences and Analytics - YouTube Video 00:02:32
    3. AT&T M2M - Wireless Enterprise Solutions - YouTube Video 00:02:47
    4. Caterpillar - Product Link - YouTube Video 00:02:36
    5. CarIQ - Making Cars Smarter - YouTube Video 00:03:10

Wednesday, December 25, 2013

Decreasing JPEG image file size

So friends/family have asked me time and again regarding this and it had become a major FAQ asked of me.
So here goes.

You can decrease the file size of a JPEG image in two ways: decreasing the image quality and decreasing the resolution. When you get a file whose size you want to decrease, try reducing the quality first, if that brings the file size under the threshold, you are looking for then you are done, if not, try decreasing the resolution.

Theory
The quality setting of JPEG image can vary from 0% (bad quality) to 100% (best quality) and refers to a parameter of the compression algorithm used by JPEG. Needless to say, digital cameras save images at quality setting of very near 100% and decreasing this to 80% will decrease the file size of the image by almost a third. The same process when applied to images that have come from scanners and mobile phone camera does not yield much reduction in file size - maybe those devices have already set the quality level to lower value.
In my experience, I have never been able to visually tell apart the differences between an photograph saved at 100% and the one saved at 80%. Technically, decreasing the image quality will cause the loss of information but you can decrease the quality down to 80% without any perceivable loss - so don't worry about it. (Details about JPEG quality here: wiki | fotoforensics | stackoverflow)

Decreasing the resolution simply refers to decreasing the number of pixels (dots) used to represent the image. Decreasing the number of pixels simply decreases the number of dots in the image, less the number of dot, less the amount of information that the computer has to save in the image file.

Instructions
So here's how to decrease the file size of image:

  1. Download and install IrfanView on your Windows PC. Its just a 2MB download.
  2. Open the JPEG image you want to compress using IrfanView - just double clicking on the image file would do since IrfanView setup would have set itself as the default program for opening JPEG files.
  3. Click on the Save as button (looks like a Floppy) and just save the image as JPEG without changing any setting. IrfanView has its JPEG quality set to 80% by default and this ought to decrease its file size. For reference, a 2592 x 1728 photo taken by my Canon 550D reduced in size from 2.5 megabytes to 702 kilobytes just by opening it in IrfanView and saving it.
    Quality setting in IrfanView
  4. If you want to decrease the file size further, you will have to decrease the resolution. NOTE THAT DECREASING THE RESOLUTION WILL CAUSE LOSS OF CLARITY AS THE NUMBER OF PIXEL REPRESENTING THE IMAGE WILL DECREASE. In case you have a very high resolution image, you can go ahead with this anyway. In IrfanView, press Ctrl+R to bring up the Resize/Resample dialog. Click the button that says "Half" - this will decrease the X and Y resolution to half their value. And then save the file. For reference, a the image in the previous step when resized down from 2592 x 1728 to 1296 x 864 caused the file size to reduce from 702 kilobytes to 223 kilobytes. Overall decreasing the quality to 80% and halving the resolution resulted in decreasing the file size to a tenth of the original size.
    Resize / Resample dialog box in IrfanView
NOTE: You can also set the image to other resolutions, just make sure you leave the "Preserve aspect ratio" box checked. Selecting a particular area of the image in IrfanView and pressing Ctrl+Y will allow you to cut out (crop) those areas of the image that you don't require - This will also help you cut down the image file size. Just remember - less the number of pixel in an image, lower its file size.

Thursday, December 19, 2013

Trouble installing VirtualBox extension pack on Windows 8

So, you have installed VirtualBox successfully on Windows 8 and now you are trying to install the corresponding Extension Pack but it won't install and you keep getting the error message "The installer failed with exit code 1". To fix that just enable Windows 7 compatibility mode for VBoxSVC.exe and VirtualBox.exe - both of these files would be present in C:\Program Files\Oracle\VirtualBox

(Note: The following has been tested with VirtualBox 4.3.6 on Windows 8.Thanks to Kiran Nevaskar for the solution and the screenshots)
  1. Open Windows Explorer and browse to C:\Program Files\Oracle\VirtualBox
  2. Right click VBoxSVC.exe and select Troubleshoot compatibility
  3. Select the options as per the screenshot below to enable compatibility mode for Windows 7
  4. Repeat process for VirtualBox.exe
  5. Try installing the extension pack again (http://download.virtualbox.org/virtualbox/4.3.6/Oracle_VM_VirtualBox_Extension_Pack-4.3.6-91406.vbox-extpack)
1) Browse to the location and right click on VBoxSVC.exe and
select "Troubleshoot Compatibility"

2) Click "Troubleshoot program"

3) Check the option as shown above

4) Select Windows 7

5) Click on "Test the program"

6) Save the settings

7) Click Close. Repeat process for VirtualBox.exe

Monday, December 16, 2013

Video panning across your family tree chart (.jpg to .mp4)

Problem statement:
I have a large panoramic JPEG file (e.g. 8038 x 1145 or more) . How do I generate a video (.avi or preferably .mp4) to zoom in on a particular sub-section of the image (say 1920 x 1080 - size of my Full HD television screen) and slowly pan across the whole image?

I have been using MyHeritage's Family Tree Builder since 2008. I have their premium plus membership. Currently I have 401 individuals cataloged in my family tree.
Beginning last year, we starting organizing an annual family get together of the descendants of Mr Mool Chand Kalra (My mother's father's father) . Genealogically, this basically comprised of 1/4 branch of my extended family, I have 3 other such branches each comprising of the siblings (and their descendants) of my other 3 grandparents. But this particular branch has more individuals (Mr. Mool Chand Kalra had a big family, and his children had equally big ones as well) than the other 3 branches. It is also the best catalog in my family tree.
Last year, during the get together, we had a short presentation where in displayed sub branches of this big branch and showed how the members of the audience were related to each other. MyHeritage's Family Tree Builder allows you to generate awesome family charts. I used this feature to generate family charts for each sub-branch of my family tree. The charting feature allows you to configure lots of features of the chart : ancestors/descendants of a person, horizontal/vertical, hide/display facts, select font sizes, export type as PDF/JPG.

This year, we have decides we aggregated photos from all the members and decided to put it on a pendrive and let a big screen LCD TV loop through the slideshow. The LCD TV will be kept in one corner of the room and people could come take a look at their convenience - forcing them to sit through a long presentation of photos would keep them from catching up with each other and might be counter-productive.

I decided that as a refreshed, I would like to throw in a jpg of the chart as well, but when I generated the chart for my great grandfather, it was huge and when displayed on a screen limited to 1920 x 1080 pixels, you could hardly make out anything. I decided to generate a video panning across the whole family chart 1920x1080 pixels at a time. 

Here is what my original looked like (I have set the font size of names set to 1, essentially hiding them to protect the privacy of my relatives) :

The descendants of Mr. Mool Chand Kalra - 8038 x 1145 pixels
Click to view the original.
Here is the Full HD (1920 x 1080) .mp4 video panning across the image
Full HD video panning across the image.
Click to view in Full HD at Youtube

I didn't want to spend a single penny to create the above video and hence choose the freeware path. And to save time, I decided to use tools I was familiar with. Here is how I got it done:
  1. Export the image as JPEG from MyHeritage's Family Tree Builder.
  2. Download Processing 2 from www.processing.org and install it
  3. Execute the following sketch. Make sure your original JPEG is in the same folder as the sketch. The name of the folder in which you place the sketch (.pde file) and the name of the sketch must be the same. Edit the name of the JPEG file in the sketch to match the name of your JPEG file. You may adjust the panning parameters - frames per second and amount of pixels to shift by each time. The panning is preset to move left from center of the image towards left and then back on to the other side of the image. The code displays a FullHD worth region of the image each draw() loop and saves it to disk. At the end you will get a folder full of frames like so:
    JPEG frames
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    import processing.video.*; 
    
    int pan_step_px=2;
    int frame_speed=30;
    int screensize_rows=1080;
    int screensize_cols=1920;
    
    
    PImage img;
    int xoffset;
    int yoffset;
    
    int pan_y_ctr;
    
    int current_direction;
    
    boolean sketchFullScreen() {
      return true;
    }
    
    void setup() {
      smooth();
      frameRate(frame_speed);
      size(screensize_cols, screensize_rows);
      img = loadImage("mool.jpg");
      xoffset=img.width/2;
      yoffset=0;
      current_direction=LEFT;
      pan_y_ctr=0;
    }
    
    void draw() {
      image(img.get(xoffset, yoffset, 1920, 1080), 0, 0);
    
      if (current_direction == LEFT) {
        xoffset = xoffset-pan_step_px;
        if (xoffset <0) {
          xoffset = 0;
          pan_y_ctr=0;
          current_direction = DOWN;
        }
      } 
      else if (current_direction == DOWN) {
        if (xoffset == 0) {
          yoffset = yoffset+pan_step_px;
          pan_y_ctr += pan_step_px;
          if (yoffset+screensize_rows >= img.height) {
            yoffset = img.height - screensize_rows;
            pan_y_ctr = 0;
            current_direction = RIGHT;
          }
          if (pan_y_ctr >= screensize_rows) {
            pan_y_ctr = 0;
            current_direction = RIGHT;
          }
        } 
        else {
          yoffset = yoffset+pan_step_px;
          pan_y_ctr += pan_step_px;
          if (yoffset+screensize_rows >= img.height) {
            yoffset = img.height - screensize_rows;
            pan_y_ctr = 0;
            //Stop
            noLoop();
          }
          if (pan_y_ctr >= screensize_rows) {
            pan_y_ctr = 0;
            current_direction = LEFT;
          }
        }
      }
      else if (current_direction == RIGHT) {
        xoffset = xoffset+pan_step_px;
        if (xoffset+screensize_cols>img.width) {
          xoffset = img.width-screensize_cols;
          pan_y_ctr=0;
          current_direction = DOWN;
        }
      }
      saveFrame("line-######.jpg");
    }
    
  4. Copy the frame JPEGs to a Linux box. I used Ubuntu 13.10 32 bit running on a VirtualBox VM.
    Making the JPEGs available inside of a Linux VM
  5. Use avconv to assemble the JPEGs (line-xxxxxx.jpg) into a .mp4 file. Use the following command:
    avconv -r 30 -i line-%06d.jpg -qscale 2 -r 30 out.mp4
    Done creating .mp4 using avconv
    -r option is used twice to indicate the input and output frame rate. I have set it to 30 fps because that is what I specified in the Processing sketch. -qscale option specifies the quality of the video between 1 and 31, 1 being the best, 31 being the worst.

    - avconv can be run on Windows too: http://libav.org/download.html
    - Processing 2 is available for Linux too.
    - MyHeritage's Family Tree Builder works only on Windows

Thursday, December 12, 2013

Why do we use 11.0592 MHz with 8051 variants?

  1. Why do we use 11.0592 MHz with MCS-51 variants?
    The original 8051 could be operated at a maximum frequency of 12 MHz (reference).
    And 11.0592 MHz was the frequency very near the maximum operating frequency which was still a multiple of the standard baud rates.
    By the way original 8051s executed a single machine cycle every 12 clocks, so at 12 MHz, the instruction execution frequency was 1 million instructions per second.
  2. What are the standard baud rates?
    Baud rate refers to number of symbols sent through a channel in one second.
    The standard baud rates are 2400, 4800, 9600, 19200, 38400, 57600, 115200 etc.
    Baud rate is also known as symbol rate.
    These are the symbol rates used in all kinds of serial communications.
    The first serial communications were those that were carried over telephones lines.
    (Reference: Bell 202 Modem, Acoustic Coupler)
  3. What is the relation between baud rate and bit rate?
    Baud rate is number of symbols per seconds.
    Bit rate is number of bits per seconds.
    One symbol can represent 1, 2 3 or more bits.
    In BPSK, each symbol represents a single bits (since there are only two symbols), hence in that case baud rate = bits per second.
    In 16QAM, each symbol represent 4 bits. So in that case bitrate is 4 times the baud rate.
  4. Where are these baud rates used?
    These baud rates are used to measure the data rates in telecommunications (wired and wireless).
    But for our discussions, the context is restricted to telecommunications over infrastructure originally intended for audio telephony.
    We operated our computer's UART at these baud rates to communicate with our modems (over RS232) which would then send data over the telephone network at the same speeds to other modems. The data rate used between the computer and the modem and the one used between two modems communication over the telephone network had to be a multiple of the baud rate.
    Since microcontroller were used in modems, the habit of using those baud rates stuck.
  5. Who decided upon these particular baud rates?
    International Telecommunications Union.
    More specifically, ITU Telecommunication Standardization Sector (ITU-T).
    In their V series recommendations - which describe the protocols that govern the telecommunications over telephone network.
  6. What are these ITU V Series recommendations based on?
    The telephone system was designed to carry human voice only.
    Even though humans can hear frequencies in the range of 20 to 20000 hertz, the maximum power density of our speech lies in the range 600 to 3000 hertz. The telephone network carries signals only in this range and attenuates frequencies below 600 hertz and above 3000 hertz. Any technology which tries to make use of the telephone network must be based on these limitation - i.e. much of the power carried by the data signal must lie within this band width.
    So if you actually read the modulation rates (aka baud rates) described in some of the V series recommendations, they are based on using modulation schemes like FSK, PSK, QAM in a channel band limited to 600 to 3000 Hz. This results in possible bitrates of 1200, 2400, 4800, 9600 14400, 28800 and so on. These were the speeds that our modems could support.

    V.22 : 1200 bits per second duplex modem standardized for use in the general switched telephone network and on point-to-point 2-wire leased telephone-type circuits

    V.32 : A family of 2-wire, duplex modems operating at data signalling rates of up to 9600 bit/s for use on the general switched telephone network and on leased telephone-type circuits
  7. Do we still need to use 11.0592 MHz?
    If your microcontroller can operate at higher frequency (like most modern day 8051s), you can use higher frequency like 14.7456 MHz and 22.1184 Mhz.
    If you want save power by operating at a lower frequency, crystals of 7.3728 MHz, 3.6864 MHz and even 1.8432 MHz

    You can also use crystals at frequencies which are not multiples of the baud rate and still get away with operating your microcontroller's UART successfully. Here's how.
  8. Besides Serial Communications, is 11.0592 also good for maintaining time using a real time chip?
    11059200 = 214 x 33 x 52
    So we can use some of these factors to get 86,400 (number of seconds in a day)
    But wait we are, not getting any where. for an RTC, we would like something like a 1 tick per second (1Hz).
    A 15 bit counter operating at 32768 hertz would overflow every one seconds - convenient to make a watch!
    More in depth discussion here.
  9. Are crystals of other frequencies used elsewhere?
    Yes. Have a look at this table.
    Other than the crystals which are multiples of baud rates and the 32.768 kHz one used in watches, the two most notable are the ones used in television circuity for NTSC and PAL signals. Read about colorburst.
  10. I still don't get it - why do we care?
    Because its funny and interesting at the same time.
    I once asked John F. Wakerly over email why TTL logic was based on +5 volts, here is what he had to say (do read the essay that he has linked to) :
This was the voltage chosen for the original TTL family.  I'm not sure of the exact reason.  It's possible that some previous logic families used 5V, but then there would still be the question for that family.  It was undoubtedly a tradeoff between power consumption, reliable switching operation, and noise margins.
Or perhaps it's more like the reason that railroad tracks are separated by the width that they are (see www.naciente.com/essay94.htm).
John

In summary, our decision to use 11.0592 MHz crystals in micro-controllers is indirectly based on the natural frequency of human hearing and speech characteristics - which is in a way similar to the solid rocket boosters having their diameters based on the width of two horses asses.

Wednesday, December 11, 2013

Enlarging polygons (Logos saved as parts) in Cadsoft Eagle

This is for regular users of Cadsoft Eagle - a software package used for designing PCBs.
If you have been using Eagle for as long as I have been using, you most definitely know how to create part libraries, write ULPs and have come up with creative ways to spruce up your PCB's silkscreen (and schematic drawings) with nice artwork - logos, line art, figures etc.

One way you can add artwork to your PCB is by drawing a monochrome figure in paint or some other graphics program and then using the import_bmp.ulp as described in this instructable

But this method imports your art work as a raster of small squares/traces which lacks fidelity - you can note the squares when zoomed in!

Consider this company logo on one of the circuits we designed

Here are the two versions of the logo. The one on top (raster) was created by importing
the BMP file of the logo using import_bmp.ulp. The one on the bottom (vector) was created
by retracing polygons by hand over the imported raster version of the logo and then deleting
the raster square. The logo on the bottom is smoother.

Usually you would have your company logo in some vector format (PS or CDR or SVG). This vector image of the logo is what you would use in your various branding artifacts and documentation. The reason one wants vector images is that they can be enlarged or shrink without loosing fidelity.

It is only reasonable to want your logo imported as a vector into your PCB's silkscreen.
The only two ways to have a vector image (in case of Eagle, this means a set of polygons) of your company logo are to either re-create the logo by hand in Eagle or if possible import SVG into Eagle using Cruz Monrreal II's ULP.

Hand tracing polygons manually over the imported raster squares and traces
to create high fidelity logos.
5 Polygons forming a logo.
Each polygon has been transposed to a different layer just so that
it appears in a different color. At the end all polygons must reside in
one of the layers used to generate the silkscreen gerber. 

Before Cruz Monrreal II developed his SVG import ULP (I haven't tried it yet), what I used to do is to import the logo as BMP into any layer in the part creation mode of Eagle, redraw polygons in a higher layer over the imported raster squares of the logo and save the polygons as a part. I would then export that script, modify the layer number in it and import it back into the schematic layer there by creating a part for the logo.

Once the logo was created using hand traced polygons in Eagle (and if desired saved as a part in one of your libraries), it became difficult to resize (enlarge or shrink). This became a problem when designing PCBs of varying sizes - we needed varying sizes of logos to go on them. The sizes of the polygons which formed the logo was specified in absolute units

Those who use import_bmp.ulp did not suffer from this problem because they could manually adjust the scale factor every time they imported the logo onto a PCB (Refer this image in the procedure described on this page)

So I wanted to be able to modify the size of the. And to do that here are the steps I followed:


  1. Export the logo (all polygons resided in only one of the layer) as an Eagle script (.scr). The .scr file is a text file which contains the coordinates of the vertices which form the polygon.
  2. Use a perl script to search for pattern of numbers specified in the format:
    (2.9396475 4.322355)
    These are the XY coordinates of the vertices forming the polygons. The perl script will multiply the abscissa and ordinates of each of the vertices by a fixed number (the pre-set magnification factor) and generate a new .scr file. Of course its not as simple as it sounds but that' the jist of it. There are a few issues that I had to take care of - read the comments in the perl script below.
  3. This new .scr file which when imported back into eagle would create and enlarged (or shrunk, depending on the pre-set magnification factor) version of the same logo.

Here is the perl script and how I shrunk the Texas Instruments Logo to half its size.

Varying sizes of TI Logo. The logo was first created by hand.
It was then exported as a script (.scr). A perl script then took this .scr file as input
and generated a new .scr file with magnified version of the logo.
The new .scr file was then re-imported back into eagle using "Execute Script"
Here is the perl script. There might still be some bugs lurking around.
I executed this perl script on my windows PC using Strawberry Perl



 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#read each line of file input.txt and find all decimal numbers in each line, multiply it by a constant and save the output in file output.txt

#!/usr/bin/perl

use strict;
use warnings;

open(my $in,  "<",  "input.scr")  or die "Can't open input.scr: $!";
open(my $out, ">",  "output.scr") or die "Can't open output.scr: $!";

my($magfactor)=2;

while (<$in>) # assigns each line in turn to $_
{

	s/[\040](\d+)[\051]/' ' . $1 . '.0)'/ge;		#append .0 to all positive integer abscissae
	s/[\050](\d+)[\040]/'(' . $1 . '.0 '/ge;		#append .0 to all positive integer ordinates
	
	s/[\040][\055](\d+)[\051]/' -' . $1 . '.0)'/ge;		#append .0 to all negative integer abscissae
	s/[\050][\055](\d+)[\040]/'(-' . $1 . '.0 '/ge;		#append .0 to all negative integer ordinates
	
	#magnify decimal numbers pairs of all coordinates by the specified factor
	s/[\050](\d+)[.](\d+)[\040](\d+)[.](\d+)[\051]/'(' . eval{eval{"$1.$2"}*$magfactor} . ' ' . eval{eval{"$3.$4"}*$magfactor} . ')'/ge;
	s/[\050][\055](\d+)[.](\d+)[\040](\d+)[.](\d+)[\051]/'(-' . eval{eval{"$1.$2"}*$magfactor} . ' ' . eval{eval{"$3.$4"}*$magfactor} . ')'/ge;
	s/[\050](\d+)[.](\d+)[\040][\055](\d+)[.](\d+)[\051]/'(' . eval{eval{"$1.$2"}*$magfactor} . ' -' . eval{eval{"$3.$4"}*$magfactor} . ')'/ge;
	s/[\050][\055](\d+)[.](\d+)[\040][\055](\d+)[.](\d+)[\051]/'(-' . eval{eval{"$1.$2"}*$magfactor} . ' -' . eval{eval{"$3.$4"}*$magfactor} . ')'/ge;
	
	#Commandwise replacement: Polygon
	s/Polygon[\040](\d+)[\040]/'Polygon ' . eval{eval{"$1"}*$magfactor} . ' '/ge;	#magnify all positive whole numbers appearing after command
	s/Polygon[\040][\055](\d+)[\040]/'Polygon  -' . eval{eval{"$1"}*$magfactor} . ' '/ge;	#magnify all negative whole numbers appearing after command

	s/Polygon[\040](\d+)[.](\d+)[\040]/'Polygon ' . eval{eval{"$1.$2"}*$magfactor} . ' '/ge;	#magnify all positive decimal numbers appearing after command
	s/Polygon[\040][\055](\d+)[.](\d+)[\040]/'Polygon -' . eval{eval{"$1.$2"}*$magfactor} . ' '/ge;	#magnify all negative decimal numbers appearing after command
	
	#Commandwise replacement: Wire
	s/Wire[\040](\d+)[\040]/'Wire ' . eval{eval{"$1"}*$magfactor} . ' '/ge;	#magnify all positive whole numbers appearing after command
	s/Wire[\040][\055](\d+)[\040]/'Wire  -' . eval{eval{"$1"}*$magfactor} . ' '/ge;	#magnify all negative whole numbers appearing after command

	s/Wire[\040][\040](\d+)[.](\d+)[\040]/'Wire  ' . eval{eval{"$1.$2"}*$magfactor} . ' '/ge;	#magnify all positive decimal numbers appearing after command
	s/Wire[\040][\040][\055](\d+)[.](\d+)[\040]/'Wire  -' . eval{eval{"$1.$2"}*$magfactor} . ' '/ge;	#magnify all negative decimal numbers appearing after command
	
	print $out "$_";

}

Files:

  1. enlargelogo.pl - The above perl script
  2. input.scr - Eagle script for creating the Texas Instruments Logo in Eagle in Layer 21 using handcrafted curved polygons.
  3. output.scr - Output when enlargelogo.pl was run on input.scr. This Eagle script would create the Texas Instruments Logo in Layer 21 but of twice the size than the one created by input.scr
The above three files archived in a zip file available here