PowerPod serial mode command set

I copied this from KM6VV.

[code]L1 tile floor
04 FF FB 80 80 80 80 0D

(start) Knee Shift
08 F7 FF 80 80 80 80 0D

(Triangle) button
10 FF EF 80 80 80 80 0D

L2 default
01 FF FE 80 80 80 80 0D

(Circle) button
20 FF DF 80 80 80 80 0D

(Square) Button
80 FF 7F 80 80 80 80 0D

(Cross) Button
40 FF BF 80 80 80 80 0D

R2 Body Low
02 FF FD 80 80 80 80 0D

(select) Lock Legs
01 FE FF 80 80 80 80 0D

R1 tall grass
08 FF F7 80 80 80 80 0D

L3 Cycle Button
02 FD FF 00 00 00 00 0D

UP Button
10 EF FF 80 80 80 80 0D

Down Button
40 BF FF 80 80 80 80 0D

Right Button
20 DF FF 80 80 80 80 0D

Left Button
80 7F FF 80 80 80 80 0D

height down
E8 FF FF 80 80 80 68 0D

Y Speed - 84
A8 FF FF 28 80 80 80 0D

steer right
20 FF FF 80 80 A0 80 0D

steer left
E7 FF F8 80 80 60 80 0D

height up
15 FF FF 80 80 80 95 0D

X Speed - 84
A8 FF FF 80 28 80 80 0D

Y Speed + 36
28 FF FF A8 80 80 80 0D

Neutral 80
00 FF FF 80 80 80 80 0D

R3 (horn) Button
04 FB FF 80 80 80 80 0D

X Speed + 36
28 FF FF 80 A8 80 80 0D

XY speed +
00 FF FF A8 A8 80 80 0D

XY Speed -
00 FF FF 28 28 80 80 0D

XY speed ±
80 FF FF A8 28 80 80 0D

XY Speed -+
80 FF FF 28 A8 80 80 0D

X Speed max
7C FF FF 80 FC 80 80 0D

Y Speed max
7C FF FF FC 80 80 80 0D
[/code]

This is a list of serial commands that work. Is this the only commands that will work?

i.e for x speed max, this makes it walk backward at max speed and for x speed -84 it walks forward at a slower pace, what value in the x speed -84 can i make it the maximum -speed.

Thanks

No, I believe you can choose any value you want for the X and Y speed that off course fit into one byte… The center point is 128 dec (80 hex ). You can go +127 to -127. You will need to recompute the checksum for different values.

This is also tru for ones like height up/down

Kurt

That is exactly the answer i was looking for!!!

So…

in hex

steer right is 20 FF FF 80 80 AO 80 0D which is pretty slow.

So i take it the A0 is the speed in this case so 127 is 7F so if i put this value in its place, how do i calculate the new checksum??

Sorry for being slow on the uptake!

Thanks

PS I have found it in the atom code

CheckSum = DualShock(1) ^ DualShock(2) ^ DualShock(3) ^ |
	DualShock(4) ^ DualShock(5) ^ DualShock(6)

but an example of the steer right i mentioned might help me grasp it a bit more!

If you look at the code, you will see:

[code]main

;SerialQuery
serout S_OUT,i9600,“Rd”] ; ‘Ready’ to recieve data now
serin S_OUT,i9600,100,NoData,[str DualShock(0)\7]

CheckSum = DualShock(1) ^ DualShock(2) ^ DualShock(3) ^ |
	DualShock(4) ^ DualShock(5) ^ DualShock(6)

[/code]
Where ^ is the exclusive or of the two values.

So if you were to put 7F in instead of A0
you would calculate the byte value for the checksum by:
FF ^FF ^ 80^80 ^ 7F ^ 80 which is FF.

So replace the 20 with an FF. Note: On windoes (vista and probably XP) you can use the calcluator in scientific mode to do the calculatations. The one above is simple without it as: the two FFs cancel out as well as the two 80s and so you are left with 7F xor 80, which is FF.

Kurt

Worked a treat. Thank you

:smiley:

From the above i have calculated max steer right…

20 FF FF 80 80 A0 80

TO

7F FF FF 80 80 FF 80

Problem being is it hardly rotates at all, sometimes it makes a half attempt. Or generally stamps its legs up and down
My serial sender is tx at 9600 on Com 5.

