About

 

This is part of a ThingBerry related blog post series.

 

 

ThingBerry is ThingWorx installed on a RaspBerry Pi, which can be used for portable demonstrations without the need of utilizing e.g. customer networks. Instead the ThingBerry provides its own custom WIFI hotspot and allows Things to connect and send / receive demo data on a small scale.

 

In this particual blog post we'll discuss on how to connect a ESP8266 module to the ThingBerry WIFI hotspot and send data from a DHT-11 sensor via the MQTT protocol.

 

As the ThingBerry is a highly unsupported environment for ThingWorx, please see this blog post for all related warnings.

 

Install MQTT broker on the ThingBerry

 

To install mosquitto as a MQTT broker, log in to the ThingBerry and run

 

sudo apt-get install mosquitto

 

This will provide a basic broker installation, which is good enough for this example.

MQTT clients (including ThingWorx) will connect to this broker to exchange messages.

There will be no added security like encrypted traffic shown in this example, it's however good practise to secure MQTT broker / client connections.

 

While the ESP8266 module is publishing information, ThingWorx will subscribe to the corresponding topics to update its internal property values with what is sent by the ESP8266 module.

 

For more information on MQTT, how to configure it for ThingWorx or more security relevant information also see

 

 

Configure the ESP8266

 

There are too many instructions on the web already on how to initially setup the ESP8266 and use it with the Arduino IDE. I'll therefore just refer to Google which covers the topic more extensively than I ever could.

 

All coding in this example is done in the Arduino IDE and is pushed to the ESP8266 (NodeMCU) via USB. For this you might need to install a CH340g USB driver for the NodeMCU.

 

In the Arduino IDE under Tools, I have set my environment to

 

  • Board: NodeMCU 1.0 (ESP-12E Module)
  • CPU Frequency: 80 MHz
  • Flash Size: 4M (3M SPIFFS)
  • Upload Speed: 115200
  • Port: COM3

 

Under Sketch > Include Library > Manage Libraries add / install the following libraries:

 

  • DHT sensor library by Adafruit
  • Adafruit Unified Sensor by Adafruit
  • PubSubClient by Nick O'Leary

 

These bring the libraries necessary to read data from the DHT-11 sensor and to configure the ESP8266 as MQTT client.

Wiring the DHT-11 sensor

 

The following image shows the PINs on the ESP8266

 

 

I'm using a DHT-11 sensor with cables included and already fixed to a board with 3 PINs.

In case you're using a different version, there might be additional components and wiring required, like a resistor etc.

Google might help here as well.

 

 

Ensure that neither board nor sensor are plugged in, and the ESP8266 is powered off.

 

To hook the sensor up to the ESP8266, join

 

  • ( - ) to GND
  • ( + ) to 3.3V
  • (out) to D3

 

After all the connections are made, connect the ESP8266 via USB to a computer / laptop with the Arudino IDE configured.

Coding

 

In the Arduino IDE use the following code - adjust the WIFI settings and the MQTT broker configuration.

Ensure to rename the ESP_xx name / topic to something more meaningful, e.g. a specific device name (or just leave it as is if in doubt).

 

Use the ssid and wpa_passphrase from the hostapd.conf used to configure the ThingBerry as WIFI hotspot.

 

Copy&paste the code below into the Arduino IDE, verify it and upload it to the ESP8266.

 

 

If searching for a WIFI connection, the device's blue LED will blink.

A successful connection to the broker and publishing the values will result in a static blue LED.

In case the LED is off, the connection to the broker is lost or messages cannot be published.

 

For troubleshooting, use the Serial Monitor function (at 115200 baud) in the Arduino IDE.

In case sensor data cannot be read but the wiring is correct and the code addressing the correct PIN verify the sensor is indeed working. It took me a long time to figure out that the first sensor I used was a defective device.

 

The current configuration sends updates every 10 seconds - longer intervals might make more sense, but can trigger a timeout for the MQTT broker. In this case the program will re-connect automatically and log corresponding messages in the Serial Monitor. This might seem like an error, but is indeed intended behavior by the code and the MQTT broker.

 

Configure MQTT Thing in ThingWorx

 

Create a new Thing in ThingWorx based on the MQTT Template.

Add two properties:

 

  • temperature
  • humidity

 

Both set to persistent and logged and Data Change Type to ALWAYS.

Also configure a Value Stream to log a history of values.

 

In the configuration, add two more subscriptions. Activate the "subscribe" checkbox and map name (local property) to topic (MQTT topic), e.g.

 

  • name = temperature; topic = ESP_xx/temp
  • name = humidity; topic = ESP_xx/hum

 

