PDA

View Full Version : Quick thoughts: DT Ints with encoders



kevlar129bp
- 4th January 2010, 16:52
Hello all,

Here I go again. Working on a project...Digitizing Arm...and needing to count pulses from 6 encoders. The encoders will be counted in quadrature, therefore, I will need to monitor interrupts from 24 different lines...

Each encoder:
Lines: 500
Counts: 2000 (in quadrature)
Gear Reduction: 10.8:1
Total Counts: 21600

WORD sized variable to hold counts

Here is my question(s):

Using DT Ints portB change interrupts, am I led to believe I am going to need 3 individual pics to achieve 24 portB lines, or is there a slicker way to get my 24 IO lines that have interrupt on change?
Should I run 6 pics (1 per encoder) to keep the counts super accurate?

The plan calls for a button to be on the stylus, and upon a button press, the counts from each encoder will be sent to the pc via RS232, to be processed into a point cloud for SolidWorks.

If I run 1 pic, the serial stream would be a piece of cake...

If I run 6 pics, does it not get a little tricky?
Maybe a "master" pic collecting the data from all the encoder pics...then
the "master" sending all the counts to the pc?...
OR
All encoder pics sharing the same TX line and "bus busy" line, therefore when an encoder pic is transmitting, it will pull the "bus busy" line high, halting other encoder pics from their transmissions?

I guess I'll stop here and see what thoughts I get. :confused:

As far as code thoughts..I'm good there. I guess I'm seeking hardware thoughts at this stage.
I think tracking the encoder counts is the most important aspect of this project...

Any thoughts at this point, are good thoughts!

Thanks all,

Chris

HenrikOlsson
- 4th January 2010, 17:18
Hi,
Why do you need 24 inputs for 6 encoders?

If it was me doing it, I'd probably go with one PIC per encoder or perahaps one PIC for two encoders, each one reporting to a master. Keeping track of multiple encoders (with this kind of resolution) in software won't be easy.

/Henrik.

kevlar129bp
- 4th January 2010, 17:29
Thanks Henrick,

Good point with the 24 IO lines ;)
I only need 12...

Channel A
Channel B

I was thinking the NOT channels too...Doh!

Thanks for the thoughts.

Anyone else want to chime in?

Chris

kevlar129bp
- 4th January 2010, 17:45
BTW:

The serial stream from the encoder pics will just be the counts...
no angles, math, etc.
That will be handled on the pc side of things.

Chris

kevlar129bp
- 5th January 2010, 00:06
Here's a screen-shot of the temporary VB prog... to give you guys a visual.

HenrikOlsson
- 5th January 2010, 07:59
That's pretty cool! I've played a bit with digitizing arms from FARO and they are very impressive devices, good luck and please keep as posted on the progress!

/Henrik.

BTW. I think the term is forward kinematics...

kevlar129bp
- 5th January 2010, 15:37
Right you are Henrik ;). Good thing it's just the form title :).
I think I am going to go with the 6 pics reporting to a master via SEROUT2.
I'll have the master report to the pc via HSEROUT. I think the speed will benefit
from this scheme as well.

Chris

HenrikOlsson
- 5th January 2010, 16:26
Hmm, SEROUT2 (ie software UART) may not be a good idea. The interrupts will screw with the timing. The PIC12F1822 looked perfect for this untill I saw it was listed as a future product... (It's an 8-pin device with USART and Interrupt on change feature). Maby you can use it for the production model ;-)

The PIC16F688, though a 14pin device, is available and has both USART and interrupt on change feature (on 6 pins), have a look at that.

kevlar129bp
- 5th January 2010, 19:34
Hey Hendrik,

I'll take a glance at the parts you mentioned. Kinda cool you mentioned the uarts. Maybe you can answer a lingering question for me... In the example of the six "slaves" reporting to the "master"... If I send HSEROUT from the slaves, what would be the protocol for receiving at the master? Would I use SERIN2? What mode? Etc, etc?

That question has driven me nuts for some time! :confused:

I'm thinking 20 Mhz on the slaves and 40 Mhz on the master.

What are your thoughts?

Thanks again,

Chris

HenrikOlsson
- 5th January 2010, 20:16
Hi Chris,
There are varoius ways to do it. You could for example have two wires between each slave and the master PIC. The master signals one slave at a time to to send the current position, and receives it with SERIN or SERIN2. When all 6 slaves are polled it sends the data to the master. The USART sends the data "true" so the master would need to receive it "true".

Another approach is to implement a RS485 network.

/Henrik.

kevlar129bp
- 5th January 2010, 20:57
I'll work on a bit of code and we'll see where it takes us...

I'll keep you posted.

Thanks,

Chris

kevlar129bp
- 6th January 2010, 02:15
Here's what I've got so far... for the "slave" pics anyhow.

Critiques are definitely welcome! :)

