Kurt's Phoenix with Arc-32

Well I have now done most of the assembly of the phoenix :smiley:

I really wish I had purchased one of the original Red Phoenix’s. The color would look nice with the arc32 :laughing: Note: I am not finished cleaning up the wires yet!!! Still need to figure out some other wires.

I still need to go through and zero out all of the servos. Will probably use a modified version of my zero program I played with last week. Changes will include: hserial (I got it for s_in/s_out, might as well use it). Conversion to HSERVO2. Will put most of this in #ifdefs so can use on non-arc32 as well…

Some things I noticed include:
a) Sure ain’t much room under there! With the shipped standoffs for the processor board the 2800mah battery did not fit so I currently have a 1600mah one (borrowed from MechBrat). Not sure if this is the best approach or put in shorter standoffs so the larger battery will fit or stay as it is…

b) The board has VL/VS1/VS2 - But I don’t see any jumpers to connect them to each other. I did hook up VL to 9V battery through switch. I then modified the wire harness to have two reds/blacks to plug into both VS1 and VS2.

c) I noticed that the center servos brackets can run into the board. I will check later to make sure limits are set in software to keep it from going there…

d) There appear to be 4 VS/VL jumper sets, need to figure out which go with which pins. With how the servo wires lay out (unless I use an extension or 2) can I reserve at least one area for +5v. Also need to dig up some jumpers to choose either +5v or VS.

e) I still need to figure out how to hook up the PS2 controller and XBEE. I know that for the PS2, Nathan used pins:

PS2DAT con P35 ;PS2 Controller DAT (Brown) PS2CMD con P37 ;PS2 controller CMD (Orange) PS2CLK con P38 ;PS2 Controller CLK (White) PS2SEL con P39 ;PS2 Controller SEL (Blue)
I also know that these are on the AUX header. P34-P39 are AUX1 pins 1-6 just need to figure out how they numbered them. First guess is top row is 1-3 and bottom row is 4-6. Also I think the hardware serial port is on pins (P36 and P38) so I don’t want to fully use his setup. Can not use standard PS2 cable for this one.

Got a lot of other non-robot stuff going on this week so may not be able to do much until next weekend…

Kurt

A quick update:

I modified my version of the servo zero finder and downloaded it to the Arc-32. That part works!!! Yeah!!!

I have not installed any of the power jumpers (VS/VL) so I did not expect it to do anything. However some of the servos are being moved. MY VS battery was not even plugged in. So VL or 9V is being supplied to some of the servos. They appear to be in the servo range of 8-15 on the board (but not all of them). Need to investigate.

Not sure if I should continue this here or create new thread…

Kurt

Oops, my mistake :blush: :imp:
One of the servos was plugged into one of the VS/VL selectors… They are right next to each other…

Now to plug in some jumpers and see if the legs move like they are supposed to!!!

Kurt

Hi Kurt,

Looks like you’re having some fun!
Yeah, you should have ordered the red one :stuck_out_tongue:. Sounds like the standoffs should be shortened a little. The conflict with the board (middle servos) shouldn’t be a problem, as you said just measure the angle limits. Using PEP for finding the limits is a good way too (if you can manage to control the ARC-32 with PEP then… :wink: ).

I believe the XBee modules with chip antenna would be the perfect receiver for an ARC-32 controlled Phoenix though… 8)

I’ve been thinking the same about the aux ports, the pins should be marked better. Hopefully there are comming some documentations soon…

It sounds your on the track. Would you mind sharing the zerofinder for ARC-32? Would be a very useful tool!

Starting your own thread might be an idea :wink:

Thanks Zenta,

Ok I split it off… Not sure if best to leave here on move to Multi-leg or to project…

Here is the current zero the servo for Arc32… Note it has not been tested on the save/restore (probably needs some work).

But if you want to play with it

Thanks for sharing Kurt!

I don’t have time to test it right now but I’ll let you know when i’ve done it.
Oh, at first I didn’t notice you’ve started a new thread.

Looking forward to follow this project. Your work with the code are going to be a great help for my own ARC-32 project.

Hi Zenta, had a few minutes and did some testing and found some problems… It would not properly save the values out to the EEPROM on the BAP because the cnt+chksum+2*number servos exceeded 32 bytes and you run into problems if you try to write more than 32 bytes at a time. So I had the code break up the write into two…

Here is the current ARC32 specific writeup on commands and pinouts.

[code]ARC32 Specific command usage

To enable the servo hardware support use:

