Open Source Dual Focus Motor Controller April 2003 README FILE
/// ====================================================================
// Copyright  © 2003 Mike Gore, Waterloo, ON N2L 5N4, Canada
// Permission is hereby granted to use this Software for any purpose
// including combining with commercial products, creating derivative
// works, and redistribution of source or binary code, without
// limitation or consideration. Any redistributed copies of this
// Software must include the above Copyright Notice.
// ====================================================================
// History
// Written:  2 April 2003       Mike Gore <>
// April 2 - April 8th extesive edits
// April 8 Alpha release
// April 11 Almost Beta Release

What is this?
Source code and diagrams for a dual focus motor controller. This design is for a modified Meade 1206
focus motor with 4096 encoder on focus knob and a stock JMI NGS-F with 2160 encoder
Also included is a beta ASCOM driver for interfacing with the controller

What do I need to make it work?
I used a PICF16F876 CPU – see diagram for more details. The compiled code is in a file called
FOCUS.HEX. You will need a Microchip PIC Start PLUS, Microchip ICD or some other method to
program the HEX file into the CPU. - Note: the .HEX and .COD file is included

Why give it away?
I use several tools that are open source and have gained a great deal from this process I hope others can continue to work on and improve this code – if so we all will have something to gain from it.

What is needed to recompile this project?
I used the HI-TECH C compiler and have made extensive use of memory banking using defines for better portability (I needed most of the PIC16F876 internal RAM for this project.) The project make extensive use of 8,16 and 32 bits signed and unsigned numbers. Except for the printf () library used by HI-TECH C I have written all of my own support function for this project. There are several other C compilers worth looking at both commercial and non-commercial (CCS, BYTECRAFT an the PIC port of SDCC) the batch file focus.bat will compile the project. I have also included a project file forMPLAB – you will have to edit the project to change directory names if you intend to use it (I would suggest a text editor and use search and replace)

Porting to another CPU?
Porting this code to a different CPU should not be all that hard – I moved from a PIC project of similar complexity to an 8031 based CPU in about 2 days using similar libraries.

What are all the switch statements for?
The PIC does not have a real stack – so these switch statements are actually state machines designed to break up all of the tasks that have to run in parallel. The processes motor0_Task (), motor1_Task (), quad0_Task (), quad1_Task (), etc run every 100uS but only a tiny bit of each one runs at any given time. Since most of the switch statements have ascending case statements with no gaps the compiler translates these into jump tables, which are very fast

Why are you duplicating  code and using constant indexes in motor0_Task () and motor1_Task (), etc?
The compiler converts the constant index into a compile time memory reference – the code is  way faster and way smaller. The speed is very important since we run so many tasks at the 100uS rate.

Why are you using a 100uS task rate?

Good question! The 1 wire bus timing was the main initial reason then the encoder update rate was another since I wanted portB but 6 and & for the ICD (In circuit debugger) – say what? (Only the top 4 bits of portB have interrupt on change and I needed all four bits to use that feature). The encoder task  also permits update on every state change giving a four fond increase in resolution when compared to just counting the A and B transitions…. However that said I am sure this model could be totally changed  and things could still be made to work.

Where is the rest of the documentation?
In the code (More or less 8-) I tried to add enough detail in the code be useful.

Code Operation:

1 = IN, 0 = OUT
32bit time value in 0.001-second steps
32bit +/- distance in encoder tics
32bit absolute position in encoder tics
0 or 1 motor number
User set limits command line arguments - see Ln definition below
A Display Motor voltage (Analog Voltage) scaled * 1000
Motor Backlash Tests (Comple option)
Init motor n parameters to factory setting and reset NVRAM
Display User Limits
Enable interactive mode = 1, Computer mode 0 (interactive mode waits for all commands to finish)
Halt move command and update NVRAM - waits for breaking to finish before returning
Move motor n to position POS – see notes (1,2,3)
Display interrupt timer overhead in CPU tics

Set Limits and Parameters for motor n
1)Limit in encoder tics (0 is always a lower limit)
2)Breaking time in 1mS increments for use after a move
3)Watchdog timeout in 1mS increments when the encoder sees no motion
4)Slow zone, the distance in encoder tics from a target when the motor switches to slow speed
5)Slop in encoder tics of backlash compensation when moving in the Outward direction
(Outward direction is with gravity, Inward is against)
6)HEX Slow speed control bit mask – 8bit PWM mask – see note (4)
7)HEX Fast speed control bit mask – 8bit PWM mask – see note (4)
8)Clutch flag, 0 = no clutch, 1 = has clutch - see note (1,5)

Example: l0,1800,200,1000,50,0,11,ff,0

Limit = 1800
Breaking time = 200mS
Watchdog = 1000mS
Slow zone = 50 encoder tics
Slop/Backlash = 0
Slow Speed = 0x11 (about 1/4th power)
Fast Speed = 0xff (full power)
Clutch = 0 (no clutch)
Move motor n for time TIME in direction DIR– see note (1,2)
Motor n position and movement status
(ie 0,IDLE or 123,BUSY
Move motor n REL distance – see note (1,2,3)
Display Status of Motor n (IDLE or BUSY)
Display Temperature *10 in degrees C
Display Firmware Version(Compile Date)
Zero motor n position values - see note(2)

Note (1) Be careful when moving motors that have no slip clutch
If the system sees no movement in a user given time then system trigger a watchdog
timer and return the error !WATCHDOG
Note (2) When a motion command finishes the NVRAM will be updated
Note (3) The move command will always finish a move in the Inward direction against gravity.
Mechanical slop setting is used to determine backlash compensation
Note (4) The PWM mask is an 8bit value that gets rotated once every 100uS. The least significant bit is used to determine if power is applied to the motor. So for example 0x03 or 0x11 represent the same value and is typical of a slow speed setting. 0xff is the fastest speed. Note: 0x11 has advantages over 0x03 in that the transitions from 0’s to 1’s is more evenly spread out and has higher frequency components
Note (5) Currently this is ignored - still thinking about how best to use it
Using the code

Copyright Notes:
 The basis for the windows ASCOM driver was orginallay written by Doug George
 I have adopted the same copyright from for my code - Please read the copyright in the source files.
(Both commercial and private use are permitted!)

  • The visual studio V6 source code for the windows driver is in the directory focus\windows
  • The baudrate  is set to 38400 buad, 8bits, no parity, no flow control
  • The code has had all basic tests done
  • The code does not have the ASCOM prefixes yet since it is still in beta testing mode
  • To setup the driver change into the directory focus\windows\DualFocusDriver\Release
  • Run the command regsvr32 dualfocusdriverdll (And if you change file locations afterward!)
  • Run testit.vbs to open the chooser - adjust any settings
  • Run regedit and open HKEY_LOCAL_MACHINE\SOFTWARE\ASCOM\FOCUS Drivers\DualFocus.Focuser and edit the (Default) key to add a driver Title.
  • Run test.vbs and you will see your new title in the dropdown list
  • You can also test the code with a serial terminal program (such as hyperterm) and run the basic tests using the commands listed in the table above - start out with "e1" command to enable interactive mode.
  • Once you are ready, run the program testit.vbs located in the focus\windows\DualFocusDriver directory. (testit - from the command prompt)