ROHM board with IBM BlueMix Quickstart for Avnet class

Dependencies:   mbed mtsas

Fork of Dragonfly_Cellular_HTTPS_Example by MultiTech

main.cpp

Committer:
BlueShadow
Date:
2016-08-12
Revision:
4:d16e07588838
Parent:
3:ff2bf7a1ece8

File content as of revision 4:d16e07588838:

/** Combination of MultiTech HTTPS Example using json with ROHM Sennsor board and IBM Bluemix
 *
 * Configures the Sensor board for Ambient Light, cellular radio, brings up the cellular link,
 * and does HTTPS POST requests.
 * To do HTTPS requests with a certain server, the root certificate used to validate that server's certificate must be installed. See ssl_certificates.h for information on how to get the proper root certificate.
 *
 *
  *
 * The following hardware is required to successfully run this program:
 *   - MultiTech UDK2 (4" square white PCB with Arduino headers, antenna
 *     connector, micro USB ports, and 40-pin connector for Dragonfly)
 *   - MultiTech Dragonfly (1"x2" green PCB with Telit radio)
 *   - Rohm Electronics Sensor Board
 *   - Expansion board (LSM6DS0
 *     3-axis accelerometer + 3-axis gyroscope, LIS3MDL 3-axis
 *     magnetometer, HTS221 humidity and temperature sensor and LPS25HB
 *     pressure sensor)
 *
 * What this program does:
 *   - reads data from all sensors on board
 *   - prints all sensor data to debug port on a periodic basis
 *   - optionally send data to BlueMix
 *   - All data is sent to a specific location determined by the student login.
 *   - BlueMix cloud platform (user must create own account and configure a device
 *       - you need to set the "VENDOR" and "MODEL"

 *       - you need to set the "do_cloud_post" flag to true for this to
 *         work
 *
 * Setup:
 *   - Correctly insert SIM card into Dragonfly
 *   - Seat the Dragonfly on the UDK2 board
 *   - Connect an antenna to the connector on the Dragonfly labled "M"
 *   - Stack the Base Shield on the UDK2 Arduino headers
 *   - Stack the MEMs board on top of the Base Shield
 *   - Plug in the power cable
 *   - Plug a micro USB cable into the port below and slightly to the
 *     left of the Dragonfly (NOT the port on the Dragonfly)
 *
 * Go have fun and make something cool!
 *
 ************************************************************************/
/*
Sample Program Description:
   This Program will enable to Multi-Tech Dragonfly platform to utilize ROHM's Multi-sensor Shield Board.
   This program will initialize all sensors on the shield and then read back the sensor data.
   Data will then be output to the UART Debug Terminal every 1 second.

Sample Program Author:
   ROHM USDC

Additional Resources:
   ROHM Sensor Shield GitHub Repository: https://github.com/ROHMUSDC/ROHM_SensorPlatform_Multi-Sensor-Shield
 * NOTE: This example changes the baud rate of the debug port to 115200 baud!
 */

#include "mbed.h"
#include "mtsas.h"
#include "ssl_certificates.h"
#include <string>   // added for string manipulation
#include <sstream>



//-------- Customise these values -----------

#define ORG "quickstart" // your organization or "quickstart"
#define DEVICE_TYPE "dragonflytype" // use this default for quickstart or customize to your registered device type
#define DEVICE_ID "dragonfly01" // use this default for quickstart or customize to your registered device id
#define TOKEN "pauljaeger" // not used with "quickstart"
#define EVENT "myEvent" // use this default or customize to your event type
//-------- Customise the above values --------


//char BlueMix_HEADER[] = "Content-Type: application/x-www-form-urlencoded; charset=utf-8\r\n";
//char BlueMix_HEADER[] = "Content-Type: application/json";

//const char BlueMix_URL[] = "http://" ORG ".internetofthings.ibmcloud.com/api/v0002/device/types/" DEVICE_TYPE "/devices/" DEVICE_ID "/events/" EVENT;
//  replace typeID and deviceId with "" and delete ()
//  replace $eventId =  IBM will define in class.


//*****************************************************************************************************************************************************
DigitalOut Led1Out(LED1);


// This line controls the regulator's battery charger.
// BC_NCE = 0 enables the battery charger
// BC_NCE = 1 disables the battery charger
DigitalOut bc_nce(PB_2);

bool init_mtsas();
char* httpResToStr(HTTPResult res);

// The MTSSerialFlowControl object represents the physical serial link between the processor and the cellular radio.
mts::MTSSerialFlowControl* io;
// The Cellular object represents the cellular radio.
mts::Cellular* radio;

// An APN is required for GSM radios.
static const char apn[] = "iot.aer.net";

bool radio_ok = false;


#define RPR0521     //RPR0521   Ambient Light Sensor.
//Define Pins for I2C Interface
I2C i2c(I2C_SDA, I2C_SCL);
bool        RepStart = true;
bool        NoRepStart = false;

