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.
||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|
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
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)
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
(ie 0,IDLE or 123,BUSY
||Move motor n REL distance see note (1,2,3)|
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 0s to 1s 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
The basis for the windows ASCOM driver was orginallay written by Doug GeorgeNotes:
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!)