Cookbook Camera Slow Motion Control

with a Serial Interface, Part 1

by Veikko A. Kanto


Introduction

The Cookbook CCD camera and its associated AP211/245 and 211/245Plus software use the computer resources to simplify the software while reducing the necessary hardware. Image acquisition relies extensively on software operations to control the functions of the camera head. To reduce the software complexity in monitoring slow motion controls, the built-in self-timing properties of the serial port are used. This document explains the functions of the hardware used in slow motion serial control. Code snippets are presented for those that would like to use the serial interface for other remote control projects.


Serial Port Basics

Serial ports transmit data using a minimum of three wires. One wire is common (ground) and the other wires are the out-going data and in-coming data line. On the computer, the wires connect to the serial port. Data from the computer is received or sent by a chip call a UART (Universal Asynchronous Receiver Transmitter).

[Serial Diagram 1]

The data is sent by changing the logic level (0 or 1) on the data line in a sequentially timed pattern. Decoding of this changing stream of information is performed by sampling the data line at fixed intervals. The data changes must occur at the same separating interval that the sampling is performed. One additional item is needed before extracting data bits from the stream is possible: the start of the data stream must be identified.

Data on serial ports is generally sent as groups of seven bits (128 possible combinations) or eight bits (256 combinations) of data bytes. The seven bit groups are usually for text-only data and the eight bit groups are usually for binary or program data. For our application as a remote control interface, eight bits gives us more controls. After the serial port receiver circuit samples and converts the bit stream into the data byte, the byte is transferred and held (latched) in an output register. In your computer, this information is read from the serial port through the computer bus. In the serial control interface for the slow motion controls, the data appears on the output pins. This data remains on the output pins until the next serial data byte is decoded. In your computer, if the data byte is not read from the serial port before the next byte is received, the old data is lost (some serial devices do have buffers that save more than one character of data).

Let's get back to how data is sent and received. The serial data output line normally rests at a logic-1 state. When the data goes to the zero or logic-0 state, this signifies the start of the serial byte stream. The start bit remains at the zero state for a period of 1/baud seconds. Baud is the bit rate, usually specified as 300, 1200, 9600, etc. At 300 baud, the bit period is 1/300 or 0.003333... seconds. The bit period is not only important to the transfer of the serial data but it is a key parameter that is used in the slow motion control (more on this subject later). The data bits follow the start bit. Let's specify the eight bits in our data byte as b7 (bit-7) through b0 (bit-0). Seven through zero is used because the binary weight of the n bit position is 2^n. The data is sent following the start bit from b0 to b7. After the last data bit is sent, the end of the data stream must be identified. The data line is set to a logic-1 for one bit period (other stop bit lengths are possible).

In order for the serial interface to sample the received data at the correct time, it must sample at the same baud rate as the data is transmitted. Once the start bit is detected, the serial interface must wait one and a half bit periods to sample the first data bit, then sample at intervals of one bit periods. The serial interface is clocked at a rate of 16X the baud rate. The faster clock rate is needed to synchronize the sampling to the data (a rate of 16X gives an uncertainty of 1/16 of the sampling position after the start bit is detected and this is quite tolerable). The sampling process is shown in the following:

[Serial Diagram 2]

The time required to send one data byte is one start plus eight data bits plus one stop bit. This is 10/baud seconds or at 300 baud, 33.33 milliseconds. If we send a data byte to set bit-2 to a logic-1 on the serial interface, it will remain high until other data arrives. If we send N successive bytes of data with bit-2 set high, and then send one data byte with bit-2 set low, the bit-2 output on the serial interface will go high for N times 33.33 milliseconds and then go back to the low logic level.

The computer takes data from a program and places it in a buffer. Data is automatically sent after the serial interface in the computer completes transmission of one byte. This attribute of the serial port simplifies programming of timed control intervals because all that is required is sending a string of data bytes with a print statement. The control program is free to perform any other task while the data is sent in the background.

There is one last concept of serial port interfaces we need before going on to build a control interface. Both the computer and the UART use standard logic levels which are generally about zero volts for a logic zero and from 3V to 5V for a logic high. The connection to the outside world (our 3-wire line) is susceptible to electrical noise and other problems associated with transmitting data over long wires. The signals from the computer conform to a standard called RS232. The output from the serial port swings both plus and minus. Logic zeros are represented as plus 9V signals and logic ones are represented as minus 9V signals. Fortunately, most computers detect signals that swing between 0 and 5V as they would the RS232 signals. This factor simplifies the design of an RS232 compatible translator for the UART chip because a simple inverter gate can be used. Sometimes computers only detect signals that go below zero and a special RS232 transmitter chip is required.

