L9110S H-Bridge breakout board

JSDL

Senior Member
Hi all, I have a question regarding the breakout module found here:

https://www.bananarobotics.com/shop/How-to-use-the-HG7881-(L9110)-Dual-Channel-Motor-Driver-Module

I have followed the coding sample in the Arduino sketch and converted it to Picaxe BASIC, however, I do not seem to be getting the same results. From what I understand, one of the pins (A-1A or B-1A) is used for speed control using a PWM signal, and the other (A-1B or B-1B) is used for direction using a digital output. In addition, on the reverse direction of the motor, it is stated that an inverted duty cycle must be used, hence the reverse FOR loop. Here is the code I wrote:

Code:
pwmout c.3, 150,100

main:

high c.5

for b0= 255 to 0 step - 1
	pwmduty c.3, b0
	sertxd("Forward: ",#b0,cr,lf)
next b0

low c.5

for b0= 0 to 255
	pwmduty c.3, b0
	sertxd("Reverse: ",#b0,cr,lf)
next b0

goto main
What happens with this code is that the motor turns in one direction from slow to fast, but for the reverse cycle, it just stalls, then starts over again once the reverse loop completes. I managed to get it working using the following code:

Code:
main:

dirsC=%11110111

pwmout c.5, 150,100

for b0= 255 to 0 step -1
	pwmduty c.5, b0
	sertxd("Forward: ",#b0,cr,lf)
next b0

pwmout c.3, 150,100

pause 100

dirsC=%11011111 ' changing pin 5 to input worked

for b0= 0 to 255
	pwmduty c.3, b0
	sertxd("Reverse: ",#b0,cr,lf)
next b0


goto main
However I am unsure as to why this works by turning pinC.3 into an input on one cycle, then turning pinc.5 into an input on the reverse cycle. Could anybody kindly explain why the first code, which seems be exactly what was written in the Arduino sketch in the link provided, works. Am I overlooking something in my first code posting? Any help would be appreciated. Thanks in advance.
 

hippy

Technical Support
Staff member
It looks like you code should work. Have you tried it without tryiing to control the speed ... ?

Code:
Do
  High C.3 : Low  C.5 : Pause 1000 ; One second one way
  Low  C.3 : High C.5 : Pause 1000 ; One second the other way
  Low  C.3 : Low  C.5 : Pause 2000 ; Two seconds stopped
Loop
That should identify if there is a pin name error, a wiring fault, or a faulty module.
 

hippy

Technical Support
Staff member
In your first code snippet; simply going from 0 to 255 and 255 to 0 does not actually 'invert the duty cycle'. It would only do that with PWMOUT period of 63. That might be the problem there.

The second works because you switch pins you are driving PWM on and perhaps only by luck as that's done in a hodge-podge way.
 

hippy

Technical Support
Staff member
Untested on real hardware but this should increase speed in one direction and then decrease it. Increase speed in reverse and then decrease it -

Code:
Symbol PWM_PERIOD = 150

Symbol A_IA       = C.3
Symbol A_IB       = C.5

Symbol reserveW0  = w0 ; b1:b0
Symbol speed      = b2

Initialise:
  Low    A_IB
  PwmOut A_IA, PWM_PERIOD, 0

Main:
  Do
    ; Forward
    For speed = 0 To 255
      Gosub GoForward
      Pause 10
    Next
    For speed = 255 To 0 Step -1
      Gosub GoForward
      Pause 10
    Next
    ; Backward
    For speed = 0 To 255
      Gosub GoBackward
      Pause 10
    Next
    For speed = 255 To 0 Step -1
      Gosub GoBackward
      Pause 10
    Next
  Loop

GoForward:
  Low     A_IB
  PwmDuty A_IA, speed
  Return

GoBackward:
  w0 = PWM_PERIOD * 4 - speed
  High    A_IB
  PwmDuty A_IA, w0  
  Return
Swap the 'GoForward:' and 'GoBackward:' labels if the direction is not how you want it.
 

AllyCat

Senior Member
Hi,

Might it be that the dirsC is turning C.5 into an Output, more than C.3 into an Input, etc.?

Which PICaxe chip are you using? Also try PWMOUT rather than PWMDUTY, which is a remarkably "complex" command (see how many bytes it adds to the code size). I did once encounter a minor bug with PWM on a 20M2 (specifically), but that was actually with PWMOUT, whilst the equivalent PWMDUTY command worked correctly.

EDIT: Ah I think hippy has spotted it. I had this niggling feeling that step -1 was not the same as inverting the PWM, but couldn't put my finger (or brain) on it.

Cheers, Alan.
 

JSDL

Senior Member
just out of curiosity, why would an inverted duty cycle only work with a PWMOUT period of 63?
 

JSDL

Senior Member
Hi Hippy, tried this code but does not work in either direction, sounds like it wants to turn as I hear a gradually increasing "humming" noise as the loop increases
 

hippy

Technical Support
Staff member
just out of curiosity, why would an inverted duty cycle only work with a PWMOUT period of 63?
Because (ish) that's the only period which would have a duty value range of 0 to 255 representing 0% to 100%.

A 0% to 100% duty when inverted becomes 100% to 0%

For PWMOUT period of 150 that 0% to 100% is a duty of 0 to 600, and needs to be 600 to 0 when inverted.

You can't therefore invert 0 to 255 to be 255 to 0.

It has to be 0 to 255 becomes (600-0) to (600-255).
 

hippy

Technical Support
Staff member
Hi Hippy, tried this code but does not work in either direction, sounds like it wants to turn as I hear a gradually increasing "humming" noise as the loop increases
Note quite sure what is going on there. It would be worth trying the code in Post #2 to see if that works, to rule out any hardware issues.

If that works then try -

Code:
Do
  High C.3 : PwmOut C.5, 150, 300 : Pause 1000 ; One second one way
  Low  C.3 : PwmOut C.5, 150, 300 : Pause 1000 ; One second the other way
  Low  C.3 : PwmOut C.5, 150,   0 : Pause 2000 ; Two seconds stopped
Loop
 

JSDL

Senior Member
got it working with this code:

Code:
symbol PWM_PERIOD=150
pwmout c.2, PWM_PERIOD,0	'initialize PWM

symbol speed=b0
symbol INVERTED_DUTY=w2

main:

high c.4

for speed= 255 to 0 step - 1
	pwmduty c.2,speed
	sertxd("Forward: ",#speed,cr,lf)
next speed

low c.4

for speed= 0 to 255
	w2=PWM_PERIOD * 4 - speed
	pwmduty c.2, INVERTED_DUTY
	sertxd("Reverse: ",#speed,cr,lf)
next speed

goto main
Thanks everyone for your input, it helped me to get this working!
 
Top