16F688 w/20Mhz



INCLUDE "DT_INTS-14-MOD.bas"
INCLUDE "ReEnterPBP.bas"

'Clock setup
Define OSC 20
'Pin setups
ANSEL = %00000000 'No analog input
TRISA = %00000111 'PortA: TRISA = %00XXXXXX
TRISC = %00000000 'PortC: TRISC = %00XXXXXX
'Usart setups
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 86 ' 57600 Baud @ SPBRGH = 0
BAUDCTL.3 = 1 ' Enable 16 bit baudrate generator
'----------------------------------------------------------------------------

MaxCount con 21600
BtnZeroCount var PORTA.0
APin var PORTA.1
BPin var PORTA.2
AOld var byte
BOld var byte
CurCount var word

ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler RAC_INT, _ABInt, PBP, yes
endm
INT_CREATE ; Creates the interrupt processor

INT_ENABLE RAC_INT ; Enable RA change interrupt
ENDASM

curcount = 0

Start:

if btnzerocount = 0 then 'btnzerocount (A.0) has pullup res
curcount = 0
endif

aold = apin
bold = bpin

hserout ["$", dec5 curcount]

goto start

ABInt:

'\\\ A caused the interrupt ///
IF apin != aold THEN 'APin IS NOT equal to AOld
IF apin != bpin THEN 'If A and B are different,
GOTO CW 'it was clockwise rotation
ELSE 'Otherwise,
GOTO CCW 'it was counter-clockwise rotation
ENDIF
ENDIF

'\\\ B caused the interrupt ///
IF Bpin != Bold THEN 'BPin IS NOT equal to BOld
IF apin == bpin THEN 'If A and B are the same,
GOTO CW 'it was clockwise rotation
ELSE 'Otherwise,
GOTO CCW 'it was counter-clockwise rotation
ENDIF
ENDIF

CW: ' -1
if curcount > 0 then
curcount = curcount -1
else
curcount = MaxCount
endif
@ INT_RETURN

CCW: ' +1
if curcount < maxcount then
curcount = curcount +1
else
curcount = 0
endif
@ INT_RETURN


Thanks again guys,
Chris

HenrikOlsson
- 6th January 2010, 08:02
Hi,
I'd move the aold=apin, bold=bpin to the ISR. If kept in the main routine it's possible that a new interrupt occurs, for example, right between those two lines which will mess with your count - I think.

kevlar129bp
- 6th January 2010, 15:35
Thanks Henrik,

Thanks for the heads up. I see your point there. Otherwise, do you think I've got viable code?

Thanks again,
Chris

HenrikOlsson
- 6th January 2010, 16:55
Hi,
Yes, it look OK to me, the quadrature decoding seems to be correct but I'm sure someone around here knows of a faster/slicker way of doing it. (I'm not saying your way is slow).

Are you sending directly to a VB program for testing or are you sending to a terminal program or something like that? If a terminal program I'd put Pause 100 or whatever in the mainloop and add a CR to the end of the "message". If you're sending to a VB program, you could send the high and low byte of the counter and put them together in the PC.

If the encoders have Index-channel you could use that to zero the counter, at startup you move each joint of the arm thru "center" and it automatically zeros.

/Henrik.

kevlar129bp
- 6th January 2010, 17:38
Hi Henrik,

