B4R Question MQTT connect to ThingSpeak

Discussion in 'B4R Questions' started by barx, Feb 11, 2018.

  1. barx

    barx Well-Known Member Licensed User

  2. XorAndOr

    XorAndOr Member Licensed User

  3. Erel

    Erel Administrator Staff Member Licensed User

    You should use Connect2 with MqttConnectOptions to set the user name and password.
    Peter Simpson likes this.
  4. barx

    barx Well-Known Member Licensed User

    Thanks Erel, I had spotted that shortly before you posted it.
    I tried many ways to get this working but each time it failed. After reading the code example I posted I also tried using .getBytes() wondering if it did the same work as
    .toCharArray in the example. Still no joy.

    After a rather long time and at the point of nearly giving up, I noted that the only thing I hadn't changed was the number of fields I was trying to update. Each time I had been trying to post 8 fields (max allowed for a ThingSpeak Channel.)

    I finally got a bite on the line when I reduced the number of fields I was posting to. I tried just one. After a few combinations of the other options, it worked!!!!

    So, i then went back to 8 fields........ no worky.

    I started back at 1, then worked my way up until it failed. Anyway it failed at anything above 6 fields. I stared at the code tirelessly, trying to see what was different between the 7th and/or 8th fields that would made it fail. Nothing was wrong that I could see. I then began to wonder if it was the actual length of what was being sent, it was the only thing that made sense. So, to increase the buffer I looked for something relating to 'MaxBufferSize' like with async stream. I didn't find anything.

    I searched google for an answer and found a pointer in the right direction. The answer was to edit the PubSubClient.h file found under '\Anywhere Software\B4R\Libraries\rMQTT\' and edit the following line

    Setting the value to 256.

    NOTE: your editor needs Admin Priviledges

    This now works for all 8 fields!!!!

    Working code example to follow as this post is getting a little long with me rambling on, sorry.
    Erel likes this.
  5. barx

    barx Well-Known Member Licensed User

    NOTE: the bits in <> are where you insert your own data / keys

    Sub Process_Globals

    Private MQTT As MqttClient
    Private MQTTOptions As MqttConnectOptions
    Private tmr0 As Timer
    End Sub

    public Sub Start

    "tmr0_tick"30000'tick every 30 seconds
    End Sub

    server.Socket.Stream, "mqtt.thingspeak.com"1883, <ClientID>, "MQTT_MessageArrived""MQTT_Disconnected")
       MQTTOptions.Initialize(<Username>, <MQTTAPIKey>) 
    'MQTTAPIKey from Account > My Profile
       If MQTT.Connect2(MQTTOptions) Then
           tmr0.Enabled = 
           tmr0.Enabled = 
    Log("not connected")
    End If
    End Sub

    Sub tmr0_Tick
    'publish data
        ...'Code to fill Fields() array with the data to send.
       Log(MQTT.Publish(MQTTHelper.ThingSpeakTopicBuilder(<ChannelID>, <ChannelIDWriteAPIKey>), MQTTHelper.GetPayload))
    End Sub

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

    Private Sub MQTT_Disconnected
    End Sub
    The little helper module look like

    public Sub ThingSpeakTopicBuilder(ChannelID As String, ChannelWriteAPIKey As StringAs String
    Return JoinStrings(Array As String("channels/", ChannelID, "/publish/", ChannelWriteAPIKey))
    End Sub

    'returns the payload
    public Sub GetPayload() As String
    Return JoinStrings(Array As String("field1=", Fields(0), "&field2=", Fields(1), "&field3=", Fields(2), "&field4=", Fields(3), "&field5=", Fields(4), "&field6=", Fields(5), "&field7=", Fields(6), "&field8=", Fields(7)))
    End Sub
    Thought I would post this in case it helps someone in future ;)