Publish to a Channel Using an Arduino Client

This example shows how to use an Arduino® MKR1000 board to record data in ThingSpeak™. The board is connected to a DHT11 sensor that measures temperature and humidity and an analog light sensor that measures the light intensity. The measured values are published to a ThingSpeak channel. If you have more than one sensor value that you want to send to ThingSpeak, you can choose to publish multiple values to a channel feed. Alternatively, if you have only one sensor, you can publish a single value to a channel field.

Code

1) Create a channel, as shown in Collect Data in a New Channel.

2) Download the libraries WiFi101.h and DHT.h to your Arduino IDE. Include the libraries SPI.h, WiFi101.h, PubSubClient.h, and DHT.h in your Arduino sketch.

Note: DHT library version 1.2.3 is reccomended over the latest version of the library. Select Sketch > Include Libraries > Manage Libraries, then enter DHT in the search bar to adjust the version your Arduino IDE uses.

#include <SPI.h>
#include <WiFi101.h>
#include <PubSubClient.h>
#include "DHT.h"

3) Define the Arduino board pins connected to your sensors.

#define DHTPIN 2 // DHT Sensor connected to digital pin 2.
#define DHTTYPE DHT11 // Type of DHT sensor.
#define LIGHTPIN A0 // Analog light sensor connected to analog pin A0.

DHT dht(DHTPIN, DHTTYPE); // Initialize DHT sensor.

4) Define the wireless network credentials to connect your Arduino board to the network, and initialize the WiFi client library.

char ssid[] = "YOUR-NETWORK-SSID"; //  Change this to your network SSID (name).
char pass[] = "YOUR-NETWORK-PWD";  // Change this to your network password.
char mqttUserName[] = "TSArduinoMQTTDemo";  // Use any name.
char mqttPass[] = "YOURMQTTAPIKEY";  // Change this to your MQTT API Key from Account > MyProfile.
char writeAPIKey[] = "XXXXXXXXXXXXXXXX";    // Change to your channel write API key.
long channelID = NNNNNN;

static const char alphanum[] ="0123456789"
                              "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
                              "abcdefghijklmnopqrstuvwxyz";  // For random generation of client ID.

WiFiClient client;                         // Initialize the Wi-Fi client library.

5) Create a partially initialized PubSubClient instance, and define the ThingSpeak MQTT broker.

WiFiClient client;  // Initialize the Wi-Fi client library.
PubSubClient mqttClient(client); // Initialize the PubSubClient library.
const char* server = "mqtt.thingspeak.com"; 

6) Define other global variables to track the last connection time and to define the time interval to publish the data.

unsigned long lastConnectionTime = 0; 
const unsigned long postingInterval = 20L * 1000L; // Post data every 20 seconds.

7) Initialize serial data transfer, connect to wireless network, and set the MQTT broker details in the setup method.

void setup() {
  
  Serial.begin(9600);
  int status = WL_IDLE_STATUS;  // Set temporary Wi-Fi status.

  // Attempt to connect to Wi-Fi network.
  while (status != WL_CONNECTED) 
  {
    status = WiFi.begin(ssid, pass); // Connect to WPA/WPA2 Wi-Fi network.
    delay(5000);
  }

  Serial.println("Connected to wifi");
  mqttClient.setServer(server, 1883);   // Set the MQTT broker details.
}

8) Establish an MQTT connection, and publish data to the channel at regular time intervals in the loop method.

void loop() {

 // Reconnect if MQTT client is not connected.
  if (!mqttClient.connected()) 
  {
    reconnect();
  }

  mqttClient.loop();   // Call the loop continuously to establish connection to the server.

  // If interval time has passed since the last connection, publish data to ThingSpeak.
  if (millis() - lastConnectionTime > postingInterval) 
  {
    mqttpublish();
  }
}

9) Define the reconnect method to connect the Arduino client with the MQTT broker.

void reconnect() 
{
  char clientID[9];

  // Loop until reconnected.
  while (!mqttClient.connected()) 
  {
    Serial.print("Attempting MQTT connection...");
    // Generate ClientID
    for (int i = 0; i < 8; i++) {
        clientID[i] = alphanum[random(51)];
    }
    clientID[8]='\0';

    // Connect to the MQTT broker.
    if (mqttClient.connect(clientID,mqttUserName,mqttPass)) 
    {
      Serial.println("connected");
    } else 
    {
      Serial.print("failed, rc=");
      // Print reason the connection failed.
      // See https://pubsubclient.knolleary.net/api.html#state for the failure code explanation.
      Serial.print(mqttClient.state());
      Serial.println(" try again in 5 seconds");
      delay(5000);
    }
  }
}

10) Define the mqttpublish method to publish the sensor data to the ThingSpeak channel feed. You can publish to multiple fields at once if you are publishing to the channel feed. This example publishes to fields 1, 2, and 3 of the channel.

void mqttpublish() {
  
  float t = dht.readTemperature(true); // Read temperature from DHT sensor.
  float h = dht.readHumidity();  // Read humidity from DHT sensor.
  int lightLevel = analogRead(LIGHTPIN); // Read voltage from light sensor.
  
  // Create data string to send to ThingSpeak.
  String data = String("field1=" + String(t, DEC) + "&field2=" + String(h, DEC) + "&field3=" + String(lightLevel, DEC));
  int length = data.length();
  char msgBuffer[length];
  data.toCharArray(msgBuffer,length+1);
  Serial.println(msgBuffer);
  
  // Create a topic string and publish data to ThingSpeak channel feed. 
  String topicString ="channels/" + String( channelID ) + "/publish/"+String(writeAPIKey);
  length=topicString.length();
  char topicBuffer[length];
  topicString.toCharArray(topicBuffer,length+1);
 
  mqttClient.publish( topicBuffer, msgBuffer );

  lastConnectionTime = millis();
}

// Use this function instead to publish to a single field directly.  Don't forget to comment out the above version.
/*
void mqttpublish() {
  
  float t = dht.readTemperature(true); // Read temperature from DHT sensor.

  String data = String(t, DEC);
  int length = data.length();
  char msgBuffer[length];
  data.toCharArray(msgBuffer,length+1);
  Serial.println(msgBuffer);
  
  // Create a topic string and publish data to ThingSpeak channel feed. 
  String topicString ="channels/" + String( channelID ) + "/publish/"+String(writeAPIKey);
  length=topicString.length();
  char topicBuffer[length];
  topicString.toCharArray(topicBuffer,length+1);
 
  mqttClient.publish( topicBuffer, msgBuffer );

  lastConnectionTime = millis();
}
*/

See Also

|

Related Examples

More About