# Robot using already existing servo amplifiers

20 May 2014 21:53 #47099 by PCW
1. Data (step in and limit sw out)
2. Direction (direction in)
3. unused
4. Write strobe (rising edge to write step/Dir to selected joint)
6. unused
7. Shoulder select
8. unused
9. L wrist select
10. R wrist select
11. unused
12. unused
13. /overrange (low when following error)
14. unused
15 /reset (active low)
16 clock (continuous)
The following user(s) said Thank You: dimech, Omkareshwarkumar121, Rm501!

20 May 2014 21:57 #47100 by andypugh
So, multiplexed step-dir?
That sounds like fun

maybe charge_pump to generate the strobe, multiswitch to select the joints and chose a stepgen output from a pair of muxes?
The following user(s) said Thank You: dimech

20 May 2014 23:12 - 20 May 2014 23:14 #47105 by dimech
Thank you PCW! You read it amazingly fast!

Ok now I have 3 additional questions

1) L WRIST and R WRIST are in differential orientation. Thus, different directions means hand is rotating and same direction moving up down the wrist. How may achieve the rotation when the direction becomes from the same pin?

2) Pin 1 has got a bidirectional attitude. Is that a problem for the parport?

3) When I have to set true pin5 (read enable)? When I am close enough based on counting?

Also for educational purpose,
Could you explain me how the last bit of counting determines the dir? That was troubling me a lot...
Last edit: 20 May 2014 23:14 by dimech.

20 May 2014 23:36 - 20 May 2014 23:38 #47108 by andypugh

dimech wrote: 1) L WRIST and R WRIST are in differential orientation. Thus, different directions means hand is rotating and same direction moving up down the wrist. How may achieve the rotation when the direction becomes from the same pin?

it is going to be something like stepgen.2.position-cmd = joint2 + joint3 and stepgen.3.position-cmd = joint1 - joint3.

In HAL this will look like:
...
...
net wrist-angle-cmd axis.2.motor-pos-cmd sum2.0.in0 sum2.1.in0
net net-wrist-rot-cmd axis.3.motor-pos-cmd sum2.0.in1 sum2.1.in1
setp sum2.0.gain0 1
setp sum2.0.gain1 1
setp sum2.1.gain0 -1
setp sum2.1.gain1 1
...
net lw-cmd sum2.0.out stepgen.2.position-cmd
net rw-cmd sum2.1.out stepgen.3.position-cmd

www.linuxcnc.org/docs/html/man/man9/sum2.9.html
www.linuxcnc.org/docs/html/man/man9/stepgen.9.html
www.linuxcnc.org/docs/html/man/man9/motion.9.html
Last edit: 20 May 2014 23:38 by andypugh.
The following user(s) said Thank You: dimech

21 May 2014 00:41 - 21 May 2014 00:46 #47111 by PCW

1) L WRIST and R WRIST are in differential orientation. Thus, different directions means hand is rotating and same direction moving up down the wrist. How may achieve the rotation when the direction becomes from the same pin?

The different joints step and direction data is written independently
That is to write L_WRIST step and direction data, you set L wrist select high (and all other selects low)
then set the step (data) and direction pins to the proper states, then assert the write strobe pin high and then low
You do the same for the other joints

I am not sure about whether you need to set the step pulse low again with a particular timing to get one count

2) Pin 1 has got a bidirectional attitude. Is that a problem for the parport?

Yes, though it may be doable with just a series resistor

3) When I have to set true pin5 (read enable)? When I am close enough based on counting?

Read enable just drives the data pin (1) with the limit switch state (again you must select the joint with one of the L wrist, R wrist or shoulder select lines high, all others low)

Also for educational purpose,
Could you explain me how the last bit of counting determines the dir? That was troubling me a lot...