The thought behind not using the index channel is:
After firmly attaching the base...
You will probe anywhere in 3d space, then click the "zero" button on the stylus.
At that point, all encoder rotations will be based from that point.
Logging 3d points will be performed by clicking the "log point" button on the stylus.
I'm hoping to have a routine to log points as fast as serially possible while holding the "log point" button down continuously.
The way I see it, this will be all variant on:
1) "slave" pic interrupt speed to acquire an accurate count
2) "slave" pic to "master" pic serial speed
3) "master" pic to pc serial speed

All of the above will hinge on the user's stylus "drag speed" across the intended surface.

Check out this link...maybe it will explain it a bit better than I can ;)

http://www.youtube.com/watch?v=UtC4zJl9D2k

Let me know whatcha think.

Thanks,
Chris

HenrikOlsson
- 6th January 2010, 18:29
Yes, but don't you need to know the absolute angle between segments in order to calculate the stylus position?

You can still use your zero button for relative measurements but shouldn't it be more like an offset from the absolute zero position?

If you wire a third signal between the master PIC and all slaves you can use that signal capture the count at all six joints simultanously", then the master "pings" each slave for the value. Perhaps that was what you meant, just thought I'd mention it if it wasn't.

This is a cool project!

kevlar129bp
- 6th January 2010, 20:59
Hey Henrik,

You are thinking correctly on the absolute angle needed.
That's where the pulse counting comes in...
On the arm I've got designed in SolidWorks now has the following:

500 line encoders
2000 counts in quadrature
10.8:1 gearing
21600 quad counts per 360 degrees

Upon "zero button" press, we'll get degrees "moved" like this:

\\\\ Snip of VB Code ////
Const DPP As Double = 1.66666666666667E-02 <<< 360 / 21600
Dim DegreesNow As Double
Dim CountsNow As Integer
DegreesNow = CountsNow * DPP

If I'm thinking correctly, that will give us the degrees "traveled" by each joint.
If I am reading your question correctly, are you referring to the angles from "zero planes"? (dead vertical and dead horizontal)

Let me know if my thinking is correct?

Hard for me to keep it all straight! :eek:

I'm will also be doing the CNC machining for the arm components as well...

Too much for 1 guy to think about!

Let me know what you think.

Thanks again,
Chris

HenrikOlsson
- 6th January 2010, 22:23
Hi Chris,
Let's take the "wrist" joint for example, or any joint for that matter, it doesn't make any difference. It and the stylus is pointing straight down and the length from the pivot point to the tip is 100mm, you press zero at this point, the counter is 0.

Now you rotate that single joint 20° (1200 counts), the tip has moved 34.2mm "away" and 6.03mm "up", you collect that point. Now move it another 20°, this time the same amount of rotation in the joint (20°) moved the tip 30.08mm "away" and 17.36mm up.

Now concider that you from the beginning had pressed zero at the "20° position", the counter is reset to 0. Now you rotate the joint 20° (and ends up the previous 40° position) the counter says 1200 counts which is of course correct but where in 3D-space is the tip?

Is it 34.2mm "away" and 6.03 "up" from your "zero" like before or is it 30.08mm "away" and 17.36 "up"? Obviosuly the later is correct but how would you calculate that when you don't know that your "zero" was actually 20° from dead straight vertical - all you got was 1200 counts.

As far as I can see it will impossible to calculate the position of the stylus without having some kind of absolute reference to start from, like all joints at 90° to each other or something. Therefor my sugestion to use the index-channel. But since you have reduction that may not be as easy as I first thought.

Does that make sense or is it me who's missing something?

/Henrik.

kevlar129bp
- 7th January 2010, 01:01
Ahhh, ya got me on that one Henrik! You are absolutely correct. It looks like it's back to the math.:( I think it's going to have to be based on the Denavit Hartenberg Representation. Crazy math, I must say. I'm actually chatting on another forum with a guy from Carnegie Mellon University, National Robotics Engineering Center. He told me one of his co-workers built a six axis arm and worked out the kinematics for it too. Oh boy, I hope I can garner some info from him! In the mean time, if you want to tinker with it, or have any thoughts on it, it would be a huge help. I hope to have something very soon, as I think this project would be beneficial to so many!

Thanks Henrik,

Keep me posted, and I will do the same.

Chris