B4R Tutorial MQTT

Discussion in 'B4R Tutorials' started by Erel, Apr 11, 2016.

  1. Erel

    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:
    Code:
    '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"10000)
         
    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:
    Code:
    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
     
  2. billzhan

    billzhan Active Member Licensed User

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

    Code:
    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(1921681105 )
        
    Private MacAddress() As Byte = Array As Byte(0xDE0xAD0xBE0xEF0xFE0xED)
        
    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"10000)
         
    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
     
    GabrielM, Laurent95 and Erel like this.
  3. Hypnos

    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!
     
  4. Erel

    Erel Administrator Staff Member Licensed User

    v1.25 is attached. It includes a new Initialize2 method that accepts the host name instead of the ip address. Please try it. Note that the host name should not include the scheme (tcp://).
     

    Attached Files:

    coslad and Hypnos like this.
  5. Hypnos

    Hypnos Active Member Licensed User

    Thank you Erel, worked!
     
    Last edited: Aug 7, 2016
    Erel likes this.
  6. rbghongade

    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?
     
  7. Erel

    Erel Administrator Staff Member Licensed User

    No. You just need to use WiFiSocket instead of EthernetClient.
     
    rbghongade likes this.
  8. rbghongade

    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 likes this.
  9. william235

    william235 Member

    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
     
  10. Erel

    Erel Administrator Staff Member Licensed User

    1. Please don't limit your questions to a single member.

    2. Please start a new thread for this in the questions forum.
     
  11. janderkan

    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: Oct 29, 2016
  12. Erel

    Erel Administrator Staff Member Licensed User

    1. Please use [code]code here...[/code] tags when posting code.
    2. Please start a new thread for this question.
     
    janderkan likes this.
  13. monki

    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
     
  14. Erel

    Erel Administrator Staff Member Licensed User

    Do you need the retained option?
     
  15. 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
     
  16. Erel

    Erel Administrator Staff Member Licensed User

    Please try the attached library (rMQTT v1.30). Copy it to the internal libraries folder.
     

    Attached Files:

  17. 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
     
  18. Erel

    Erel Administrator Staff Member Licensed User

    I've just tested it and it works.

    If you run mosquitto in verbose mode you can see the retain flag:
    And I did receive the message on the other client after subscribing to the topic.
     
  19. 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.
     
  20. Erel

    Erel Administrator Staff Member Licensed User

    Test it with an external broker.
     
Loading...
  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice