This is the initial version of the IIoT quickstart program implemented on the AT&T IoT kit.

Dependencies:   WNCInterface mbed-rtos mbed

IBM Watson IoT Platform Quickstart program using the AT&T/Avnet IoT Starter Kit

Using the AT&T Cellular IoT Starter Kit from Avnet the this program publishes temperature and/or humidity to the IBM Watson IoT Platform Quickstart site. The user can switch between temperature or humidity. The user can select which data series to display by selecting the event at the bottom of the display.

NOTE: This doc is specific to using the AT&T Cellular IoT Starter Kit which contains a FRDM-K64F from NXP. Ensure that the mbed online compiler has the platform set to FRDM-K64F.

1. Launch mbed online compiler in your browser

2. In a seperate browser Tab, goto the Avnet BluemixQS site and select the Import into Compiler button in the upper right portion of the window.

3. With the example program imported into you work-space, you have all the components needed. Simply execute the Compile button.

Expected execution outcome

Once the program is compiled and downloaded to the IoT Kit, perform the following steps:

1. Using a terminal program such as Hyperterm or Putty, connect to the Kit (select comm parameters of 115200-N81)

2. Press the `reset` button, then you should see the program start running! When it runs, the output will look similar to:

Sample Ouput

HTS221 Detected (0xBC)
  Temp  is: 89.66 F 
  Humid is: 08 %
      _____
     *     *
    *____   *____             Bluemix Quick Start example
   * *===*   *==*             using the AT&T IoT Starter Kit
  *___*===*___**  AVNET
       *======*
        *====*

This demonstration program operates the same as the original 
MicroZed IIoT Starter Kit except it only reads from the HTS221 
temp sensor (no 31855 currently present and no generated data).

Local network info...
IP address is 10.61.23.226
MAC address is 11:02:72:14:95:91
Gateway address is 10.61.23.225
Your <uniqueID> is: IoT-11027214-2016

To run the demo, go to 'https://quickstart.internetofthings.ibmcloud.com/#/'
and enter 'IoT-11027214-2016' as your device ID.  The temperature data will then be displayed
as it is received. You can switch between temperature and humidity by depressing SW2.
---------------------------------------------------------------


(0) Attempting TCP connect to quickstart.messaging.internetofthings.ibmcloud.com:1883:  Success!
(0) Attempting MQTT connect to quickstart.messaging.internetofthings.ibmcloud.com:1883: Success!
Publishing MQTT message '{"d" : {"temp" : " 90.2" }}' (27)

3. Once the program is running, go to https://quickstart.internetofthings.ibmcloud.com/# and enter your device ID (this is IoT-11027214-2016 in the above sample output) and select the GO button. As data is received it will automatically graphed and displayed below the graph. If you want to switch and display humidity rather than temperature (temperature is the default), depress SW2 on the FRDM-K64F board and select humid in the data under the graph.

License

This library is released under the Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License and may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

main.cpp

Committer:
root@developer-sjc-cyan-compiler.local.mbed.org
Date:
2016-11-17
Revision:
2:d6c16dd96091
Parent:
1:d8d4c57daaad

File content as of revision 2:d6c16dd96091:

//#define MQTT_DEBUG

//org=9k09br
//type=cc
//id=Mz-1107199-7010
//auth-method=token
//auth-token=SecurityToekn99
//

#include "mbed.h"
#include "MQTTClient.h"
#include "MQTTFormat.h"

//#include "MQTTEthernet.h"
#include "MQTTWNCInterface.h"
#include "rtos.h"
#include "k64f.h"
#include "HTS221.h"

I2C i2c(PTC11, PTC10);         //SDA, SCL -- define the I2C pins being used
MODSERIAL pc(USBTX,USBRX,256,256);

#include "hardware.h"


// connect options for MQTT broker
#define CLIENT      "quickstart"
#define URL         CLIENT ".messaging.internetofthings.ibmcloud.com"
#define CONFIGTYPE  "d:" CLIENT ":MicroZed:%s"

#define PORT        1883                           // MQTT broker port number
#define CLIENTID    "96430312d8f7"                 // use MAC address without colons
#define USERNAME ""                                    // not required for demo app
#define PASSWORD ""                                    // not required for demo app
#define PUBLISH_TOPIC "iot-2/evt/status/fmt/json"              // MQTT topic
#define SUBSCRIBTOPIC "iot-2/cmd/+/fmt/+"

#define HTS221_STR  "  Temp  is: %0.2f F \n\r  Humid is: %02d %%\n\r"

Queue<uint32_t, 6> messageQ;

struct rcvd_errs{
    int err;
    char *er;
    };
    