ENABLEHSERVO2

Hardware servo specific commands:
HSERVO [pin1\pos1{\speed1}{,pinN\posN{\speedN}}]

example 1:
	HSERVO [0\0]					;set servo pulse poisiton to center(1.5ms pulse width) immediately

example 2:
	HSERVO [0\10000\100]	;Start servo pulse moving toward 10000, 100 steps every 20ms. Servo pulse will hold at 10000 when it reaches it.

example 3:
	HSERVO [0\0,p1\0]		;set servo0 pulse to center and sevo1 pulse to center

Note that before a speed argument can be used on a servo pin, the servo pin must be set to an immediate position and given enough time for the actual servo to reach that position(see eaxmple 1).
example:
  HSERVO [0\0]
  pause 2000		;allow servo to initialize to it's center position

HSERVOWAIT [pin1{,pinN}]
Wait until the specified servo pin(s) have reached there position.

example:
	HSERVO [0\10000\100]
	HSERVOWAIT [0]				;will pause here until p0 reaches 10000

Harware servo specific functions:
HSERVOPOS pin
Returns the current position of the specified servo

example:
	HSERVO [0\10000\100]
	while(hservopos(0)<>10000) ;loop until the servo reaches 10000
	    ;do stuff here
	wend

HSERVOIDLE pin
returns the IDLE state of the servo(eg not Zero if the servo is idle(holding position)

example:
	HSERVO [0\10000\100]
	while(hservoidle(0)=0) ;loop until the servo becomes idle
	   ;do stuff here
	wend

HSERVOSTATE pin
returns the state of the specified pin. Analog capable pins will return a value between 0 and 1023.
Digital pins will return 0 or 1023.

example:
   if(hservostate(15)>512)then ;if voltage on p16 is higher than 2.5v
      ;do stuff here
   endif
   
Servo pins that return AD values are 8 to 15 and 24 to 31.

Special HSERVOSTATE pin numbers.
32 returns VS1 A/D value
33 returns VL A/D value
34 returns VS2 A/D value
35 returns AUX1 pin 6 A/D value

ARC32 pin names for use with regular comands(eg high,low,input,output, serin,serout etc…)
P# Connection Hitachi/Hardware functions
P0 servo0 (P54/WKP4)
P1 servo1 (P55/WKP5/ADTRG)
P2 servo2 (P10/TMOW)
P3 servo3 (P11/PWM)
P4 servo4 (P12)
P5 servo5 (P75/TMCIV)
P6 servo6 (P76/TMOV)
P7 servo7 (P23)

P16 servo16 (P53/WKP3)
P17 servo17 (P52/WKP2)
P18 servo18 (P51/WKP1)
P19 servo19 (P50/WKP0)
P20 servo20 (P30)
P21 servo21 (P31)
P22 servo22 (P32)
P23 servo23 (P33)

P28 servo28 (P17/IRQ3/TRGV)
P29 servo29 (P16/IRQ2)
P30 servo30 (P15/IRQ1/TMIB1)
P31 servo41 (P14/IRQ0)

S_IN USB (P21)
S_OUT USB (P22)

P34 AUX1 pin1 (P57/SCL)
P35 AUX1 pin2 (P56/SDA)
P36 AUX1 pin3 (P72/TXD_2)
P37 AUX1 pin4 (P70/SCK3_2)
P38 AUX1 pin5 (P71/RXD_2)
P39 AUX1 pin6 (P37) and (PB3)
P40 AUX2 pin2 (P24) with pullup
P41 AUX2 pin4 (P85) with pullup
P42 AUX2 pin6 (P86) with pullup
P43 AUX2 pin8 (P87) with pullup
P44 Status LED (P36)
P45 Batt LED (P74/TMRIV)
P46 MUX A (P34)
P47 MUX B (P35)
P48 U24 X (P60/FTIOA0)
P49 U24 Y (P61/FTIOB0)
P50 U21 X (P62/FTIOC0)
P51 U21 Y (P63/FTIOD0)
P52 U22 X (P64/FTIOA1)
P53 U22 Y (P65/FTIOB1)
P54 U23 Y (P66/FTIOC1)
P55 U23 X (P67/FTIOD1)
P56 VS1 (PB0/AN0)
P57 VL (PB1/AN1)
P58 VS2 (PB2/AN2)[/code]

Just a NOTE. Do not try using ADIN while HSERVO2 is enabled. It will conflict with the HSERVO handler. To get the AD values for any of the pins use the HSERVOSTATE function.

Thanks Nathan,

I had it from email from you, but was not sure if could post those details yet.

Kurt

I am hoping to get back to the main code this weekend. Trying to do a few things when I get some spair time and also trying to plan some the code and features. Some of the things I am thinking of trying to do include:

a) Finish the zero offsets. - I think it is partially working, but now trying to decide on how to save the values. Currently it is like my Brat code that saved just the servos that I have in the order I have them. I am thinking about changing it to saving it in servo order with either a full 32 or maybe a start index/count. More on this in a second

