B4R Tutorial MQTT

Erel

Administrator
Staff member
Licensed User
MQTT is an excellent solution for connection of multiple devices.

Tutorial about MQTT: [IoT] MQTT Protocol

The rMQTT library, which is based on PubSubClient open source project, makes it simple to connect to a MQTT broker.

The first step is to connect to the network (not server) as described in this tutorial: https://www.b4x.com/android/forum/threads/ethernet-network-tutorial.65664/

The next step is to initialize MqttClient and call Connect:
B4X:
'ethClient is an unconnected EthernetSocket object.
mqtt.Initialize(ethClient.Stream, serverIp, serverPort, "arduino", "Mqtt_MessageArrived", "Mqtt_Disconnected")

Sub Connect(unused As Byte)
   If mqtt.Connect = False Then
     Log("trying to connect again")
     CallSubPlus("Connect", 1000, 0)
     Return
   End If
   Log("Connected to broker")
   mqtt.Subscribe("arduino", 0)
End Sub

Sub Mqtt_MessageArrived (Topic As String, Payload() As Byte)
   Log("Message arrived. Topic=", Topic, " payload: ", Payload)
End Sub

Sub Mqtt_Disconnected
   Log("Disconnected")
   mqtt.Close
   Connect(0)
End Sub
The above code will reconnect automatically if the connection has broken.

The B4J code with the broker:
B4X:
Sub Process_Globals
   Private broker As MqttBroker
   Private client As MqttClient
End Sub

Sub AppStart (Args() As String)
   broker.Initialize("", 51042)
   broker.DebugLog = False
   broker.Start
   client.Initialize("client", "tcp://127.0.0.1:51042", "pc")
   client.Connect   
   StartMessageLoop
End Sub

Sub Client_Connected (Success As Boolean)
   If Success Then
     client.Subscribe("pc", 0)
   End If
End Sub

Sub Client_MessageArrived (Topic As String, Payload() As Byte)
   If Topic = "pc" Then
     If Payload(0) = 0 Then
       Log("Button is down")
     Else
       Log("Button is up")
     End If
     client.Publish("arduino", "thank you for your message".GetBytes("utf8"))
   End If
End Sub
 

billzhan

Active Member
Licensed User
Get it works with uno r3 . Uploading failed for the first time, second uploading is OK

B4X:
Sub Process_Globals
    Public Serial1 As Serial
   
    Private eth As Ethernet
    Private ethClient As EthernetSocket
    Private btn As Pin
    Private serverIp() As Byte = Array As Byte(192, 168, 1, 105 )
    Private MacAddress() As Byte = Array As Byte(0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED)
    Private const serverPort As UInt = 50000  '51042

    Private mqtt As MqttClient
    'Private astream As AsyncStreams
End Sub

Private Sub AppStart
    Serial1.Initialize(115200)
    Log("AppStart")
    If eth.InitializeDHCP(MacAddress) = False Then
        Log("Error connecting to network.")
        Return
    Else
        Log("Connected to network. My ip address: ", eth.LocalIp)
    End If
    btn.Initialize(btn.A0, btn.MODE_INPUT_PULLUP)
    btn.AddListener("Btn_StateChanged")
   
   
    mqtt.Initialize(ethClient.Stream, serverIp, serverPort, "arduino", "Mqtt_MessageArrived", "Mqtt_Disconnected")
    Connect(0)
End Sub

Sub Btn_StateChanged (State As Boolean)
    If ethClient.Connected Then
        Dim s As Byte 
        If State Then s = 1 Else s = 0
        'astream.Write(Array As Byte(s))
        mqtt.Publish("pc" , Array As Byte(s) ) 
    End If
End Sub



'============mqtt 

Sub Connect(unused As Byte)
   If mqtt.Connect = False Then
     Log("trying to connect again")
     CallSubPlus("Connect", 1000, 0)
     Return
   End If
   Log("Connected to broker")
   mqtt.Subscribe("arduino", 0)
End Sub

Sub Mqtt_MessageArrived (Topic As String, Payload() As Byte)
   Log("Message arrived. Topic=", Topic, " payload: ", Payload)
End Sub

Sub Mqtt_Disconnected
   Log("Disconnected")
   mqtt.Close
   Connect(0)
End Sub
 

Hypnos

Active Member
Licensed User
I want my B4R MQTT client connect to external borker (e.g. cloudmqtt.com), is it possible to use server hostname instead of server IP? Thanks!
 

rbghongade

Active Member
Licensed User
Dear Erel,
Are there any differences while implementing MQTT client on WeMos board as compared to Arduino Uno +Ethernet Shield?
 

rbghongade

Active Member
Licensed User
Dear Erel,
Thanks for the pointer! I was able to implement MQTT client on ESP8266 within a couple of hours! Possible only because of the B4X ecosystem!
 
Erel:

I keep getting this message:

Compiling & deploying Ino project (NodeMCU 1.0 (ESP-12E Module) - COM4) Error
Could not find file 'C:\Users\WJM_ProBook\Desktop\safe_code\Objects\src\src'.

I have not idea what this means...it just started happening after a couple of clean starts. Do you have any thoughts on this?

Thanks,
Bill
 

janderkan

Active Member
Licensed User
Hi
When using Mqtt.Initialize2 on Wemos mini everything works fine if the server string is defined in kode.
But when I read the string from eeprom I am not able to connect to the server.
This emulates the problem.

This works:
Dim Str As String = "m21.cloudmqtt.com"
mqtt.Initialize2(Client.Stream, Str, MqttPort, "test", "Mqtt_MessageArrived", "Mqtt_Disconnected")
mqtt.connect

This does not work:
Dim BC as ByteConverter
Dim Str As String = BC.StringFromBytes("m21.cloudmqtt.com".GetBytes)
mqtt.Initialize2(Client.Stream, Str, MqttPort, "test", "Mqtt_MessageArrived", "Mqtt_Disconnected")
mqtt.connect
 
Last edited:

monki

Active Member
Licensed User
Hello erel,
it is possible as in the b4a version available the publish2 (topic, payload, retained) function also add in B4r.

Thanks,
monki
 

monki

Active Member
Licensed User
Yes,
I have 2 Esp boards to the Fresh Water level measurement on my boat . Since the measurement from battery spar reasons only hourly takes place it would be good if the last value (retained option) is available.

monki
 

monki

Active Member
Licensed User
Hello Erel,
Thank you for the new library, I have tested it but "mqtt0.Publish2 (data, text, True)" does not work. The same command in B4A works perfectly. I get the the last message from the broker also if the publisher is no longer connected to the broker. For B4R, the Publish2 command works just like the Publish command, the message is not stored on the broker.

monki
 

monki

Active Member
Licensed User
Hello Erel,
I have no mosquito installed.
My test environment consists of an Android device with jMqttBroker. As client I have an Android Tablet and a wemos D1 Miniboard, with the Android Mqttclient it works perfectly the message is stored on the Broker, with the Wemos board and the B4R Mqttclient is unfortunately not.
 
Top