Upload Data to Thingspeak through MQTT with an ESP8266

Sending  values to Thingspeak via the Thingspeak API is well known. There is another way as well: through MQTT. Thingspeak has recently (5 dec 2016) added a (one way) MQTT broker for this at mqtt.thingspeak.com:1883.

There are two topics one can use:
To upload more than 1 field in one session use:
channels/<channelID/publish/<channelAPI>

To upload an individual channel use:
channels/<channelID>/publish/fields/field1/<channelAPI> (just using field1 as example)

In the first case, the payload string is as follows:
field1=<value1>&field2=<value2>&status=MQTTPUBLISH

In the second case the payload string is just <value1>

In the program below I am using the PubSubClient from Knolleary. The “credentials.h” file is a file that defines my WiFi credentials, you can either create such a file yourself or just insert your wificredentials.

I am using an ESP8266 to make the connection but ofcourse it is also possible to use an Arduino with Ethernet connection when you make the proper changes  in this file in order to connect to Ethernet.

To avoid using again a DHT11 as an example, I show uploading variables by using micros() and a counter

#include "PubSubClient.h" //Knolleary
#include  <ESP8266WiFi.h> //ESP8266WiFi.h
#include   <credentials.h> //This is a personal file containing web credentials

const char* ssid = WAN_SSID;// this constant is defined in my credentials file
const char* password = WAN_PW;// ditto
//char* topic="channels/<channelID/publish/<channelAPI>
char* topic = "channels/123456/publish/T8I9IO457BAJE386"; 
char* server = "mqtt.thingspeak.com";

WiFiClient wifiClient;
PubSubClient client(server, 1883, wifiClient);

void callback(char* topic, byte* payload, unsigned int length) {
  // handle message arrived
}

void setup() {
  Serial.begin(115200);
  delay(10);
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);
  
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected");  
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());

String clientName="ESP-Thingspeak";
  Serial.print("Connecting to ");
  Serial.print(server);
  Serial.print(" as ");
  Serial.println(clientName);
  
  if (client.connect((char*) clientName.c_str())) {
    Serial.println("Connected to MQTT broker");
    Serial.print("Topic is: ");
    Serial.println(topic);
    
    if (client.publish(topic, "hello from ESP8266")) {
      Serial.println("Publish ok");
    }
    else {
      Serial.println("Publish failed");
    }
  }
  else {
    Serial.println("MQTT connect failed");
    Serial.println("Will reset and try again...");
    abort();
  }
}

void loop() {
  static int counter = 0;
  String payload="field1=";
  payload+=micros();
  payload+="&field2=";
  payload+=counter;
  payload+="&status=MQTTPUBLISH";
  
  if (client.connected()){
    Serial.print("Sending payload: ");
    Serial.println(payload);
    
    if (client.publish(topic, (char*) payload.c_str())) {
      Serial.println("Publish ok");
    }
    else {
      Serial.println("Publish failed");
    }
  }
  ++counter;
  delay(20000);
}

The file is available for download here. Whether this is a better method than with the api remains to be seen.
Currently the connection time is limited because of the limited number of sockets on Thingspeak so it is ‘connect->upload->disconnect’. Thingspeak currently cannot be used as a ‘broker’. The traffic is one way only. If your client is already connected to an MQTT network on your own private or public broker, then this method cannot be used without ‘bridging’ the two ‘networks’

Advertisements

4 thoughts on “Upload Data to Thingspeak through MQTT with an ESP8266”

  1. Hi
    I tried to use your sketch from “Upload Data to Thingspeak through MQTT with an ESP8266” which in the first place looks fine. But later I found out, that the very first payload was sort of empty i.e. the fields1 and 2 transferred no data. In the second and all following transmissions everything was fine.
    Since I wanted to put my ESP8266 into deep sleep, where I don’t need anything in loop this ends up in showing no data in thingspeak.
    Do you have any idea how to prevent that.

    1. I did not come across this problem myself, but I would think the easiest way would be to do a check if there is valid data (i.e. not an empty field) and if not, just skip the upload.

      1. The problem was, that thingspeak will not accept more than one message within 15 seconds. In this case the first publishing was “hello from ESP8266” and shortly after this the two fields were published. Thingspeak just left the fields empty. You can see this by downloading the data from thingspeak.
        Strictly limiting the publishings to a period greater than 15 seconds and not sending “hello from ESP8266” in the setup helps to send data right after waking up from deep sleep.

      2. I am happy you found it. I have not used Thingspeak seriously for a while, I remember it as being 10 secs, so maybe they changed their conditions.
        As you can see there is a 20 sec delay between publishing, but that doesnt count for that first hello message. As it was fine when I tested it, I presume Thingspeak has become a bit more strict plus, I still have an “old account” that allows a bit more.
        Sadly i only have that till end of year, as I am suddenly charged I think 75 Euro per month to keep those priviliges

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

w

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.