Asked — Edited
Resolved Resolved by DJ Sures!

H-Bridge Dc Motor Movement Script

I'm looking to see if I'm scripting correct.

I'm doing the power train to a BB-9. The way the drive is set up is it uses multiple DC planetary motors each with a single motor h-bridge. The motors are dome spin, dome tilt, ball rolling and motor tilt, which causes it to turn and a spin which lets it spin in place to face a different direction.

Since I can only add 1 h-bridge control, I want to use that for the ball rolling and motor tilt, so the other motor controls I'm creating scripts.

Am I doing this correct? Or is there an easier way?

Dome spin is pretty simple since it's a 360 degrees with no stops.


:start
goto(left)
goto(Start)

: Left
Set(d4, on)
Set(d5, off)
Return()
Halt()

I have a second script to spin it right, a third script to stop the spin and a fourth script that centers the dome to a specified ADC reading. If the spinning script is running, running the stop or centering script won't work unless I add ScriptStop to their script, is this correct?


ControlCommand("Script Manager", ScriptStop, "Dome Spin Right")
ControlCommand("Script Manager", ScriptStop, "Dome Spin Left")
:start
goto( Stop)
goto(Start)

: Stop
Set(d4, off)
Set(d5, off)
Halt()

My last question deals with the dome tilting front or back, it does have a range it can go. From my ADC readings, 93 is center, 139 and 38 are the max ranges front and back. Here is one of the tilt direction scripts, using this, will it stop correctly when it reaches the max 139?


$adcSpecified = 139
:start

$adcCurrent = GetADC(adc2)

if ($adcCurrent < $adcSpecified)
goto( front )
endif
if ($adcCurrent = $adcspecified)
goto( Stop)
endif
goto(Start)

: Front
Set(d1, on)
Set(d2, off)
Return()

: Stop
Set(d1, off)
Set(d2, off)
Halt()

This will also have 4 scripts, front, back, stop and center. Also I have 5v going to the EZ-B, D0 and D3 connect to the vcc and ground to the h-bridge and the signal from them I have it connecting to the PWM inputs of the H-Bridges which will be a question for later!

Thanks I added a video of the dome spin test.


ARC Pro

Upgrade to ARC Pro

Your robot can be more than a simple automated machine with the power of ARC Pro!

#2  

The custom command would work for movement, but I can only add one of them, I still need to use scripts for dome control, which is in addition to movement, that's why the scripts.

I have for movement- forward, reverse, left and right, which the h-bridge control will work for movement.

I also have in addition to movement- Dome spin, dome tilt, and body spin, which is the scripting I'm working on first.

The movement will be last because I still need a DC motor that is out of stock, once I get that I can assemble the drive completely.

Thanks.

PRO
Synthiam
#5  

okay awesome - as you continue reading with my code review, i highly recommend using Blockly and watching episodes of The Robot Program. Read the programs you write like a book or food recipe. If you have ever cooked a meal from a food recipe, programming is EXACTLY the same, serious.

A recipe contains step by step instructions to do something. So is programming. If you do randomly skip around the instructions, the recipe won't turn out. The same is with programming.

Read each line of your program and think about it for a second. If you were to ask someone to get you a glass of water, you're not going to ask them to get the water BEFORE the glass. Does that make sense? The order you do things is important.

I have some recommendations with this...


:start
goto(left)
goto(Start)

: Left
Set(d4, on)
Set(d5, off)
Return()
Halt()

It appears the code jumps around a lot, which uses a significant amount of processor resources. Also, the logic is really difficult to understand. The HALT() is never actually executed, because Return() is called before it. Also, the goto(Start) and goto(left) is a loop within a loop. It can be rewritten like this...


:start
Set(d4, on)
Set(d5, off)
goto(start)

I highly recommend to learn programming by watching The Robot Program and using Blockly. Here is the code created in Blockly, which visually shows you what a loop looks like...

User-inserted image

Now, I'm struggling with this piece of a code, bare with me. It looks similar to the first piece of code you posted, but there's ControlCommand() and a partial loop within a loop.


ControlCommand(&quot;Script Manager&quot;, ScriptStop, &quot;Dome Spin Right&quot;)
ControlCommand(&quot;Script Manager&quot;, ScriptStop, &quot;Dome Spin Left&quot;)
:start
goto( Stop)
goto(Start)

: Stop
Set(d4, off)
Set(d5, off)
Halt()

