$Id: README,v 1.9 2003/10/05 05:17:42 dwalters Exp $
-- Open Automaton Project: http://oap.sourceforge.net -- 

HEAD CONTROL MODULE INTRODUCTION
--------------------------------

This README covers the source code and circuit schematics for the Open 
Automaton Project Head Control Module.

The Head Control Module is a hardware device that controls the Pan and Tilt
servomotors of the head, as well as taking passive infrared sensor readings
from the head-mounted Eltec infrared sensor. This device passes control and 
sensor readings data to and from the robot's mainboard via the I2C interface,
using the SMBus protocol.

The circuit schematic (head_control_module.sch) was developed in gschem, part
of the gEDA package, version 20030525.

Circuit schematic symbols that are not in the symbol library bundled with gEDA
are included as separate sym files (these .sym files can be copied into your
local symbol directory, typically /usr/local/share/gEDA/sym/local/).


LICENSING
---------

All source code and electronic circuit designs are copyright (C) 2003, Dafydd 
Walters.

The Open Automaton Project software is distributed under the terms of the GNU
General Public License. See the file COPYING.SOFTWARE for details.

Please see the file COPYING.ELECTRONICS to see the terms under which the
electronic circuit designs of the Open Automaton Project are distributed.


CIRCUIT NOTES
-------------