#ifdef RPR0521
int         RPR0521_addr_w = 0x70;          //7bit addr = 0x38, with write bit 0
int         RPR0521_addr_r = 0x71;          //7bit addr = 0x38, with read bit 1
char        RPR0521_ModeControl[2] = {0x41, 0xE6};
char        RPR0521_ALSPSControl[2] = {0x42, 0x03};
char        RPR0521_Persist[2] = {0x43, 0x20};
char        RPR0521_Addr_ReadData = 0x44;
char        RPR0521_Content_ReadData[6];
int         RPR0521_PS_RAWOUT = 0;                  //this is an output
float       RPR0521_PS_OUT = 0;
int         RPR0521_ALS_D0_RAWOUT = 0;
int         RPR0521_ALS_D1_RAWOUT = 0;
float       RPR0521_ALS_DataRatio = 0;
float       RPR0521_ALS_OUT = 0;                    //this is an output
float       RPR0521_ALS[2];                         // is this ok taking an int to the [0] value and float to [1]???????????
#endif

bool init_mtsas();
void ReadRPR0521_ALS ();
char* httpResToStr(HTTPResult res);


namespace patch  // I have no idea why this is in the code *********************
{
template < typename T > std::string to_string( const T& n )
{
    std::ostringstream stm ;
    stm << n ;
    return stm.str() ;
}
}


/****************************************************************************************************
// main
 ****************************************************************************************************/

int main()
{
    // Disable the battery charger unless a battery is attached.
    bc_nce = 1;

    static int post_interval_ms = 500; //************* I don't want to wait 30 seconds ************************/

    // Change the baud rate of the debug port from the default 9600 to 115200.
    Serial debug(USBTX, USBRX);

    debug.baud(115200);

    //Sets the log level to INFO, higher log levels produce more log output.
    //Possible levels: NONE, FATAL, ERROR, WARNING, INFO, DEBUG, TRACE
    mts::MTSLog::setLogLevel(mts::MTSLog::TRACE_LEVEL);



//****************************************************************************************************
//        Initialize I2C Devices ************
//****************************************************************************************************/

#ifdef RPR0521
    i2c.write(RPR0521_addr_w, &RPR0521_ModeControl[0], 2, false);
    i2c.write(RPR0521_addr_w, &RPR0521_ALSPSControl[0], 2, false);
    i2c.write(RPR0521_addr_w, &RPR0521_Persist[0], 2, false);
#endif

//****************************************************************************************************/
// Initialization Radio Section **********************************************************
//****************************************************************************************************/
    logInfo("initializing cellular radio");
    radio_ok = init_mtsas();
    if (! radio_ok) {
        while (true) {
            logError("failed to initialize cellular radio");
            wait(1);
        }
    }

    Timer post_timer;
    post_timer.start();
    int timeStamp;
    int countingLoop = 0;
    Timer loop_timer;
    loop_timer.start();

    logInfo("setting APN");
    if (radio->setApn(apn) != MTS_SUCCESS)
        logError("failed to set APN to \"%s\"", apn);
    logInfo("APN set successful");

    logInfo("bringing up the link");                  //added to the program to create a connection outside of the while(1) loop.
    if (! radio->connect()) {
        logError("failed to bring up the link");
        //return 0;
    } else {

        logInfo("Entering loop");
        while (countingLoop < 25 ) {
            if (post_timer.read_ms() > post_interval_ms  ) {            // can this be changed to seconds?
                timeStamp = post_timer.read_ms();
                logDebug("timer read %d", timeStamp);
                logDebug("timer value %d",  post_interval_ms );
                logDebug("loop count value %d",  countingLoop );

#ifdef RPR0521      //als digital
                ReadRPR0521_ALS ();
                int sensor_data = RPR0521_ALS[0];
                int proximity_data = RPR0521_ALS[1];
#else
                int sensor_data = -1;
                int proximity_data = -1;
#endif
                logDebug("\r\nPosting Light Reading: %d Proximity Reading: %d",sensor_data,proximity_data);

                logDebug("https://quickstart.internetofthings.ibmcloud.com");

//            http_tx.clear();

                logInfo("bringing up the link");

                // HTTPClient object used for HTTP requests.
                HTTPClient http;

                // Enable strict certificate validation.
                http.setPeerVerification(VERIFY_PEER);

                // Load certificates defined in ssl_certificates.h.
                // See comments in ssl_certificates.h for information on how to get and format root certificates.
                if (http.addRootCACertificate(ssl_certificates) != HTTP_OK)
                    logError("loading SSL certificates failed");

                // HTTP POST example - QUickstart

                char http_rx_buf[1024];
                char http_tx_buf[1024];

                memset(http_tx_buf, 0, sizeof(http_tx_buf));
                memset(http_rx_buf, 0, sizeof(http_rx_buf));
                snprintf(http_tx_buf, sizeof(http_tx_buf), "{ \"Light\": \"%d\" , \"Proximity\": \"%d\" }", sensor_data,proximity_data);
                logDebug("%s",http_tx_buf);
                HTTPResult res;

                // IHTTPDataIn object - will contain data received from server.
                HTTPText http_rx(http_rx_buf, sizeof(http_rx_buf));

                // IHTTPDataOut object - contains data to be posted to server.
                // HTTPJson automatically adds the JSON content-type header to the request.
                HTTPJson http_tx(http_tx_buf, strlen(http_tx_buf)+1);

                // Make a HTTP POST request to http://httpbin.org/
                res = http.post("http://quickstart.internetofthings.ibmcloud.com/api/v0002/device/types/dragonflytype/devices/dragonfly02/events/myEvent", http_tx, &http_rx);
                if (res != HTTP_OK)
                    logError("HTTPS POST to Bluemix failed [%d][%s]", res, httpResToStr(res));
                else
                    logInfo("HTTPS POST to Bluemix succeeded [%d]\r\n%s", http.getHTTPResponseCode(), http_rx_buf);

                //logInfo("finished - bringing down link");
//                radio->disconnect();
                post_timer.reset();
                countingLoop +=1;
            }
        }

        //return 0;
    }
    radio->disconnect();
    timeStamp = loop_timer.read_ms();
    logInfo("loop timer = %d", timeStamp);

    logInfo("\r\n\n\nEnd Of Line\r\n");
}


