B4R Tutorial Servo motor and Arduino

Thanks to @Erel and the new rservo library (Beta#7), we've access to servo motors.

Servos are a motor type that allows for precise control of angular or linear position, velocity and acceleration (wiki);there're various types with different characteristics (torque, velocity, etc)

There're very cheap models like this one and usually used on actuators, robotic arms, etc..

upload_2016-4-20_15-58-24.png
upload_2016-4-20_15-59-19.png


upload_2016-4-20_16-23-9.png

B4X:
Sub Process_Globals
    'These global variables will be declared once when the application starts.
    'Public variables can be accessed from all modules.
    Public Serial1 As Serial
    Public servo1 As Servo
    Public pinservo As Pin
    Public Timer1 As Timer
    Public angleservo As UInt
    Public upangle As Boolean

End Sub

Private Sub AppStart
    Serial1.Initialize(115200)
    Log("AppStart")
    pinservo.Initialize (4,pinservo.MODE_OUTPUT)    'connect servo to pin 4 of Arduino
    servo1.Attach(pinservo.PinNumber)                'assign servo to device on pin servo

    Timer1.Initialize ("Timer1_Tick",1000)            'Call Timer every second
    Timer1.Enabled=True

    angleservo=servo1.Read                             'initial servo angle
    upangle=True                                    'Increment angle

End Sub

Sub Timer1_Tick

    angleservo=servo1.read
   
    Select upangle                                    'Increment angle           
   
        Case True   
            If (angleservo >=0 And angleservo <180) Then
                Log ("up angle ",angleservo)
                angleservo=angleservo +1
                servo1.Write(angleservo)
            End If
       
            If angleservo=180 Then upangle=False
       
        Case False                                    'Decrement angle
       
            If angleservo <=180 And angleservo>0 Then
                Log ("down angle ",angleservo)
                angleservo=angleservo-1
                servo1.Write(angleservo)
            End If
       
            If angleservo=0 Then upangle=True
   
    End Select

End Sub

Servos are quite power-hungry so if you connect several sensors to Arduino, you'll need to use a separate power supply for servo motors (battery ,etc..)
 
Last edited:

Cableguy

Expert
Licensed User
Longtime User
I have tested with one of my TOWER PRO 9G servo (analog) and it works quite well, except for a "small" IDE issue, when the timer value is too low, like 5 instead of 50, and the IDE becomes unusable because of all the log qeue... it would be nice to be able to deploy in debug mode so that we could stop the program from the IDE
 

johndb

Active Member
Licensed User
Longtime User
Thanks to @Erel and the new rservo library (Beta#7), we've access to servo motors.

Servos are a motor type that allows for precise control of angular or linear position, velocity and acceleration (wiki);there're various types with different characteristics (torque, velocity, etc)

There're very cheap models like this one and usually used on actuators, robotic arms, etc..

View attachment 43401 View attachment 43402


B4X:
Sub Process_Globals
    'These global variables will be declared once when the application starts.
    'Public variables can be accessed from all modules.
    Public Serial1 As Serial
    Public servo1 As Servo
    Public pinservo As Pin
    Public Timer1 As Timer
    Public angleservo As UInt
    Public upangle As Boolean

End Sub

Private Sub AppStart
    Serial1.Initialize(115200)
    Log("AppStart")
    pinservo.Initialize (4,pinservo.MODE_OUTPUT)    'connect servo to pin 4 of Arduino
    servo1.Attach(pinservo.PinNumber)                'assign servo to device on pin servo

    Timer1.Initialize ("Timer1_Tick",50)            'Call Timer every second
    Timer1.Enabled=True

    angleservo=servo1.Read                             'initial servo angle
    upangle=True                                    'Increment angle

End Sub

Sub Timer1_Tick

    angleservo=servo1.read
   
    Select upangle                                    'Increment angle           
   
        Case True   
            If (angleservo >=0 And angleservo <180) Then
                Log ("up angle ",angleservo)
                angleservo=angleservo +1
                servo1.Write(angleservo)
            End If
       
            If angleservo=180 Then upangle=False
       
        Case False                                    'Decrement angle
       
            If angleservo <=180 And angleservo>0 Then
                Log ("down angle ",angleservo)
                angleservo=angleservo-1
                servo1.Write(angleservo)
            End If
       
            If angleservo=0 Then upangle=True
   
    End Select

End Sub

Servos are quite power-hungry so if you connect several sensors to Arduino, you'll need to use a separate power supply for servo motors (battery ,etc..)
Very nice. Thanks for posting.
I use modified servos for my robots for wheel drives instead of regular motors. Servos allow greater directional control and speed. I'm in the process of modifying my "stamp" controlled robot to "uno" and @Erel's new B4R is a game changer :)

John
 

Beja

Expert
Licensed User
Longtime User
Very useful tutorial, thank you.
Can't wait to try it.
 

rwblinn

Well-Known Member
Licensed User
Longtime User
Hi,

set the timer to 1000 to verify if all steps are carried out and noticed that the first / last 3 steps are not carried out, means:
angles 0, 10,20 nothing happens, first at angle 30 the servo moves. The same when moving in the other direction = first 3 steps nothing happens.
The log shows that the steps are carried out.

Did use external power and as a servo the Modelcraft Mini-Servo MC1811.
Changed the angle range from 0 - 60, same result = 3 instead of 6 steps are carried out.

Any idea what the cause could be?
 
Last edited:

inakigarm

Well-Known Member
Licensed User
Longtime User
With Micro Servo 9g SG90 (first post image) I haven't notice this behaviour (all the steps are Ok); I've powered from arduino directly.
 

Cableguy

Expert
Licensed User
Longtime User
The servo itself has its own protection...
Remember that all servos take a "digital" own input that gets treated inside the servo logic using inner feedback.
Analogic servos only difference from digital ones is the way the FeedBack is done... on analogic servos the feedback is provided by a in-sync potentiometer, while in digital it's a optic decoder
 

Hans- Joachim Krahe

Active Member
Licensed User
Longtime User
smooth move on Potentiometer input:
B4X:
AnalogUInt1 = AnalogPin1.AnalogRead
    i = AnalogUInt1/ 5 + 48

    Do Until servoAnglePos1 = i
       If servoAnglePos1 < i Then
            j= (i - servoAnglePos1)/2
            If j > 1 Then
                servoAnglePos1 = servoAnglePos1 + j
            Else
                servoAnglePos1 = servoAnglePos1 + 1
            End If
        End If
        If servoAnglePos1 > i Then
            j= (servoAnglePos1 - i)/2
            If j > 1 Then
                servoAnglePos1 = servoAnglePos1 - j
            Else
                servoAnglePos1 = servoAnglePos1 - 1
            End If
        
        End If
        servo1Pin.AnalogWrite(servoAnglePos1)
        myDelday = servoAnglePos1/30
        Delay (myDelday)
loop
 
Last edited:

Eme Fibonacci

Well-Known Member
Licensed User
Longtime User
Hi, I'm starting with B4R. How does the control the servo speed?

The only way is with timer?

Thank you.
 

Hans- Joachim Krahe

Active Member
Licensed User
Longtime User
...yes, it's inside a timer, that watches a resistor on analogread port. The timer compares old value and actual value and goes sub by change of resistor. as inside sub value is compared too, servo follows the changes with less interrupts.

its easy , have fun:)
 

Eme Fibonacci

Well-Known Member
Licensed User
Longtime User
Thanks for the tutorial. It Works very well.

I think instead:

B4X:
Timer1.Initialize ("Timer1_Tick",50) 'Call Timer every second
Would it be this:
B4X:
Timer1.Initialize ("Timer1_Tick",50) 'Call Timer every TICK
 
Top