Converting from a BAP28 to a BAP40

Quick Update:
I edited the first post to put information in, such that S_IN and S_OUT are internally on two different IO pins and as such full duplex. So you have full use of HSERIAL here. Likewise notes on Real time clock (RTC)

Also yesterday, I did hack up a battery connector such that I could plug the N type connector into the Lab board and then a hooked up a power cable from there to the logic portion of the SSC-32. I then downloaded the a fresh copy of phoenix 1.3, changed the timer, changed the dimension information to use with my CHR-3, changed some sbytes to swords and downloaded it to the BAP40, which I have hooked up to the SSC-32 on the hex and I had it walking! :slight_smile:

Kurt

Awesome! 8)

SER_IN and SER_OUT are taken over by HSERIAL? Interesting.

Good work on ferreting out the details of the 40-pin chip!

“Type N” connector? Must not be my RF connector!

Alan KM6VV

Hi Alan,

The Type N Coaxial DC Power Plug from Radio Shack (274-1573) appeared to be close if not the same as the power plug that I had on the Wall Wart from Lynxmotion, which plugs into the board. I do need to tighten up the connection as when the hex walks it sometimes shakes free. I will probably start off with a wire zip… to hold it in place…

Yep having fun playing with this as well as the DIY remote/Mech Brat. But now off to changing oil in the tractor…

Kurt

Hi Kurt,

I can see you’re having fun here. :smiley:

You’ve noticed that the BAP40 runs on a different frequency. Now the first question popped up in my mind was: Is it possible to drive the SSC at full speed (115.2) using the serout command?

I know it’s possible with the HSEROUT command but it’s innterrupt driven and can give some problems in other commands like we found out in the DIY RC project.

Thanks,

Xan

Hi Xan,

Yep, having fun. I am splitting my Robot time between this and the XBee stuff with the DIY. I have a bunch coded now for the DIY, including setting the destination address and the Remote address (to handle multiple people with DIY in the same area). Also coded the ability to only send information when it changes, still need a little on the robot side to handle it. But now is time to start testing/debugging it… But that is a different thread.

I can give it a try! :smiley: We already have a timer interrupt in the phoenix code that you use to keep from outputing a new SSC command until the last one had a chance to complete. Currently I did a straight conversion from using W timer to using Z channel 1, which we still generate timer interrupts. I was thinking of maybe converting this to use a different timer either B1 or the RTC. With these two you can set the increment to be as slow as system clock/8192. So if the slowest move that we wish to time is lets say .2 seconds, then that would take a counter that goes up to: Clock * .2 / 8192 or
20,000,000 * .2 / 8192 = 488+ or lets say 489, which can fit into the 8 bit timer as you can use the overflow flag as a 9th bit.

I hope that makes sense
Kurt

Might be able to run the BAP on this board?

Must have jumpers, as the power/gnd pins would be different from the '877, etc.

Alan KM6VV

Edit: “BAP”

Not sure what the ABP is. This board does run all of the Basic Atoms as well as Basic Atom Pros, Probably most basic Stamps as well. The 40 pin connector has the same width as the other boards, so with some chips you use only some of the pins.

Kurt

Sorry, make that BAP.

Alan KM6VV

Hi Xan and others,

My first attempt of running the SSC-32 at full speed had problems, but when I went back to slower it still did. I think I need to work a little on the wiring. The Type-N plug has a tendancy to wiggle loose and turn off the processor, which makes the robot have problems walking :slight_smile:

Yesterday I spent some time back on the DIY code and was adding a time out timer that if my Brat does not receive any notifications of something new from the remote at will ask for data, as a way to make sure that we did not lose it… For the brat I am going to ask once a second as the brat can not move very far in a second… Later for rover I may make that time much smaller as it might go a long ways in a second!

But while I was looking to add the timer to the DIY I decided some of our current timers are overkill, this may include the one on the phoenix for example. That is we may use WTimer and divide the clock/8 which gives us .5uS resolution. But when we use the clock values we are converting to miliseconds by dividing by 2000. So I am converting the code for the DIY to use TimerA and will be changing my HEX Bap40 to use timerB1. While these are only 8 bit timers, they have the ability to only increment by Clock/8192. So if my math is correct that using this, we only process interrupts something like 7.6 times per second, so almost no overhead!.

In case you are interested in trying it out, the code will look something like:
(Note: not fully tested yet, so use at your own and robots risk :slight_smile: )

...
wTimerCnt				var	word	; used now also in timing of how long since we received a message
wCurTimer				var	word	; Last used 
...