Any ideas???

And if i send a command like cross repeatedly AFAP, it takes a good 10 secs between each time

If i send

7F FF FF 80 FF 80 80

this should walk back at max speed like on the power pod serial control demo serial_h3 as the code is there to see!
But when i send this it does it at a tenth of the speed.

As the serial_h3 program works, the serial sender i am using in roborealm is setup exactly the same so im struggling to narrow down the mismatch! Surely they should both be identical speeds as its the same code!!

This program will only properly receive a command when the program is sitting in a serin command as the input is done through bit banging (no hardware support). So if you send the cross button being pressed, it will not process another command until the cross command has completed. If you look at the cross command you will see there is the equivlent of about 18 pauses of 288 or over 5 seconds to complete the command.

As for steering right, have you tried other values to see the differences. For example I think one of the examples showed walk max speed and it had a value I think of FC. Also I can not remember if this is turn or rototate…

Kurt

Yes it is a rotate command.

So the code is delaying me by for example 5 seconds even when im swamping the board with my “cross button” every few ms. I see that now.
Is there anyway to change this so it responds continuously or so at least it looks like it is.

Im only interested in the steer right and left and the walk forward and back commands. As mentioned the serial_h3 demo program in the powerpod tools directory is fantastic when it is set to maximum fwd or back.

I have a program kicking out these hex sequences based on a balls movement, i just need to know how to make it respond in “realish” time like the serial_h3 demo

Any advice please kurte??

If it were me, I would probably, update the input protocol between the two systems. Currently they are very very dependant on each other to get any performance. IE the host program must be ready to output the same command over and over again just to get it to walk. And it must do so at the exact point after it receives the request from the Atom Pro.

In particular the current main loop:

[code]-------------Main loop
main

;SerialQuery
serout S_OUT,i9600,“Rd”] ; ‘Ready’ to recieve data now
serin S_OUT,i9600,100,NoData,[str DualShock(0)\7]

CheckSum = DualShock(1) ^ DualShock(2) ^ DualShock(3) ^ |
	DualShock(4) ^ DualShock(5) ^ DualShock(6)

;serout S_OUT,i9600,[CheckSum]

if CheckSum <> DualShock(0) then
Sound 9,[50\2000]
NoData
DualShock(1) = $FF
DualShock(2) = $FF
for Index = 3 to 6
DualShock(Index) = $80
next
endif
[/code]
So what would I do different? I would probably try to make it where it could start walking at some speed and keep going that way until it gets another command. I would also try to build some form of failsafe in, such that if the communications is lost it would stop reasonably soon. There are many ways of doing this, but if it were me, I would probably try a hack I found when I had my TV brat be able to communicate with my VB app on a PC.

The outline of it would go something like:

The SIN/SOUT lines on the BAP is the IO line that can also be IRQ0, which is interesting. So I would set this up in my program. On the PC if you send a single byte of 0xff it forms one very nice simple pulse, which can be used to trigger the interrupt on the BAP. So here is how I would first try it out:

First I would setup the interrupt on the BAP:


; initialize PC communications, use an Int0
ONINTERRUPT IRQ0INT, HANDLE_S_IN_INT

;==============================================================================
; Initialize communications with PC
; lets setup to get interrupted if we get a rising edge on IRQ0.  
;==============================================================================
	PMR1.bit4 = 1 ; enable pin to IRQ0 interrupt instead of normal I/O
	IEGR1.bit0 = 0 ; Interrupt IRQ0 on falling edge
	enable irq0
	ienr1.bit0 = 1

	enable			; global enable interrupts to be processed

This would go in the init code. I would then have an interrupt handler that would respond with a serin to receive a new command. Here is a simple one from my test program that currently only receives one byte:

;============================================================================== ; We received an interrupt on IRQ0 so something is coming in on the S_IN/S_OUT line. ; ;============================================================================== HANDLE_S_IN_INT: ; disable our own interrupt. PMR1.bit4 = 0 ; restore pin n to normal IO enable ; Allow other interrupts to be processed serin s_in, i9600, [bKeyboardCmd] resume ; and return

In your case I would have it read in a new command into a different buffer than the one that is being processed.