I'm not sure what it's doing, but i recommend writing it like this by removing the loops, because the loop didn't actually do anything in the original snippet, due to the Halt()


ControlCommand(&quot;Script Manager&quot;, ScriptStop, &quot;Dome Spin Right&quot;)
ControlCommand(&quot;Script Manager&quot;, ScriptStop, &quot;Dome Spin Left&quot;)
Set(d4, off)
Set(d5, off)

Lastly, let's take a look at this - which is actually pretty close to making sense and almost works, but not quite...


$adcSpecified = 139
:start

$adcCurrent = GetADC(adc2)

if ($adcCurrent &lt; $adcSpecified)
goto( front )
endif
if ($adcCurrent = $adcspecified)
goto( Stop)
endif
goto(Start)

: Front
Set(d1, on)
Set(d2, off)
Return()

: Stop
Set(d1, off)
Set(d2, off)
Halt()

Here is what i recommend, by using a RANGE for the ADC, since ADC is never perfect. Also, there are a lot of "goto" for no reason. So i changed the code to be more effective...


$adcSpecified = 139
:start

$adcCurrent = GetADC(adc2)

# If the adc value is within a range, stop the script
if ($adcCurrent &gt; $adcSpecified - 2 and $adcCurrent &lt; $adcSpecified + 2)

  Set(d1, off)
  Set(d2, off)

  halt()

elseif ($adcCurrent &lt; $adcSpecified)

  Set(d1, on)
  Set(d2, off)

elseif ($adcCurrent &gt; $adcSpecified)

  # I am only guessing here, but you want to reverse the direction?
  Set(d1, off)
  Set(d2, on)

endif

goto(start)

#6  

Great, thanks!

I had it more complicated and using up more resources than needed.

PRO
Synthiam
#7  

If you’d like, feel free to post the project in this thread and I can take a peak at it? See if there’s any pointers I have

#8  

OK, I'll attach it. I tested it and it works great, sort of.

Sometimes the head tilt goes past the stop point and slams into the frame. I have to turn the PWM to zero to stop it. It's intermittent. The other is the dome centering, it jerks back and forth and doesn't stop.

I have the h-Bridge loaded for forward and revese and it works fine, but I think I'll have to replace it with custom movement panel. Forward and reverse are just that, but the left and right, actually tilts the whole body and uses a pot to determine limits on left right and centering, like the dome tilt.

I'm waiting on a motor so I can finish assemble and then do the body tilt.

BB-9eEZB.EZB

Thanks, Dan

PRO
Synthiam
#9  

What you're trying to make is a servo. You'd like the motor to spin into a position based on the POT reading by GetADC(). This is actually quite simple process, read below...

I have tips...

1. ALL SCRIPTS ARE LOOPING There's no reason for the scripts to loop. Looping a STOP or LEFT or RIGHT, etc... will continually send the SET() commands hundreds of times per second, if not more. The SET() command only needs to be sent ONCE for it to register. Once you send a SET(), it's done, there's no need to repeat.

Remove the LOOP on all of those scripts that only SET() in a loop, such as..

  • dome spin stop
  • dome spin left
  • dome spin right

In fact, I don't know why these scripts exist at all. They have no bounds checking. They just set digital ports for moving a motor in one direction, for ever. I think these three scripts should be deleted.

2. REMOVE or PAUSE ADC GRAPH CONTROLS There are 9 ADC graph controls, not including the GETADC() in the scripts. That's a lot of querying the exact same data over, which is going to interfere with the scripts. If you PAUSE the controls, the scripts will run much faster and reliable. The controls are querying ADC over and over, which is taking priority from the GETADC()

Think of it as having two people asking one person to do the same thing. You have the control asking for GETADC(), then a millisecond later the script is asking for GETADC().

3. Dome Spin Center - WHY IS THERE CONTROLCOMMAND() There are two ControlCommand() to tell the dome to move left AND right at the same time, but that doesn't make any sense... Remove them from this script. The script starts and right away tells two other scripts to do completely opposite things, in loops for ever. Why?

You cannot have a motor spin left and right at the same time. And you certainly can't do that in a loop.

Dome Spin Center should only look exactly like this...


$adcSpecified = 238

:start

$adcCurrent = GetADC(adc1)

# If the adc value is within a range, stop the script
 if ($adcCurrent &gt; $adcSpecified - 2 and $adcCurrent &lt; $adcSpecified + 2)

  Set(d4, off)
  Set(d5, off)

  halt()

elseif ($adcCurrent &lt; $adcSpecified)

  Set(d4, on)
  Set(d5, off)

elseif ($adcCurrent &gt; $adcSpecified)

  Set(d4, off)
  Set(d5, on)

endif

goto(start)

4. DOME TILT FRONT & BACK & CENTER MISSING BOTH DIRECTION MOVEMENTS The Dome Spin Center script that i edited in the above response checks for a range AND moves the dome in two different directions based. This way the motor knows how to actually center. Otherwise, it'll just spin one direction for ever.

Dome Tilt Front should look like this....


$adcSpecified = 115
:start

$adcCurrent = GetADC(adc2)

# If the adc value is within a range, stop the script
if ($adcCurrent &gt; $adcSpecified - 2 and $adcCurrent &lt; $adcSpecified + 2)

  Set(d1, off)
  Set(d2, off)

  halt()

elseif ($adcCurrent &lt; $adcSpecified)

  Set(d1, off)
  Set(d2, on)

elseif ($adcCurrent &gt; $adcSpecified)

  Set(d1, on)
  Set(d2, off)

endif

goto(start)

Dome Tilt Back should look like this...


$adcSpecified = 75
:start

$adcCurrent = GetADC(adc2)

# If the adc value is within a range, stop the script
if ($adcCurrent &gt; $adcSpecified - 2 and $adcCurrent &lt; $adcSpecified + 2)

  Set(d1, off)
  Set(d2, off)

  halt()

elseif ($adcCurrent &gt; $adcSpecified)

  Set(d1, on)
  Set(d2, off)

elseif ($adcCurrent &lt; $adcSpecified)

  Set(d1, off)
  Set(d2, on)

endif

goto(start)

Dome Tilt Center should look like this...


$adcSpecified = 93
:start

$adcCurrent = GetADC(adc2)

# If the adc value is within a range, stop the script
if ($adcCurrent &gt; $adcSpecified - 2 and $adcCurrent &lt; $adcSpecified + 2)

  Set(d1, off)
  Set(d2, off)

  halt()

elseif ($adcCurrent &lt; $adcSpecified)

 Set(d1, off)
 Set(d2, on)

elseif ($adcCurrent &gt; $adcSpecified)

  # I am only guessing here, but you want to reverse the direction?
  Set(d1, on)
  Set(d2, off)

endif

goto(start)

#10  

Thanks DJ Sures!

OK, I added a custom movement, forward and reverse are just setting the digital ports on/off. For the turning, the body tilts side to side and has a pot for left and right tilt end stops. The dome centering worked fine, then it would start to jerk back and forth after testing it a few times, so I'm unsure if it was just a hiccup.

I have a question, I'm going to add a remote joystick to control it down the road. The body tilt stops left or right and trying to center it, I had to hit the stop button about where I thought center was. Is there a way to have it go back to center when the left or right is released? I don't know if I'm over simplifying it, but add something like the centering script of the dome tilt to the stop segment of the body tilt to center the body when the body tilt is stopped?

I added the project and a video of it. You can see it rocking, it's basically on a 10lb bowl with a lazy susan and one last motor that will allow it to spin on it's axis. I still have to hook it up and attach my last h-bridge to control it. I just need to find a spot to mount it.

I need to cleanup the wiring and zip tie them up and I want to hot glue some of the plugs on the hbridges so the don't come free. I have a few body panels left to print and then I can start the assembly!

BB-9eEZB.EZB

PRO
Synthiam
#11  

The motor for tilt when turning - how many volts are you giving it? What amperage is the battery

#12  

It's getting 12v and it's a 20000mAh battery.
It says Current: 400A (Start) 800A (Peak) i have 20 amp fuses on the motors.

#13  

I have a couple more questions.

I've attached my project.

I have my joystick and it controls the movement with joystick 1. When it stops I have the left or right tilt go to center. But when moving forward or backward and I go left or right, I can't figure out how to center the tilt while still moving.

I have all the buttons on the joystick set and they work fine, but I still have the head tilt motions left. I would like to use joystick 2 for it, but it only allows setting ports, no scripting. I tried to see if I could create a virtual servo then add a script to it, but couldn't figure that out if that's the way to go.

Thanks

BB-9eEZB.EZB