B4R Tutorial Using a Wemos D1 R2 and stepper motor - control over wifi

This may be of interest to someone. I am using a Wemos D1 R2 in AP mode to serve a webpage to a client. The Wemos creates a server called "Wemos_Server" using the IP 192.168.4.1.

When the browser opens this IP, a page is generated with three button: Start, Stop and Reverse. This controls a stepper motor. The speed can be controlled using the timer.


These are my first attempts with B4R, there are other (better) ways.

The fritzing image:

Stepper_Wifi_bb.png

Code as follows:

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.
   
    'Wemos D1 R2
    ' Pin    GPIO    Function
    '____    ______    ___________
    ' D0    GPIO16
    ' D1    GPIO5    SCL
    ' D2    GPIO4    SDA
    ' D3    GPIO0
    ' D4    GPIO2    BUILTIN_LED
    ' D5    GPIO14    SCK
    ' D6    GPIO12    MISO
    ' D7    GPIO13    MOSI
    ' D8    GPIO15
    ' A0    A0
   
    Public Serial1 As Serial
   
    'Motor variables
    Dim IN1 As Pin
    Dim IN2 As Pin
    Dim IN3 As Pin
    Dim IN4 As Pin
    Dim Steps As Int=0
    Dim Direction As Boolean=True
    Dim timer1 As Timer
   
    'Wifi variables
    Private bc As ByteConverter
    Private wifi As ESP8266WiFi
    Private server As WiFiServerSocket
    Private astream As AsyncStreams
End Sub

Private Sub AppStart
    Serial1.Initialize(115200)
    Log("AppStart")
   
    IN1.Initialize(5,IN1.MODE_OUTPUT)
    IN2.Initialize(4,IN2.MODE_OUTPUT)
    IN3.Initialize(12,IN3.MODE_OUTPUT)
    IN4.Initialize(13,IN4.MODE_OUTPUT)
    ResetMotor
   
    timer1.Initialize("timer1_Tick",25)        'Delay between switching coils on motor
   
    Log(wifi.StartAccessPoint("Wemos_Server"))
    Log(wifi.AccessPointIp)
    RunNative("SetAP", Null)
    Log(wifi.AccessPointIp)
    Log(wifi.LocalIp)
    server.Initialize(80, "server_NewConnection")
    server.Listen
   
End Sub

#if C
void SetAP(B4R::Object* o) {
   WiFi.mode(WIFI_AP);
}
#end if

Sub Server_NewConnection (NewSocket As WiFiSocket)
    astream.Initialize( NewSocket.Stream, "astream_NewData", "astream_Error")
    astream.WaitForMoreDataDelay = 100
    astream.MaxBufferSize = 400  ' was 400
    'Log("New connection..")
End Sub

Sub DisplayWebpage
    Dim html1, html2, html3, html4, html5 As String
   
    'Prepare default strings for webpage
    html1="<!DOCTYPE html><html><head><meta name='viewport' content='width=device-width, initial-scale=1.0'/><meta charset='utf-8'><style>body {font-size:140%;} #main {display: table; margin: auto;  padding: 0 10px 0 10px; } h2,{text-align:center; } .button { padding:10px 10px 10px 10px; width:100%;  background-color: #4CAF50; font-size: 120%;}</style><title>Wifi Motor Control</title></head><body><div id='main'><h2>Motor Control</h2>"
    html2="<form id='F1' action='START'><input class='button' type='submit' value='START' ></form><br><br>"
    html3="<form id='F2' action='STOP'><input class='button' type='submit' value='STOP' ></form><br><br>"
    html4="<form id='F3' action='REVERSE'><input class='button' type='submit' value='REVERSE' ></form><br>"
    html5="</div></body></html>"
       
    astream.Write("HTTP/1.1 200").Write(CRLF).Write(CRLF)
    astream.Write(html1).Write(CRLF)
    astream.Write(html2).Write(CRLF)
    astream.Write(html3).Write(CRLF)
    astream.Write(html4).Write(CRLF)
    astream.Write(html5).Write(CRLF)
       
End Sub

'React to commands sent from the browser
Sub astream_NewData (Buffer() As Byte)
    Log("***********************************************************")
    Log("Stack buffer usage: ",StackBufferUsage)
    Log(" ")
    Log("New data: ", Buffer, CRLF)
    Log(" ")
    Log("***********************************************************")
    Log(" ")
       
    If bc.IndexOf(Buffer, "GET") <> -1 Then
        If bc.IndexOf(Buffer, "GET /START") <> -1 Then
            timer1.Enabled=True
           
        Else If bc.IndexOf(Buffer, "GET /STOP") <> -1 Then
            timer1.Enabled=False
           
        Else If bc.IndexOf(Buffer, "GET /REVERSE") <> -1 Then
            timer1.Enabled=False
            ResetMotor
            Direction=Not(Direction)                'change direction
            timer1.Enabled=True
        End If
       
        DisplayWebpage                                    'Browser opened, show web controls
        CallSubPlus("CloseConnection", 200, 0)
       
    End If
   
End Sub

Sub ResetMotor
    IN1.DigitalWrite(False)                        'reset all outputs
    IN2.DigitalWrite(False)
    IN3.DigitalWrite(False)
    IN4.DigitalWrite(False)
End Sub

Sub astream_Error
    'Log("Astream error")
    server.Listen
End Sub

Private Sub CloseConnection(u As Byte)
    'Log("Close connection")
    If server.Socket.Connected Then
        server.Socket.Stream.Flush
        server.Socket.Close
    End If
End Sub

Sub timer1_Tick
    stepper
End Sub

Sub stepper
    Select Steps
        Case 0
            IN1.DigitalWrite(True)
            IN2.DigitalWrite(True)
            IN3.DigitalWrite(False)
            IN4.DigitalWrite(False)
        Case 1
            IN1.DigitalWrite(False)
            IN2.DigitalWrite(True)
            IN3.DigitalWrite(True)
            IN4.DigitalWrite(False)
               
        Case 2
            IN1.DigitalWrite(False)
            IN2.DigitalWrite(False)
            IN3.DigitalWrite(True)
            IN4.DigitalWrite(True)
        Case 3
            IN1.DigitalWrite(True)
            IN2.DigitalWrite(False)
            IN3.DigitalWrite(False)
            IN4.DigitalWrite(True)
    End Select
    IncStep
End Sub

Sub IncStep
    If Direction=True Then
        Steps=Steps+1
    Else
        Steps=Steps-1
    End If
   
    If Steps>3 Then Steps=0
    If Steps<0 Then Steps=3
End Sub
 
Top