rcvd_errs response[] = {
    200, "200 OK - Request has succeeded.",
    201, "201 Created - Request has been fulfilled and a new resource created.",
    202, "202 Accepted - The request has been accepted for processing, but the processing will be completed asynchronously",
    204, "204 No Content - The server has fulfilled the request but does not need to return an entity-body.",
    400, "400 Bad Request - Bad request (e.g. sending an array when the API is expecting a hash.)",
    401, "401 Unauthorized - No valid API key provided.",
    403, "403 Forbidden - You tried to access a disabled device, or your API key is not allowed to access that resource, etc.",
    404, "404 Not Found - The requested item could not be found.",
    405, "405 Method Not Allowed - The HTTP method specified is not allowed.",
    415, "415 Unsupported Media Type - The requested media type is currently not supported.",
    422, "422 Unprocessable Entity - Can result from sending invalid fields.",
    429, "429 Too Many Requests - The user has sent too many requests in a given period of time.",
    500, "500 Server errors - Something went wrong in the M2X server",
    502, "502 Server errors - Something went wrong in the M2X server",
    503, "503 Server errors - Something went wrong in the M2X server",
    504, "504 Server errors - Something went wrong in the M2X server",
    };
#define RCMAX   sizeof(response)/sizeof(rcvd_errs)

char * response_str(int rc) {
    static char *unkown = "Unknown error code...";
    int i=0;
    while( response[i].err != rc && i < RCMAX)
        i++;
    return (i<RCMAX? response[i].er : unkown);
}

// LED color control function
void controlLED(color_t led_color) {
    switch(led_color) {
        case red :
            greenLED = blueLED = 1;          
            redLED = 0.7;
            break;
        case green :
            redLED = blueLED = 1;
            greenLED = 0.7;
            break;
        case blue :
            redLED = greenLED = 1;
            blueLED = 0.7;
            break;
        case off :
            redLED = greenLED = blueLED = 1;
            break;
    }
}
    
// Switch 2 interrupt handler
void sw2_ISR(void) {
    messageQ.put((uint32_t*)22);
}

// Switch3 interrupt handler
void sw3_ISR(void) {
    messageQ.put((uint32_t*)33);
}
 
// MQTT message arrived callback function
void messageArrived(MQTT::MessageData& md) {
    MQTT::Message &message = md.message;
    printf("Receiving MQTT message:  %.*s\r\n", message.payloadlen, (char*)message.payload);
    
    if (message.payloadlen == 3) {
        if (strncmp((char*)message.payload, "red", 3) == 0)
            controlLED(red);
        
        else if(strncmp((char*)message.payload, "grn", 3) == 0)
            controlLED(green);
        
        else if(strncmp((char*)message.payload, "blu", 3) == 0)
            controlLED(blue);
        
        else if(strncmp((char*)message.payload, "off", 3) == 0)
            controlLED(off);
    }        
}