The Eltec passive infrared human body heat sensor detects movement of heat
sources along a particular axis (along the same direction as the tab on the
perimiter of the detector's metal body).  It is important to mount this sensor
so that it is oriented to detect movement along the same axis as the Pan
servo. 

A polyethylene freznel lens should be mounted at the appropriate distance
from the detector to ensure that infrared energy is focused on to the detector
correctly (the sensor kit from Acroname includes the lens and a cut-out
pattern which can be used to construct a suitable concentrating cone that 
holds the lens and the detector at the correct distance apart).

This circuit provides power to the servos from a 7805 voltage regulator. The
7805 (with a heatsink attached) can deliver up to 1A. The current consumed
by the other components is negligible, so servos that draw an absolute 
maximum current of 490mA each should chosen for Pan and Tilt.

Due to surges and spikes associated with motors, it's important to place
tantalum bead supply decoupling capacitors very close to each of the Pan and
Tilt RC servo connectors. If you can completely separate the power supplies of 
the servos from the rest of the circuit, so much the better.

Most servos specify a PWM period of 20ms, with an "on-time" pulse width range 
of 1ms to 2ms. However, this range does not allow servos to reach their
potential maximum positions, so the Head Control Module outputs a PWM pulse
which can be driven anywhere in the range 0.5ms to 2.5ms. This extended range
alows the servos to be driven to their end stops.  HOWEVER, you should
establish what the drive limits of your particular servos are, because you 
should never drive servos quite as far as their end stop postions. You can 
establish by trial and error what drive setpoint values correspond to these 
positions just short of the end stops, by using the oap-head utility.


SMBUS INTERFACE
---------------

This module is a slave on the I2C SMBus, with the fixed address 88
(the address can be changed by modifying the source code and re-compiling).
The device responds to the following host (master) commands:

Read Byte Data, Command = 1: Report Pan servo setpoint (one data byte). The
                             actual driven position of the servo will
                             eventually "catch up" with this value, depending
                             on the value of the "Maximum Change Per Period"
                             setting.

Read Word Data, Command = 2: Report Pan servo actual driven position (two data
                             bytes). The first data byte is the actual driven
                             position of the servo, and the second is the 
                             current 8-bit timer count (20ms per tick).

Read Byte Data, Command = 3: Report Tilt servo setpoint (one data byte). The
                             actual driven position of the servo will
                             eventually "catch up" with this value, depending
                             on the value of the "Maximum Change Per Period"
                             setting.

Read Word Data, Command = 4: Report Tilt servo actual driven position (two data
                             bytes). The first data byte is the actual driven
                             position of the servo, and the second is the 
                             current 8-bit timer count (20ms per tick).

Read Byte Data, Command = 5: Report "Maximum Change Per Period" setting (one 
                             data byte).  This is the maximum change per update
                             period (which is 20ms) of the servo's driven
                             position. The smaller this value is, the slower
                             (and smoother) the servos will appear to respond
                             to changes in setpoint. See the command 102 for 
                             more information on this setting.

Read Byte Data, Command = 6: Report raw analog IR sensor reading (one data
                             byte). This is useful only for testing (and
                             establishing a suitable value for the "IR Sensor
                             Neutral Value" setting). Triggered IR detections 
                             (see commands 9,10,12,13) should be used when 
                             actually sensing heat sources.

Read Byte Data, Command = 7: Report the value of the "IR Sensor Neutral Value"
                             setting (one data byte). This is the ADC count 
                             that the IR sensor is expected to hover around
                             when there's no moving heat source present.

Read Byte Data, Command = 8: Report the value of the "IR Sensor Trigger
                             Threshold" setting (one data byte). This is the
                             number of ADC counts above or below the "IR
                             Sensor Neutral Value" setting that triggers a
                             detection event.

Read Byte Data, Command = 9: Report the value of the Pan servo actual driven
                             position for the stored IR detection event (one
                             data byte). Host should use command 10 first to
                             check if a detection event occurred, and to
                             "lock" it (i.e. prevent it from being
                             overwitten by another event).

Read Byte Data, Command =10: Report the IR triggered event status (one data
                             byte). The data byte returned is zero if no
                             event has been triggered, and one if an event
                             has been triggered. When 1 is returned, this 
                             command has the side effect of "locking" the 
                             event data so that it cannot be overwritten by 
                             another event when the triggered event mode is
                             "Last Event" or "Maximum Event" (the lock has no
                             effect if the triggered event mode is "First
                             Event"). The purpose of the lock is to allow all
                             the characteristics of the event to be read by
                             the host (using commands 9,12,13) without fear of
                             another event being triggered in between the
                             calls to the various commands to read the event
                             characteristics. Command 105 releases the lock and
                             discards the stored event (command 10 would 
                             return zero immediately after command 105 is 
                             issued).

Read Byte Data, Command =11: Report the "IR Triggered Event Mode" setting (one
                             data byte). 1 = First Event (stop storing events
                             after the first one is triggered), 2 = Last Event
                             (overwrite the stored event each time one is
                             detected, so that the most recent event is always
                             the one that's stored), and 3 = Maximum Event
                             (only overwrite the stored event if an event is
                             detected with a bigger detection spike than the
                             stored event). 0 = IR sensing completely disabled.

Read Byte Data, Command =12: Report the IR triggered event ADC bitcount (one
                             data bye).  Host should use command 10 first to
                             check if a detection event occurred, and to
                             "lock" it (i.e. prevent it from being
                             overwitten by another event).

Read Byte Data, Command =13: Report the 8-bit timer value at the time the
                             stored IR event was triggered (one data byte).
                             Host should use command 10 first to
                             check if a detection event occurred, and to
                             "lock" it (i.e. prevent it from being
                             overwitten by another event).

Read Byte Data, Command =14: Report the current 8-bit timer value (one data
                             byte). This is a free running counter that 
                             increments by one every 20ms (the servo drive 
                             period), so it wraps around every 5.12 seconds.

Read Byte Date, Command =15: Report the status of the PWM outputs.
                             0 = outputs disabled (servos limp). This is the
                             initial default, low power mode. In this mode,
                             the free running timer counter and the infrared
                             sensing is also disabled.
                             1 = PWM output active (timer counter and infrared
                             sensing also enabled).

Write Byte Data, Command = 100 : Set the Pan servo position setpoint (one data
                                 byte).

Write Byte Data, Command = 101 : Set the Tilt servo position setpoint (one data
                                 byte).

Write Byte Data, Command = 102 : Set the "Maximum Change Per Period" setting
                                 (one data byte). This is the maximum change 
                                 per update period (which is 20ms) of a
                                 servo's driven position. The smaller this 
                                 value is, the slower (and smoother) the 
                                 servos will appear to respond to changes in 
                                 setpoint. For example, a value of 1
                             means that a servo's actual driven position can
                             only change by a maximum of 1 count per period.
                             Since the maximum range of driven position is 
                             expressed as a 1 byte value (0 to 255), the time
                             it would take to pan from one stop to the other
                             is [20ms x 256], which is just over 5 seconds. A
                             setting value of 2 would halve that time. If you
                             want to get meaningful Pan position data from the
                             IR sensor triggered detections, this setting
                             should be low enough to ensure that the loaded
                             servos can keep up with driven positions. 
                             Another advantage of driving the servos in this
                             way is that the smoother motion will put less
                             stress on the servos' gears and bearings,
                             prolonging their life. If you're not interested in
                             the IR sensor data and you just want the servos to
                             move to a new setpoint position as fast as 
                             possible, use 255 as the value for this setting.
                             This configuration setting is stored in 
                             nonvolatile EEPROM.
                     
Write Byte Data, Command = 103 : Set the "IR Sensor Neutral Value" setting
                                 (one data byte). This configuration setting
                                 is stored in nonvolatile EEPROM.

Write Byte Data, Command = 104 : Set the "IR Sensor Trigger Threshold" setting
                                 (one data byte). This configuration setting
                                 is stored in nonvolatile EEPROM.

Send Byte, Command = 105       : Reset the IR triggered event (no data bytes).

Write Byte Data, Command = 106 : Set the "IR Triggered Event Mode" setting
                                 (one data byte). 1 = First Event (stop storing
                                 events after the first one is triggered), 
                                 2 = Last Event (overwrite the stored event
                                 each time one is detected, so that the most
                                 recent event is always the one that's stored),
                                 and 3 = Maximum Event (only overwrite the 
                                 stored event if an event is detected with a 
                                 bigger detection spike than the stored event).
                                 0 = IR sensing completely disabled. This
                                 configuration setting is stored in nonvolatile
                                 EEPROM.

Send Byte, Command = 107       : Reset the 8-bit timer counter (no data bytes).

Send Byte, Command = 108       : Activate PWM Output. Also enables the free
                                 running timer counter and infrared sensing.

Send Byte, Command = 109       : Disable PWM Output. In this low power mode, 
                                 the free running timer counter and the 
                                 infrared sensing are also disabled. This is 
                                 the initial default mode of the module.

PEC (Packet Error Checking) is disabled for all SMBus commands.


FIRMWARE NOTES
--------------

The software for the PICMicro is written in assembly language, and compiles 
using the GNU PIC Assembler, gpasm. To compile the source code into a hex file 
suitable for programming a PIC16F819 device, type

    gpasm -n head_control_module.asm

The resulting hex file will be called head_control_module.hex  The -n option 
puts DOS-style CR-LF newline sequences in the .hex file, required by most 
device programmers. 

It also compiles with the MPASM compiler for Microsoft Windows that is a part
of the MPLAB suite from Microchip. However, you must make sure the assembly
(.asm) file is in Windows/DOS format (i.e. with CR-LF sequences at the end of
each line) before it will successfully compile in MPASM for Windows.

Some device programmers require the configuration bits to be set manually. It
is very important that these are set correctly. The Head Control Module
requires the following configuration bit settings:

 - Flash Code Protection off
 - CCP1 on RB3
 - In-circuit Debugger disabled
 - Flash write enable off
 - EE Code Protection off
 - Low Voltage Programming Enable off, RB3 is I/O
 - Brown-out Reset Enable on
 - RA5/MCLR pin function is digital I/O
 - Power-Up Timer on
 - Watchdog Timer off
 - Oscillator: INTRC, port I/O function of RA6 and RA7

The above configuration settings are represented by the configuration word
2F50 in hexadecimal.