Show Source


The contents of this page derive from tinkering, poking, tracing, and other low-assurance methods of engineering! Please do not depend on any of the contents seriously.


If you are in any way responsible for the construction of this device, write to me and I will buy you several beverages of your choosing; seriously, this thing is amazing.

What little information exists about this device online can be found at ; the CDL144 I have is the larger of the two products of the family, the other being the CDL54. Mine came configured with 4 SCSI CD-ROM drives and 6 magazines (for a capacity of 108 CDs). I have subsequently replaced the drives with bluray capable SATA devices and put an embedded computer in some free space in the device. I will get pictures up eventually.

Software Library

Based on the effort described on this page, I have started writing software to actually make use of the robot through its debugging interface. See the README .

Hardware Description

Central logic board

Major ICs on the Kodak logic board include:

  • Motorola MC68332ACFC16 CPU; datasheet
  • Symbios Logic 53CF92 SCSI bridge
  • AMD AM29F040 FLASH (512Kx8)
  • Toshiba TC551001BFL-70L memory (128Kx8 SRAM)
  • ST M48Z08-100PC1 nonvolatile memory (8Kx8)
  • max708 supervisory circuit
  • PBL 3770A motor controllers (x2 for one stepper)
  • lmd18245t motor controllers (x2 for one stepper)


  • Every header is uniquely sized, so there’s no possibility of confusion, other than J2/J18. The stepper goes in J18.
  • J1 is power. I’ll get a pinout later.
  • J2 is clearly a debugging header of some form, as the wires chase off to the 68Ks debugging pins. Does not appear to be JTAG.
  • J4 is a serial interface for debugging and commanding the robot. Pin 1 is +5V power, then RX then TX, then ground. Due to the JST connector, it may be tempting to grab ground from nearby on J5. Don’t do that; it yields a lot of bitflips for reasons unknown.
  • J5 is unknown, but it looks like board-edge-side is all ground pins and board-internal-side is logic lines pulled high. Some kind of configuration jumpers?
  • J10 interfaces to the supervisory circuit, possibly to be a reset button?
  • J11 connects to the mailbox circuitry
  • J16 connects to the top sensor board
  • J20 connects to terminator power on the SCSI bus. It appears that the device is held in some kind of very early RESET state (it doesn’t even get as far as printing out the welcome message on the serial port) if there isn’t external teriminator power... Jumping J20 solves that problem, but still requires that there be a terminator on the SCSI line.


The picker itself contains a few sensors (the barcode scanner, a photo slot interruptor to measure tray arm position, and another photo slot interruptor to detect CD presence), but is mostly gears.

Bottom Sensor Board

Contains three presumably-IR LEDs and attaches to a membrane contact sensor used to detect picker zero position.

Top Sensor Board

