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...
Send message - Android source code
Libraries: ByteConverter and jMQTT
Receive message - WeMos D1 mini source code
Libraries: rESP8266, rESP8266WiFi, rMQTT and rRandomAccessFile
How to wire up the WeMos D1 mini to the shift register, the white wires connects to relays 7 to 0
YouTube video of an Android device controlling 8 relays over 4G
Enjoy...
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
Send message - Android source code
Libraries: ByteConverter and jMQTT
B4X:
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(0, 999999999) '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
B4X:
'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(0, 999999999) '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", 1000, 0)
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
YouTube video of an Android device controlling 8 relays over 4G
Enjoy...
Last edited: