Resources
Home
Downloads
Mailing list
Search this site
Link to this site

TT Web Site Manager
Documentation
Download
Tutorials
FAQ

TT calendar library
About
Documentation
Download
Demo

Other code
poptasticDB
Simple XML parser function
Email address validation function

TT articles
Mending a dead iBook battery
Battery guide for small devices
Build your own TV modulator
PHP Nipkow disk generator
The Napier coffeemaker

Mechanical television is the earliest form of television invented by John Logie Baird in the 1920s. For more information on mechanical TV in general please visit the web site of the Narrow bandwidth TV association.

A mechanical TV system scans the image using a spinning disk called a Nipkow disk with a series of holes drilled to form a spiral. This page describes a piece of software that creates a template for a Nipkow disk as a printable PDF file, and a brief description of how the PDF might be used.

Looking at the design of homemade mechanical TV cameras and monitors it becomes apparent that they are rather bulky pieces of kit and most people who build them seem to build everything from scratch. Looking at what I have to hand I would like to try using the mechanism from an old CD-ROM drive to avoid having to build all the hardware, so the software listing below has the physical parameters of a CD-ROM defined within it. If the CD based mechanical TV camera sees the light of day after writing this software, I'll post details of it on this site. Meanwhile if you use this disk or software in your projects and post details on the web could I request that you link back to this page.

The software listing below is a PHP script designed to be run on a PHP4 enabled web server with PHP's PDF extensions installed. It returns a printable PDF file designed to produce an image of a Nipkow disk from your printer with exactly the dimensions you specify. It calculates a hole size, though this is more accurately described as a dot size and may be smaller than is needed or is practical to drill. It could probably also be adapted to run as a command line PHP script by removing the http header code at the bottom and writing to a file instead. This is a versatile piece of software allowing disks of many different TV standards to be created, however disks with too many lines may be impractical. There are several PHP variables in the script which define the properties of the disk returned, these are listed below.
$pagewidth Width of the PDF page in point.
$pageheight Height of the PDF page in point.
$rotation Disk rotation: clockwise or anticlockwise.
$scanlines Number of scan lines.
$aspectratio Aspect ratio, width:height expressed as $aspectratio:1.
$diameter_mm Disk diameter in mm.
$hole_diameter_mm Diameter of hole in centre in mm.
$synchole_distance Distance of sync hole from edge of disk in mm.
$outsideline_distance Distance of outside scan line from edge of disk in mm.

And here is an example PDF of a CD sized Nipkow disk based on the nbtv.org 32 line standard. It is intended that it be printed on paper, cut out and glued to a CD and the holes drilled through paper and CD. It could however be printed directly onto a CD-R with the foil removed or printed onto transparent film to avoid any need for drilling. You will need the Adobe Acrobat reader installed on your computer to view and print this file.

Here is the software listing itself.

< ?php
#Nipkow disk generator for mechanical TV http://www.technotoad.com
#adapted by John W. List from Uwe Steinmann's PDF clock example in PHP docs
#so parts © Copyright the PHP Documentation Group, Uwe Steinmann, John W. List.

#Page width and height in point. A4=595.28x841.89, US Letter=612.00x792.00
#thanks to http://www.ros.co.nz/pdf for the dimensions
#$pagewidth = 595.28;
#$pageheight = 841.89;
#end up using page size smaller than paper because of pdf reader shrinking to printer margins.
$pagewidth = 550;
$pageheight = 700;

#disk rotation: clockwise or anticlockwise
$rotation = "anticlockwise";

#TV standard. Baird=30, nbtv.org=32
$scanlines = 32;

#Aspect ratio, width:height $aspectratio:1, for example nbtv.org is 2:3 i.e. 0.667:1
$aspectratio = 0.667;

#Disk diameter in mm. CD=120
$diameter_mm = 120;

#Diameter of hole in centre in mm. CD=15
$hole_diameter_mm = 15;

#Distance of sync hole from edge of disk in mm.
$synchole_distance = 3;

#Distance of outside scan line from edge of disk in mm.
$outsideline_distance = 6;

#take one point to be 0.3528mm, calculate radius in point
$one_point = 0.3528;
$radius = ($diameter_mm/$one_point)/2;
$hole_radius = ($hole_diameter_mm/$one_point)/2;
$centre_dot_radius = (1/$one_point)/2; #1mm dot at centre