b) Get the PS2 and XBEES to be able to communicate properly. Figure out wiring. XBees - will use hserial2.

c) get it to walk - Convert from SSC-32 output to HSERVO2, this will remove the usage of my own serial input/output functions.

d) Make sequences work - this should be fun. I am and will be working on a combination VB and BAP program that can download sequences using EEP files from the PC. Will probably start off stand alone programs. The BAP program(s) will have versions to save to the SSC-32 eeprom or in my case to the Arc32 eeprom. On the Arc will try to write a simple emulator that can take these sequences and run them. Probably will only support start/stop. If I change a) above to save in servo offsets, this would probably make it easier to use the saved offsets to make the sequences work on mutiple robots without changes (or at least I hope so). Depending on how far I take this, I may make the program be able to Append or replace sequences.

Got to run. Suggestions or Comments?

Kurt

As I mentioned in the previous post, I will only get a little time until this weekend to work on this. But I am trying to get a head start…

As I already mentioned in Xans Code thread, I am trying to decide what is the best way to work when to issue the next command. Should I continue to do it by using the timer or should I do it by testing and finding out when the previous hservo command completes.

I started playing with the servo driver. I think I will still leave it with the ServoDriverStart/ServoDriverCommit split, with the start doing as many calculations as possible in the Start phase and then only do the HSERVO command in the commit as to try to get it going as quickly as possible. So far the functions look like:

;[HServo]
awCoxaHServo	var sword(6)
awFemurHServo	var sword(6)
awTibiaHServo	var sword(6)
...
ServoDriverStart:
  ;Update Right Legs
  for LegIndex = 0 to 2
    awCoxaHServo(LegIndex) = (-CoxaAngle1(LegIndex) * StepsPerDegree ) / 10 ; Convert angle to HServo value
    awFemurHServo(LegIndex) = (-FemurAngle1(LegIndex) * StepsPerDegree ) / 10
    awTibiaHServo(LegIndex) = (-TibiaAngle1(LegIndex) * StepsPerDegree ) / 10
  next
  
  ;Update Left Legs
  for LegIndex = 3 to 5
    awCoxaHServo(LegIndex) = (CoxaAngle1(LegIndex) * StepsPerDegree ) / 10
    awFemurHServo(LegIndex) = (FemurAngle1(LegIndex) * StepsPerDegree ) / 10
    awTibiaHServo(LegIndex) = (TibiaAngle1(LegIndex) * StepsPerDegree ) / 10
  next  
  return
  
