PDA

View Full Version : PC joystick to (Servo or Stepper) STEP/DIRECTION



boroko
- 28th October 2010, 09:00
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

ScaleRobotics
- 28th October 2010, 13:12
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

boroko
- 28th October 2010, 13:56
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!

cncmachineguy
- 28th October 2010, 15:49
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.

boroko
- 29th October 2010, 02:08
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

cncmachineguy
- 29th October 2010, 03:22
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

boroko
- 29th October 2010, 06:43
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.

HenrikOlsson
- 29th October 2010, 11:14
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.

cncmachineguy
- 29th October 2010, 12:48
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":)

cncmachineguy
- 29th October 2010, 13:28
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.

boroko
- 29th October 2010, 14:11
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

boroko
- 29th October 2010, 15:48
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.

cncmachineguy
- 30th October 2010, 01:21
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. :)

boroko
- 30th October 2010, 02:23
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

cncmachineguy
- 30th October 2010, 04:47
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.;)

boroko
- 30th October 2010, 19:31
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

boroko
- 30th October 2010, 22:08
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

boroko
- 30th October 2010, 23:40
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?

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

cncmachineguy
- 31st October 2010, 01:10
Bo, I'll pm about the site. Feels like spamming to discuss it here.

Deleted wrong information

cncmachineguy
- 31st October 2010, 14:46
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.

boroko
- 31st October 2010, 19:15
Well, here's what I have so far:
I'm going to throw it on a LabX1 and see what happens.


'************************************************* ***************
'* 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

cncmachineguy
- 31st October 2010, 19:55
Seems like a great start! Personally I don't see any issues up front. Do you have a scope to watch the outputs?

boroko
- 31st October 2010, 20:09
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

cncmachineguy
- 31st October 2010, 20:14
I don't know if I was any help actually, but you are welcome! Would love some pics of you babys :)