Contains three OPL821 IR sensors from Optek ( and a Sharp GP1A70R photointerruptor sensor ( The former stare into beam channels from the bottom sensor board and form the receiving end of the Drawer, Tray, and CD sensors. The latter is used as part of a disk encoder for the picker position.

Serial Interface

Connecting at 9600 8n1 to J4 and powering up the machine yields:

(C)1996 KODAK AG Technik, Muehlhausen/Germany

Lynx PM Firmware Version:  1.41 (Jul 18 1997)
Lynx PM Download Version 1.01 (Jul 21 1997)
KAGOS68K Version: V1.01 (May 20 1997)
FLASH Checksum is OK: 01097577
Lynx Model: 144P

Selftest of SCSI Controller successfully passed
Status #0: IDLE: no errors.

Asking for help yields:

Command (Abbr.) |  Description
AddOffset (A)   | add a offset to a location.
Barcode (B)     | read barcode of a magazine.
CWHEEL  (C)     | read codewheel count.
CLS             | clear screen.
DL              | download a Lynx firmware.
Drive   (D)     | open/close drive drawer.
EX              | display # of exceptions.
GetCount        | get the current SW actuation counter value.
GetLogs         | get the event logs or error logs.
Help    (H)     | this menu.
Init            | initialize the robotics.
Inv             | initiate an inventory of magazines.
LED             | turn on/off/flash red and greed LED.
Lift    (L)     | position the picker at an element.
Loc             | get/set the position of the elements.
Mailbox (MB)    | open/close mailbox.
Move    (M)     | transportation of CD.
MoveMag (MM)    | transportation of all CDs of a magazine.
ParBar          | get/set barcode system parameters.
ParLift         | get/set lift system parameters.
ParMB           | get/set mailbox system parameters.
ParTray         | get/set tray system parameters.
Pattern (PAT)   | get/set the pattern of the stepper motors.
Pick    (P)     | pick a CD out of tray.
PickRel (PR)    | pick and release a CD.
Queue   (Q)     | display msg queue status.
Ramp            | modify the lift and tray motor ramp.
Release (R)     | release a CD into tray.
Reset           | reset the system.
SCSI            | view/change robotics SCSI-parameters
Sensor  (S)     | get status of the sensors.
Setbaud         | change the RS232 interface baudrate.
Status  (ST)    | get status of the robotics.
Task            | get the ready task queue.
Tray    (T)     | open/close tray.
Ver             | display current version and Lynx model.

Unfortunately, many commands seem to take parameters and there doesn’t seem to be a way to find out what they are in all cases.

  • status is informative:

    Tray Status: No errors.
      Picker:     CD=o  Home=ffff
      Mailbox:    CD=o
      Drives:     D1=o D2=o D3=o D4=o
      Drivehome:  D1=ffff D2=ffff D3=ffff D4=ffff
      Magazine 2: absent!
      Magazine 3: absent!
      Magazine 4: absent!
      Magazine 5: Barcode:    1, Slot 1-18= xxxxx xxxoo ooooo ooo
      Magazine 6: Barcode:    2, Slot 1-18= ooooo ooooo ooooo ooo
      Magazine 7: Barcode:    3, Slot 1-18= ooooo ooooo ooooo ooo
      Magazine 8: Barcode:    4, Slot 1-18= ooooo ooooo ooooo ooo
      Magazine 9: Barcode:    5, Slot 1-18= ooooo ooooo ooooo ooo
      Magazine 10: Barcode:    6, Slot 1-18= ooooo ooooo ooooo ooo

    Drivehome appears to be the last source of a move command to a drive; Picker Home being the last place we picked a CD up and Drivehome being the last place from which a CD was moved to that drive. See Hexadecimal Lift Positions.

  • As is sensor:

    ClearPath: Drawer= o      Tray=  o     CD=o
    Home:      Lift=   o      Crank= o
    Mailbox:   In  =   yes    Out=   no    Button=clear
    Others:    Door=   closed CDPicked=no  Barcode=0
    Magazine Present [10..2]=111111000
  • And SCSI:

    SCSI configuration settings:
    SCSI: ID=5, Parity=enabled, Slow Cable Mode=disabled
    Selftest successfully passed
  • The various parameter commands reveal a wealth of configuration material that is probably best left unchanged:

    Tray system parameters:
    RS=-20.829°, RP=4.886°, RT=29.829°, PS=327.857°, PP=299.829°, PT=289.800°
    Gear=3.500, Rot=400steps, PCD=219.857°, RCD=99.771°, ICD0=79.971°, ICD1=229.886°
    PI=139.886°, RI=179.743°, PO=59.914°, RO=249.943°
    Mailbox system parameters:
    PWM=20000Hz, Timeout=5s
    AccOpenCycle=85%, DecOpenCycle=20%, DecOpenTime=50ms, OpenedCycle=20%
    AccCloseCycle1=85%, DecCloseCycle=20%, DecCloseTime=20ms
    AccCloseCycle2=60%, AccCloseTime2=200ms, AccCloseCycle3=90%, AccCloseTime3=100ms
    Lift system parameters:
    Min=-9.975mm, Max=600.000mm, Def=188.925mm
    Lead=30.000mm, Rot=400steps, Codewheel=50slots, CodewheelError=3slots
    Barcode system parameters:
    MagOffset=-1.500mm, DrvOffset=-1.500mm, Length=42.000mm
    CDL>pat tray
    Tray Motor Pattern: D4 F2 D6 CF D7 F1 D5 CC
    Low Current Pattern: 111010xx
    CDL>pat lift
    Lift Motor Pattern: F0 E9 CD EB F3 EA CE E8
    Low Current Pattern: 000101xx
  • As does loc

    Mailbox:   538.890mm
    Drivebases:  1=-19.110mm 2=33.890mm 3=86.890mm 4=139.890mm
    Driveoffset: 1=28.000mm 2=28.000mm 3=28.000mm 4=28.000mm
    Magazines: 2=29.890mm 3=82.890mm 4=135.890mm 5=188.890mm 6=241.890mm
               7=294.890mm 8=347.890mm 9=400.890mm 10=453.890mm
               Slotoffset: 2.470mm
  • task seems to show information relevant to developers about the embedded (RT)OS:

        Position:    Task Name(#):
        0        idle(#2)
        1        root(#1)
        Position:    Task Name(#):
        0        robo(#9)
        1        conf(#11)
        2        mail(#5)
        3        led (#4)
    date = 01/01/0000, time = 00:10:56, tick = 29
  • As does queue:

    Message Queue#0 'scro': 0 pending messages / 1 pending tasks
        Position:    Task Name(#):
        0        robo(#9)
    Message Queue#1 'rosc': 0 pending messages / 0 pending tasks
    Message Queue#2 'mail': 0 pending messages / 1 pending tasks
        Position:    Task Name(#):
        0        mail(#5)
    Message Queue#3 'mbsc': 0 pending messages / 0 pending tasks
    Message Queue#4 'mbro': 0 pending messages / 0 pending tasks
    Message Queue#5 'led ': 0 pending messages / 1 pending tasks
        Position:    Task Name(#):
        0        led (#4)
    Message Queue#6 'debg': 0 pending messages / 0 pending tasks
    Message Queue#7 'sccm': 0 pending messages / 1 pending tasks
        Position:    Task Name(#):
        0        scmd(#7)
    Message Queue#8 'cdbs': 0 pending messages / 1 pending tasks
        Position:    Task Name(#):
        0        dbas(#10)
    Message Queue#9 'dbsr': 0 pending messages / 0 pending tasks
    Message Queue#10 'dbss': 0 pending messages / 0 pending tasks
    Message Queue#11 'dbmb': 0 pending messages / 0 pending tasks
    Message Queue#12 'nvrr': 0 pending messages / 0 pending tasks
    Message Queue#13 'nvrd': 0 pending messages / 0 pending tasks
    Message Queue#14 'nvdb': 0 pending messages / 0 pending tasks
    Message Queue#15 'nvrs': 0 pending messages / 0 pending tasks
    Message Queue#16 'cnvr': 0 pending messages / 1 pending tasks
        Position:    Task Name(#):
        0        conf(#11)
  • mb o (“mailbox open”) and mb c (“mailbox close”) do what you’d expect. The robot will reinventory the mailbox after mb c. mb s or just mb by itself will reveal the mailbox status.

  • init triggers some part of the startup sequence. Like b it cannot read barcodes, despite them being read correctly at startup?

  • inv takes inventory. all causes the machine to take inventory of everything and print the status information. m5 inventories magazine 5.

  • tray shows the number of steps and degrees of the tray control arm. If given a floating point number, it will move the tray arm to that position. Since the pick arm is linked to the tray control arm, “t 4.886” (that is, RP= from above) and t 299.829 (that is, PP= from above) will put down and pick up a CD, respectively. I suggest not steering the robot this way, though it is excellent when it comes to aligning a new CD drive.

  • led takes two parameters, a LED indicator ({a,r,y,all}) and a state ({on,of,bl}) (or {on,off,blink}, even). a means both LEDs, r means the red LED, and y means the “busy” LED in the middle. None of the other single letters or digits seem to do anything; it is unclear to me what the third LED is wired to, if anything. The manual describes the third LED as meaning “power”, however it is off on my device.

  • move takes two lift positions.

    WARNING: Opening the wrong drive will cause the system to drop the CD or crash into the tray, neither of which are what you want, I’m sure. Don’t mess up. If you think you might mess up, do it with the chassis open and be ready to pull power immediately.

  • b m5 is supposed to read a magazine barcode, but mostly I have seen it return ERROR. Despite that, barcodes are read correctly at initialization time. (Sometimes it works and I cannot figure out why)

  • Pick, Release and PickRel confuse me – they take a lift position but don’t appear to do anything with it, acting instead in situ and corrupting the status database.

  • Drive takes one parameter, being a number between 1 and 4... but I don’t know what it does. I do not understand how it could do what it claims to do.

    Using “D”, I think, I’ve managed to make “status” say “D1=e”, but I don’t know how.

  • Lift can be used to manually set the picker’s elevation:

    • l 0 will move the picker as low as it can go (but curiously will not change the Home sensor output) and other numeric arguments work as you might expect.
    • l d3, l m5s3, l mb all work as expected.

Occasionally, the unit will complain about a ERROR #82: Clear Path error. and refuse to move the robotics. I assume this means that it thinks something has gotten in the way. A reset, with a full inventory, should suffice to clear the error; I wish there were a less obtrusive way.

Hexadecimal Lift Positions

Most of the time, the robot refers to things in a kind of logically named scheme: drives are dN, magazines are mN, slots within magazines are mNsN and the mailbox is mb.

The robot does, however, have some curious ideas about names for things in different contexts; the Drivehome status field, the Picker Home status field, and the Lift command refer to “lift element positions” (which are denoted in hex) and appear to behave as follows:

  • mb is element 100
  • d1 through d4 are 200 through 203 in order
  • m2s1 starts us off at 1000 and we count up from there; m5s1 is 1036, m5s5 is 103a, m5s18 is 1047, m6s1 is 1048, m6s18 is 1059, m7s1 is 105a, etc.
  • Everything else (intermediate positions or no home) are indicated by ffff (-1).

In tabular form:

Human mnemonic Numeric (hex) What
d1d4 200 - 203 Drives
m2, m3, ... n/a Magazines
m2s1, m6s7, ... 1000 and up Slots within magazines
mb 100 Mailbox

Tray Positions

For use with “t” commands; integer approximations are accepted at the command line.

Angle State partray
4.886 Tray fully closed RP
120.086 Tray extended, picker on initial descent  
139.886 Tray extended, picker almost fully inserted PI
149.914 Tray extended, picker near center range  
180.000 Tray extended, picker retracting with CD near RI
190.029 Tray extended, picker almost fully retracted  
327.857 Tray fully retracted, picker has CD PS

Drive Status Codes

The “status” command will give single letters for drive status: “D1=?” where ”?” is apparently one of...

b blocked?
e error?
o empty
u unknown?
x full

The o and x have similar meanings for magazine information. Magazines can also display b if you permit the machine to inventory and forget to close the door lever. (Grinds a lot of gears, try to avoid it.)