It looks like this code could be valuable to quite a few users, so here you go. I originally developed this system about 15 years ago using basic stamps, but over the years it has had modifications as the hardware has changed and moved on to PICS. I work at a National Laboratory and wanted to save the Govt some money, so instead of buying commercial stepper systems I developed my own. The system began as a single stepper that needed to be moved remotely via RS-232. It eventually grew to a requirement to drive about 10 separate (UNIPOLAR) motors on a laser table to operate attenuators and X-Y linear stages. The theory behind the system is each stepper has its own PIC. All PICS are sitting on a single RS-232 bus in parallel. Each PIC "listens" for its name to be called and reponds only when called. This avoids any chance of a communication collision. The code will work for any number of PICS placed on the single RS-232 bus until you have loaded down the impedance of the bus so far that you cannot sustain communications. I have never needed more than 10 steppers on a single bus, but if you work out the math you could calculate the maximum. This code doesn't use the USART pin, so I have a 20K resistor on each PIC for the SerIn pin.
Hardware: Each stepper motor is on an apparatus that has a limit switch for the "home" position. If a power failure occurs or if requested to reset via the RS-232, it will drive the stage home and reset its counter to zero position.
I have found that the system is so reliable that I do not need to have additional encoders to sense the position. If you ensure that your motor is not overloaded and drive it with the proper current, it will never slip poles and the software count of current position will be quite accurate.
Software: The code follows. This same software is loaded into each PIC on the system, but the name and travel limit settings are changed for each . I have another version of the code that allows one to input a new name and travel limit via the RS-232 into NVRAM, but I felt it was overly complicated for sharing.
Command protocol: A terminal program (terraterm or equivalent) would send the name of the stepper followed by a space and then the new postion command or a special control code.
Example 1. Send the stepper to reset position:
ATTENB 65535<CR>
Example 2. Move the stepper to position 415:
ATTENB 415<CR>
Example 3. Ask the stepper its current position:
ATTENB 65534<CR>
The PIC would then respond with "AttenB @ 415"
Heres the PIC code:
Hope you find it useful. You should realize of course that this serial network is not limited to stepper motors. I also have the ability to remotely send values to DAC's, position Servos, Control and readback digital I/O and remotely read ADC's and via the same network using very similar code that has been modified for the application. I call the system PSUB. (polarized source universal bus)Code:'**************************************************************** '* Name : StepNetwork.pbp Target=PIC16F84 OR F628 * '* Author : John C. Hansknecht * '* Notice : Copyright (c) 2004 * '* : All Rights Reserved * '* Date : 10/14/04 * '* Version : 1.0 * '* Notes : ' Universal code for all stepper controllers in a serial network. ' Only the name and travel limit ' are changed for the specific device. '**************************************************************** '_______ Declarations _____________________________________________________ PAUSE 500 include "modedefs.bas" '@ device INTRC_OSC_NOCLKOUT 'default to internal oscillator '@ device WDT_ON 'watchdog timer on '@ device PWRT_ON 'power on timer on '@ device MCLR_OFF ' master clear option off '@ device BOD_OFF ' brown out detect '@ device LVP_OFF ' low voltage programming off '@ device PROTECT_OFF ' program code protect off Steps var word I var word newval var word oldval var word resetbit var byte b0 var byte pins var portb endstop var portb.4 define osc 4 '_______ Initializations __________________________________________________ TRISB = %10110000 pins = 0 ' Initialize output all output transistor OFF. oldval = 0 input portb.5 'make serout a high impedence so all others can talk '________Main program______________________________________________________ pause 500 reset: resetbit = 0 if endstop = 0 then del1 'take motor CCW to limit switch on pwrup. oldval = 0 Cmd:resetbit = 1 serin 7,N2400,["ATTENB"],#newval ' Get orders from terminal. if newval = 65534 then report 'just report current position if newval = 65535 then reset 'send motor to limit switch if newval > 600 then Cmd ' My own software motion limit if newval < oldval then delstep if newval = oldval then Cmd ' else we will drop into addstep (inferred goto) addstep: steps = newval - oldval for I = 1 to Steps ' Number of steps. for b0 = 0 to 7 'full step mode used here. LOOKUP b0,[9,1,3,2,6,4,12,8],PINS 'forward drive sequence pause 1 next b0 NEXT I oldval = newval 'make oldval reflect the current position. goto Cmd delstep: steps = oldval - newval FOR I = 1 TO steps del1: for b0 = 0 to 7 'enters sub here if resetting motor LOOKUP b0,[12,4,6,2,3,1,9,8],PINS pause 1 next b0 if resetbit = 0 then reset 'exit this sub if resetting motor NEXT I oldval = newval goto Cmd report: serout 5, N2400, ["ATTENB @ ",#oldval,13] input portb.5 'make serout pin an input so others can talk goto Cmd '___ End of program ________________________________________________________
John




Bookmarks