;--------------------------------------------------------------------
;[Servo Driver Commit] Do the actual HSERVO in the commit phase
ServoDriverCommit:
	hservo [cRFCoxaPin	\	awCoxaHServo(cRF)	\	abs(HServoPos(cRFCoxaPin)-awCoxaHServo(cRF))*20/SSCTime, |
			cRFFemurPin	\	awFemurHServo(cRF)	\	abs(HServoPos(cRFFemurPin)-awFemurHServo(cRF))*20/SSCTime, |
			cRFTibiaPin	\	awTibiaHServo(cRF)	\	abs(HServoPos(cRFTibiaPin)-awTibiaHServo(cRF))*20/SSCTime, |
			cRMCoxaPin	\	awCoxaHServo(cRM)	\	abs(HServoPos(cRMCoxaPin)-awCoxaHServo(cRM))*20/SSCTime, |
			cRMFemurPin	\	awFemurHServo(cRM)	\	abs(HServoPos(cRMFemurPin)-awFemurHServo(cRM))*20/SSCTime, |
			cRMTibiaPin	\	awTibiaHServo(cRM)	\	abs(HServoPos(cRMTibiaPin)-awTibiaHServo(cRM))*20/SSCTime, |
	  		cRRCoxaPin	\	awCoxaHServo(cRR)	\	abs(HServoPos(cRRCoxaPin)-awCoxaHServo(cRR))*20/SSCTime, |
			cRRFemurPin	\	awFemurHServo(cRR)	\	abs(HServoPos(cRRFemurPin)-awFemurHServo(cRR))*20/SSCTime, |
	  		cRRTibiaPin	\	awTibiaHServo(cRR)	\	abs(HServoPos(cRRTibiaPin)-awTibiaHServo(cRR))*20/SSCTime, |
			cLFCoxaPin	\	awCoxaHServo(cLF)	\	abs(HServoPos(cLFCoxaPin)-awCoxaHServo(cLF))*20/SSCTime, |
	  		cLFFemurPin	\	awFemurHServo(cLF)	\	abs(HServoPos(cLFFemurPin)-awFemurHServo(cLF))*20/SSCTime, |
			cLFTibiaPin	\	awTibiaHServo(cLF)	\	abs(HServoPos(cLFTibiaPin)-awTibiaHServo(cLF))*20/SSCTime, |
	  		cLMCoxaPin	\	awCoxaHServo(cLM)	\	abs(HServoPos(cLMCoxaPin)-awCoxaHServo(cLM))*20/SSCTime, |
			cLMFemurPin	\	awFemurHServo(cLM)	\	abs(HServoPos(cLMFemurPin)-awFemurHServo(cLM))*20/SSCTime, |
	  		cLMTibiaPin	\	awTibiaHServo(cLM)	\	abs(HServoPos(cLMTibiaPin)-awTibiaHServo(cLM))*20/SSCTime, |
			cLRCoxaPin	\	awCoxaHServo(cLR)	\	abs(HServoPos(cLRCoxaPin)-awCoxaHServo(cLR))*20/SSCTime, |
	 		cLRFemurPin	\	awFemurHServo(cLR)	\	abs(HServoPos(cLRFemurPin)-awFemurHServo(cLR))*20/SSCTime, |
			cLRTibiaPin	\	awTibiaHServo(cLR)	\	abs(HServoPos(cLRTibiaPin)-awTibiaHServo(cLR))*20/SSCTime]

  PrevSSCTime = SSCTime
return
;--------------------------------------------------------------------
;[FREE SERVOS] Frees all the servos
FreeServos
	hservo [cRFCoxaPin	\	-30000, |
			cRFFemurPin	\	-30000, |
			cRFTibiaPin	\	-30000, |
			cRMCoxaPin	\	-30000, |
			cRMFemurPin	\	-30000, |
			cRMTibiaPin	\	-30000, |
	 		cRRCoxaPin	\	-30000, |
			cRRFemurPin	\	-30000, |
	  		cRRTibiaPin	\	-30000, |
			cLFCoxaPin	\	-30000, |
	  		cLFFemurPin	\	-30000, |
			cLFTibiaPin	\	-30000, |
	  		cLMCoxaPin	\	-30000, |
			cLMFemurPin	\	-30000, |
	  		cLMTibiaPin	\	-30000, |
			cLRCoxaPin	\	-30000, |
	 		cLRFemurPin	\	-30000, |
			cLRTibiaPin	\	-30000]
	return

But I am not happy with the call to HServoPos for each pin in the commit to get the last position. May change the Start to remember the differences and/or compute the per servo times. Suggestions?

Kurt

Hi Kurt,

It looks like you’ve a good plan for what to do. I hope the XBee part are going to be compatible with the XBee DIY remote? :wink:

I’m not sure what you mean by the index/count but I think it would be a good idea to make it more universal.

First - yes the XBEE stuff will be compatible - (I hope). I suspect that the main differences with Arc32 version is that I am going to have to convert all of the HSERIAL stuff to HSERIAL2 stuff. The bright side is I will also be able to convert the debug serout s_out to HSERIAL at a high speed. This is where I really wish that the Basic supported Macros. Sure would be nice for the XBEE stuff if I could simply do things like:

#ifdef BAP28 #define XBeeOutput(...) HSerout(...) #else #define XBeeOutput(...) HSerout2(...) #endif ... ; need to output something XBeeOutput[MyVar]

versus what I will need to do everywhere:

#ifdef BAP28
Hserout[MyVar]
#else
Hserout2[MyVar]
#endif

But you do it the way you got to… Alternatively it sounded like Nathan would consider a way to tell the compiler to swap the HSERIALS, which would help in this case (Will keep my fingers crossed :smiley:)…

