cancel
Showing results for 
Search instead for 
Did you mean: 
cancel
Showing results for 
Search instead for 
Did you mean: 

Community Tip - Have a PTC product question you need answered fast? Chances are someone has asked it before. Learn about the community search. X

Connect an Arduino Developer Board

100% helpful (1/1)

 

Connect an ESP8266 WiFi module using the Arduino programming environment and the ThingWorx REST API.

 

This information was created for a previous version of ThingWorx and may not be fully accurate. Report any issues with this article here.

 

Guide Concept

 

This project will introduce the utilities ThingWorx provides for connections to an Adafruit Feather.

 

Following the steps in this guide, you will have a fully configured setup between your Adafruit Feather and the ThingWorx platform to begin your IoT development.

 

We will teach you how to utilize the ThingWorx REST API and the Arduino programming language to connect your Adafruit Feather for IoT application development.

 

You'll learn how to

 

  • Connect an ESP8266 WiFi module to a ThingWorx server
  • Use the Arduino programming environment with the ThingWorx REST API

 

NOTE:  The estimated time to complete this guide is 30 minutes. 

 

 

Step 1: Install Software

 

Arduino

 

There are three pieces of software to install before getting started with the ThingWorx-specfic code:

  1. Install FTDI USB driver.
  2. If you have connected development boards to your PC in the past you probably already have this installed. The latest Arduino IDE full install will also install the driver.

    NOTE: SparkFun has an excellent FTDI Driver Installation guide.

 

3. Arduino IDE - version 1.6.4 or later recommended.

4. Install ESP8266 addon into Arduino IDE.

5. The SparkFun Setting Up the Arduino IDE Tutorial is a great guide to getting started with their board.

6. Adafruit also has a great with their board Testing a Wifi Connection Tutorial.

 

When everything is set-up correctly and you are able to upload and see the Blink demo flashing the LED on the board you are ready to move to the next step.

 

ThingWorx Foundation Server

 

  1. Start, and Launch your ThingWorx Foundation server.
  2. Log into Composer.  You will need a ThingWorx appKey to authorize the board.  Follow these instructions in Create an Application Key to create an appKey that you will copy into the source code in the next step.

 

 

 

Step 2: Set up Arduino IDE, Developer Board, and ThingWorx Server

 

Once you are able to run the blink test sketch, your IDE and board are set-up correctly. To learn how to run the blink test, read the SparkFun Board Instructions and the Adafruit board instructions.

 

Arduino IDE

 

Before you will be able to run the code below that connects a developement board to a ThingWorx Foundation server, you will need to modify the code with four pieces of information specific to your environment. You will need:

 

  1. A WiFi access point SSID
  2. The correct password for the WiFi access point
  3. The IP address or URL of a ThingWorx Foundation Server
  4. A valid appKey created by your ThingWorx Foundation Server. To create an appKey, follow these instructions to Create An Application Key

 

Create a new sketch in the Arduino IDE then copy and paste the code below into the IDE.

 

Modify the WiFi Definitions and the ThingWorx server definitions shown in the code with your specficic information then save the sketch with a new name. The next step will describe what you should see when you upload and run the code on your developer board.

 

/**
 * 
 * ESP8266_ThingWorx_REST_Demo.ino
 *
 *  
 *  (c) PTC, Inc. 2016-2020
 *
 */

#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <WiFiClientSecureBearSSL.h>

//////////////////////
// WiFi Definitions //
//////////////////////
const char WiFiSSID[] = "Liberty454"; // WiFi access point SSID
const char WiFiPSK[] = "Flutie22"; // WiFi password - empty string for open access points

//////////////////////////////////////////////
// ThingWorx server definitions            //
//  modify for a specific platform instance //
//////////////////////////////////////////////
const char TWPlatformBaseURL[] = "https://pp-2007011431nt.devportal.ptc.io";
const char appKey[] = "2d4e9440-3e51-452f-a057-b55d45289264";

////////////////////////////////////////////////////////
// Pin Definitions - board specific for Adafruit board//
////////////////////////////////////////////////////////
const int RED_LED = 0; // Thing's onboard, red LED - 
const int BLUE_LED = 2; // Thing's onboard, blue LED
const int ANALOG_PIN = A0; // The only analog pin on the Thing

const int OFF = HIGH;
const int ON = LOW;

// this will set as the Accept header for all the HTTP requests to the ThingWorx server
// valid values are: application/json, text/xml, text/csv, text/html (default)
#define ACCEPT_TYPE "text/csv"  

/////////////////////
//Attempt to make a WiFi connection. Checks if connection has been made once per second until timeout is reached
//returns TRUE if successful or FALSE if timed out
/////////////////////
boolean connectToWiFi(int timeout){

  Serial.println("Connecting to: " + String(WiFiSSID));
  WiFi.begin(WiFiSSID, WiFiPSK);

  // loop while WiFi is not connected waiting one second between checks
  uint8_t tries = 0; // counter for how many times we have checked
  while ((WiFi.status() != WL_CONNECTED) && (tries < timeout) ){ // stop checking if connection has been made OR we have timed out
    tries++;
    Serial.printf(".");// print . for progress bar
    Serial.println(WiFi.status());
    delay(2000);
  }
  Serial.println("*"); //visual indication that board is connected or timeout

  if (WiFi.status() == WL_CONNECTED){ //check that WiFi is connected, print status and device IP address before returning
    Serial.println("WiFi connected");
    Serial.println("IP address: ");
    Serial.println(WiFi.localIP());
    return true;
  } else { //if WiFi is not connected we must have exceeded WiFi connection timeout
    return false;
  }

}

//////////////////////////
//create a name for the board that is probably unique by appending last two bytes of MAC address
//return name as a String
///////////////////////////////
String getUniqueDeviceName(){ 

    String uniqueName;
    uint8_t mac[WL_MAC_ADDR_LENGTH];
    WiFi.macAddress(mac); // WiFi does NOT need to be connected for this call
    String macID = String(mac[WL_MAC_ADDR_LENGTH - 2], HEX) +
                    String(mac[WL_MAC_ADDR_LENGTH - 1], HEX);
    macID.toUpperCase();
    uniqueName = "ESP8266Board-" + macID;
    Serial.println("DeviceID>" + uniqueName);
    return uniqueName;
}

///////////////////////////////
// make HTTP GET to a specific Thing and Propertry on a ThingWorx server
// thingName - Name of Thing on server to make GET from
// property - Property of thingName to make GET from
// returns HTTP response code from server and prints full response
///////////////////////////////
int httpGetPropertry(String thingName, String property){
    std::unique_ptr<BearSSL::WiFiClientSecure>client(new BearSSL::WiFiClientSecure);
    client->setInsecure();
    HTTPClient https;
        int httpCode = -1;
        String response = "";
        Serial.print("[httpsGetPropertry] begin...");
        String fullRequestURL = String(TWPlatformBaseURL) + "/Thingworx/Things/"+ thingName +"/Properties/"+ property +"?appKey=" + String(appKey);

        https.begin(*client,fullRequestURL);
        https.addHeader("Accept",ACCEPT_TYPE,false,false);
        Serial.println("GET URL>" + fullRequestURL +"<");
        // start connection and send HTTP header
        httpCode = https.GET();
        // httpCode will be negative on error
        if(httpCode > 0) {
            response = https.getString();
            Serial.printf("[httpGetPropertry] response code:%d body>",httpCode);
            Serial.println(response + "<\n");
        } else {
            Serial.printf("[httpGetPropertry] failed, error: %s\n\n", https.errorToString(httpCode).c_str());
        }
        https.end();
        return httpCode;

}

///////////////////////////////
// makes HTTP POST to platform to CreateThing service using input string as the new Things's name. 
// Returns server response code
///////////////////////////////
int createThing(String nameOfThing){
        std::unique_ptr<BearSSL::WiFiClientSecure>client(new BearSSL::WiFiClientSecure);
    client->setInsecure();
    HTTPClient https;
        int httpCode = -1;
        String response = "";
        Serial.print("[createThing] begin...");
        String fullRequestURL = String(TWPlatformBaseURL) + "/Thingworx/Resources/EntityServices/Services/CreateThing?appKey=" + String(appKey);
        https.begin(*client,fullRequestURL);
        https.addHeader("Accept",ACCEPT_TYPE,false,false);
        https.addHeader("Content-Type","application/json",false,false);
        Serial.println("POST URL>" + fullRequestURL + "<");
        // start connection and send HTTP header
        httpCode = https.POST("{\"name\": \""+ nameOfThing +"\",\"thingTemplateName\": \"GenericThing\"}");
        // httpCode will be negative on error
        if(httpCode > 0) {
            response = https.getString();
            Serial.printf("[createThing] response code:%d body>",httpCode);
            Serial.println(response + "<\n");

        } else {
            Serial.printf("[createThing] POST... failed, error: %s\n\n", https.errorToString(httpCode).c_str());
        }
        https.end();
        return httpCode;
}