This is 2's complement counting so for example if I count down when at 0b00000000
the next count is 0b11111111 (-1 in 2's complement). In 2's complement the MSB is referred to as the sign bit
(negative counts have a '1' sign bit)

en.wikipedia.org/wiki/Two%27s_complement
Last edit: 21 May 2014 00:46 by PCW.
The following user(s) said Thank You: dimech

21 May 2014 01:50 - 21 May 2014 01:52 #47116 by dimech
Thank you a lot!

I will need few days make it clear in my head!

I also have to read the mans of charge_pump, multiswitch, stepgen, ... and make the hal "schematic" in my head

best regards
Last edit: 21 May 2014 01:52 by dimech.

03 Jun 2014 21:25 #47660 by dimech
Hello,
I am back with furthermore questions!

I still cannot understand, how the motor driver boards, read steps. The strobe just pass input state to output at the rising edge. So, state can be true or false and will be like that, until the next strobe?
If that happens, how I determine the velocity and the number of steps?

Also, do I have to make a hal component for the kinematics?

Can I convert a .C file to hal component?

03 Jun 2014 23:13 #47663 by andypugh

dimech wrote: The strobe just pass input state to output at the rising edge. So, state can be true or false and will be like that, until the next strobe?

It is more that the driver ignores the value on the step/dir pins until the next strobe.

If that happens, how I determine the velocity and the number of steps?

You don't, the software does that.

Also, do I have to make a hal component for the kinematics?!

It might turn out to be the easiest way.
"comp" can compile and install kinematics files written in C.
www.linuxcnc.org/docs/html/motion/kinematics.html
www.linuxcnc.org/docs/html/hal/comp.html
The following user(s) said Thank You: dimech

11 Jul 2014 18:00 #48645 by dimech
Hello again!

All this time I was experimenting on Hal based of what you said but only in my laptop without connecting the Hal with the hardware.

Before start try things in the real word I would like your confirmations suggestions or corrections for some of my thoughts. Also I need more guidelines on some Hal issues

Hardware issues,

read enable and SW are really a trouble for me. So I decide to connect them (the switches) with the parport, but I need 13 outputs and 7 inputs and that is not doable. So I thought put all the SW in the same pin and by using a Hal and2 with axis.N.amp-enable-out to isolate them.

Another issue is the steps. I think, the counters in the driver boards increase the velocity by counting, so we do not have steps but velocity stages. Is that true?

Also do I have to reset the entire drive board each time I change a joint move?

HAL issues,

mux8 need a 3bit information how am I generate those 3bit for a joint?

Where am I connect the error occur pins from the drive unit?

That's for now,

12 Jul 2014 03:05 - 12 Jul 2014 03:05 #48664 by andypugh

dimech wrote: mux8 need a 3bit information how am I generate those 3bit for a joint?

I think that you can do a lot of this with a self-driving mux

For a bit-type mux you probably need to use mux_generic
www.linuxcnc.org/docs/devel/html/man/man9/mux_generic.9.html

Here is the idea, it might not be immediately obvious how this is meant to work

It is important to realise that a HAL component runs every thread, and every thread it reads the inputs, writes the outputs, and exits.
This means that you can sequence things by connecting the outputs of a component to its own inputs.

So, if we were to take a 32-bit unsigned mux we could use it as a look-up table, where each entry contains the data you want to output and the "address" of the next entry in the table.

Lets take a simple 4-entry example, we could format the data like this (where aaa, bbb are the 30 binary data bits available as output)
01aaa
10bbb
11ccc
00ddd

If we take the output of the mux through "bitslice"
net foo mux-gen.00.out => bitlsice.0.in

Now the mux4-bit we created will cycle through its entries automatically.

What I propose is that you can define bit 0 as the strobe, and bits 1 2 and 3 as the select bits for two _other_ bitwise muxes that gate-through the step and dir signals.

So, mux entry 0 contains the address of mux entry 1, and the bit pattern for stepgen 0, and a strobe of 0.
mux entry 1 has the address to 2, the same bit pattern to select the stepgen-mux, and strobe 1.

I have forgotten how many stepgens you need to drive, bit lets guess at 8. To make this easy I am going to be inefficient with the bits.
nibble 0 (bits 0-3) is strobe, nibble1 (bits 4 to 6) is stepgen address, nibble 3 (bits 8 -11) is the address of the next entry. Things could be more efficient packed more tightly, but then I would find it harder to work out the hex in my head
There is room for _far_ more data in this scheme, and the table could have 1024 entries
```loadrt mux_generic config=uu16,bb8,bb8

#note the addf order, this is important

net data mux-gen.00.out-u32 => bitslice.0.in

# This is the data table, (0x means "this is a hex number")
setp mux-gen.00.in-u32-00 0x100
setp mux-gen.01.in-u32-00 0x201
setp mux-gen.02.in-u32-00 0x310
setp mux-gen.03.in-u32-00 0x411
setp mux-gen.04.in-u32-00 0x520
setp mux-gen.05.in-u32-00 0x621
setp mux-gen.06.in-u32-00 0x730
setp mux-gen.07.in-u32-00 0x831
setp mux-gen.08.in-u32-00 0x940
setp mux-gen.09.in-u32-00 0xA41
setp mux-gen.10.in-u32-00 0xB50
setp mux-gen.11.in-u32-00 0xC51
setp mux-gen.12.in-u32-00 0xD60
setp mux-gen.13.in-u32-00 0xE61
setp mux-gen.14.in-u32-00 0xF70
setp mux-gen.15.in-u32-00 0x071

#loop-back the select pins to make the mux self-driving

net strobe bitslice.0.bit-00 => parport.0.pin-AA-out

#connect the select pins for the step-dir diverters
net sel0 bitslice.0.bit-4 => mux-gen.01.sel0 mux-gen.02.sel0
net sel1 bitslice.0.bit-5 => mux-gen.01.sel1 mux-gen.02.sel1
net sel2 bitslice.0.bit-6 => mux-gen.02.sel2 mux-gen.02.sel2

#And finally connect up the stepgens
net step-out mux-gen.01.out-bit => parport.0.pin-BB-out
net step0 stepgen.0.step => mux-gen.01.in-bit-00
net step1 stepgen.1.step => mux-gen.01.in-bit-01
net step2 stepgen.2.step => mux-gen.01.in-bit-02
net step3 stepgen.3.step => mux-gen.01.in-bit-03
net step4 stepgen.4.step => mux-gen.01.in-bit-04
net step5 stepgen.5.step => mux-gen.01.in-bit-05
net step6 stepgen.6.step => mux-gen.01.in-bit-06
net step7 stepgen.7.step => mux-gen.01.in-bit-07

net step-out mux-gen.02.out-bit => parport.0.pin-CC-out
net step0 stepgen.0.dir => mux-gen.01.in-bit-00
net step1 stepgen.1.dir => mux-gen.01.in-bit-01
net step2 stepgen.2.dir => mux-gen.01.in-bit-02
net step3 stepgen.3.dir => mux-gen.01.in-bit-03
net step4 stepgen.4.dir => mux-gen.01.in-bit-04
net step5 stepgen.5.dir => mux-gen.01.in-bit-05
net step6 stepgen.6.dir => mux-gen.01.in-bit-06
net step7 stepgen.7.dir => mux-gen.01.in-bit-07```

Note that this code is entirely untested, I just typed it in while scanning the docs. Also be aware that neither bitslice nor mux-generic are in the current release, you would need to install 2.6 or Master (precompiled packages are available, it is just a bit of config and a package-manager upgrade).

I will also admit that I am really rather proud of this bit of HAL-wrangling
Last edit: 12 Jul 2014 03:05 by andypugh.
The following user(s) said Thank You: dimech