PC joystick to (Servo or Stepper) STEP/DIRECTION


Closed Thread
Results 1 to 24 of 24

Hybrid View

  1. #1
    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

  2. #2
    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!

  3. #3
    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!

  4. #4
    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

  5. #5
    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!

  6. #6
    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

  7. #7
    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 : 0

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