B4R Library rCheapStepper - library for the 28BYJ-48 stepper motor using ULN2003 driver board

A wrap for this Github project.

I have not tested or tried to figure out all the wrapped methods. Just using the stepSingle(Boolean) method to move the stepper motor. Will spend some more time on this to figure out some of the other methods exposed.

The attached B4R project positions the motor very accurately (using variable "stepcount" to track the position of the motor shaft).

See the comments in the attached B4R code for what the attached B4R project does:
1. Clicking on button "Move" moves the motor shaft by the number of degrees specified (in the attached example a random number generated from the natural noise on pin A0)
2. Clicking on button "Home" returns the motor shaft to the home position via the shortest angle/route
3. Clicking on button "Nudge" rotates the motor shaft in clockwise direction by "nudgesteps" and the home position will be set according to the last applied "nudgesteps"

B4R lib attached (rCheapStepper):
1. Copy the rCheapStepper folder and its contents (.h and .cpp files) to your B4R additional libs folder
2. Copy rCheapStepper.xml to the root of your B4R additional libs folder.

Note:
1. You can set a value other than 4096 for the number of steps (some motors do 4076 steps per revolution)
2. You can set the shaft speed (rpm) - I am using 16rpm as max (see setting in B4R code) as it seems to work well.
3. Using some inline C code to generate a random number from the natural noise on pin A0.
4. The Looper - it has to be there.
5. Some methods are blocking and some are non-blocking (main thread)



connections_bb.png


Sample Code:
B4X:
#Region Project Attributes
    #AutoFlushLogs: True
    #CheckArrayBounds: True
    #StackBufferSize: 300
#End Region

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
  
    Dim cs As CheapStepper
  
    Dim p4, p5, p6 As Pin
    Dim p4click, p5click, p6click As Boolean = False
    Dim stepcount As Long = 0              'keep track of where the stepper motor is relative to the startup or set position
    Dim num As Long                        'it is set by the inline C code and called in p5_StateChanged - random number by reading the natural noise on pin A0
    Dim clockwise As Boolean = True        'clockwise = True, anti-clockwise = False
    Dim nudgesteps As Int = 20
  
End Sub

Private Sub AppStart
    Serial1.Initialize(115200)
    Log("AppStart")
    p4.Initialize(4, p4.MODE_INPUT_PULLUP)  'button to nudge the shaft clockwise forward in "nudgesteps" - see value assigned to nudgesteps above
    p5.Initialize(5, p5.MODE_INPUT_PULLUP)  'button that creates a random number and move the motor shaft accordingly (from shaft current position)
    p6.Initialize(6, p6.MODE_INPUT_PULLUP)  'button to move motor shaft to home position via the shortest route (smallest travel angle)
  
    p4.AddListener("p4_StateChanged")       'add a listener for the button
    p5.AddListener("p5_StateChanged")       'add a listener for the button
    p6.AddListener("p6_StateChanged")       'add a listener for the button
  
    cs.Initialize(8, 9, 10, 11)             'the motor is connected via the motor driver to pins 8, 9, 10, and 11
    cs.Rpm = 16                             'Seems to work well at 16rpm
    cs.TotalSteps = 4096                    '4096 per revolution for the motor that I am using - define your own motor steps

    AddLooper("myLooper")                   'we need to call cs.run continuously

End Sub

Sub myLooper
  
    cs.run                                  'this call needs to be called continuously to keep the stepper motor moving and updated
  
End Sub

Sub p5_StateChanged                         'step a number of random degrees in clockwise direction
  
    If p5click = False Then                 'only execute code on button down
        Log("state 5 changed")
        p5click = Not(p5click)
        RunNative("getRandomNumber", Null)  'get a random number from  0 to 360 from the Inline C code - it comes from the natural noise on pin A0
        Dim deg As Int = num
        Log("DEG = ", deg)
        Dim dir As Byte = Rnd(0,2)          'select a random direction - 0 is clockwise and 1 is anti-clockwise

        If dir = 0 Then
            clockwise = True                'go clockwise
        Else
            clockwise = False                'go anti-clockwise
        End If
        Dim steps As Int = 4096 * (deg / 360) '4096 = 1 revolution. Based on the "random" value (0 to 360) crearted by the inline C code, calculate the number of steps to move
        For i = 0 To steps
            cs.stepSingle(clockwise)          'do the move in single steps
        Next
        If clockwise = True Then              'keep track of how many steps we are moving clockwise/anti-clokwise       
            stepcount = stepcount + steps     'if clockwise - add
        Else
            stepcount = stepcount - steps     'if anti-clockwise - subtract
        End If     
        Log("Step Count = ", stepcount)
    Else
        p5click = False
    End If

End Sub

Sub p6_StateChanged                                             'go back to the initial zero position via the shortest turn path
  
    If p6click = False Then                                     'only execute code on button down
        Log("state 6 changed")
        p6click = Not(p6click)
        stepcount = stepcount Mod 4096                          'how far are we away from the home position?
        Log("MOD stepcount = ", stepcount)
      
        If stepcount > 2048 Then                                'we are past halve way from home in clockwise direction.
            stepcount = 4096 - stepcount                        'this will be the shortest path to the home position             
            For i = 0 To stepcount - 1
                cs.stepSingle(True)                             'go clockwise back to home position - it is the shortest path
            Next
        else If stepcount >= 0 And stepcount <= 2048 Then       'we are less than halve way from home in clockwise direction.
            For i = 0 To stepcount - 1                          'take the shortest path home
                cs.stepSingle(False)                            'go anti-clockwise back to home position - it is the shortest path
            Next
        Else If stepcount < 0 And stepcount > -2048 Then        'we are less than halve way from home in anti-clockwise direction.
            stepcount = -1 * stepcount                          'this will be the shortest path to the home position
            For i = 0 To stepcount - 1
                cs.stepSingle(True)                             'go clockwise back to home position - it is the shortest path
            Next
        Else If stepcount <= -2048 And stepcount > -4096 Then   'we are more than halve way from home in anti-clockwise direction.
            stepcount = 4096 + stepcount                        'this will be the shortest path to the home position
            For i = 0 To stepcount - 1
                cs.stepSingle(False)                            'go anti-clockwise back to home position - it is the shortest path
            Next
        End If
        stepcount = 0                                           'set the home position
    Else
        p6click = False
    End If
  
End Sub

Sub p4_StateChanged                                       'move clockwise in steps of 10 micro steps and set the home tracking position accordingly
  
    If p4click = False Then                               'only execute code on button down
        Log("state 4 changed")
        p4click = Not(p4click)
            cs.newMove(True, nudgesteps)                  'move the motor shaft by defined "nudgesteps" in the clockwise direction
        stepcount = 0                                     'the position will set the new "home" position. stepcount will be calculated from here.
    Else
        p4click = False
    End If

End Sub

'Generate a random number (0 to 360) from the natural "noise" on pin A0
#If C

void getRandomNumber (B4R::Object* o) {
   long randNumber;
   randomSeed(analogRead(0));
   randNumber = random(361);
   b4r_main::_num = randNumber;
}

#End If

20190720_175953.jpg
 

Attachments

  • rCheapStepper.zip
    282.9 KB · Views: 444
  • b4rCheapStepper.zip
    2.5 KB · Views: 422
Last edited:
Top