int main() {
    int rc, qStart=0, txSel=0, good = 0;
    Timer tmr;
    char* topic = PUBLISH_TOPIC;
    char clientID[100], buf[100];
    string st, uniqueID;

    HTS221 hts221;

    pc.baud(115200);
    rc = hts221.init();
    if ( rc  ) {
        pc.printf(BLU "HTS221 Detected (0x%02X)\n\r",rc);
        pc.printf(HTS221_STR, CTOF(hts221.readTemperature()), hts221.readHumidity()/10);
    }
    else {
        pc.printf(RED "HTS221 NOT DETECTED!\n\r");
    }


    // turn off LED  
    controlLED(blue);
    
    // set SW2 and SW3 to generate interrupt on falling edge 
    switch2.fall(&sw2_ISR);
    switch3.fall(&sw3_ISR);

    // initialize ethernet interface
    MQTTwnc ipstack = MQTTwnc();
    
    // get and display client network info
    WNCInterface& eth = ipstack.getEth();
    
    // construct the MQTT client
    MQTT::Client<MQTTwnc, Countdown> client = MQTT::Client<MQTTwnc, Countdown>(ipstack);
    
    char* hostname = URL;
    int port = PORT;
    st = eth.getMACAddress();
    uniqueID="IoT-";
    uniqueID += st[0];
    uniqueID += st[1];
    uniqueID += st[3];
    uniqueID += st[4];
    uniqueID += st[6];
    uniqueID += st[7];
    uniqueID += st[9];
    uniqueID += st[10];
    uniqueID += "-2016";
    
    sprintf(clientID, CONFIGTYPE, uniqueID.c_str());

    printf("      _____\r\n");
    printf("     *     *\r\n");
    printf("    *____   *____             Bluemix Quick Start example\r\n");
    printf("   * *===*   *==*             using the AT&T IoT Starter Kit\r\n");
    printf("  *___*===*___**  AVNET\r\n");
    printf("       *======*\r\n");
    printf("        *====*\r\n");
    printf("\r\n");
    printf("This demonstration program operates the same as the original \r\n");
    printf("MicroZed IIoT Starter Kit except it only reads from the HTS221 \r\n");
    printf("temp sensor (no 31855 currently present and no generated data).\r\n");
    printf("\r\n");
    printf("Local network info...\r\n");    
    printf("IP address is %s\r\n", eth.getIPAddress());
    printf("MAC address is %s\r\n", eth.getMACAddress());
    printf("Gateway address is %s\r\n", eth.getGateway());
    printf("Your <uniqueID> is: %s\r\n", uniqueID.c_str());
    printf("\r\nTo run the demo, go to 'https://quickstart.internetofthings.ibmcloud.com/#/'\r\n");
    printf("and enter '%s' as your device ID.  The temprature data will then be displayed\r\n",uniqueID.c_str());
    printf("as it is received. You can switch between temprature and humidity by depressing SW2.\r\n");
    printf("---------------------------------------------------------------\r\n");

    MQTTPacket_connectData data = MQTTPacket_connectData_initializer;       

    int tries;
    
    while( !good ) {    
        tries=0;
        // connect to TCP socket and check return code
        tmr.start();
        rc = 1;
        while( rc && tries < 3) {
            printf("\r\n\r\n(%d) Attempting TCP connect to %s:%d:  ", tries++, hostname, port);
            rc = ipstack.connect(hostname, port);
            if( rc ) {
                printf("Failed (%d)!\r\n",rc);
                while( tmr.read_ms() < 5000 ) ;
                tmr.reset();
            }
            else {
                printf("Success!\r\n");
                rc = 0;
            }
        }
        if( tries < 3 )
          tries = 0;
        else
          continue;
        
        data.willFlag = 0;  
        data.MQTTVersion = 3;

        data.clientID.cstring = clientID;
    //    data.username.cstring = USERNAME;
    //    data.password.cstring = PASSWORD;
        data.keepAliveInterval = 10;
        data.cleansession = 1;
    
        rc = 1;
        tmr.reset(); 
        while( !client.isConnected() && rc && tries < 3) {
            printf("(%d) Attempting MQTT connect to %s:%d: ", tries++, hostname, port);
            rc = client.connect(data);
            if( rc ) {
                printf("Failed (%d)!\r\n",rc);
                while( tmr.read_ms() < 5000 );
                tmr.reset();
            }
            else
                printf("Success!\r\n");
        }

        if( tries < 3 )
          tries = 0;
        else
          continue;

#if 0
//Only need to subscribe if we are not running quickstart        
        // subscribe to MQTT topic
        tmr.reset();
        rc = 1;
        while( rc && client.isConnected() && tries < 3) {
            printf("(%d) Attempting to subscribing to MQTT topic %s: ", tries, SUBSCRIBTOPIC);
            rc = client.subscribe(SUBSCRIBTOPIC, MQTT::QOS0, messageArrived);
            if( rc ) {
                printf("Failed (%d)!\r\n", rc);
                while( tmr.read_ms() < 5000 );
                tries++;
                tmr.reset();
            }
            else {
                good=1;
                printf("Subscribe successful!\r\n");
            }
        }
#else
    good = 1;
#endif
        while (!good);
    }        
    
    MQTT::Message message;
    message.qos = MQTT::QOS0;
    message.retained = false;
    message.dup = false;
    message.payload = (void*)buf;
    
    while(true) {
        osEvent switchEvent = messageQ.get(100);
      
        if( switchEvent.value.v == 22 )  //switch between sending humidity & temp
          txSel = !txSel;
          
        if( switchEvent.value.v == 33)   //user wants to run in Quickstart of Demo mode
          qStart = !qStart;
                    
        memset(buf,0x00,sizeof(buf));
        if( txSel ) {
            rc = hts221.readHumidity();
            sprintf(buf, "{\"d\" : {\"humd\" : \"%2d.%d\" }}", rc/10, rc-((rc/10)*10));
            printf("Publishing MQTT message '%s' ", (char*)message.payload);
            }
        else {
             sprintf(buf, "{\"d\" : {\"temp\" : \"%5.1f\" }}", CTOF(hts221.readTemperature()));
             printf("Publishing MQTT message '%s' ", (char*)message.payload);
            }
         message.payloadlen = strlen(buf);
         printf("(%d)\r\n",message.payloadlen);
         rc = client.publish(topic, message);
         if( rc ) {
             printf("Publish request failed! (%d)\r\n",rc);
             FATAL_WNC_ERROR(resume);
             }

        client.yield(6000);
    }           
}