We have defined three basic functions that are required to transmit and receive serial data from the computer: 1) a UART, 2) a 16X clock, and 3) RS232 translation. There is a fourth function required for the transmitter section of the UART to operate. The data on the inputs must be latched into the UART. This can occur at any time but the intervals must be greater than the time require to transmit one character. A control input is strobed (changed from a logic-1 to logic-0 then back to a logic-1) to transfer the data into the UART. Data is transferred when the input is changed from the logic-0 to logic-1 state. During this transition, the data on the inputs to the UART must not change or the data sent becomes ambiguous.

[Serial Diagram 3]


Getting The Worm Gear Period From Synchronous Motor Drives

Guiding only operations do not require the UART to send data back to the computer. Additional circuitry is required if you want the computer to learn and correct for the periodic error in a synchronous motor worm drive. Refer to page 167 in the CCD Camera Cookbook for the circuit.

Acquisition programs AP211/245 use the BASIC program ON COM interrupt to detect the presence of a received byte from the UART. A divide-by-144 counter is used to divide the 60 Hertz clock, from the synchronous motor drive oscillator, down to a 2.4 second period which is then used to strobe the UART. When the interrupt is generated by a byte being received, the program is directed to a routine that saves all slow motion commands, given during the 2.4-second period, into an array. After one turn of the worm gear (100 or 200 2.4-second periods), the commands stored in the array are sent back to the UART each time a character is received.

The position of the worm gear is known due to the operation of the synchronous motor. The synchronous motor is locked to the 60 Hertz clock (which can be lower or higher in frequency for slow motion control). If the number of clock transitions to the motor are known, then the motor rotations and the worm position are known. Meade telescopes with the LX3 type drives use 180 tooth gears. The motor clock runs at a rate of 60.167 cycles to turn the telescope at the sidereal rate. If the motor ran at 60 Hertz, the telescope would turn once every 24 hours and 24 hours times 60 minutes times 60 seconds times 60 Hertz is 5,184,00 clock cycles. There are 180 teeth and the worm turns once every 28,800 cycles. Dividing the clock by 144 allows us to make 200 control points for one turn of the worm gear. Gears with 360 or 359 teeth only need 100 control points because they turn twice as fast. In principle, this technique would work for stepper motor type drives if the number of clock pulses for each rotation of the worm gear was known.


Using 6402 CMOS UARTS

The AY-3-1015D UART is becoming expensive or hard to find. Although the 6402 UART is a direct replacement for the AY-3-1015D part, it is neither functionally identical nor is it electrically identical. The inputs on the AY-3-1015D chip have pull up resistors. If the input is left open, it pulls up to a logic-1 level. The 6402 part has a CMOS input and it floats to some unknown state. To use the 6402 part, pins 18, 34, 35, 37, 38 and 39 must be connected together. These pins then must be connected to a pull up resistor. One end of a 1K ohm resistor is connected to +5V and the other end to these pins.

The second problem with the 6402 UART is that it transmits two data bytes instead of one data byte when the strobe to the transmitter section remains low for a long period. The circuit shown on page 167 of the book does not work for the PEC function. A short duration pulse must be generated for the UART strobe. This circuit shows the changes you should make to the output of the divide-by-144 counters. (Note: the circuit is a large GIF image. You may prefer to download rather than view this file.) The line from pin 9 on the 74LS163 chip to pin 23 on the UART is replaced with a series 0.001uF capacitor and a 4.7K pull up resistor. This RC circuit makes a short low-going pulse that is cleaned up by using the spare gates on the 74LS14 chip.

A control-only circuit which uses the 6402 UART is shown with the required pull up resistors in the following schematic diagram. (Note: the circuit is a large GIF image. You may prefer to download rather than view this file.) This works on Meade telescopes with the CCD input jack (I don't own a telescope with this configuration, but the circuit has been tested on a friend's LX200 telescope).


Controlling the UART from BASIC

Sending and receiving data through the serial port is not unlike printing data to the screen or getting data from the keyboard. The serial port is also like a writing data to a disk file. First the port must be opened, then data can be transferred. When the port is opened it is also configured for the number of data bits, the baud rate and other parameters. You must select an open serial port such as COM1 or COM2. Don't use a serial port that the mouse is connected to unless you first disable the mouse driver. Open the serial port with the following statement.