As I mentioned, the simplist compatiblity thing would be to store the offsets would be to store them out in servo order like it is on the SSC-32 which stores them as 32 consecutive bytes starting at EEPROM address 32. I could easily do this, which might make it easier to migrate sequences to it. We have 4k bytes of EEPROM so I don’t think this will be a problem.

Back to having fun!
Kurt

I suggest you keep using hservopos for two reasons.

  1. It will work even if you start a new move in the middle of a current move because you are getting the current actual position and not “remembering” what the last position should be.

and

  1. hservopos is a very quick function. It’s grabbing a word value from memory adding a 30000 offset and returning. The fact is hservopos is most likely faster than using your own variable to store what the last position should be because it doesn’t have to determine what kind of variable it is using where if you are grabbing the value from your own variable the routines to do so have to check what kind of variable you are using. You’d need to use some kind of inline asm code to get any faster. I thought the same thing originally when I converted Xan’s Phoenix code but determined it was simply faster and more flexible to use hservopos to calc the speed.

I think I may add an optional argument to hservo though if this is going to be usefull.

eg: hservo time,[servo1\pos1,…,servoN\posN]

If time is specified the speed arguments would be ignored and the speed would be calculated like I did in the phoenix code. Any thoughts on that?

Thanks Nathan,

I understand what you are saying, I will play around with both versions to see if it makes sense to pre-compute the speeds for the next move, before the move ends, in which case I need to save away the previous values to compute them.

Yes I think having an optional speed variable would be great. In that way it more directly emulates the SSC-32

Kurt

This would sure be a great option!

A quick update before I go back out and work in the garden! :frowning:

I have made some progress with my Arc32 based phoenix :smiley: I have the Servo finder now saving the data out for 32 servos in servo order. Now I need to break down and finish zeroing out my own servos and take care of setting the servos in 1 click… (yeah I know :blush: but having fun with code).

I have the phoenix code building for either PS2 or XBEE. I may change the code slightly that allows both to be on at the same time, with giving one priority (ie if I am not in a started state, check both controls and wait until 1 tells us to start…).

I currently have the XBee hooked up using HSERIAL2.
On Aux1 pinout: pins are
Top Row: 2 4 6 8
Bottom Row: 1 3 5 7
Pinouts:
1=SCL
2=SDA
3=TXD2
4=SCK
5=RXD2
6=AN3
7=GND
8=VCC
XBEE using pins 3 5 7 8

Aux2 Header
Inside board row: 2 4 6 8
outside board row: 1 3 5 7
Pinouts:
1=GND
2=P24
3=GND
4=P85
5=GND
6=P86
7=GND
8=P87

I am going to start out trying the PS2 on these 2 4 6 8. Will pick up power at one of the jumpers and gnd on some random gnd pin…

With the XBEE it understands the button presses and it looks like it is trying to walk with the different gaits :smiley:.

Still more testing and probably lots of fixing, but just in case anyone wishes to take a sneak peek.

Zenta I rearranged some of the code from the other xbee code. That is I moved the timer code into the main phoenix_v21.bas and The XBEE support stuff into phoenix_control_diy-xbee.bas. the Timer based serout is not needed. Once I am happy with this will see how to maybe merge code back into other projects.

Hopefully I will get some more time later today.

Kurt

Started playing with some of this yesterday evening. Am first working on how to download. Started playing with two simple apps, one VB and the other runs on the BAP. At first I was simply trying to echo the stuff from the .EEP file down to the BAP but may convert to the XBEE stuff as easier to do the communications at least when using BAP28. But will first still trying to get standard IO working as others may wish to be able to download .EEP files to their SSC-32 or BAP…

Current approach is to now have the VB app understand a little about sequences. That is it will be able to read the first part of the file to know how many sequences there are, then extract the bytes associated with the sequences. It can read the first three bytes of a sequence to compute the size:

Ran into a minor issue with the .EEP file that I have. It appears to have 3 sequences on it and my calculations are that these three sequences take 5524 bytes, which will be hard to fit into a 4K EEPROM :wink:. May have to edit one of them out… Zenta do you have a standard SSC-32 with a 24LC32P EEPROM? Or does yours have a bigger one?

Kurt

The SSC-32 supports up to 24LC256 32k eeproms. :wink:

I see the website does show a smaller one listen in the features list. Sigh… We will fix it.

:open_mouth:
Yep, but I think it now ships with the 4K?

I could also probably make the Arc32 support more than 4K, but that would imply adding on an external I2C EEPROM as it’s a little harder to replace (soldered surface mount)

For now I just chop out one of the sequences for my test…

Kurt