PC joystick to (Servo or Stepper) STEP/DIRECTION


Closed Thread
Results 1 to 24 of 24
  1. #1
    Join Date
    Feb 2008
    Location
    Michigan, USA
    Posts
    231

    Default PC joystick to (Servo or Stepper) STEP/DIRECTION

    I have found a need to read an old PC joystick and generate some movement commands.
    The joystick is the older type with a 15 pin DB (DA actually) connector. Mine makes 3) 20k to 80k pots and 4 switch contacts available at the connector

    My purpose is to drive a CNC gantry using servo or stepper motors (STEP and DIRECTION signals, not pulse length on hobby servos). The basics of manipulating the readings would be the same for use with a game or hobby servos and this may be useful to others.

    Thd PIC will output X and Y movements based on the distance from center on the joystick with a small null in the center to prevent creep.

    I have been unable to find anyone working on this with a search, so I will make a go of it and solicit any suggestions.

    Since my joystick has 3 pots (X, Y, and trim) and 4 switches that can be read , the goal is to
    grab the analog and determine if the X and Y are above or below center and set a direction pin to 1 or 0. Then the magnitude of the signal from center (minus the dead zone) will determine the number of pulses generated. The trim pot will modify the number of pulses and act kind of like a speed control or limit to tune the movement of the device. The switches will be used to activate extra functions on the device.

    Reading the A/D should be straight forward, but I mulling how to control 2 pulse streams and adjust them using a third. Current target is a 18F2331 or 18F4431 and I'm going to see if I can get the PWM outputs to do what I want.

    So far this is preliminary, so I'm just fishing to see if there is any interest. If there is, I will post my progress.

    Bo

  2. #2
    Join Date
    Feb 2006
    Location
    Gilroy, CA
    Posts
    1,530


    Did you find this post helpful? Yes | No

    Default

    Hey Bo,

    Not sure if you saw this one. It is to drive an x/y table with two stepper motors. May be of some help if you choose steppers.

    http://www.picbasic.co.uk/forum/content.php?r=223

    Walter
    http://www.scalerobotics.com

  3. #3
    Join Date
    Feb 2008
    Location
    Michigan, USA
    Posts
    231


    Did you find this post helpful? Yes | No

    Default

    Thanks for the hint Walter, After some sleep, I will study it and see what I can learn. I remember seeing that post once, but didn't study it or think to apply his solution to my problem. He's using Step/Direction, so I'm sure there some answers there.

    After a few hours of looking at my original problem, it became apparent that I was going to have to find out how to generate 2 independent pulse trains that had variable frequency in order to move the motors in two axises. I am currently looking at the timers, CCP's, and the HWPWM for a clean way to do that. At first glance, I overlooked that it was considerably different than varying the width of pulses over a constant period (ie.. PWM). I seem to remember where someone did the calculations with a formula on the fly. I'm going to see if I can do that with the PR2 register and get somewhere with 2 timers.

    I will keep this post updated as I learn more.

    Bo

    BTW, better up your sampling rate, you're not even near Nyquist!

  4. #4
    Join Date
    Aug 2010
    Location
    Maryland, USA
    Posts
    869


    Did you find this post helpful? Yes | No

    Default

    Some prelimary questions: How fast do you want max jog to be? how many steps per rev? This info will drive how you toggle the output pins for the steps. My first thought is intrupt based toggle. But it really depends on the speed you want to achieve, and how precise you want that speed.

    If you think about the a/d answer being the modifer for a delay between toggles, I am not sure you have much math to do.

    Lets assume 10 bit A/D, with 24 bits of dead band. so you have 500 possibilties for the speed. So 0 max, and 500 is stop. This is because 0 delay would be full speed.

    Now we just need to know osc speed for the rest of the math

    If you use 2 counters as the delay, your A/D answer can change the count needed to toggle. Then establish a duration for what a count represents and load that into the timer. when the timer rolls over, update both counters. If either or both have reached their count, toggle the pin for that motor.
    Last edited by cncmachineguy; - 28th October 2010 at 15:53.
    -Bert

    The glass is not half full or half empty, Its twice as big as needed for the job!

    http://foamcasualty.com/ - Warbird R/C scratch building with foam!

  5. #5
    Join Date
    Feb 2008
    Location
    Michigan, USA
    Posts
    231


    Did you find this post helpful? Yes | No

    Default

    I'm coming up with about 6000 pulses per second for max travel speed (2.375" travel/rev, 360cpr encoder X 4, 10"/sec Max jog), so that is about 167uS as the quickest pulse repetition.

    That helps me focus on a target. I'm going to see if I can monkey poke tonight and come up with something.

    Thanks for helping me clarify my thoughts.
    Bo

  6. #6
    Join Date
    Aug 2010
    Location
    Maryland, USA
    Posts
    869


    Did you find this post helpful? Yes | No

    Default

    are you using steppers with encoders?
    the step/dir implies using steppers, the 360 cpr x 4 encoder suggests encoders. I ask for 2 reasond, 1 just because its pretty cool if you are closing the loop, but more important is if you are reading the encoder for 2 axis and generating the steps for 2 steppers, timing will become important. how fast is your pic running?

    If you are using steppers, how many steps per rev are they? Is your drive running full step, half step,...

    I'm actually very intrested in this concept. I never thought of a joystick for a jog control
    -Bert

    The glass is not half full or half empty, Its twice as big as needed for the job!

    http://foamcasualty.com/ - Warbird R/C scratch building with foam!

  7. #7
    Join Date
    Feb 2008
    Location
    Michigan, USA
    Posts
    231


    Did you find this post helpful? Yes | No

    Default

    I had been playing with the idea of reading a PS2 mouse but that became cumbersome. When I realized that an old joystick had the pots directly available at the connector, it seemed like it was worth a try.

    Actually there are two answers to your question, I have two tables. One is a small one, roughly 6"x 6" x 6" that uses steppers without feedback. Built it primarily for engraving nameplates and printed circuit boards. Mostly proof of concept. it currently runs 200 step motors at 1/2 step, and I don't need to control that one manually.It uses some kit stepper drives that I built. but I may upgrade to Gecko 201's and have a fractional step choice later.

    The larger one is a 4' x 6' gantry with servos. Both tables are primarily controlled by PC running Mach3, but on the gantry, I wanted a way to do some manual moves for artistic uses. I could use a Manual Pulse Generator through Mach3, but this seemed an interesting way to experiment and have a intuitive way to control 2 axises at once. The beauty of the drive system that I have built is that either one uses Step/Direction control. The servo table uses Gecko 340 drives.

    Timing on the PIC is "whatever works". Since the 18F2331 will run at 40MHz, I should have enough. I was thinking about the 500 range on either side also. Seems to give some deadband without wasting too much control. The third pot (trim on the joystick) will be used as a modifier in the math to control the overall speed so that I can tailor the response to the job at hand.

  8. #8
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,521


    Did you find this post helpful? Yes | No

    Default

    There are joystick and "gamepad" control plugins available for Mach3 in case you end up not wanting to get it done with a PIC.

    /Henrik.

  9. #9
    Join Date
    Aug 2010
    Location
    Maryland, USA
    Posts
    869


    Did you find this post helpful? Yes | No

    Default

    Sometimes I must laugh at myself. I know I read the third pot was to adjust the speed, but I still keep thinking about it as the more you move the joystick, the faster you go.

    OK, re-read the original post and have my brain going the right direction.
    grab the analog and determine if the X and Y are above or below center and set a direction pin to 1 or 0.
    that is what threw me. center point can't determine direction, because if you are right of center and you need to move left, joystick will still be right of center. Direction needs to be determined by pot vaule being higher or lower then the last value.

    So controlling it this way, I would not worry about "trimming the speed" and still use the third pot for Z. The speed will be controlled by how fast you move the joystick. Something to keep in mind here, with 6' of travel, moving 3' will take 3.6 seconds (@ max jog of 10"/sec). So for realtime control, you will have to move the joystick very slowly.

    now for some math:
    to move 72 inches you need to make 72/2.375= 30.315 rev of the motor
    at 1440 pulses per rev thats 30.315*1440=43653.6 pulses.
    now divide 43654/1024=42.63 pulse resolution.

    So for each bit of the A/D value you have to output 42.63 pulses for the 6' travel.
    and for the 4' axis you need to output 28.42 pulses.

    I would approach it like this: pulse output will always be at 6000 pps. I would set up a timer to run so it takes 166uS to roll over. (@ 4Mhz clock, you could use an 8 bit timer preloaded with 90 for 166uS)
    on each timer rollover, reload clock,check position and toggle if necessary.

    Now for the pulse streams:

    To make things much easier on the coding, I would make home be a corner so all my positions are in the positive X,Y direction.

    Multiply the A/D by 42.63 for the 6' and 28.42 for the 4' axis. this is your target position in pulses. Current position is a counter which is keeping number of pulses sent from the time you said everything was zero (homed). If current pos = target pos then no toggle. If current pos<target then toggle with dir=1 If current pos > target pos then toggle with dir = 0.
    (Of course dir may be backwards, all depends on your setup). If you decide to use the third pot as Z, just fill in the travel (in inches) above for the Z multiplier.

    For your drift control and to accomdate for hand jitter, maybe have a control check to say, no movement unless A/D value changed by more then 2 points. of course that will decrease resolution, but right now thats all I can think of.

    Of course you could just get the plugin Henrik is talking about, But to me there is value in having a way to move the machine with out the control. Of course, Mach will not know the machine is moving so you won't be able to use this as a jog device per say. I assume you will unplug the puter input to the drives and plug in your "jog Stick"
    -Bert

    The glass is not half full or half empty, Its twice as big as needed for the job!

    http://foamcasualty.com/ - Warbird R/C scratch building with foam!

  10. #10
    Join Date
    Aug 2010
    Location
    Maryland, USA
    Posts
    869


    Did you find this post helpful? Yes | No

    Default

    1 more thing to think about. Homing. when the pic is reset or on startup, you need to home the drives of course. I would do this by jumping to my "home routine" first and wait for a button press from 1 of the 4 on the jog stick. Now if you have home switches installed, you can just run a loop to send pulses at a fixed rate and check for the switch after each pulse. then when all axis are on switches set current pos to zero and goto main.

    if you don't have switches, maybe do something like hold 1 switch for confirmation and hold 1 of the remaining switches for each axis to travel in the direction of home. when you are where you want to be, release both then press 1 again to confirm that axis. do this for each axis.

    You main loop will just have to get A/D values(all 3) and check for timer overflow. and if you have limit switches, watch for them here also.
    -Bert

    The glass is not half full or half empty, Its twice as big as needed for the job!

    http://foamcasualty.com/ - Warbird R/C scratch building with foam!

  11. #11
    Join Date
    Feb 2008
    Location
    Michigan, USA
    Posts
    231


    Did you find this post helpful? Yes | No

    Default

    I will have to study your reply more when I have a bit more time, but for clarification, I need to give a few more details.

    The intent of the analog of the joystick is to variably control the speed in each axis in 0-500 counts of the A/D in the respective direction: ie 0-500 = max speed to 0 in the - direction, 501-527 = no movement even though the DIR bit has changed, 528-1028 will drive 0 to max in the + direction. It will still control speed. The trim, or "Z" will control the gain for both channels. For instance, when the gain is low, the max deflection in any direction will be very small (read: slow). When the trim is full, the full deflection of the stick will drive in the respective direction as quickly at the device is able.

    I only quickly read your post because I need to go, but if I misread it, I apologize and will look at it in a few hours.

    Thanks for your feedback.
    bo

  12. #12
    Join Date
    Feb 2008
    Location
    Michigan, USA
    Posts
    231


    Did you find this post helpful? Yes | No

    Default

    More reading.... I'm thinking we are looking at this a bit differently.

    For normal CNC, I can control the position accurately with Mach3 with limits and such. What the joystick is for is relative movement and is basically freehand. The limits will be in effect for protection, but are not needed for normal positioning. The closed loop with the joystick is the person with his hand on it. On this specific application, the Z axis is actually a separately controlled process. Specifically, when the trigger on the joystick is activated, it starts an operation at the X-Y location that you manually positioned it to. Later additions will inhibit the X-Y movement when this process starts, but for now it just needs to position the head. Think "Helicopter". More stick, more pronounced movement. If you want it to stop, center the stick, pull the trigger, and the magic happens right where you want it. when it is done, move the stick to the new location and do it again. You are only controlling direction and speed.

    OK, I hope that adds some clarification.

  13. #13
    Join Date
    Aug 2010
    Location
    Maryland, USA
    Posts
    869


    Did you find this post helpful? Yes | No

    Default

    Ok, I know I can be a bit dense at times, but I think I finally have it. All you really want to do is jog x,y to a point, fire the trigger(this will invoke cycle start or run), a program will run in mach, when done you will jog to a new position and run again. And I get that the trim will be used to set the full scale speed of for the stick. ie: trim in 1 position, full stick may be 200pps max, while another position will be 400 pps max. full trim will set full stick to 6000 pps max, and all the numbers in between. Do I finally have it?

    I think with a small bit of rearranging, my posts still apply in concept, just not in operation. I did realize the person is closing the loop, but I know on my mills and lathes, it it far too easy to jog right onto a limit, without which it would crash.

    What I did not realize was you are planning to have mach still be able to run also. To me, the software side for the pic is pretty stright forward, but I am not sure how you will interface the 2 (joy stick and mach). How you will be doing this might have bearing on your program.

    After you have time to read over all the babbling I did, feel free to keep asking questions. I enjoy helping on things like this as I love puzzles.
    -Bert

    The glass is not half full or half empty, Its twice as big as needed for the job!

    http://foamcasualty.com/ - Warbird R/C scratch building with foam!

  14. #14
    Join Date
    Feb 2008
    Location
    Michigan, USA
    Posts
    231


    Did you find this post helpful? Yes | No

    Default Seems no one can hear all the voices in my head....

    Sorry about that, all of this made prefect sense in my head, I didn't do a very good job of explaining it to you.

    The comment about Mach3 should have been clarified. The control panel will have a selector to determine if Mach3 will have the control or it will be given to the joystick exclusively. They will never share control and the joystick isn't meant to control through Mach3. The control panel may be shared with my mill in the future, in which case a pendant will make more sense. For now, the gantry isn't set up for heavy machining and just needs a semi-automated positioning. I think Henrik is correct, Mach3 has a provision for joystick input, but this is more an experiment in direct control with the PIC and joystick. Currently the application with the gantry and Mach3 may be masking the usefulness of this. Since Step/Direction controls are easily available and can be used with servos or steppers, there are a lot of uses for an independent control system that is very intuitive. I'm thinking animatronics and such too.

    I have had a little time and started to study your thoughts and I agree, the main parts are there. I also am studying Walter's link to glean how it was done there. Sorry I don't have any code to share yet, I'm still working through the structure.

    Bo

  15. #15
    Join Date
    Aug 2010
    Location
    Maryland, USA
    Posts
    869


    Did you find this post helpful? Yes | No

    Default No Worries :)

    Nobody ever hears mine either. It doesn't really matter if I understand what you intend to do. It only matters if I understand your question(s). So assuming I have the joystick operation correct, I can try and help you with the structure. Its no matter about mach. You asked for help with the actual driving of the step part. I, as I always do, went off making assumptions about your application. Sorry bout that. Seems after 20 years of helping customers in a small job shop machine shop, I now try to get at what they want to do, just in case there is more to the question then they realize. I will call it a job hazzard.
    -Bert

    The glass is not half full or half empty, Its twice as big as needed for the job!

    http://foamcasualty.com/ - Warbird R/C scratch building with foam!

  16. #16
    Join Date
    Feb 2008
    Location
    Michigan, USA
    Posts
    231


    Did you find this post helpful? Yes | No

    Talking Sidetracked

    OK, Bert, I just got sucked into your site for the past few hours! Shame on you for distracting me! I'm suppose to be cranking out code!

    That's neat stuff, I and never considered some of these techniques. Pretty amazing results.

    Do you discuss your phlat-cha-ma-callit anywhere? Also would love to know more about your 4D hotwire. Couldn't discern much from the picture.

    You know what.... better yet, don't tell me about it, otherwise, I'll never get anything done!

    Back to MicroCode Studio....

    Bo

  17. #17
    Join Date
    Feb 2008
    Location
    Michigan, USA
    Posts
    231


    Did you find this post helpful? Yes | No

    Default Math thoughts

    So here is the path that my mind is headed down:

    Pulley Circumference 2.375"
    Rev/Sec 4.21
    Travel/Sec 10"
    Pulse/sec 6063
    Counts/bit A-D 12.126
    Freq of pulses 165 uS

    My conclusion so far is:
    You have a control range of 500 A/D counts on each side (plus/minus)
    for every bit of A/D change, you increment your pulses sent out by 12.126 @ full speed
    you have to be able to send a pulse every 165 uS to get full speed
    encoder counts of 1440/rev give you a movement of 0.00165" per count

    So, as long as I can read the A/D's, adjust the gain, check limits, and send out 2 pulse trains in under that time, I should be able to make it work.

    Anybody see any holes?

    Bo
    Last edited by boroko; - 30th October 2010 at 22:27.

  18. #18
    Join Date
    Feb 2008
    Location
    Michigan, USA
    Posts
    231


    Did you find this post helpful? Yes | No

    Default Trying to get the algorithm

    What I'm not seeing is a way to connect the 0-500 A/D reading to the 165uS rollover of the timer.

    Setting one of the timers so that at max Z, it will rollover at 165uS, I can adjust that timer with the Z to slow it down and get the "gain", ie: increase the time it takes to rollover

    Reading the A/D, I can tell whether it is above 528 or below 500 and set direction.

    Each of the 4 possible 0-500 values signify the number of those rollovers that generate pulses out.

    Does this snippet look plausible?
    Code:
    IntCnt  var  word
    ADval   var  word[3]
    Holdoff var  word[3]       
    '**** Interrupt ****************
           IntCnt = IntCnt + 1       
           ADval[n]*12 = Holdoff[n]
           if IntCnt = Holdoff[n] then Pulse
              else NoPulse
              endif
    Pulse: 
           Pin[n] low         ' drive a step pulse active
           IntCnt = 0         ' clear count of interrupts 
           pauseus 2          ' delay to meet minimum time for drive
           Pin[n] high        ' return the pulse to inactive
           return             '
    NoPulse:
           return             ' go back without sending a pulse
    Bo

  19. #19
    Join Date
    Aug 2010
    Location
    Maryland, USA
    Posts
    869


    Did you find this post helpful? Yes | No

    Default

    Bo, I'll pm about the site. Feels like spamming to discuss it here.

    Deleted wrong information
    Last edited by cncmachineguy; - 31st October 2010 at 01:42. Reason: i was wrong
    -Bert

    The glass is not half full or half empty, Its twice as big as needed for the job!

    http://foamcasualty.com/ - Warbird R/C scratch building with foam!

  20. #20
    Join Date
    Aug 2010
    Location
    Maryland, USA
    Posts
    869


    Did you find this post helpful? Yes | No

    Default

    0-500 A/D:
    In my head, I see it like this. 1 timer for the 165uS time base.
    2 software counters, 1 for X and 1 for Y.
    These counters will count from 0 to modified A/D value.
    If the counter >= A/D value(0-500 not the whole value) send a pluse, reset counter.

    I would have my main loop do this:
    check for timer overflow , if overflow, inc both counters and reload timer.
    check limit switches, if any hit, don't allow movement in that direction
    get A/D values
    gosub A/D massage therpy
    Main Loop

    now does this make sense? lets see, if A/D= 0, pulses will send every 165uS. full speed
    if A/D = 500, pulses will send every 165*500=82mS. so Very slow

    Then have the Z pot change the timer duration and you are golden (i think).

    Of course A/D massage therpy may be a trick. This is where you turn the value into 0-500 upper and lower.

    Oh, and since this is not a tracker, you don't need to worry about the 12 pulses per a/d bit. That was just to scale the joystick to the travel of your table.
    -Bert

    The glass is not half full or half empty, Its twice as big as needed for the job!

    http://foamcasualty.com/ - Warbird R/C scratch building with foam!

  21. #21
    Join Date
    Feb 2008
    Location
    Michigan, USA
    Posts
    231


    Did you find this post helpful? Yes | No

    Default UNTESTED, but it compiles

    Well, here's what I have so far:
    I'm going to throw it on a LabX1 and see what happens.

    Code:
    '****************************************************************
    '*  Name    : Joystick-StepDir.BAS                              *
    '*  Author  : Mark A.Rokus                                      *
    '*  Notice  : Copyright (c) 2010 Controlled Surroundings Inc.   *
    '*          : All Rights Reserved                               *
    '*  Date    : 10/31/2010                                        *
    '*  Version : 1.0                                               *
    '*  Notes   :                                                   *
    '*  Needs   :  Button routine and decel near limits             *
    '****************************************************************   
    ' Read joystick and buttons and control Step/Direction drives.
    ' On power up, Beep and drive HOME, check centering of X & Y pots before 
    ' enabling output.  After ok, double beep, measure deflection, determine 
    ' direction, and increase pulses.
    ' Z (trim) analog input modifies the timer preload to control speed
    '*********************************************************************
    
    ' PC Joystick port.  DB15
    ' 1: 5v
    ' 2: B1
    ' 3: X1 (0-100k)
    ' 4: GndB1
    ' 5: GndB2
    ' 6: Y1 (0-100k)
    ' 7: B2
    ' 8: 5v
    ' 9: 5v
    ' 10: B4
    ' 11: X2 (0-100k) 
    ' 12: Gnd
    ' 13: Y2 (0-100k) 
    ' 14: B3
    ' 15: 5v 
    '                            18F4331/18F4431
    '                 -------------------u------------------
    '       Vpp    -1 |MCLR/vpp/RE3             RB7/KBI3/PGD|40-  PGD             
    '       X1     -2 |RA0/AN0                  RB6/KBI2/PGC|39-  PGC              
    '       Y1     -3 |RA1/AN1             RB5/KBI1/PWM4/PGM|38-   Man Enc B in            
    '       Y2     -4 |RA2/AN2/Vr-/CAP1/Indx   RB4/KBI0/PWM5|37-   Man Enc A in                    
    ' Trav EncA in -5 |RA3/AN3/Vr+/CAP2/QEA         RB3/PWM3|36-   S4  Thumb                          
    ' Trav EncB in -6 |RA4/AN4/CAP3/QEB             RB2/PWM2|35-   S3  Down                           
    '    Beeper    -7 |RA5/AN5/LVDIN                RB1/PWM1|34-   S2  Up
    '     Cut      -8 |RE0/AN6                      RB0/PWM0|33-   S1  Trigger
    '     Pack     -9 |RE1/AN7                          Vdd+|32    +
    '     Stroke   -10|RE2/AN8                          Vss-|31-   -
    '         +    -11|AVdd                        RD7/PWM7 |30-   Adir
    '         -    -12|AVss                        RD6/PWM6 |29-   Astep 
    '              -13|OSC1/CLK1/RA7              RD5/PWM4  |28-   Zdir             
    '              -14|OSC2/CLK0/RA6              RD4/FLTA3 |27-   Zstep  
    '    Xlim+     -15|RC0/T1OSO/T1CKI         RC7/RX/DT/SDO|26-   RX
    '    Xlim-     -16|RC1/T1OSI/CCP2/FLTA      RC6/TX/CK/SS|25-   TX
    '    Ylim+     -17|RC2/CCP1/FLTB        RC5/INT2/SCK/SCL|24-   Zlim- 
    '    Ylim-     -18|RC3/T0CKI/T5CKI/Int0 RC4/INT1/SDI/SDA|23-   Zlim+ 
    '    Xstep     -19|RD0/T0CKI/T5CKI           RD3/SCK/SCL|22-   Ydir
    '    Xdir      -20|RD1/SDO                   RD2/SDI/SDA|21-   Ystep
    '                 |_____________________________________|
    
       DEFINE OSC 40
    DEFINE HSER_RCSTA 90h ' Enable serial port & continuous receive
    DEFINE HSER_TXSTA 24h ' Enable transmit, BRGH = 1
    DEFINE HSER_CLROERR 1 ' Clear overflow automatically
    DEFINE HSER_SPBRG 173 ' 57600 Baud @ 40MHz, -0.22%
    SPBRGH = 0
    BAUDCON.3 = 1         ' Enable 16 bit baudrate generator
    	
    clear
    beeper   var PORTA.5
    SwTrig   var PORTB.0 
    SwUp     var PORTB.1 
    SwDwn    var PORTB.2
    SwTmb    var PORTB.3
    XlimFar  var PORTC.0
    XlimNear var PORTC.1
    YlimFar  var PORTC.2
    YlimNear var PORTC.3
    ZlimFar  var PORTC.4
    ZlimNear var PORTC.5
    Xs_out   var PORTD.0          ' Step PULSE output to motor, Active LOW
    Xd_out   var PORTD.1          ' LEVEL output for direction 
    Ys_out   var PORTD.2          ' Step PULSE output to motor, Active LOW
    Yd_out   var PORTD.3          ' LEVEL output for direction 
    Zs_out   var PORTD.4          ' LEVEL output for direction 
    Zd_out   var PORTD.5          ' Step PULSE output to motor, Active LOW
    Ad_out   var PORTD.6          ' LEVEL output for direction 
    As_out   var PORTD.7          ' Step PULSE output to motor, Active LOW
    Cut      VAR PORTE.0
    Pack     var PORTE.1
    Stroke   var PORTE.2
    Dir      VAR byte             ' Direction
    Xdir     var Dir.0
    Ydir     var dir.1
    Zdir     var Dir.2
    Adir     var Dir.3          
    Xch      VAR WORD             'channels for A/D
    Ych      VAR WORD
    Zch      VAR WORD
    Ach      VAR WORD
    Xspd     var word
    Yspd     var word
    IntCnt   var word[2]
    Holdoff  var word[2]
    Xpos     var word             ' counter for X position 
    Ypos     var word             ' counter for Y position 
    
    INCLUDE "DT_INTS-18.bas"     ' Base Interrupt System
    INCLUDE "ReEnterPBP-18.bas"  ' Include if using PBP interrupts
    
    'OPTION_REG = %00000000       ' Pull-up Enabled
    T0CON      = %10001000       ' no PS, PL65535 = .8uS, PL0 = 6.55mS
    TRISA      = %00011111
    TRISB      = $FF
    TRISC      = %10111111
    TRISD      = %00000000
    TRISE      = %00000000
    PORTD      = $00               ' start out HI. Moves on LOW pulse 
    
    '**** Analog setup  ****
        ' Single shot, multi-channel, simultaneous Mode2, Groups A+B, then C+D
        ADCON0 = %00011101   
        ADCON1 = %00010000   ' Set +/- Vref to AVdd/AVss, FIFO buffer enabled
        ADCON2 = %11111111   ' Right justified, 64 Tad, Frc
        ADCON3 = 0           ' Disable all triggers
        ADCHS = %11000000    ' Channel select for AN0,1,2
        ANSEL0 = %00000111   ' AN0,1,2 analog input, rest digital   
    '*********
        ASM
    INT_LIST  macro    ; IntSource,        Label,  Type, ResetFlag?
            INT_Handler   TMR0_INT,      _PulseCk,  PBP,  yes
        endm
        INT_CREATE                        ; Creates the interrupt processor
    ENDASM
     
    goto Start      
    '=============  SUBS  ================================
    
    '********  SUB: Get A/D readings *************************
    GetAD:                  
        ADCON0.1 = 1         ' Start conversion (Bruce t=6768)
        WHILE ADCON0.1=1     ' Wait for it to complete (all 3channels)
        WEND   
        Xch.HighByte = ADRESH ' get result from AN0
         Xch.LowByte = ADRESL  ' Increment buffer pointer    
        Ych.HighByte = ADRESH ' get result from AN1
         Ych.LowByte = ADRESL  ' Increment buffer pointer    
        Zch.HighByte = ADRESH ' get result fron AN2
         Zch.LowByte = ADRESL  ' Increment buffer pointer     
        Return     
    '*******  SUB: Direction / Speed Check *********************************** 
    DirChk:  'get direction
      if Xch > 513 then        ' Above center
         Xdir = 1 
        if Xch < 529 then      ' below NULL, 
         Xspd = 0              ' No output
         else
         Xspd = Xch - 528      ' 528 TO 1028 - 528 = 0 TO 500
        endif
       endif   
      if Xch < 514 then 
         Xdir = 0  
        if Xch > 499 then  
         Xspd = 0
         else
         Xspd = 500 - Xch      ' 500 - 499 TO 0 = 0 TO 500
        endif
       endif
    
      if Ych > 513 then 
         Ydir = 1 
        if Ych < 529 then    
         Yspd = 0     
         else
         Yspd = Ych - 528      ' 528 TO 1028 - 528 = 0 TO 500
        endif
       endif   
      if Ych < 514 then 
         Ydir = 0  
        if Ych > 499 then  
         Yspd = 0
         else
         Yspd = 500 - Ych      ' 500 - 499 TO 0 = 0 TO 500
        endif
       endif
       RETURN          
    '******* SUB:  Home Routine ************************************
    Home:
      Xdir = 0                  ' set home and clear Xpos and Ypos
      Ydir = 0 
      TMR0H = 0                 ' Set pulses @ 6.5mS (65535 preload)
      TMR0L = 0
    HomeX:
        WHILE XlimNear = 0        ' Drive to Home X slowly
           Xs_out = 0         ' drive a step pulse active 
           pauseus 3          ' delay to meet minimum time for drive        
           Xs_out = 1        ' return the pulse to inactive
        wend
        while XlimNear = 1 
           Xs_out = 0         ' drive a step pulse active 
           pauseus 3          ' delay to meet minimum time for drive        
           Xs_out = 1        ' return the pulse to inactive 
        wend   
           Xpos = 0           ' clear the counter to keep track of location
    HomeY:
        WHILE YlimNear =0        ' Drive to Home X slowly
           Ys_out = 0         ' drive a step pulse active 
           pauseus 3          ' delay to meet minimum time for drive        
           Ys_out = 1        ' return the pulse to inactive
        wend
        while YlimNear = 1 
           Ys_out = 0         ' drive a step pulse active 
           pauseus 3          ' delay to meet minimum time for drive        
           Ys_out = 1        ' return the pulse to inactive 
        wend   
           Ypos = 0           ' clear the counter to keep track of location
        return       
    '***** Initial setup  ****************************************
    Start:                      
      while SwTmb =0
      wend
      beeper = 1                ' sound horn to warn of movement
      pause 1000
      beeper = 0
      pause 1000
      call Home                 ' initial homing & zeroing of position counters          
    ZeroStick:
      call GetAD                ' check 0 readings on joystick
      while (Xch < 500) or (Xch > 527)or (Ych < 500) or (Ych > 527)
      wend
      beeper = 1                ' sound horn Done
      pause 500
      beeper = 0
      pause 500
      beeper = 1                
      pause 500
      beeper = 0
      pause 500  
    @    INT_ENABLE  TMR0_INT             ; enable Timer 0         
    '******* MAIN ***********************************************   
    Main:
      call GetAD
       TMR0H = Zch.HighByte     ' setup speed by getting Z as preload
       TMR0L = Zch.LowByte      ' to Timer 0
      call DirChk               ' sets direction, speed, and null
    ' show results
      hserout ["A/D X = ",DEC Xch," A/D Y = ",DEC Ych," A/D Speed = ",DEC Zch,13,10]
      hserout ["Position X= ",DEC Xpos,", Y= ",dec Ypos,13,10]   
      GOTO Main
    '******** Interrupt *******************************
    PulseCk:      
           Holdoff[0] = (Xspd*12)   ' 12 = approx step/bit ratio
           if IntCnt[0] = Holdoff[0] then 
               goto PulseX
              else 
               goto ChkY
           endif
    PulseX: 
           Xs_out = 0         ' drive a step pulse active 
           if Xdir = 1 then 
            Xpos = Xpos + 1
           else 
            Xpos = Xpos - 1        
            Xs_out = 1        ' return the pulse to inactive
           endif 
           IntCnt[0] = 0      ' clear count of interrupts
    ChkY:       
           Holdoff[1] = Yspd*12 
           if IntCnt[1] = Holdoff[1] then 
               goto PulseY
              else 
               goto NoPulse
           endif
    PulseY: 
           Ys_out = 0         ' drive a step pulse active 
           if Ydir =1 then 
            Ypos = Ypos + 1
           else 
            Ypos = Ypos - 1
            Ys_out = 1        ' return the pulse to inactive
           endif
           IntCnt[1] = 0      ' clear count of interrupts 
    NoPulse:
           IntCnt[0] = IntCnt[0] + 1   ' keep track of times -
           IntCnt[1] = IntCnt[1] + 1   ' through the interrupt
    @ INT_RETURN             '    
    ;********* End of Interrupt **********************
        END
    The floor is open for comment....
    Bo

  22. #22
    Join Date
    Aug 2010
    Location
    Maryland, USA
    Posts
    869


    Did you find this post helpful? Yes | No

    Default

    Seems like a great start! Personally I don't see any issues up front. Do you have a scope to watch the outputs?
    -Bert

    The glass is not half full or half empty, Its twice as big as needed for the job!

    http://foamcasualty.com/ - Warbird R/C scratch building with foam!

  23. #23
    Join Date
    Feb 2008
    Location
    Michigan, USA
    Posts
    231


    Did you find this post helpful? Yes | No

    Default

    My Tektronix 2445 failed me a while ago. Of course it is a custom IC that is pure unobtanium.

    Good news is that I have a 2465 coming Tuesday. Isn't ebay great!

    In the mean time, I'll check it with a hand held Velleman HPS40

    Thanks for all your help
    Updates to follow

    Bo

  24. #24
    Join Date
    Aug 2010
    Location
    Maryland, USA
    Posts
    869


    Did you find this post helpful? Yes | No

    Default

    I don't know if I was any help actually, but you are welcome! Would love some pics of you babys
    -Bert

    The glass is not half full or half empty, Its twice as big as needed for the job!

    http://foamcasualty.com/ - Warbird R/C scratch building with foam!

Members who have read this thread : 1

You do not have permission to view the list of names.

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts