Replacing a PWM,Dir Hbridge with a -100, 0, 100 duty cycle Hbridge for Dance bot
I am trying to implement my H-Bridge in place of Hannos dance bot hbridge. His H-bridge uses a two wire connection (PWM,and Dir), while mine uses a three wire connection ( An enable pin , forward pin , and forward inverse pin). I found this object http://obex.parallax.com/objects/455/ on the object exchange Saturday after blowing one of my LMD18200 hbridge. I spent the week trying to do it myself with no luck. I have tested the object with my hbridge and motors and everything is working fine.
If anyone has any idea on how to do this please help.
If anyone has any idea on how to do this please help.
Hannos H-bridge{*******************************************************
* (C) 2010 HannoWare.com *
* Drive 2 motors with h-bridge and read encoder *
* AppletImage=motor.gif *
********************************************************}
CON
_clkmode = xtal1 + pll16x
_xinfreq = 5_000_000
MAXSPEED=4000
motorUpdateHz=200
'pins for h-bridge: 3,4,26,27
'pins for encoder: 12,13
m1Dir= |<3
m1Pwm= |<4
m2Dir= |<26
m2Pwm= |<27
var
long pwm[6] 'structure populated by spin code to set motor direction
obj
vp : "Conduit"
qs:"QuickSample"
pub Main|mvel,pos[2],cmd[2],join,but,frame[400],lastP,ncnt
{testing harness for driving/measuring motors
mvel=motor velocity- only monitoring one encoder
pos=position for two motors
cmd=command power for two motors
join=set to 1 by viewport to tell both motors to move at same speed
but=button clicked in viewport to trigger a speed test
frame=used by quicksample to measure the io port
lastp= last position- used to calculate mvel
ncnt= next cnt, used to control time of loop}
vp.register(qs.sampleINA(@frame,1)) 'sample INA with 1 cog up to 20Mhz
vp.config(string("var:io(bits=[4m1p,3m1r,27m2p,26m2r,12enc,13enc]),mvel,pos1,pos2,m1(min=-5000,max=5000),m2(min=-5000,max=5000),join,but"))
vp.config(string("lsa:view=io,timescale=1ms,trigger=io[30]r"))
vp.config(string("dso:view=[mvel,pos1,pos2,m1,m2],timescale=1s"))
vp.config(string("edit:join(mode=switch),m1(mode=scroll),m2(mode=scroll)"))
vp.config(string("start:dso"))
vp.share(@mvel,@but)
start(@pos)
ncnt:=cnt
if 0 'set to 1 to do speed test
repeat
if but
ncnt:=cnt
pos~
lastP~
repeat motorUpdatehz
Update(cmd[0],cmd[0])
waitcnt(ncnt+=clkfreq/motorUpdateHz)
mvel:=pos-lastP
lastP:=pos
Update(0,0)
but~
repeat
if join
Update(cmd[0],cmd[0])
else
Update(cmd[0],cmd[1])
mvel:=pos-lastP
lastP:=pos
waitcnt(ncnt+=clkfreq/motorUpdateHz)'}}
pub Start(posPtr)
'starts 1 encoder cog and 1 motor cog. initializes positions
setupEncoder(posPtr)
setupMotor
long[posPtr]~
long[posPtr+1]~
pub Update(speed,speed2)|p0,p2,t
'updates motor control with desired speed
p0:=m1pwm+m2pwm
if speed>0
p0+=m1dir
if speed2>0
p0+=m2dir
pwm[0]:=p0
speed:= (||speed) <#MAXSPEED
speed2:= (||speed2) <#MAXSPEED
if speed > speed2
p0-=m2pwm
pwm[1]:=(speed2)+5 '2505
pwm[3]:=(speed-speed2)+5 '2505
pwm[5]:=5+(5000-speed) '15
else
p0-=m1pwm
pwm[1]:=(speed)+5
pwm[3]:=(speed2-speed)+5
pwm[5]:=5+(5000-speed2)
pwm[2]:=p0
pwm[4]:=0
pub setupMotor
pwm[1]:=5
pwm[3]:=5
pwm[5]:=5
diraV:=m1Dir|m1Pwm|m2Dir|m2Pwm
andV:=!diraV
cognew(@doPWM,@pwm)
pub setupEncoder(posPtr)
cognew(@count,posPtr)
dat
org
count
mov m2w,par
add m2w,#4
mov :t,ina 'get ina- 1011
:loop ' 21 instr= 80 cnts=1Ms/sec
and :t,mAEnc 't shows before flank, what A bit where
waitpne :t,mAEnc 'wait for encoder A bits to change
mov :t1,ina
and :t1,mABEnc 't1 shows after flank, what AB bits are
mov :t2,:t1
and :t2,mAEnc
xor :t2,:t ' t2 shows which A bits changed
mov :t,:t1 ' get t ready for next measurement
shr :t2,#12
rcr :t2,#1 wc ' check if A on motor 1 changed
if_nc shr :t1,#14 ' leave both t2, t1 shifted if take jump
if_nc jmp #:doM2 '
shr :t1,#12
rcr :t1,#1 wc ' check if A=1
if_nc shr :t1,#1
if_nc jmp #:doM2
rcr :t1,#1 wc ' check fwd/bkw on motor 1
rdlong m1Cnt,par'added
if_c add m1Cnt,#1
if_nc sub m1Cnt,#1
wrlong m1Cnt,par
'ready to do motor 2, t1 shifted 14, t2 shifted 13
:doM2
shr :t2,#9
rcr :t2,#1 wc ' check if A on motor 2 changed
if_nc jmp #:loop
shr :t1,#8
rcr :t1,#1 wc ' check if a=1
if_nc jmp #:loop
rcr :t1,#1 wc ' check if fwd/bkw on motor 2
rdlong m2cnt,m2w 'added
if_nc add m2Cnt,#1
if_c sub m2Cnt,#1
wrlong m2Cnt,m2w
jmp #:loop
:t2 long 1
:t1 long 1
:t long 1
m2W long 1
mAEnc long 00_0000_0001_0000_0000_0000 '12
mABEnc long 00_0000_0011_0000_0000_0000' 12,13 '00011
m1Cnt long 0
m2Cnt long 0
' outputs pwm to motors
' uses pwm structure to get bit values and duty cycles
org
doPWM or dira,dirav
loop mov ptr,par
mov :i,#3
:duty rdlong orV,ptr 'get value to or
add ptr,#4
mov :t,outa
rdlong timeV,ptr 'get wait
add ptr,#4
and :t,andV
or :t,orV
mov outa,:t
add timeV,cnt
waitcnt timeV,#0
djnz :i,#:duty
jmp #loop
:t long 1
:i long 1
diraV long 1
andV long 1
ptr long 1
orV long 1
timeV long 1

Comments
As you know by now, indentation in part of Spin code. The forum software deleted extra spaces unless you use code tags as shown in the link Circuitsoft provided.
It would help me figure out how to incorporate the other H-bridge driver in you balancing bot code if you archive the code you're using. In order to archive your code you need to first compile it and then in the Propeller Tool select 'File\Archive "file name"\project' which will create a zip file with all the objects used.
Please include any other code you want us to look at as an attachment or as a link (as you did above to the OBEX code).
I know I've modified H-bridges drivers to use different types on enable or direction pins.
You mentioned in your PM you bot was balancing for a while. How long did it balance and could it keep upright if you gave it a little push? That's very cool to have had it balance at all.
but someone let the dog in and it attacked the robot. Blowing the unprotected LMD18200 h bridge.
Hanno breaks the time of the PASM driver into three sections.
The first section is when only one motor is on (the one with a faster speed command).
The second section is when both motors are on at the same time.
The final section of time is the time when both motors are off.
Hanno uses a mask to set the H-bridge control pins high or low. It wasn't very hard to modify his code to add the additional two control pins.
Here's the modified "CON" section of the code. This code replaces the original "CON" section.
I added pins P5 and P25. Just change these numbers to match the pins you're using. Remember not to use P30 or P31 since the communication object uses those pins. It's also a good idea not to use P28 and P29 for things other than I2C devices (EEPROM, real time clock, etc.)
I also needed to change the "setupMotor" section in order to pass the new pin mask to the PASM driver. Here's the new "setupMotor" method (this replaces the previous "setupMotor" method.
I found it interesting that the PASM portion of the driver didn't need to be changed. The biggest changes were made to the "update" method. Here's the new "update" method.
pub Update(speed,speed2)|p0,p2,t 'updates motor control with desired speed p0:=m1pwm+m2pwm ' combined PWM pin mask if speed>0 p0+=forward1 ' if #1 positive speed add direction pin to mask else p0+=backward1 if speed2>0 p0+=forward2 ' if #2 positive speed add direction pin to mask else p0+=backward2 pwm[0]:=p0 ' set both motors on mask to where the PASM portion ' can read it speed:= (||speed) <#MAXSPEED speed2:= (||speed2) <#MAXSPEED if speed > speed2 ' if motor #1 should be on longer than motor #2 p0-=m2pwm ' mask with motor #1 off pwm[1]:=(speed2)+5 '2505 ' time both motor on pwm[3]:=(speed-speed2)+5 '2505 ' time while on motor #1 is on pwm[5]:=5+(5000-speed) '15 ' both motors off time else p0-=m1pwm pwm[1]:=(speed)+5 pwm[3]:=(speed2-speed)+5 pwm[5]:=5+(5000-speed2) pwm[2]:=p0 pwm[4]:=0Since I don't have the objects this program uses handy, I wasn't able to test compile it.
In my ealier post I gave instructions on how to archive your program. It will help us (myself and other who may help in the future) if you use the archive feature so we can be sure we have all the objects needed. (Don't sweat it this time. From your PMs, it sounds like you've been busy at work.)
Attaching code as a file has the advantage of not having errors introduced by the forum software. For example the percent signs for "mAEnc" and "mBAEnc" were removed by the forum software in your earlier post (the percent sign is a common glitch).
I've attached the Spin file for the modified program. Hopefully it does the trick.
I'm pretty excited to have learned these new tricks from Hanno. I think I can reclaim one of the cogs in my Mecanum wheeled robot by using Hanno's PWM technique. Instead of breaking the time into three pieces for two wheels, I can break the time into five pieces and control four motors/wheels.
Let us know how your robots doing. It would be great to see some video of it in action.
I went over the code while drinking my joe, and realized I was somewhat close. But not close enough.
I will post videos as soon as possible. Duane I am sure others will want to build a bot with what you done.
Hanno did an awsome job putting it together. One of the other problems I had was the gyro. The GWS PG-03. For some reason out of the box it did not work. Others have had that problem
I was able to replace it with another gyro (PZ-200, heli gyro) and it workes fine. I plan to replace the hobby gyro with a gyro from the parallax store. That way all will be able to build a dance bot
with parallax parts.
This should be possible but not necessarily simple. I don't think any of the gyros Parallax sells use the same signal protocol as an RC gyro.
Let me know if the H-bridge program works or not. I haven't even compiled it much less tested it.