OPEN "COM1: 300,N,8,1,BIN,RS,OP0,DS0"FOR RANDOM AS #1

Sending data out the serial port only requires the conversion of the data to ASCII then printing the data through the open serial device with a PRINT # statement. Because the print statement sends a carriage return, this must be suppressed with a semicolon at the end of the print statement (or the data to the serial port will change). Sending data is given in the following code sample:

'Set bits 0 and 3 to a logic high level, other bits are zero.
d%=1+8: REM 2^0 and 2^3
PRINT #1, CHR$(d%);

Receiving data requires polling the serial device for data. The polling can take place anywhere in the program. Because the data rate is so slow in our applications (once every 2.4 seconds), I prefer to use the ON COM(n) statement to generate an interrupt. The program can not jump out of an INPUT prompt and service data which is available (but neither can you poll for data). Here is how to check for serial data:

IF NOT EOF(1) THEN
   d$ = INPUT$(1, #1) :REM data is in character form
   d%=ASC(d$): REM data convertered to integer form
END IF

There is nothing better than a running program to help in understanding how it all fits together. Here is some code to send and receive data from the UART interface. You can modify it for you own use.

'This program sends data through the serial port to a UART interface.
'If the PEC circuit is present, the period for the received byte is timed
'and the frequency of the clock drive can be set to within 0.1Hz.
'(c) 1996 V.A. Kanto

'Prompt and get which serial port to use COM1 or COM2
getcom:
CLS
PRINT "Enter 1 for COM1 or 2 for COM2"
a$ = ""
WHILE a$ = ""
   a$ = INKEY$
WEND

SELECT CASE a$
   CASE "2"
     COM$ = "COM2: 300,N,8,1,BIN,RS,OP0,DS0"
     n% = 2
   CASE "1"
     COM$ = "COM1: 300,N,8,1,BIN,RS,OP0,DS0"
     n% = 1
   CASE ELSE
     GOTO getcom
END SELECT
tref = TIMER

'Activate the serial port for receive and transmit
OPEN COM$ FOR RANDOM AS #1
ON COM(n%) GOSUB getdata
fave = 60
COM(n%) ON

CLS

'Clear serial port
sdata% = 0
PRINT #1, CHR$(sdata%);

'Print Menu
CLS
PRINT "1: Toggle bit-0"
PRINT "2: Toggle bit-1"
PRINT "4: Toggle bit-2"
PRINT "8: Toggle bit-3"
PRINT "0: Pulse bit-4 high for one second"
PRINT "Q: Quit Program"

'Poll for key input. If an INPUT statement is used, the ON COM will not
'respond until the Enter Key is pressed.

DO
   LOCATE 8, 1
   PRINT USING "Data Sent = # # # #"; 8 AND sdata%; 4 AND sdata%; 2 AND sdata%; 1 AND sdata%
   a$ = ""
   WHILE a$ = ""
     a$ = INKEY$
   WEND
   SELECT CASE a$
     CASE "1": sdata% = sdata% XOR 1
     CASE "2": sdata% = sdata% XOR 2
     CASE "4": sdata% = sdata% XOR 4
     CASE "8": sdata% = sdata% XOR 8
     CASE "0"
       n$ = CHR$(sdata% + 16)
       'note: use semicolon to prevent a return character from being sent.
       '30 characters times 1/30 seconds per character = 1 second of on time.
       PRINT #1, STRING$(30, n$);
     CASE "Q", "q": END
   END SELECT
'Here is where the byte is sent. This also turns off bit-4 (16)
   PRINT #1, CHR$(sdata%);
LOOP

'Handle ON COM interupt. Test for a character and get the period between
'the receipt of characters.
getdata:
   IF NOT EOF(1) THEN
     t = TIMER
     dt = t - tref
     tref = t
     f = 144 / dt
     fave = fave * .9 + .1 * f
     d$ = INPUT$(1, #1)
     LOCATE 10, 1
     PRINT USING "Data=### f=###.## fave=###.##"; ASC(d$); f; fave
   END IF
RETURN


Continue on to Part 2

Return to the Cookbook Home Page

Return to the Text DataBase Page


Send email to Veikko Kanto at: n7vk@worldnet.att.net)