Shop OBEX P1 Docs P2 Docs Learn Events
SX48 and HB25 — Parallax Forums

SX48 and HB25

Bill ChennaultBill Chennault Posts: 1,198
edited 2009-03-14 23:30 in General Discussion
All--

I can't get my SX48 module and an HB25 to like each other! This is one of the HB25s that helped drive Ugly Buster. I have an LED attached to a pin that becomes active after the HB25 returns a 1 to indicate it is ready. The LED lights, so the loop was exited. I am GUESSING that the pulse width numbers are way wrong, since I used them on BS2 and merely moved them to the 20mhz SX48 environment.

The SSR powers up and brings up the 12 volt system and the fans on the HB25s come on. My multimeter tells me 12 volts gets applied to the HB25, also.

Does anyone have any code that uses an HB25 in the SX environment?

Here is mine . . .

Device· SX48, OSCHS1···' Could "OSCHS1" be incorrect?
Freq·20_000_000

·
LED················· Pin···· RB.3······ ' Just turns on a LED for testing.
HB25·············· Pin···· RB.4·······' HB-25 control pin.
Twelve_vdc···Pin···· RE.7····· · ' SSR power pin.

Program Start
Start:
··· High Twelve_vdc
··· PAUSE 1000
··· ' Wait for left HB-25 to power up . . .
··· DO
··· LOOP UNTIL HB25 = 1
··· LOW HB25·························· ' Make I/O Pins Output/Low.
··· PAUSE 20··························· ·' Wait For HB-25 to Initialize.
··· PULSOUT HB25, 750········· ' Stop the motor. (750 works on a BS2. What works on a 20mhz SX48?)
··· PAUSE 20
··· HIGH LED····' Indicator that the HB25 is ready.
·
··· PULSOUT HB25, 870···········' 870 works with a BS2.
··· PAUSE 20
··· END


I wish I knew how to post those neat code blocks everyone uses.

--Bill

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
You are what you write.