; Timer A init, used for timing of messages and some times for timing code...
TMA = 0	; clock / 8192					; Low resolution clock - used for timeouts...
ONASMINTERRUPT TIMERAINT, HANDLE_TIMERA_ASM 
ENABLE TIMERAINT
gosub ResetTimerAVal

...
gosub GetTimerVal], wCurTimer
	
; BUGBUG:: chould convert timer value to milliseconds by (T * 8192 * 1000)/16000000 or (T * 64)/125 so 1 second is aprox 1953
if wCurTImer > 1953 then
...
;==============================================================================
;[Handle_Timer_asm] - Handle timer A overlfow in assembly language.  Currently only
;used for timings for debuging the speed of the code
;Now used to time how long since we received a message from the remote.
;this is important when we are in the NEW message mode, as we could be hung
;out with the robot walking and no new commands coming in.
;==============================================================================

   BEGINASMSUB 
HANDLE_TIMERA_ASM 
	push.w 	r1                  ; first save away ER1 as we will mess with it. 
	bclr 	#6,@IRR1:8               ; clear the cooresponding bit in the interrupt pending mask 
	mov.w 	@WTIMERCNT:16,r1      ; Add 256 to our counter 
	inc.b 	r1h 
	mov.w 	r1, @WTIMERCNT:16 
	pop.w 	r1 
	rte 
	ENDASMSUB 

;--------------------------------------------------------------------
;[getTimerVal] - Gets the Timer value from our overflow counter as well as the TCA counter.  It
;                makes sure of consistancy. That is it is very posible that 
;                after we grabed the timers value it overflows, before we grab the other part
;                so we check to make sure it is correct and if necesary regrab things.
;==============================================================================

bTimerTmp	var	byte
GetTimerVal:	
	bTimerTmp = WtimerCnt.highbyte
	wTimerCnt.lowbyte = TCA
	if wTimerCnt.highbyte <> bTimerTmp then GetTimerVal	; make sure consistent value
	return wTimerCnt

;--------------------------------------------------------------------
;[ResetTimerAVal] - Resets the timer
;==============================================================================
ResetTimerAVal:
	TCA = 0
	wTimerCnt = 0
	return

Notes in this code. I hard coded the conversion to miliseconds, Earlier I had a conversion constant that we would divide by. Should change this to a multiplier(64) and a diviser (125).

Also I added a simple reset function that zeroed the timer. I found in for example the phoenix code we would grab start and end time and subtract and maybe have to worry about wrap around. That approach would still easily work. If so I would probably convert the timer functions to 32 bits instead of 16.

That is all for now

Kurt

A quick update. I finally got the battery and baud rate to work again back at the slower 38.4K rate, so I tried again at the higher baud rate 115.2K and the legs were spastic and not moving correctly (Yes I did change the baud rate jumpers on the SSC-32 as well :laughing:)

So I hooked up the logic analyzer to see what was being output. I configured the program to have it automatically guess what the baud rate is by looking like. It was able to properly convert the pulses to characters, but it said the baud rate was 123711, if I tell the analyzer that it is 115200 it does not get the characters correct. I will also report this to Nathan.

If I look at the generated baud modes, I think they are setup as maybe 10 clocks per increment, that is:

i38400 generates 0x4034 where the 0x4000 is for the Inverted bit. 0x34 which is 52*10 clocks should be the pulse width which converts to an actual baud rate of 38462 (20,000,000/520)

I115200 generates 0x4011 so 0x11=17 and 17*10 clocks which converts to an actual baud rate of 117647. I could try fudging and maybe mass in 0x4012 and see what I get.

Kurt

Kurt

Hi Kurt,

I’m following your work :wink:, and as usual its very interesting!
Using the second HSERIAL on the new 3687 for maxing the speed to the SSC32 sounds very promising, especially combined with XBEE control! I hope you get it right. :smiley:

Btw, Did you write what board you used for holding the 40 pin BAP?

Keep up the good work!

ARC32 board by chance?

Alan KM6VV

I thought that was a secret… :wink:
I’ve never seen it, just heard of it… :smiling_imp:

I was more thinking that he used a BasicATOM Universal Development Board or something like that.

Thanks Guys,

Arc32??? My lips are sealed :wink:

I am using one of there univeral boards: basicmicro.com/Product.aspx?prod … egoryID=15

I tried ordering in their web page with paypall and ran into lots of problems. Ended up faxing in the order! But am now having fun

Kurt

By ARC-32, do you mean the combination of the SSC-32 and Bot Board / Atom Pro 40 Plus that actually does the servo pulses in hardware to eliminate the serial servo control bottlenecks? Never heard of it. :blush:

Perhaps this will help your hearing a bit…

