Asked
— Edited
For Dave and Richard and anyone else who is interested, here is fully working and tested code for using the Kangaroo (with bi-directional comms) via the UART on the V4 with encoder feedback.
I am still quite new with EZ scripting so the code may not be as elegant as I would like, I could not find an ASCII to decimal function in ARC so I had to write a block of code to do this DJ maybe I am missing something here?
Anyway I think this does show how fantastic and versatile the V4 is, well done DJ and team!
Tony
# -------------------------------------------------
# Name : V4_Roo_serial
# Author : Tony Ellis
# Date : 01/07/2014
# Version : 1.0
# -------------------------------------------------
definearray($byte,10)
$wheel_turn=63890
$dly=50
$FLAG=0
uartinit(0,0,19200) # initalise UART
# ***** Initalise Kangaroo
uartwrite(0,0,"D,start",13) # drive channel start
uartwrite(0,0,"T,start",13) # turn channel start
uartwrite(0,0,"T,p0",13) # this is also needed at start
#goto(START)
$val=2*$wheel_turn # load position
$COMM_CHR="DF3" # D=drive channel - F=move forward - 3=speed 3
goto(INC_POS)
halt()
:START
$val=$wheel_turn-500
$position=0
$unit=round($val/8)
$str="4000"
$x=1
goto(RAMP)
$str="7000"
$x=2
goto(RAMP)
$str="10000"
$x=3
goto(RAMP)
$str="7500"
$x=6
goto(RAMP)
$str="5500"
$x=7
goto(RAMP)
$str="2500"
$x=8
goto(RAMP)
uartwrite(0,0,"D,s0",13)
halt()
:RAMP
uartwrite(0,0,"D,s"+$str,13)
$v=$unit*$x
REPEATUNTIL($position>$v)
goto(GET_POS)
ENDREPEATUNTIL
print("position="+$position)
print("speed="+$str)
return
# -------------------------------------------------
# Subroutines
# ***** POSITION commands *****
:INC_POS # increment position subroutine
$str=tostring($val) # convert variable to string
$COMM="pi" # determine direction
IF (getcharat($COMM_CHR,1)="R")
$COMM="pi-"
ENDIF
goto(SEND_DATA)
goto(GET_POS)
REPEATUNTIL($FLAG=1)
goto(GET_POS)
ENDREPEATUNTIL
print("POSITION = "+$position)
return
:GET_POS # get current position subroutine
uartwrite(0,0,"D,getp",13)
sleep($dly)
goto(GET_DATA)
print($position)
return
# -------------------------------------------------
:SEND_DATA
$M_SPEED=(getbyteat($COMM_CHR,2)-48)*1200
$string=(getcharat($COMM_CHR,0)+","+$COMM+$str+"s"+$M_SPEED) # build data packet
uartwrite(0,0,$string,13) # send packet
sleep($dly) # delay required
return
# -------------------------------------------------
:GET_DATA
$num_bytes=uartavailable(0,0)
$data=uartread(0,0,$num_bytes)
$byte1=getbyteat($data,0) # byte 1 = command
$byte2=getbyteat($data,1) # byte 2 = ","
$byte3=getbyteat($data,2) # byte 3 = command completed status
# ***** Convert ASCII digits to decimal number
$total=0
$multiplier=1
$x=$num_bytes-2
REPEATUNTIL($x=3)#$num_bytes-7)
$byte[$x]=getbyteat($data,($x-1))
$byte[$x]=($byte[$x]-48)*$multiplier
$total=$total+$byte[$x]
$multiplier=$multiplier*10
$x--
ENDREPEATUNTIL
# ***** Determine byte 3
# $FLAG=0
IF ($byte3=80)
$FLAG=1 # "P" returned so move completed
ELSEIF ($byte3=112)
$FLAG=2 # lowercase "p" so move not completed
ELSEIF ($byte3=83)
$FLAG=3 # "S" returned so speed reached
ELSEIF ($byte3=115)
$FLAG=4 # lowercase "s" so still accelerating
ENDIF
IF ($FLAG<3)
$position=$total
ELSEIF ($FLAG>2)
$speed=$total
ENDIF
return
That is strange something in the UBB code is forcing a "click to watch video" piece of text in my listing? That part should read as below.
:RAMP uartwrite(0,0,"D,s"+$str,13) $v=$unit*$x
Thats even odder I cannot write that line of code down even outside the UBB code, it always converts it to that text note?
As I cannot give the line of code here, anyone that wants a full listing just send me a email.
Tony
Tony,
When I find the forum takes over the code I post it to pastebin.com or upload a project to the cloud which can then be merged in to another project easily.
I only wish I could try this out, one day I'll get there with a sabertooth and kangaroo though (too many other things pushing it to the side currently)
Hi @Tony(Toymaker),
This is grand news! Thanks so much for taking the time to do this. You have no idea how much I appreciate your help. Very timely also as I was going to spend this weekend trying to get the script worked out to turn my motor to points and add ramping. You probably saw my post yesterday evening asking for help getting the right script commands to get the Kangaroo to return it's position information. With the understanding of what I was doing wrong with that script and your work I truly think I can get ramping to work on my motor (I had the wrong board numbered in the command as I'm using two EZB's and then one I want to operate is Board 1 not 0).
I've just quickly looked over your script above and it looks like a work of art. I do understand I need to change a few values to get it to work as needed for me. Things like what board I want to initiate and the channel names. Looks like you changed the Kangaroo channel names from 1 and 2 to T and D. I'm sure I'll have to make a few other tweaks but we'll see. There is a bunch of other commands I have no earthly idea how they work or do (like definearray) but that's why you decided to help and while working this through it's how I learn.
I will however need to see that one command that won't show properly in this thread. I wish they would work on fixing this annoyance. Hopefully when they get some extra time it will happen. I'll send you a private e-mail as requested.
Again, Thanks so much!
I would love to have a copy
I do not have Tony's email addy.
Old-FireFighter138(at)neo(dot)rr(dot)com
Please & Thankyou
Dave, yes I saw your post and that triggered me into posting the script.
I have sent you the whole ARC project so you can play with it all.
Some things to remember
Your wheel turn value would will be lower (probably half) as you are using the motors with a different gearbox,
The baud rate I use is 19200, you may want to change this to 9600
The "D" (Drive) and "T" (Turn) channels are because I am using the Kangaroo in mixed mode for 2 motor locomotion, for single motors you will need to change this to "1" or "2" etc
You will need to autotune the Kangaroo first, I use the DEscribe software where it is much easier to do than by using the small push switch on the board. You can also change the baud rate here.
The definearray is for the byte array that is required in the ASCII to decimal subroutine.
There should be everything you need in that script to do what you want.
Tony
Thanks again Tony! You've been an unbelievable assist and help. I hope I haven't been to much of a pain.
I have been into and used the DEscribe software and am fairly familiar with it. It does work great and I do like using it to tune instead of the button pushing method. However it's less then intuitive and user friendly for a Techno-dud like me but I seem to muddle through with persistence and little help from my friends.
Well @Tony, I suppose you kinda knew this was going to happen but I'm lost in your script and cant quite wrap my head around it. blush I feel real bad as you it looks like you put a lot of work into this and a boob like me cant understand it. tired
I kinda see what your doing here and maybe it my application but I'm sure it's just my lack of experience with code. After going through it a few times and changing the things you told me I just cant get it to do anything but loop. I went through the script but lost your logic path about half way through.
It looks like this script is set up to drive a couple wheels at different speeds for turning? Could you take a look at the printout below I copied from the script console window and see if you notice anything. It should be everything from start-up to the second loop. As I said it just keeps looping till I manually stop it and the motor does not turn.
How does this script get the position value I want to stop at and the speed I want it to max out at? For example after tuning the Kangaroo it tells me my position spread is between 0 and 157307 and speeds between 0 and 22000. Lets say i want only one motor (channel 1) to go to position 79440 at a speed of 10000. How do I get that into this script?
BTW, I do see the yellow LED flash on the Kangaroo when it receives the "Start" commands so I know it's receiving the code.
Thanks!
here's the printout
Here's the code you wrote with the changes I made:
Dave, because I am using the Kangaroo for 2 motor locomotion I have only tested it in "mixed mode", I have not tried it in "independent mode" (single motor). Have you got 2 motor units? If so could you try my original code in mixed mode to see if you can get that working, and then we can work from there.
If not, I will set up my system to independent mode and try here. But please bear with me, I am redesigning my multi-million selling toy product "Cube World" Cube World first US TV advert to bring it back to the market after 7 years and its taking most of my time! But I will try to make some time later this week and maybe do a video which may help.
Don't worry Dave working together, we will get your rig working, its just a matter of time.
My example shows 2 ways of using the Kangaroo subroutines you need to enable the "goto(START)" line to use the second.
To explain the first
$val holds the position that you want to get to, in the example it is 2 complete wheel revolutions
$COMM_CHR is a string that holds a simple way that I devised to build a motion command Example "DF3" D = drive channel it could also be T for turn channel (in mixed mode) F = move forward it could also be R for reverse 3 = speed 3 I use speeds 0 to 9 this gets converted to actual speed ($M_SPEED) in the first line of the SEND_DATA subroutine So "TR9" would give TURN, REVERSE, SPEED 9
Goto(INC_POS) is go to the increment position subroutine (and other nested subroutines) where everything gets converted into detail that the Kangaroo is looking for.
The second example shows a different way of using the subroutines
Your listing (first one numbered) does not seem to set $FLAG (lines 123 etc) this is critical (ie FLAG=1) as it allows a return from the INC_POS routine, without this flag the REPEATUNTIL routine will go on for ever.
Tony