I would then change the main loop, to check to see if a new valid command has been received. This could be done by having your interrupt handler setting a variable to some value. If there is a new valid command, move it into the current command and process it. If no new command continue with the old current command. Maybe increment some variable that says how many times this command has been processed, or decrement some variable. Maybe each command when processed sets what the maximum number of times a command can be repeated before a new command is received. IE maybe you only want to process the cross command once, but the walking or turning command can be repeated 1000 times…

Once the command has been moved into the curernt command, you would need to reneable the IRQ0 interrupt:

[code] elseif (bKeyboardCmd <> 0)
serout S_OUT, i9600, [hex bKeyboardCmd, 13]
bKeyboardCmd = 0
PMR1.bit4 = 1 ; setup to interrupt again on IRQ0

endif

[/code] Again that was from my test program, that currently is incomplete… but it does show setting up IRQ0 again (pmr1.bit4)

Of course the PC side would have to be changed to handle this. But it should be simple: Simply output one byte ff, wait a small amount of time to allow the BAP to get to the serin and then output the new command. Also with this I would expierment with checking to see if my new command is the same as the old command and if so don’t output it again unless some time has elapsed.

Sorry I got to run. I hope this makes some sense.

Kurt

That does appear a bit complicated for my level of ability :smiley:

But im willing to try, i have 7 days till completion.

I see exactly what you are trying to tell me, send, wait, output.

If you could help me incorparate this into my code, i would be forever in your debt!

First hurdle is

; initialize PC communications, use an Int0
ONINTERRUPT IRQ0INT, HANDLE_S_IN_INT
;==============================================================================
; Initialize communications with PC
; lets setup to get interrupted if we get a rising edge on IRQ0.
;==============================================================================
PMR1.bit4 = 1 ; enable pin to IRQ0 interrupt instead of normal I/O
IEGR1.bit0 = 0 ; Interrupt IRQ0 on falling edge
enable irq0
ienr1.bit0 = 1

enable ; global enable interrupts to be processed

how do i incorporate this? Ive found my int section but if i put that in it obviously doesn’t recognise ONINTERRUPT

Hi,

Kurte has a possible solution well covered.

But another possibility would be to use a BUFFERED hardware USART input into the BB2. You’ll have to check the pins, but isn’t at least the receive side of the USART free? A different ‘H’ serin command would be used. You’ll probably have to provide an RS-232 buffer chip as well. But it might be worth it. With my PIC4620 and home-brew board (C code), I used the USART and had no problems.

Alan KM6VV

Yes, you could try Alan’s approach of using the hardware serial port which is on the Atom Pro pins 14 and 15. As he mentioned these have TTL input/output level signals and to connect up to a pc you need this converted to RS-232 level signals. By using some external chip and an appropriate connector. Sparkfun I know sells a little breakout board that does this.

However another way may be to try using the one built onto the SSC-32. I keep meaning to try this, but on a robot that you have a BB2(with atom or pro) communicating to the SSC-32, you typically remove the communication jumpers on the SSC-32 and then run a set of wires (2 or 3). Now in theory you could then maybe add more jumpers from the Pro to the SSC-32 to the other side of those jumpers which should use the conversion chip and the IO connector… Worth a shot.

Assuming you do get the HSERIAL hooked up, you could simply try converting SERIN to HSERIN. You will also need to initilize the HSERIAL system…

Kurt

Hi again,

I did a quick hack up of the Serial version of powerpod, to integrate the stuff I talked about using the interrupt. It compiled, but I have not tested it as I have not set up a PC program to talk to it. So no quarantees on how well it would work…

I Will post the updates in a new thread and maybe we should extract the later parts of this conversation off of this sticky thread so we can simply leave the command set as a sticky. I think the first part of the conversation is good to leave in the sticky as it talks about how to change the commands in the command format.

Kurt

Kurt,

Good call on “borrowing” the RS-232 level converter from the SSC32! I remember you (?) posting on it before.

I think using the ‘H’ serial routines will be a nice improvement for those wishing to do coms.

I also seem to remember a switch setup for using the com on a BB2/SSC32 pair. We might also address that in this thread (where ever it’s put).

I’d also mention that it’s possible to send text along with the SSC32 commands; thus allowing a terminal program to “eavesdrop” and get comments out. The “Debug” might do that also (MBasic?). The SSC32 doesn’t seem to mind.

Let us know how you make out!

Alan KM6VV

wow. too many, thx