Ensure the correct servernames, ports etc. are configured (an empty servername will use the localhost).

 

Save the configuration.

Property values should now be updated from the MQTT broker, depending on what the device is sending.

 

Code

 

#include "DHT.h"
#include "PubSubClient.h"
#include "ESP8266WiFi.h"

/*
*
* Configure parameters for sensor and network / MQTT connections
*
*/

// setup DHT 11 pin and sensor

#define DHTPin D3
#define DHTTYPE DHT11

// setup WiFi credentials

#define WLAN_SSID "mySSID"
#define WLAN_PASS "WIFIpassword"

// setup MQTT

#define MQTTBROKER "mqttbrokerhostname"
#define MQTTPORT 1883

// setup built-in blue LED

#define LED 2

/*
* ============================================================
*
* DO NOT CHANGE ANYTHING BELOW
* (unless you know what you're doing)
*
*/

// initiate DHT

DHT dht(DHTPin, DHTTYPE);

// initiate MQTT client

WiFiClient wifiClient;
PubSubClient client(MQTTBROKER, MQTTPORT, wifiClient);

/*
* setup
*/

void setup() {

  // switch off internal LED

  pinMode(LED, OUTPUT);
  digitalWrite(LED, HIGH);

  // start serial monitor

  Serial.begin(115200);

  // start DHT

  dht.begin();

  // start WiFi

  WiFi.begin(WLAN_SSID, WLAN_PASS);

}

/*
* the loop
*/

void loop() {

  // while not connected to WiFi, print "."
  // after connection exit the loop
  // blink LED while having no WiFi signal

  boolean wifiReconnect = false;

  while (WiFi.status() != WL_CONNECTED) {
  
    digitalWrite(LED, LOW);
  
    delay(200);
  
    Serial.print(".");
  
    digitalWrite(LED, HIGH);
  
    delay(300);

    wifiReconnect = true;
  
  }

  // if WiFi has reconnected, print new connection information and turn on LED

  if (wifiReconnect == true) {
  
    // print connection information and local IP address, mac address

    Serial.println();
    Serial.println("WiFi connected");
    Serial.println(WiFi.localIP());
    Serial.println(WiFi.macAddress());
    Serial.println();

    // turn on built-in LED to indiciate successful WiFi connection

    digitalWrite(LED, LOW);

  }

  // if MQTT client is not connected, connect again
  // turn on built-in LED to indicate a successful connection

  if (!client.connected()) {

    Serial.println("Disconnected from MQTT server... trying to connect");

    if (client.connect("ESP_xx")) {

      Serial.println("Connected to MQTT server");
      Serial.println("Topic = ESP_xx");
    
      digitalWrite(LED, LOW);
    
    } else {

      Serial.println("MQTT connection failed");

      digitalWrite(LED, HIGH);
    
    }

    Serial.println();
  
  }

  // read temperature and humidity from sensor

  float t = dht.readTemperature();
  float h = dht.readHumidity();

  if (isnan(t) || isnan(h)) {

    // if temperature or humidity is not a number, print error

    Serial.println("Failed retrieving data from DHT sensor");
  
  } else {

    // print temperature and humidity

    Serial.print(t);
    Serial.print("° - ");
    Serial.print(h);
    Serial.print("%");
    Serial.println();

    // only send values to MQTT broker, if client is connected

    if (client.connected()) {

      // boolean to check for errors during payload transfer

      bool isError = false;

      // create payload and publish values via MQTT client
      // use buffer to convert float to char*

      char buffer[10];

      dtostrf(t, 0, 0, buffer);
    
      if (client.publish("ESP_xx/temp", buffer)) {
      
        Serial.print("  published /temp  ");
      
      } else {
      
        Serial.print("  failed /temp  ");
        isError = true;
      
      }
       
      dtostrf(h, 0, 0, buffer);
    
      if (client.publish("ESP_xx/hum", buffer)) {
      
        Serial.print("  published /hum  ");
      
      } else {
      
        Serial.print("  failed /hum  ");
        isError = true;
      
      }

      Serial.println();
    
      // on error, turn off LED

      if (isError == true) {

        digitalWrite(LED, HIGH);

      } else {
      
        digitalWrite(LED, LOW);
      
      }

    }
  
  }

  // sleep for 10 seconds
  // if sleep > default mosquitto timeout : a reconnect is forced for each update-cycle

  delay(10000);
  
}