/***********************************************
  *   below are the call routines
/***********************************************/

bool init_mtsas()
{
    io = new mts::MTSSerialFlowControl(RADIO_TX, RADIO_RX, RADIO_RTS, RADIO_CTS);
    if (! io)
        return false;

    // radio default baud rate is 115200
    io->baud(115200);
    radio = mts::CellularFactory::create(io);
    if (! radio)
        return false;

    // Transport must be set properly before any TCPSocketConnection or UDPSocket objects are created
    Transport::setTransport(radio);

    return true;
}

char* httpResToStr(HTTPResult res)
{
    switch(res) {
        case HTTP_PROCESSING:
            return "HTTP_PROCESSING";
        case HTTP_PARSE:
            return "HTTP_PARSE";
        case HTTP_DNS:
            return "HTTP_DNS";
        case HTTP_PRTCL:
            return "HTTP_PRTCL";
        case HTTP_NOTFOUND:
            return "HTTP_NOTFOUND";
        case HTTP_REFUSED:
            return "HTTP_REFUSED";
        case HTTP_ERROR:
            return "HTTP_ERROR";
        case HTTP_TIMEOUT:
            return "HTTP_TIMEOUT";
        case HTTP_CONN:
            return "HTTP_CONN";
        case HTTP_CLOSED:
            return "HTTP_CLOSED";
        case HTTP_REDIRECT:
            return "HTTP_REDIRECT";
        case HTTP_OK:
            return "HTTP_OK";
        default:
            return "HTTP Result unknown";
    }
}


#ifdef RPR0521       //als digital
void ReadRPR0521_ALS ()
{
    i2c.write(RPR0521_addr_w, &RPR0521_Addr_ReadData, 1, RepStart);
    i2c.read(RPR0521_addr_r, &RPR0521_Content_ReadData[0], 6, NoRepStart);

    RPR0521_ALS[1] = (RPR0521_Content_ReadData[1]<<8) | (RPR0521_Content_ReadData[0]);
    RPR0521_ALS_D0_RAWOUT = (RPR0521_Content_ReadData[3]<<8) | (RPR0521_Content_ReadData[2]);
    RPR0521_ALS_D1_RAWOUT = (RPR0521_Content_ReadData[5]<<8) | (RPR0521_Content_ReadData[4]);
    RPR0521_ALS_DataRatio = (float)RPR0521_ALS_D1_RAWOUT / (float)RPR0521_ALS_D0_RAWOUT;

    if(RPR0521_ALS_DataRatio < (float)0.595) {
        RPR0521_ALS[0] = ((float)1.682*(float)RPR0521_ALS_D0_RAWOUT - (float)1.877*(float)RPR0521_ALS_D1_RAWOUT);
    } else if(RPR0521_ALS_DataRatio < (float)1.015) {
        RPR0521_ALS[0] = ((float)0.644*(float)RPR0521_ALS_D0_RAWOUT - (float)0.132*(float)RPR0521_ALS_D1_RAWOUT);
    } else if(RPR0521_ALS_DataRatio < (float)1.352) {
        RPR0521_ALS[0] = ((float)0.756*(float)RPR0521_ALS_D0_RAWOUT - (float)0.243*(float)RPR0521_ALS_D1_RAWOUT);
    } else if(RPR0521_ALS_DataRatio < (float)3.053) {
        RPR0521_ALS[0] = ((float)0.766*(float)RPR0521_ALS_D0_RAWOUT - (float)0.25*(float)RPR0521_ALS_D1_RAWOUT);
    } else {
        RPR0521_ALS[0] = 0;
    }
    logDebug("RPR-0521 ALS/PROX Sensor Data:\r\n");
    logDebug(" ALS = %0.2f lx\r\n", RPR0521_ALS[0]);
    logDebug(" PROX= %0.2f ADC Counts\r\n", RPR0521_ALS[1]);     //defined as a float but is an unsigned.

}
#endif