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 and initialize the DHT sensor..

#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[] = "XXXXXXXXXXXXXXXXX";      // Change to your MQTT API Key from Account > MyProfile.   
char writeAPIKey[] = "YYYYYYYYYYYYYYYY";    // Change to your channel write API key.
long channelID = 000000;                    // Change to your channel ID.
int fieldNumber = 4;                        // Field to use is publishing to only one field.

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.

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) 
  {
    mqttPublishFeed(); // Publish three values simultaneously.
    // mqttPublishField(fieldNumber); // Use this function to publish to a single field
 

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 mqttPublishFeed method to publish the sensor data to a ThingSpeak channel feed. You can publish to multiple fields at once using this function. This example publishes to fields 1, 2, and 3 of the channel.

void mqttPublishFeed() {
  
  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();
  const char *msgBuffer;
  msgBuffer=data.c_str();
  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();
  const char *topicBuffer;
  topicBuffer = topicString.c_str();
  mqttClient.publish( topicBuffer, msgBuffer );
  lastConnectionTime = millis();
}

11) Define the mqttPublishField method to publish the sensor data to a ThingSpeak channel field.

void mqttPublishField(int fieldNum) {
  
  float t = dht.readTemperature(true); // Read temperature from DHT sensor.
  
  // Create data string to send to ThingSpeak.
  String data = String(t, DEC);
  int length = data.length();
  const char *msgBuffer;
  msgBuffer = data.c_str();
  Serial.println(msgBuffer);
  
  // Create a topic string and publish data to ThingSpeak channel feed. 
  String topicString ="channels/" + String( channelID ) + "/publish/fields/field" + String(fieldNum) + "/" + String(writeAPIKey);
  length = topicString.length();
  const char *topicBuffer;
  topicBuffer = topicString.c_str();
  mqttClient.publish( topicBuffer, msgBuffer );

  lastConnectionTime = millis();
}

See Also

|

Related Examples

More About