B4R Tutorial MQTT controlling 8 relays, WeMos D1 mini WiFi, Android 4G

Discussion in 'B4R Tutorials' started by Peter Simpson, Jun 21, 2017.

  1. Peter Simpson

    Peter Simpson Well-Known Member Licensed User

    Here is a short tutorial on how to control an 8 channel relay module via MQTT. Below you will find both the WeMos and Android source codes needed to get started. The relay module is connected to a 74HC595 shift register that in turn is connected by only 3 wires to a WeMos D1 mini based microcontroller. The microcontroller receives MQTT messages/commands through WiFi, the MQTT messages/commands are send by an Android phone through 4G.

    So what is MQTT?
    Well the quick and dirty answer to that question is that MQTT (Message Queuing Telemetry Transport) is an ISO standard, lightweight, low-bandwidth, machine to machine, TCP/IP publish or subscribe messaging protocol which is great for controlling IoT (Internet of Things) devices from over the internet.

    There are plenty of free online MQTT brokers that you can choose from, I personally use a service called CloudMQTT and they can be found right here...
    Please note: For this screen shot I sent all the 'Messages' in plain readable text for testing purposes
    Untitled-2.png

    Send message - Android source code
    Libraries: ByteConverter and jMQTT

    Code:
    Sub Process_Globals
        
    Private MQTT As MqttClient
        
    Private MQTTUser As String = "xxxxxxx"
        
    Private MQTTPassword As String = "_xxxxxxx"
        
    Private MQTTServerURI As String = "tcp://m21.cloudmqtt.com:14925"
        
    Private BC As ByteConverter
    End Sub

    Sub Globals
        
    Private lblStatus As Label
        
    Private SpnTimerMinutes As Spinner
    End Sub

    Sub Activity_Create(FirstTime As Boolean)
        
    If FirstTime Then
            
    CallSub(Me, MQTT_Connect)
        
    End If

        
    Activity.LoadLayout("Relay_Switches")

        
    'Populate Spinner With Minutes
        For i = 10 To 60 Step 10
            SpnTimerMinutes.Add(i)
        
    Next
    End Sub

    Sub Activity_Resume
    End Sub

    Sub Activity_Pause (UserClosed As Boolean)
    End Sub

    'Connect to CloudMQTT broker
    Sub MQTT_Connect
            
    Dim ClientId As String = Rnd(0999999999'create a unique id
            MQTT.Initialize("MQTT", MQTTServerURI, ClientId)

            
    Dim ConnOpt As MqttConnectOptions
                ConnOpt.Initialize(MQTTUser, MQTTPassword)
            MQTT.Connect2(ConnOpt)
    End Sub

    Sub MQTT_Connected (Success As Boolean)
        
    If Success = False Then
            
    Log(LastException)
            lblStatus.Text = 
    "Error connecting"
        
    Else
            lblStatus.Text = 
    " - Connected to broker"
            MQTT.Subscribe(
    "drawers/#"0)
        
    End If
    End Sub

    Private Sub MQTT_Disconnected
        lblStatus.Text = 
    " - Disconnected from broker"
    End Sub

    Private Sub MQTT_MessageArrived (Topic As String, Payload() As Byte)
    End Sub

    'PLEASE NOTE:
    'ALTERNATIVELY YOU CAN ALSO CREATED BUTTONS DYNAMICALLY ON THE FLY AND USED A SENDER TO MONITOR BUTTON CLICKS
    Sub ToggleButton0_CheckedChange(Checked As Boolean)
        MQTT.Publish(
    "Relay_0", BC.StringToBytes(Checked, "utf8"))
    End Sub

    Sub ToggleButton1_CheckedChange(Checked As Boolean)
        MQTT.Publish(
    "Relay_1", BC.StringToBytes(Checked, "utf8"))
    End Sub

    Sub ToggleButton2_CheckedChange(Checked As Boolean)
        MQTT.Publish(
    "Relay_2", BC.StringToBytes(Checked, "utf8"))
    End Sub

    Sub ToggleButton3_CheckedChange(Checked As Boolean)
        MQTT.Publish(
    "Relay_3", BC.StringToBytes(Checked, "utf8"))
    End Sub

    Sub ToggleButton4_CheckedChange(Checked As Boolean)
        MQTT.Publish(
    "Relay_4", BC.StringToBytes(Checked, "utf8"))
    End Sub

    Sub ToggleButton5_CheckedChange(Checked As Boolean)
        MQTT.Publish(
    "Relay_5", BC.StringToBytes(Checked, "utf8"))
    End Sub

    Sub ToggleButton6_CheckedChange(Checked As Boolean)
        MQTT.Publish(
    "Relay_6", BC.StringToBytes(Checked, "utf8"))
    End Sub

    Sub ToggleButton7_CheckedChange(Checked As Boolean)
        MQTT.Publish(
    "Relay_7", BC.StringToBytes(Checked, "utf8"))
    End Sub

    Sub BtnStart_Click
        
    'Code to come shortly for auto power off relays...
    End Sub
    Receive message - WeMos D1 mini source code
    Libraries: rESP8266, rESP8266WiFi, rMQTT and rRandomAccessFile

    Code:
    'WIRE LEGEND for 74HC595 shift register
    '8 GND = GND
    '16 Vcc = 5V
    '14 = D1
    '12 = GND
    '12 = D2
    '11 = D3
    '10 = 5V
    'QA to QH is connected to relays 7 to 0

    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

        
    Private AStream As AsyncStreams
        
    Private WiFi As ESP8266WiFi
        
    Private WiFiStr As WiFiSocket
        
    Private MQTT As MqttClient
        
    Private MQTTOpt As MqttConnectOptions
        
    Private MQTTUser As String = "xxxxxxx"
        
    Private MQTTPassword As String = "_xxxxxxx"
        
    Private MQTTHostName As String = "m21.cloudmqtt.com"
        
    Private MQTTPort As Int = 14925
        
    Private DS, STCP, SHCP As Pin
        
    Private Relays As Int = 8
        
    Private Registers(Relays) As Boolean
        
    Private ESPin As D1Pins
    End Sub

    Private Sub AppStart
        Serial1.Initialize(
    115200)
        Delay(
    1000)
        
    Log("AppStart")

        DS.Initialize(ESPin.D1, DS.MODE_OUTPUT) 
    'Arduino Pin 8, SR Pin 14 Serial In
        STCP.Initialize(ESPin.D2, STCP.MODE_OUTPUT) 'Arduino Pin 11, SR Pin 12 RCK
        SHCP.Initialize(ESPin.D3, SHCP.MODE_OUTPUT) 'Arduino Pin 12, SR Pin 11 Serial Clock

        
    'Clear Register Values
        ClearAllReg

        AStream.Initialize(Serial1.Stream, 
    "Astream_NewData""Astream_Error")

        
    'Connect to local WiFi Access Point
        WiFi.Connect2("Access Point""Access Point Password")
        
    If WiFi.IsConnected Then Log("Connected to WiFi, Local IP ", WiFi.LocalIp) Else Log("Not Connected to WiFi")

        
    'Connect to CloudMQTT broker
        Dim ClientId As String = Rnd(0999999999'create a unique id
        MQTT.Initialize2(WiFiStr.stream, MQTTHostName, MQTTPort, ClientId, "MQTT_MessageArrived""MQTT_Disconnected")
        MQTTOpt.Initialize(MQTTUser, MQTTPassword)
        MQTT_Connect(
    0)
    End Sub

    Sub MQTT_MessageArrived (Topic As String, Payload() As Byte)
        
    Log("Topic = ", Topic, " and Payload = ", Payload)

        
    Dim State As Boolean
        
    Dim BC As ByteConverter
        
    If BC.StringFromBytes(Payload) = "true" Then State = True Else State = False

        
    Select Case Topic
            
    Case "Relay_0"
                Registers(
    0) = Not(State)
            
    Case "Relay_1"
                Registers(
    1) = Not(State)
            
    Case "Relay_2"
                Registers(
    2) = Not(State)
            
    Case "Relay_3"
                Registers(
    3) = Not(State)
            
    Case "Relay_4"
                Registers(
    4) = Not(State)
            
    Case "Relay_5"
                Registers(
    5) = Not(State)
            
    Case "Relay_6"
                Registers(
    6) = Not(State)
            
    Case "Relay_7"
                Registers(
    7) = Not(State)
        
    End Select

        WriteToReg
    End Sub

    Sub MQTT_Connect(Unused As Byte)
        
    If MQTT.Connect = False Then
            
    Log("Trying to connect to broker")
            MQTT.Connect2(MQTTOpt)
            CallSubPlus(
    "MQTT_Connect"10000)
        
    Else
            
    Log("Connected to broker")

            
    For i = 0 To Relays - 1
                MQTT.Subscribe(JoinStrings(
    Array As String("Relay_", i)), 0)
            
    Next
        
    End If
    End Sub

    Sub MQTT_Disconnected
        
    Log("Disconnected")
        MQTT.Close
        MQTT_Connect(
    0)
    End Sub

    Sub Astream_NewData (Buffer() As Byte)
        
    Log("Received: ", Buffer)
    End Sub

    Sub AStream_Error
        
    Log("error")
    End Sub

    'Write To Registers
    Private Sub WriteToReg()
        STCP.DigitalWrite(
    False)

        
    Dim i As Int = 0
        
    Do While i <= Relays - 1
            SHCP.DigitalWrite(
    False)
            DS.DigitalWrite(Registers(i))
            SHCP.DigitalWrite(
    True)
            i = i + 
    1
        
    Loop

        STCP.DigitalWrite(
    True)
    End Sub

    'Clear All Registers
    Private Sub ClearAllReg()
        
    Dim i As Int = Relays - 1
        
    Do While i >= 0
            Registers(i) = 
    True 'True = NO
            i = i - 1
            WriteToReg
        
    Loop
    End Sub
    How to wire up the WeMos D1 mini to the shift register, the white wires connects to relays 7 to 0
    Shift-register-WeMos-8-Relays_bb.png

    YouTube video of an Android device controlling 8 relays over 4G


    Enjoy...
     
    Last edited: Jun 26, 2017
    miker2069, gvoulg, ellpopeb4a and 2 others like this.
  2. Erel

    Erel Administrator Staff Member Licensed User

    Great tutorial! For your next project I recommend you to try B4RSerializator. With B4RSerializator it would have been simpler to send the relay number (or name) together with the new state.
     
  3. hugo ivan

    hugo ivan New Member

    i want to control a nodemcu with an aplicattion
    like power on a led or something like that
     
  4. Peter Simpson

    Peter Simpson Well-Known Member Licensed User

    Hello @hugo ivan, so what exactly is your questions to do with?
     
Loading...