#calculate dimensions of scanned area of disk.
#Our scanned area is not quite rectangular, only the middle line is the
# length it would be if it were. To get the width of the scanned area
# we need to calculate the length of this middle line to get our scanned height.
$degreesperdot = 360/$scanlines;
#approximating a "slice" of the disk to be roughly a triangle, calculate length of outside scan line.
$outside_line = (($diameter_mm/2) -$outsideline_distance)*sin(deg2rad($degreesperdot));  
$scanned_height = $outside_line/(1+(2*$aspectratio)*tan(deg2rad($degreesperdot)));
$scanned_width = $aspectratio * $scanned_height;
$dot_width = ($scanned_width/$scanlines)/$one_point; #in point
$outside_dot_radius = (($diameter_mm/2) - $outsideline_distance)/$one_point; #in point
$synchole_radius = (($diameter_mm/2) - $synchole_distance)/$one_point;


$pdf = pdf_new();

if (!pdf_open_file($pdf, "")) {
    print error;
    exit;
};

pdf_set_parameter($pdf, "warning", "true");

pdf_set_info($pdf, "Creator", "nipkow.php");
pdf_set_info($pdf, "Author", "John W. List");
pdf_set_info($pdf, "Title", "Nipkow disk generator");

    pdf_begin_page($pdf,$pagewidth,$pageheight);

    #put the origin in the middle of the page
    pdf_translate($pdf, $pagewidth/2, $pageheight/2);
    pdf_save($pdf);

    #Draw full size circle
    pdf_setrgbcolor($pdf, 0.0, 0.0, 0.0);
    pdf_circle($pdf, 0, 0, $radius);
    pdf_fill($pdf);
    pdf_restore($pdf);
    pdf_save($pdf);

    #Draw centre circle
    pdf_setrgbcolor($pdf, 1.0, 1.0, 1.0);
    pdf_circle($pdf, 0, 0, $hole_radius);
    pdf_fill($pdf);
    pdf_restore($pdf);
    pdf_save($pdf);

    #Draw little dot in centre
    pdf_setrgbcolor($pdf, 0.0, 0.0, 0.0);
    pdf_circle($pdf, 0, 0, $centre_dot_radius);
    pdf_fill($pdf);
    pdf_restore($pdf);
    pdf_save($pdf);

    #Draw sync holes
    #end at 360- degreesperdot for field sync
    for ($alpha = 0; $alpha < (360-$degreesperdot); $alpha += $degreesperdot) { 

       pdf_setrgbcolor($pdf, 1.0, 1.0, 1.0);
       $sync = synchole_radius;
       pdf_circle($pdf, $sync * cos(deg2rad($alpha)),  $sync * sin(deg2rad($alpha)), $dot_width);
       pdf_fill($pdf);

    }

    pdf_restore($pdf);
    pdf_save($pdf);

    if($rotation=="clockwise"){
        $current = $outside_dot_radius; 
    }
    else{
        $current = $outside_dot_radius-($scanned_width/$one_point);   
    }
    #Draw scan holes
    for ($alpha = 0; $alpha < 360; $alpha += $degreesperdot) {

       pdf_setrgbcolor($pdf, 1.0, 1.0, 1.0);
       pdf_circle($pdf, $current * cos(deg2rad($alpha)),  $current * sin(deg2rad($alpha)), $dot_width);
       pdf_fill($pdf);
       if($rotation=="clockwise"){
          $current -= $dot_width;
       }
       else{
          $current += $dot_width;
       }
    }

    pdf_restore($pdf);
    pdf_save($pdf);

    #Put up some explanatory text
    $font = pdf_findfont($pdf, "Arial", "winansi", 1);
    pdf_setfont($pdf, $font, 10);
    pdf_set_value($pdf, "textrendering", 1);
    $copyright_text = "Nipkow disk generator 1.0  © copyright John W. List http://www.technotoad.com";
    pdf_show_xy($pdf, $copyright_text, -$radius, $radius+70);
    $line2 = "Disk diameter: " . $diameter_mm . "mm  ";
    $line2 .= "Scan lines: " . $scanlines . " Aspect ratio: " . $aspectratio . ":1";
    pdf_show_xy($pdf, $line2, -$radius, $radius+60);
    $line3 = "Rotation: " . $rotation . " Drill diameter: " . round($scanned_width/$scanlines,3) . "mm";
    pdf_show_xy($pdf, $line3, -$radius, $radius+50);



    pdf_restore($pdf);
    pdf_save($pdf);

    pdf_restore($pdf);
    pdf_end_page($pdf);


pdf_close($pdf);

$buf = pdf_get_buffer($pdf);
$len = strlen($buf);

header("Content-type: application/pdf");
header("Content-Length: $len");
header("Content-Disposition: inline; filename=nipkow.pdf");
print $buf;

pdf_delete($pdf);
? >

© copyright John W. List 1998 - 2007