///////////////////////////////
// make HTTP POST to ThingWorx server Thing service
// nameOfThing - Name of Thing to POST to
// endPoint - Services URL to invoke
// postBody - Body of POST to send to ThingWorx platform
// returns HTTP response code from server
///////////////////////////////
int postToThing(String nameOfThing, String endPoint, String postBody){
        std::unique_ptr<BearSSL::WiFiClientSecure>client(new BearSSL::WiFiClientSecure);
    client->setInsecure();
    HTTPClient https;
        int httpCode = -1;
        String response = "";
        Serial.print("[postToThing] begin...");
        String fullRequestURL = String(TWPlatformBaseURL) + "/Thingworx/Things/"+ nameOfThing +"/Services/"+ endPoint +"?appKey=" + String(appKey);
        Serial.println("URL>" + fullRequestURL + "<");
        https.begin(*client,fullRequestURL);
        https.addHeader("Accept",ACCEPT_TYPE,false,false);
        https.addHeader("Content-Type","application/json",false,false);
        Serial.println("[postToThing] POST body>" + postBody + "<");
        // start connection and send HTTP header
        httpCode = https.POST(postBody);
        // httpCode will be negative on error
        if(httpCode > 0) {

            response = https.getString();
            Serial.printf("[postToThing] response code:%d body>",httpCode);
            Serial.println(response + "<\n");

        } else {
            Serial.printf("[postToThing] POST... failed, error: %s\n\n", https.errorToString(httpCode).c_str());
        }
        https.end();
        return httpCode;
}

void setup() {

    pinMode(RED_LED, OUTPUT);
    pinMode(BLUE_LED, OUTPUT);

    Serial.begin(115200);
    Serial.setDebugOutput(true);
    Serial.println();
    Serial.println();
    Serial.println();

    Serial.printf("Starting...\n");

    for(uint8_t t = 4; t > 0; t--) {
        Serial.printf("   WAIT %d...\n", t);
        Serial.flush();
        delay(1000);
    }

    connectToWiFi(10);

}

void loop() {

    String thingName = getUniqueDeviceName(); //unique name for this Thing so many work on one ThingWorx server

    while (WiFi.status() == WL_CONNECTED) { //confirm WiFi is connected before looping as long as WiFi is connected

      int getResponseCode = httpGetPropertry(thingName, "SomeNumber");

      if (getResponseCode == 404){ // a 404 means connected, but either no Thing or no property

        // first we will try to create a new Thing on the platform
        int postResp = createThing(thingName); // saving the response code for retry logic in the future

        //  the newly crated Thing has to be enabled
        postResp = postToThing(thingName,"EnableThing","");  //POST to EnableThing endpoint with no body

        // after the new Thing is enabled it must be restarted
        postResp = postToThing(thingName,"RestartThing","");  //POST to RestartThing endpoint with no body

        // add a property to the Thing 3rd parameter is ugly because required quotes are escaped with backslashes
        postResp = postToThing(thingName,"AddPropertyDefinition", "{\"name\":\"SomeNumber\",\"type\":\"NUMBER\"}"); 
        //POST body contains JSON object with property name and property type 

        // after changes to a Thing's structure it must be restarted
        postResp = postToThing(thingName,"RestartThing",""); //POST to RestartThing endpoint with no body
      }

      delay(2000);

    }// end WiFi connected while loop
    Serial.printf("****Wifi connection dropped****\n");
    WiFi.disconnect(true);
    delay(10000);
    connectToWiFi(10);
}

 

 

Step 3: Run Arduino Demo

 

  1. Click on the right arrow in the Arduino IDE toolbar to upload and start the sketch.


    Arduino_upload.png

Note:The compile and upload process will take almost a minute and will show [ 100% ] when it is completed successfully.

2. After the upload is complete, click on Tools > Serial Monitor and select 115200 baud from the drop down in the lower right.     

 

 

serial_monitor.png

 

Check Connection on ThingWorx Server

 

  1. Open the Composer window of your ThingWorx Foundation server and click on the browse folder icon, then Things.

    arduino-thing.PNG

     

    You will see a Thing named "ESP8266Board-XXXX" with XXXX replaced by the last 4 digits of your boards WiFi MAC address.

  2. Click on the Thing then click the Properties and Alerts tab in the left column.
  3. Click the pencil "Set value" icon in the value column and enter a number in the text box.
  4. Click the "Check" button to set the value.

     

    AdafruitThing_setProperty.png

  5. Open the Arduino Serial monitor window, and you will see the value you just entered on the platform shown in the serial output.

 

Step 4: Next Steps

 

Congratulations! You've successfully completed the Connect an Arduino Developer Board Quickstart.

 

This guide has given you the basic tools to:

 

  • Set up Arduino IDE
  • Run Arduino demo
  • Check connection on ThingWorx Server

 

Learn More

 

We recommend the following resources to continue your learning experience:

  

Capability Guide
Connect Use REST API to Access ThingWorx
Build Data Model Introduction

 

Additional Resources

 

If you have questions, issues, or need additional information, refer to:

  

Resource Link
Community Developer Community Forum
Support REST API Help Center
Version history
Last update:
‎Dec 04, 2023 08:01 AM
Updated by:
Labels (2)
Contributors