bribe.jpg

OOPS! Seems like I’ve stumbled into a conspiracy! I haven’t heard of it either, but I like it!

Alan KM6VV

A slight update here. It turns out that on the Pro40 using the the H8/3687 at 20mhz, that using hserial at 115200 will not work very well. That is if you look at their formulas for the hardware serial port, that there would be about an 8.5% error at that baud rate. Here is additional information that I received from Nathan.

Edit: Note: this may also be true with BAP28 running at 16mhz on the H8/3694, where you have hardware baud rates:
Note: numbers will bye N * 32 so the the hardware baud rates are something like

1 = 500,000
2 = 250,000
3 = 166,666
4 = 125,000
5 = 100,000
6 = 83,333
7 = 71,428
8 = 62,500
9 = 55,555
10 = 50,000
11 = 45,454
12 = 41,666
13 = 38,461

So for XBee or SSC-32 baud rate of 38400 we have a real low error rate something like a .15%
for 57600 XBee probably something like 3.7% error
for 115200 again 8.5% error

So for now will leave xbee at 38400…
Kurt

I slight update to this and soon maybe trying out XBee control of my Hex as well…

I decided to prepare the Hex code based off of Xans phoenix 1.3 code to try it with the DIY remote with XBee. Zenta mentioned that he now has some XBees and would like to try it on his hex as well. But we have concerns that the HSERIAL to control the XBee may cause the serouts to the SsC to not work properly. So I decided to try converting the hex code to use my Timer assisted serout functions, so I am now in the process of doing that. I now have the code compiling for both Bap28s and Bap40s. While at it I removed the TimerW interrupts for a timer and on the Bap28 used TimerA and Bap40 TimerB1 where timer increments on clock/8192. Also updated the TASerout function to hopefully work on Bap40. TimerV is on both modules, but had to scale the times for the differences in clock speeds. If it works, I may also be able to drive the SSC-32 at full speed, but we will see…

Since my output function only works with a buffer and size, I had to do some conversion of ServoDriver function. I now calls functions to output each pin and looks something like:

[code]ServoDriver:
;Front Right leg
gosub ServoOutputPin[RFCoxaPin,TOINT(TOFLOAT(-RFCoxaAngle +90)/0.10588238)+650]
gosub ServoOutputPin[RFFemurPin,TOINT(TOFLOAT(-RFFemurAngle+90)/0.10588238)+650]
gosub ServoOutputPin[RFTibiaPin,TOINT(TOFLOAT(-RFTibiaAngle+90)/0.10588238)+650]

;Send
gosub ServoOutputTime[SSCTime]

PrevSSCTime = SSCTime
return

;--------------------------------------------------------------------
;[SOItoAVal] Internal convert the number into ascii in our output buffer…
; Warning:: this uses the variables internal to the two output functions…
SOPin var WORD
SOVal var WORD
SOIndex var WORD
SOBuf var byte(12)

SOIToAVal:

SOPin = 10000	; reuse here...

; find the first digit to output
while (SOPin >= SOVal) and (SOPin > 1)
	SOPin = SOPin / 10
wend

do
	SOBuf(SOIndex) = SOVal/SOPin + "0"
	SOIndex = SOIndex + 1
	SOVal = SOVal // SOPin
	SOPin = SOPin / 10
while (SOPIN > 0)

return

;--------------------------------------------------------------------
;[ServoOutputPin] Output information about one pin
ServoOutputPin[SOPin, SOVal] :
SOBuf(0) = “#”
SOBuf(1) = (SOPin/10) + “0”
SOBuf(2) = (SOPin//10) + “0”
SOBuf(3) = “P”

SOIndex = 4

gosub SOItoAVal		; use our internal function to convert SOVal to ascii starting at SOIndex in SOBuf

gosub TASerout[SSC_OUT, SSC_BAUTE, @SOBuf, SOIndex]

return

;--------------------------------------------------------------------
;[ServoOutputTime] Output Time Value
ServoOutputTime[SOVal] :
SOBuf(0) = “T”
SOIndex = 1
gosub SOIToAVal ; convert our time value to ascii string starting at SOIndex

SOBuf(SOIndex) = 13		; end with CR
	
gosub TASerout[SSC_OUT, SSC_BAUTE, @SOBuf, SOIndex + 1] ; output our string remember to add CR at end!

return

;--------------------------------------------------------------------
;[FREE SERVOS] Frees all the servos
FreeServos
for Index = 0 to 31
gosub ServoOutputPin[Index,0]
next

gosub ServoOutputTime[200]

return

[/code]

Now off to testing it out and then trying out an XBee on it!
Kurt