B4R Question MQTT connect to ThingSpeak

barx

Well-Known Member
Licensed User
Longtime User

barx

Well-Known Member
Licensed User
Longtime User
You should use Connect2 with MqttConnectOptions to set the user name and password.

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

#define MQTT_MAX_PACKET_SIZE 128

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.
 
Upvote 0

barx

Well-Known Member
Licensed User
Longtime User
NOTE: the bits in <> are where you insert your own data / keys

B4X:
Sub Process_Globals

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

public Sub Start

   tmr0.Initialize("tmr0_tick", 30000) 'tick every 30 seconds
   ...
End Sub

   MQTT.Initialize2(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 = True
   Else
       tmr0.Enabled = False
       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

B4X:
public Sub ThingSpeakTopicBuilder(ChannelID As String, ChannelWriteAPIKey As String) As 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 ;)
 
Upvote 0
Top