Comments

  • RobotWorkshopRobotWorkshop Posts: 2,307
    edited 2009-03-13 20:44
    Hello Bill,

    I have a pair of the HB-25's but I haven't tried them with the SX48 yet. It is my understanding that you can send normal SERVO like signals to them and they should work fine if you treat them like a servo and keep sending pulses.

    My son and I built a small SUMO style robot with a pair of continuous rotation servos that has an SX48 as the brain programmed in SX/B. To drive the servos I use the built-in pair of 16-BIT hardware timers. They are nice since you just setup what pulse you want then forget it until you need to change. Since there hasn't been too many examples for using the 16-bit timers I had hoped to write this up in a way it could be included in the latest SX/B help file. I'm really surprised that I don't see more people using them in their own projects.

    The timers are defined on specific pins on the SX48.

    MotRht VAR RB.6 ' Right Motor speed/direction (PWM)

    MotLft VAR RC.2 ' Left Motor speed/directiom (PWM)

    dutyCycle VAR Word ' Hold the duty cycle

    ' Setup timers

    dutyCycle = 49995 ' Overall cycle should be about 50 Hz
    TIMER1 PRESCALE, 3
    TIMER2 PRESCALE, 3

    After that moving the motors is a piece of cake!

    No movement:

    TIMER1 PWM, 3800, dutyCycle
    or
    TIMER2 PWM, 3800, dutyCycle

    and then the movements can be:

    TIMER1 PWM, 2500, dutyCycle ' Move one direction
    or
    TIMER1 PWM, 5000, dutyCycle ' Move other direction

    Just substitute the TIMER1 with TIMER2 for the other motor!

    I haven't tried this with SX/B v2 yet but hope to soon.

    The timers are nice since they are hardware based and run in the background. This is independent of the main program execution or Interrupts. Some of the timer modes can generate Interrupts and those should be masked or otherwise accounted for within your ISR routine.

    Robert
  • Bill ChennaultBill Chennault Posts: 1,198
    edited 2009-03-13 21:17
    Robert--

    Maybe the HB25s will not work with the SX48 . . . I dunno. However, I do know that if it will, it is the neatest motor controller I have ever run across as it is just as simple to use as my code indicates. It is a true "fire and forget" motor controller. It is not correct to call it a servo, although it will operate in that mode. (I have never done it.)

    I have used them extensively in several projects run by BS2, BS2px24, and BS2p40 microcontrollers. Each different speed microcontroller requires a different pulse width in the PULSOUT command. For example, the BS2 uses a range of from 500 to 1000 with 750 being "neutal" or stop. Numbers larger than 750 make a motor spin in one direction in relation to the size of the number. Numbers smaller than 750 make a motor spin in the other direction in relation to the size of the number with 500 being the fastest in one direction and 1000 being the fastest in the other direction.

    When you switch to a faster processor, a statement in the BS2/HB25 environment such as PULSOUT 0,1000 would cause a motor to spin as fast as the HB25 would drive it in what we usually call "forward." However, the same statement in the BS2px24/HB25 environment wouldn't do anything (I don't think; it has been a while).

    If all else fails, I will have to implement either something like your solution or return to my multi-processor solution using the SX48 as the Master. However, I want to use the SX48/HB25 combination due to the superior features of the SX48 and HB25.

    I appreciate your help!

    --Bill

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    You are what you write.
  • JonnyMacJonnyMac Posts: 9,213
    edited 2009-03-13 21:53
    It will work, you just have to make some code tweaks.

    Hints:
    -- make your control pin an output and low to start -- PULSOUT simply inverts the port status
    -- in SX/B the PULSOUT resolution is 10us, so PULSOUT values of 100 to 200 will give you pulses of 1ms to 2ms

    TIP: Even though SX/B is like PBASIC, you should consult the help file when translating so that these kinds of timing issues don't bite you. SX/B is close to PBASIC, but no a clone.

    Sounds like you're starting to have fun, though!

    Post Edited (JonnyMac) : 3/13/2009 10:02:07 PM GMT
  • Bill ChennaultBill Chennault Posts: 1,198
    edited 2009-03-13 22:09
    JonnyMac--

    Yes, I AM having a lot of fun!

    Ugly Buster's descendent is now·communicating via Bluetooth with VB using a game pad as input. When I solve the HB25 issue--I PRINTED your hints and tips!--I will post a video clip of the machine under remote control.

    --Bill

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    You are what you write.
  • Bill ChennaultBill Chennault Posts: 1,198
    edited 2009-03-14 15:23
    JonnyMac and All--

    A little more help, please?

    Your 100ms to 200ms pulse widths SHOULD be right in the ball park as I read the HB25 documentation. On page 2 it reads . . .

    "Pulse time can be anywhere from 0.8 ms to 2.2 ms."

    Doesn't the simple code below do exactly that?

    Device········ ·SX48, OSCHS1··· ·' Could "OSCHS1" be incorrect?
    Freq·········· ·20_000_000

    LED············ Pin·RB.3
    HB25·········· ·Pin·RB.4··' HB-25 control pin.
    Twelve_vdc····· Pin·RE.7··' SSR power pin.
    idx·············Var·Byte
    Program Start

    output··HB25
    low··HB25

    Start:
    ··· High Twelve_vdc
    ··· PAUSE 1000
    ··· ' Wait for left HB-25 to power up . . .
    ··· DO
    ··· LOOP UNTIL HB25 = 1
    ··· LOW HB25··························· ' Make I/O Pins Output/Low.
    ··· PAUSE 20··························· ' Wait For HB-25 to Initialize.
    ··· PULSOUT HB25, 150·················· ' Stop the motor. (750 works on a BS2. What works on a 20mhz SX48?)
    ··· PAUSE 20
    ····

    ··· for idx = 80 to 220·················' send pulses which are from .8 ms to 2.2 ms (HB25 docs; page 2)
    ··· PULSOUT HB25, idx·············
    ··· PAUSE 20
    ··· High Led
    ··· pause 1000
    ··· low led
    ··· pause 1000
    ··· next
    ··· low led
    ··· END

    What do you think?

    --Bill

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    You are what you write.
  • Bill ChennaultBill Chennault Posts: 1,198
    edited 2009-03-14 15:42
    JonnyMac--

    DECOUPLING CAPACITOR: 0.1uf!

    Your numbers are very close. As I wrote earlier, I calculated they should 80 to 220. I will determine them empirically just to make sure. However, 150 is "neutral" (stop).

    Back in a few with final (or at least more) results!

    Thank you for your help.

    --Bill

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    You are what you write.
  • JonnyMacJonnyMac Posts: 9,213
    edited 2009-03-14 16:18
    A couple hints, Bill:

    1) Don't use PAUSE -- wrap this in a subroutine. Why? Because SX/B compiles keywords in place and every time you use PAUSE (or any other keyword) it it is simply expanded into the Assembly code needed and as PAUSE-ing happens a lot, using the PAUSE keyword more than once can chew through your code space very quickly. See attached.

    2) While not as egregious as PAUSE, don't use HIGH and LOW if a pin is already in an output state, use Led = 0 instead of LOW Led -- this, too, will save a little bit of space.

    [noparse][[/noparse]Edit] Corrected definition of HB25 pin -- needs to start as an input.

    Post Edited (JonnyMac) : 3/14/2009 5:32:01 PM GMT
  • Bill ChennaultBill Chennault Posts: 1,198
    edited 2009-03-14 16:38
    All--

    An SX running at 20mhz controlling a Parallax HB-25 motor controller will successfully use numbers representing PULSOUT pulse widths in the range of 80 to 220. This range, as with any microcontroller driving an HB-25, is split into two parts. I have arbitrarily named the first part "reverse" and the second part "forward." I imagine others do, as well.

    Forward is that part of the 80 - 220 range from 150 to 220, with 150 representing "stop" and 220 representing full speed in the forward direction.

    Reverse is that part of the 80 - 220 range from 150 to 80, with 150 representing "stop" and 80 representing full speed in the reverse direction.

    Here is some sample code written for an SX48 operating at 20mhz controlling an HB-25 . . .



    ' This program is an example of using Robert Doerr's SX48 Module to control a Parallax HB-25 motor controller.
    ' The program employs vital pulse widths in the PULSOUT statements derived from JonnyMac's suggestions.
    ' This program is written strictly for clarity and makes no use of advanced programming techniques that may
    ' make it both far faster and smaller.

    Device··SX48, OSCHS1
    Freq··20_000_000··' This SX48 has a 20mhz resonator.

    LED·········· Pin·RB.3·OUTPUT···········' EDIT: Thank you, JonnyMac for telling me these pins should be set to OUTPUT.
    HB25········· Pin·RB.4······ ·········· ' HB-25 control pin.
    Twelve_vdc·· ·Pin·RE.7·OUTPUT·········· ' SSR power pin.
    idx·········· Var·Byte·············· ·· ' Loop index variable.

    Program Start

    Output··HB25························· · ' Make the SX pin dedicated to the HB25 write pin an output.
    Low·····HB25··························· ' Make the HB25 write pin low.

    Start:
    ··· High Twelve_vdc
    ··· Pause 1000
    ··· ' Wait for the HB-25 to power up . . .
    ··· DO
    ··· LOOP UNTIL HB25 = 1
    ··· LOW HB25··························· ' Make I/O Pins Output/Low.
    ··· Pause 20··························· ' Wait For HB-25 to Initialize.
    ··· Pulsout HB25, 150·················· ' Stop the motor. (750 works on a BS2. What works on a 20mhz SX48?)
    ··· Pause 500························· ·' Convenient pause . . . It could be eliminated.
    ···
    ··· For idx = 150 to 80 step -1··· ···· ' Ramp up using a pulse width of 150 (stop) to 80 (maximum reverse).
    ····· Pulsout HB25, idx·············
    ····· Pause 20··························' Conventional pause to allow the HB25 to "settle."
    ····· Pause 50··························' Arbitrarily chosen additional Pause For slower ramping purposes (they could have been combined).
    ··· Next
    ···
    ··· For idx = 80 to 150··············· ·' Ramp down using a pulse width of 80 (maximum reverse) to 150 (stop).
    ····· Pulsout HB25, idx·············
    ····· Pause 20
    ····· Pause 50
    ··· Next

    ··· Pulsout HB25, 150·················· ' Stop the motor. (A pulse width of 150 will stop the motor.)
    ··· Pause 20··

    ··· For idx = 150 to 220··············· ' Ramp up using a pulse width of 150 (stop) to 220 (maximum Forward).
    ····· Pulsout HB25, idx·············
    ····· Pause 20
    ····· Pause 50
    ··· Next

    ··· For idx = 220 to 150 step -1········' Ramp down using a pulse width of 220 (maximum Forward) to 150 (stop).
    ····· Pulsout HB25, idx·············
    ····· Pause 20
    ····· Pause 50
    ··· Next

    ··· Pulsout HB25, 150·················· ' Stop the motor. (A pulse width of 150 will stop the motor.)
    ··· Pause 20··

    ··· Low Twelve_vdc······················' Shut off the 12vdc system by turning off the solid state relay.
    ··· END

    --Bill

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    You are what you write.

    Post Edited (Bill Chennault) : 3/14/2009 6:35:24 PM GMT
  • Bill ChennaultBill Chennault Posts: 1,198
    edited 2009-03-14 18:31
    All--

    Everyone with an interest should REALLY take a look at JonnyMac's attached code, above. Where I wrote for total clarity, he wrote with total expertise. The difference is amazing: His code is much shorter.

    I can't wait to take a look at it to compare the compiled version of JonnyMac's code to the compiled version of my code. I am certain there will be an astounding difference!

    Thanks, JonnyMac.

    --Bill

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    You are what you write.
  • JonnyMacJonnyMac Posts: 9,213
    edited 2009-03-14 18:33
    I don't understand how my code is any less clear than yours, Bill. You use HB25 instead of RB.4 in your program, so why is aliasing PAUSE as DELAY_MS any less clear? This is rhetorical question, of course, and we can debate it over beers at some future time.

    BTW, make sure that the HB25 pin is initially defined as an INPUT, otherwise the wait-for-it-to-be-ready code won't work.
  • Bill ChennaultBill Chennault Posts: 1,198
    edited 2009-03-14 19:26
    JonnyMac--

    Got'cha on that HB25 input clarification. I THOUGHT that all pins defaulted to INPUT status upon power on or reset?

    I'll take you up on that beer! Obviously, we may need more than one. [noparse]:)[/noparse]

    If YOU think your code is as clear as mine then YOU have already proved my point. YOU are the expert. I am the dummy. Your code cannot be easily read by a dummy.

    Mine can.

    But, your code is vastly better than mine as it takes up far less space. Consider PULSOUT. Every time I use PULSOUT, 23 lines of assembler code are generated. Every time you use your SUB HB25_OUT, 23 lines of assembly code are generated. The vast difference is that I use PULSOUT (in the last code I posted) SEVEN times, thereby generating 7 x 23 = 161 lines of assembly code.·I could re-write your code, using your advanced techniques, to·have the same functionality·as my code and it would use the same 23 lines of assembly every time you called the subroutine. That is a savings of 161 - 23 = 138 lines of code in PULSOUT alone.

    Your code is much BETTER. My code is much CLEARER. As a "student", I hope to advance from my CLEAR (easy to understand) code to your BETTER (less easy to understand) code. That's the best way to learn things: Start simple and advance from there. It is not a contest. If we were teachers, I would be teaching the first, simple·programming classes and you would be teaching one of the last, most advanced programming classes.

    I'll buy the first beer.

    --Dummy Bill

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    You are what you write.
  • JonnyMacJonnyMac Posts: 9,213
    edited 2009-03-14 20:46
    SX/B initially makes all pins inputs but as you've seen in my listing you can change that to output in the PIN definition -- this save steps later.

    I will respectfully disagree with you, a) being a dummy (this tends to be used as an excuse not to do things the "right" way) and, b) my code is more difficult to read (less clear) than yours. In fact, I think mine is a tad easier because I use names that are somewhat self-explanatory. Unless you knew that PAUSE worked in milliseconds you could be confused; DELAY_MS, on the other hand, comes right out and says what it does.

    On these points we will, as gentlemen, agree to disagree -- but agree to have beers when the opportunity presents itself. I prefer clarity of code with minimal comments to simplistic (bad habit in my opinion) code that requires a lot of additional text to explain what it does. The great thing about our country is that we can agree to disagree without wanting to shed blood! tongue.gif

    My [noparse][[/noparse]perhaps maniacal] insistence on teaching things the right way first is that humans have a difficult time breaking habits -- teaching bad programming habits from the beginning is a disservice, in my humble opinion. I believe this to be true because I get a lot of programming help requests from students which, when I give them some code, are often kicked back with, "But I learned it this way." and "this way" was not the best way....

    Hey, as long as we're all having fun, nothing else really matters!
  • Bill ChennaultBill Chennault Posts: 1,198
    edited 2009-03-14 23:17
    JonnyMac--

    Well, if we are going to have beers, then I agree with you. See how easy I am?

    --Bill

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    You are what you write.
  • JonnyMacJonnyMac Posts: 9,213
    edited 2009-03-14 23:30
    My kind of easy!
Sign In or Register to comment.